Skip to content

Commit 838042a

Browse files
committed
Prepare struct_gep for opaque pointers
Imlement struct_gep using LLVMBuildStructGEP2 which takes an explicit type argument instead of deriving it from a pointer type.
1 parent 87d713f commit 838042a

File tree

6 files changed

+20
-12
lines changed

6 files changed

+20
-12
lines changed

compiler/rustc_codegen_llvm/src/builder.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -497,9 +497,10 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
497497
OperandValue::Immediate(self.to_immediate(llval, place.layout))
498498
} else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
499499
let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
500+
let pair_ty = place.layout.llvm_type(self);
500501

501502
let mut load = |i, scalar: &abi::Scalar, align| {
502-
let llptr = self.struct_gep(place.llval, i as u64);
503+
let llptr = self.struct_gep(pair_ty, place.llval, i as u64);
503504
let llty = place.layout.scalar_pair_element_llvm_type(self, i, false);
504505
let load = self.load(llty, llptr, align);
505506
scalar_load_metadata(self, load, scalar);
@@ -663,9 +664,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
663664
}
664665
}
665666

666-
fn struct_gep(&mut self, ptr: &'ll Value, idx: u64) -> &'ll Value {
667+
fn struct_gep(&mut self, ty: &'ll Type, ptr: &'ll Value, idx: u64) -> &'ll Value {
667668
assert_eq!(idx as c_uint as u64, idx);
668-
unsafe { llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, UNNAMED) }
669+
unsafe { llvm::LLVMBuildStructGEP2(self.llbuilder, ty, ptr, idx as c_uint, UNNAMED) }
669670
}
670671

671672
/* Casts */

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1408,8 +1408,9 @@ extern "C" {
14081408
NumIndices: c_uint,
14091409
Name: *const c_char,
14101410
) -> &'a Value;
1411-
pub fn LLVMBuildStructGEP(
1411+
pub fn LLVMBuildStructGEP2(
14121412
B: &Builder<'a>,
1413+
Ty: &'a Type,
14131414
Pointer: &'a Value,
14141415
Idx: c_uint,
14151416
Name: *const c_char,

compiler/rustc_codegen_llvm/src/va_arg.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ fn emit_aapcs_va_arg(
9898
// Implementation of the AAPCS64 calling convention for va_args see
9999
// https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst
100100
let va_list_addr = list.immediate();
101+
let va_list_ty = list.deref(bx.cx).layout.llvm_type(bx);
101102
let layout = bx.cx.layout_of(target_ty);
102103

103104
let mut maybe_reg = bx.build_sibling_block("va_arg.maybe_reg");
@@ -109,11 +110,11 @@ fn emit_aapcs_va_arg(
109110

110111
let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
111112
let (reg_off, reg_top_index, slot_size) = if gr_type {
112-
let gr_offs = bx.struct_gep(va_list_addr, 7);
113+
let gr_offs = bx.struct_gep(va_list_ty, va_list_addr, 7);
113114
let nreg = (layout.size.bytes() + 7) / 8;
114115
(gr_offs, 3, nreg * 8)
115116
} else {
116-
let vr_off = bx.struct_gep(va_list_addr, 9);
117+
let vr_off = bx.struct_gep(va_list_ty, va_list_addr, 9);
117118
let nreg = (layout.size.bytes() + 15) / 16;
118119
(vr_off, 5, nreg * 16)
119120
};
@@ -141,7 +142,7 @@ fn emit_aapcs_va_arg(
141142
maybe_reg.cond_br(use_stack, &on_stack.llbb(), &in_reg.llbb());
142143

143144
let top_type = bx.type_i8p();
144-
let top = in_reg.struct_gep(va_list_addr, reg_top_index);
145+
let top = in_reg.struct_gep(va_list_ty, va_list_addr, reg_top_index);
145146
let top = in_reg.load(top_type, top, bx.tcx().data_layout.pointer_align.abi);
146147

147148
// reg_value = *(@top + reg_off_v);

compiler/rustc_codegen_ssa/src/mir/operand.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,15 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
311311
Abi::ScalarPair(ref a, ref b) => (a, b),
312312
_ => bug!("store_with_flags: invalid ScalarPair layout: {:#?}", dest.layout),
313313
};
314+
let ty = bx.backend_type(dest.layout);
314315
let b_offset = a_scalar.value.size(bx).align_to(b_scalar.value.align(bx).abi);
315316

316-
let llptr = bx.struct_gep(dest.llval, 0);
317+
let llptr = bx.struct_gep(ty, dest.llval, 0);
317318
let val = bx.from_immediate(a);
318319
let align = dest.align;
319320
bx.store_with_flags(val, llptr, align, flags);
320321

321-
let llptr = bx.struct_gep(dest.llval, 1);
322+
let llptr = bx.struct_gep(ty, dest.llval, 1);
322323
let val = bx.from_immediate(b);
323324
let align = dest.align.restrict_for_offset(b_offset);
324325
bx.store_with_flags(val, llptr, align, flags);

compiler/rustc_codegen_ssa/src/mir/place.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
103103
if offset == a.value.size(bx.cx()).align_to(b.value.align(bx.cx()).abi) =>
104104
{
105105
// Offset matches second field.
106-
bx.struct_gep(self.llval, 1)
106+
let ty = bx.backend_type(self.layout);
107+
bx.struct_gep(ty, self.llval, 1)
107108
}
108109
Abi::Scalar(_) | Abi::ScalarPair(..) | Abi::Vector { .. } if field.is_zst() => {
109110
// ZST fields are not included in Scalar, ScalarPair, and Vector layouts, so manually offset the pointer.
@@ -119,7 +120,10 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
119120
self.layout
120121
);
121122
}
122-
_ => bx.struct_gep(self.llval, bx.cx().backend_field_index(self.layout, ix)),
123+
_ => {
124+
let ty = bx.backend_type(self.layout);
125+
bx.struct_gep(ty, self.llval, bx.cx().backend_field_index(self.layout, ix))
126+
}
123127
};
124128
PlaceRef {
125129
// HACK(eddyb): have to bitcast pointers until LLVM removes pointee types.

compiler/rustc_codegen_ssa/src/traits/builder.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ pub trait BuilderMethods<'a, 'tcx>:
178178

179179
fn gep(&mut self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
180180
fn inbounds_gep(&mut self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
181-
fn struct_gep(&mut self, ptr: Self::Value, idx: u64) -> Self::Value;
181+
fn struct_gep(&mut self, ty: Self::Type, ptr: Self::Value, idx: u64) -> Self::Value;
182182

183183
fn trunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
184184
fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;

0 commit comments

Comments
 (0)