1
Fork 0

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.
This commit is contained in:
Tomasz Miąsko 2021-08-01 00:00:00 +00:00
parent 87d713ff2b
commit 838042aa4e
6 changed files with 20 additions and 12 deletions

View file

@ -497,9 +497,10 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
OperandValue::Immediate(self.to_immediate(llval, place.layout))
} else if let abi::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
let pair_ty = place.layout.llvm_type(self);
let mut load = |i, scalar: &abi::Scalar, align| {
let llptr = self.struct_gep(place.llval, i as u64);
let llptr = self.struct_gep(pair_ty, place.llval, i as u64);
let llty = place.layout.scalar_pair_element_llvm_type(self, i, false);
let load = self.load(llty, llptr, align);
scalar_load_metadata(self, load, scalar);
@ -663,9 +664,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
}
}
fn struct_gep(&mut self, ptr: &'ll Value, idx: u64) -> &'ll Value {
fn struct_gep(&mut self, ty: &'ll Type, ptr: &'ll Value, idx: u64) -> &'ll Value {
assert_eq!(idx as c_uint as u64, idx);
unsafe { llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, UNNAMED) }
unsafe { llvm::LLVMBuildStructGEP2(self.llbuilder, ty, ptr, idx as c_uint, UNNAMED) }
}
/* Casts */

View file

@ -1408,8 +1408,9 @@ extern "C" {
NumIndices: c_uint,
Name: *const c_char,
) -> &'a Value;
pub fn LLVMBuildStructGEP(
pub fn LLVMBuildStructGEP2(
B: &Builder<'a>,
Ty: &'a Type,
Pointer: &'a Value,
Idx: c_uint,
Name: *const c_char,

View file

@ -98,6 +98,7 @@ fn emit_aapcs_va_arg(
// Implementation of the AAPCS64 calling convention for va_args see
// https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst
let va_list_addr = list.immediate();
let va_list_ty = list.deref(bx.cx).layout.llvm_type(bx);
let layout = bx.cx.layout_of(target_ty);
let mut maybe_reg = bx.build_sibling_block("va_arg.maybe_reg");
@ -109,11 +110,11 @@ fn emit_aapcs_va_arg(
let gr_type = target_ty.is_any_ptr() || target_ty.is_integral();
let (reg_off, reg_top_index, slot_size) = if gr_type {
let gr_offs = bx.struct_gep(va_list_addr, 7);
let gr_offs = bx.struct_gep(va_list_ty, va_list_addr, 7);
let nreg = (layout.size.bytes() + 7) / 8;
(gr_offs, 3, nreg * 8)
} else {
let vr_off = bx.struct_gep(va_list_addr, 9);
let vr_off = bx.struct_gep(va_list_ty, va_list_addr, 9);
let nreg = (layout.size.bytes() + 15) / 16;
(vr_off, 5, nreg * 16)
};
@ -141,7 +142,7 @@ fn emit_aapcs_va_arg(
maybe_reg.cond_br(use_stack, &on_stack.llbb(), &in_reg.llbb());
let top_type = bx.type_i8p();
let top = in_reg.struct_gep(va_list_addr, reg_top_index);
let top = in_reg.struct_gep(va_list_ty, va_list_addr, reg_top_index);
let top = in_reg.load(top_type, top, bx.tcx().data_layout.pointer_align.abi);
// reg_value = *(@top + reg_off_v);