codegen: be more explicit about setting giving names to allocas.

This commit is contained in:
Eduard-Mihai Burtescu 2019-09-12 19:04:30 +03:00
parent f71826e8f2
commit e9214a147b
10 changed files with 42 additions and 55 deletions

View File

@ -229,7 +229,7 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
// We instead thus allocate some scratch space... // We instead thus allocate some scratch space...
let scratch_size = cast.size(bx); let scratch_size = cast.size(bx);
let scratch_align = cast.align(bx); let scratch_align = cast.align(bx);
let llscratch = bx.alloca(cast.llvm_type(bx), "abi_cast", scratch_align); let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align);
bx.lifetime_start(llscratch, scratch_size); bx.lifetime_start(llscratch, scratch_size);
// ...where we first store the value... // ...where we first store the value...

View File

@ -387,23 +387,17 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
) )
} }
fn alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { fn alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
let mut bx = Builder::with_cx(self.cx); let mut bx = Builder::with_cx(self.cx);
bx.position_at_start(unsafe { bx.position_at_start(unsafe {
llvm::LLVMGetFirstBasicBlock(self.llfn()) llvm::LLVMGetFirstBasicBlock(self.llfn())
}); });
bx.dynamic_alloca(ty, name, align) bx.dynamic_alloca(ty, align)
} }
fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value { fn dynamic_alloca(&mut self, ty: &'ll Type, align: Align) -> &'ll Value {
unsafe { unsafe {
let alloca = if name.is_empty() { let alloca = llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED);
llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED)
} else {
let name = SmallCStr::new(name);
llvm::LLVMBuildAlloca(self.llbuilder, ty,
name.as_ptr())
};
llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
alloca alloca
} }
@ -412,16 +406,9 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
fn array_alloca(&mut self, fn array_alloca(&mut self,
ty: &'ll Type, ty: &'ll Type,
len: &'ll Value, len: &'ll Value,
name: &str,
align: Align) -> &'ll Value { align: Align) -> &'ll Value {
unsafe { unsafe {
let alloca = if name.is_empty() { let alloca = llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED);
llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED)
} else {
let name = SmallCStr::new(name);
llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len,
name.as_ptr())
};
llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint); llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
alloca alloca
} }

View File

@ -871,7 +871,7 @@ fn codegen_msvc_try(
// More information can be found in libstd's seh.rs implementation. // More information can be found in libstd's seh.rs implementation.
let i64p = bx.type_ptr_to(bx.type_i64()); let i64p = bx.type_ptr_to(bx.type_i64());
let ptr_align = bx.tcx().data_layout.pointer_align.abi; let ptr_align = bx.tcx().data_layout.pointer_align.abi;
let slot = bx.alloca(i64p, "slot", ptr_align); let slot = bx.alloca(i64p, ptr_align);
bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None); bx.invoke(func, &[data], normal.llbb(), catchswitch.llbb(), None);
normal.ret(bx.const_i32(0)); normal.ret(bx.const_i32(0));

View File

@ -276,7 +276,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let llslot = match op.val { let llslot = match op.val {
Immediate(_) | Pair(..) => { Immediate(_) | Pair(..) => {
let scratch = let scratch =
PlaceRef::alloca(&mut bx, self.fn_ty.ret.layout, "ret"); PlaceRef::alloca(&mut bx, self.fn_ty.ret.layout);
op.val.store(&mut bx, scratch); op.val.store(&mut bx, scratch);
scratch.llval scratch.llval
} }
@ -767,7 +767,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
match (arg, op.val) { match (arg, op.val) {
(&mir::Operand::Copy(_), Ref(_, None, _)) | (&mir::Operand::Copy(_), Ref(_, None, _)) |
(&mir::Operand::Constant(_), Ref(_, None, _)) => { (&mir::Operand::Constant(_), Ref(_, None, _)) => {
let tmp = PlaceRef::alloca(&mut bx, op.layout, "const"); let tmp = PlaceRef::alloca(&mut bx, op.layout);
op.val.store(&mut bx, tmp); op.val.store(&mut bx, tmp);
op.val = Ref(tmp.llval, None, tmp.align); op.val = Ref(tmp.llval, None, tmp.align);
} }
@ -925,7 +925,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
Immediate(_) | Pair(..) => { Immediate(_) | Pair(..) => {
match arg.mode { match arg.mode {
PassMode::Indirect(..) | PassMode::Cast(_) => { PassMode::Indirect(..) | PassMode::Cast(_) => {
let scratch = PlaceRef::alloca(bx, arg.layout, "arg"); let scratch = PlaceRef::alloca(bx, arg.layout);
op.val.store(bx, scratch); op.val.store(bx, scratch);
(scratch.llval, scratch.align, true) (scratch.llval, scratch.align, true)
} }
@ -940,7 +940,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't // think that ATM (Rust 1.16) we only pass temporaries, but we shouldn't
// have scary latent bugs around. // have scary latent bugs around.
let scratch = PlaceRef::alloca(bx, arg.layout, "arg"); let scratch = PlaceRef::alloca(bx, arg.layout);
base::memcpy_ty(bx, scratch.llval, scratch.align, llval, align, base::memcpy_ty(bx, scratch.llval, scratch.align, llval, align,
op.layout, MemFlags::empty()); op.layout, MemFlags::empty());
(scratch.llval, scratch.align, true) (scratch.llval, scratch.align, true)
@ -1017,7 +1017,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
cx.tcx().mk_mut_ptr(cx.tcx().types.u8), cx.tcx().mk_mut_ptr(cx.tcx().types.u8),
cx.tcx().types.i32 cx.tcx().types.i32
])); ]));
let slot = PlaceRef::alloca(bx, layout, "personalityslot"); let slot = PlaceRef::alloca(bx, layout);
self.personality_slot = Some(slot); self.personality_slot = Some(slot);
slot slot
} }
@ -1116,7 +1116,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return if fn_ret.is_indirect() { return if fn_ret.is_indirect() {
// Odd, but possible, case, we have an operand temporary, // Odd, but possible, case, we have an operand temporary,
// but the calling convention has an indirect return. // but the calling convention has an indirect return.
let tmp = PlaceRef::alloca(bx, fn_ret.layout, "tmp_ret"); let tmp = PlaceRef::alloca(bx, fn_ret.layout);
tmp.storage_live(bx); tmp.storage_live(bx);
llargs.push(tmp.llval); llargs.push(tmp.llval);
ReturnDest::IndirectOperand(tmp, index) ReturnDest::IndirectOperand(tmp, index)
@ -1124,7 +1124,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// Currently, intrinsics always need a location to store // Currently, intrinsics always need a location to store
// the result, so we create a temporary `alloca` for the // the result, so we create a temporary `alloca` for the
// result. // result.
let tmp = PlaceRef::alloca(bx, fn_ret.layout, "tmp_ret"); let tmp = PlaceRef::alloca(bx, fn_ret.layout);
tmp.storage_live(bx); tmp.storage_live(bx);
ReturnDest::IndirectOperand(tmp, index) ReturnDest::IndirectOperand(tmp, index)
} else { } else {
@ -1174,7 +1174,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
LocalRef::Operand(None) => { LocalRef::Operand(None) => {
let dst_layout = bx.layout_of(self.monomorphized_place_ty(&dst.as_ref())); let dst_layout = bx.layout_of(self.monomorphized_place_ty(&dst.as_ref()));
assert!(!dst_layout.ty.has_erasable_regions()); assert!(!dst_layout.ty.has_erasable_regions());
let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp"); let place = PlaceRef::alloca(bx, dst_layout);
place.storage_live(bx); place.storage_live(bx);
self.codegen_transmute_into(bx, src, place); self.codegen_transmute_into(bx, src, place);
let op = bx.load_operand(place); let op = bx.load_operand(place);
@ -1227,7 +1227,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
DirectOperand(index) => { DirectOperand(index) => {
// If there is a cast, we have to store and reload. // If there is a cast, we have to store and reload.
let op = if let PassMode::Cast(_) = ret_ty.mode { let op = if let PassMode::Cast(_) = ret_ty.mode {
let tmp = PlaceRef::alloca(bx, ret_ty.layout, "tmp_ret"); let tmp = PlaceRef::alloca(bx, ret_ty.layout);
tmp.storage_live(bx); tmp.storage_live(bx);
bx.store_arg_ty(&ret_ty, llval, tmp); bx.store_arg_ty(&ret_ty, llval, tmp);
let op = bx.load_operand(tmp); let op = bx.load_operand(tmp);

View File

@ -268,11 +268,13 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
debug!("alloc: {:?} ({}) -> place", local, name); debug!("alloc: {:?} ({}) -> place", local, name);
if layout.is_unsized() { if layout.is_unsized() {
let indirect_place = let indirect_place =
PlaceRef::alloca_unsized_indirect(&mut bx, layout, &name.as_str()); PlaceRef::alloca_unsized_indirect(&mut bx, layout);
bx.set_var_name(indirect_place.llval, name);
// FIXME: add an appropriate debuginfo // FIXME: add an appropriate debuginfo
LocalRef::UnsizedPlace(indirect_place) LocalRef::UnsizedPlace(indirect_place)
} else { } else {
let place = PlaceRef::alloca(&mut bx, layout, &name.as_str()); let place = PlaceRef::alloca(&mut bx, layout);
bx.set_var_name(place.llval, name);
if dbg { if dbg {
let (scope, span) = fx.debug_loc(mir::SourceInfo { let (scope, span) = fx.debug_loc(mir::SourceInfo {
span: decl.source_info.span, span: decl.source_info.span,
@ -293,14 +295,13 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
} else if memory_locals.contains(local) { } else if memory_locals.contains(local) {
debug!("alloc: {:?} -> place", local); debug!("alloc: {:?} -> place", local);
if layout.is_unsized() { if layout.is_unsized() {
let indirect_place = PlaceRef::alloca_unsized_indirect( let indirect_place = PlaceRef::alloca_unsized_indirect(&mut bx, layout);
&mut bx, bx.set_var_name(indirect_place.llval, format_args!("{:?}", local));
layout,
&format!("{:?}", local),
);
LocalRef::UnsizedPlace(indirect_place) LocalRef::UnsizedPlace(indirect_place)
} else { } else {
LocalRef::Place(PlaceRef::alloca(&mut bx, layout, &format!("{:?}", local))) let place = PlaceRef::alloca(&mut bx, layout);
bx.set_var_name(place.llval, format_args!("{:?}", local));
LocalRef::Place(place)
} }
} else { } else {
// If this is an immediate local, we do not create an // If this is an immediate local, we do not create an
@ -470,7 +471,8 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
_ => bug!("spread argument isn't a tuple?!") _ => bug!("spread argument isn't a tuple?!")
}; };
let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty), &name); let place = PlaceRef::alloca(bx, bx.layout_of(arg_ty));
bx.set_var_name(place.llval, name);
for i in 0..tupled_arg_tys.len() { for i in 0..tupled_arg_tys.len() {
let arg = &fx.fn_ty.args[idx]; let arg = &fx.fn_ty.args[idx];
idx += 1; idx += 1;
@ -558,11 +560,13 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
llarg_idx += 1; llarg_idx += 1;
let indirect_operand = OperandValue::Pair(llarg, llextra); let indirect_operand = OperandValue::Pair(llarg, llextra);
let tmp = PlaceRef::alloca_unsized_indirect(bx, arg.layout, &name); let tmp = PlaceRef::alloca_unsized_indirect(bx, arg.layout);
bx.set_var_name(tmp.llval, name);
indirect_operand.store(bx, tmp); indirect_operand.store(bx, tmp);
tmp tmp
} else { } else {
let tmp = PlaceRef::alloca(bx, arg.layout, &name); let tmp = PlaceRef::alloca(bx, arg.layout);
bx.set_var_name(tmp.llval, name);
if fx.fn_ty.c_variadic && last_arg_idx.map(|idx| arg_index == idx).unwrap_or(false) { if fx.fn_ty.c_variadic && last_arg_idx.map(|idx| arg_index == idx).unwrap_or(false) {
let va_list_did = match tcx.lang_items().va_list() { let va_list_did = match tcx.lang_items().va_list() {
Some(did) => did, Some(did) => did,

View File

@ -367,7 +367,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
// Allocate an appropriate region on the stack, and copy the value into it // Allocate an appropriate region on the stack, and copy the value into it
let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra)); let (llsize, _) = glue::size_and_align_of_dst(bx, unsized_ty, Some(llextra));
let lldst = bx.array_alloca(bx.cx().type_i8(), llsize, "unsized_tmp", max_align); let lldst = bx.array_alloca(bx.cx().type_i8(), llsize, max_align);
bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags); bx.memcpy(lldst, max_align, llptr, min_align, llsize, flags);
// Store the allocated region and the extra to the indirect place. // Store the allocated region and the extra to the indirect place.

View File

@ -71,11 +71,9 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>( pub fn alloca<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx, bx: &mut Bx,
layout: TyLayout<'tcx>, layout: TyLayout<'tcx>,
name: &str
) -> Self { ) -> Self {
debug!("alloca({:?}: {:?})", name, layout);
assert!(!layout.is_unsized(), "tried to statically allocate unsized place"); assert!(!layout.is_unsized(), "tried to statically allocate unsized place");
let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align.abi); let tmp = bx.alloca(bx.cx().backend_type(layout), layout.align.abi);
Self::new_sized(tmp, layout) Self::new_sized(tmp, layout)
} }
@ -83,13 +81,11 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
pub fn alloca_unsized_indirect<Bx: BuilderMethods<'a, 'tcx, Value = V>>( pub fn alloca_unsized_indirect<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
bx: &mut Bx, bx: &mut Bx,
layout: TyLayout<'tcx>, layout: TyLayout<'tcx>,
name: &str,
) -> Self { ) -> Self {
debug!("alloca_unsized_indirect({:?}: {:?})", name, layout);
assert!(layout.is_unsized(), "tried to allocate indirect place for sized values"); assert!(layout.is_unsized(), "tried to allocate indirect place for sized values");
let ptr_ty = bx.cx().tcx().mk_mut_ptr(layout.ty); let ptr_ty = bx.cx().tcx().mk_mut_ptr(layout.ty);
let ptr_layout = bx.cx().layout_of(ptr_ty); let ptr_layout = bx.cx().layout_of(ptr_ty);
Self::alloca(bx, ptr_layout, name) Self::alloca(bx, ptr_layout)
} }
pub fn len<Cx: ConstMethods<'tcx, Value = V>>( pub fn len<Cx: ConstMethods<'tcx, Value = V>>(

View File

@ -64,7 +64,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
// index into the struct, and this case isn't // index into the struct, and this case isn't
// important enough for it. // important enough for it.
debug!("codegen_rvalue: creating ugly alloca"); debug!("codegen_rvalue: creating ugly alloca");
let scratch = PlaceRef::alloca(&mut bx, operand.layout, "__unsize_temp"); let scratch = PlaceRef::alloca(&mut bx, operand.layout);
scratch.storage_live(&mut bx); scratch.storage_live(&mut bx);
operand.val.store(&mut bx, scratch); operand.val.store(&mut bx, scratch);
base::coerce_unsized_into(&mut bx, scratch, dest); base::coerce_unsized_into(&mut bx, scratch, dest);

View File

@ -109,13 +109,12 @@ pub trait BuilderMethods<'a, 'tcx>:
rhs: Self::Value, rhs: Self::Value,
) -> (Self::Value, Self::Value); ) -> (Self::Value, Self::Value);
fn alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value; fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
fn dynamic_alloca(&mut self, ty: Self::Type, name: &str, align: Align) -> Self::Value; fn dynamic_alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value;
fn array_alloca( fn array_alloca(
&mut self, &mut self,
ty: Self::Type, ty: Self::Type,
len: Self::Value, len: Self::Value,
name: &str,
align: Align, align: Align,
) -> Self::Value; ) -> Self::Value;

View File

@ -20,12 +20,13 @@ pub fn test() {
let _s = S; let _s = S;
// Check that the personality slot alloca gets a lifetime start in each cleanup block, not just // Check that the personality slot alloca gets a lifetime start in each cleanup block, not just
// in the first one. // in the first one.
// CHECK: [[SLOT:%[0-9]+]] = alloca { i8*, i32 }
// CHECK-LABEL: cleanup: // CHECK-LABEL: cleanup:
// CHECK: bitcast{{.*}}personalityslot // CHECK: [[BITCAST:%[0-9]+]] = bitcast { i8*, i32 }* [[SLOT]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start // CHECK-NEXT: call void @llvm.lifetime.start.{{.*}}({{.*}}, i8* [[BITCAST]])
// CHECK-LABEL: cleanup1: // CHECK-LABEL: cleanup1:
// CHECK: bitcast{{.*}}personalityslot // CHECK: [[BITCAST1:%[0-9]+]] = bitcast { i8*, i32 }* [[SLOT]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.start // CHECK-NEXT: call void @llvm.lifetime.start.{{.*}}({{.*}}, i8* [[BITCAST1]])
might_unwind(); might_unwind();
let _t = S; let _t = S;
might_unwind(); might_unwind();