Make all allocas named so we can see where they originate

in the generated LLVM code.
This commit is contained in:
Niko Matsakis 2013-06-20 15:21:37 -04:00
parent 90843b6f58
commit 41efcdf299
14 changed files with 60 additions and 46 deletions

@ -268,7 +268,7 @@ pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
}
lit(UnitLikeStructLit(pat_id)) => {
let struct_ty = ty::node_id_to_type(bcx.tcx(), pat_id);
let datumblock = datum::scratch_datum(bcx, struct_ty, true);
let datumblock = datum::scratch_datum(bcx, struct_ty, "", true);
return single_result(datumblock.to_result(bcx));
}
lit(ConstLit(lit_id)) => {
@ -927,7 +927,7 @@ pub fn extract_vec_elems(bcx: block,
ty::mt {ty: vt.unit_ty, mutbl: ast::m_imm},
ty::vstore_slice(ty::re_static)
);
let scratch = scratch_datum(bcx, slice_ty, false);
let scratch = scratch_datum(bcx, slice_ty, "", false);
Store(bcx, slice_begin,
GEPi(bcx, scratch.val, [0u, abi::slice_elt_base])
);
@ -1095,9 +1095,9 @@ pub fn compare_values(cx: block,
match ty::get(rhs_t).sty {
ty::ty_estr(ty::vstore_uniq) => {
let scratch_lhs = alloca(cx, val_ty(lhs));
let scratch_lhs = alloca(cx, val_ty(lhs), "__lhs");
Store(cx, lhs, scratch_lhs);
let scratch_rhs = alloca(cx, val_ty(rhs));
let scratch_rhs = alloca(cx, val_ty(rhs), "__rhs");
Store(cx, rhs, scratch_rhs);
let did = cx.tcx().lang_items.uniq_str_eq_fn();
let result = callee::trans_lang_call(cx, did, [scratch_lhs, scratch_rhs], None);
@ -1636,12 +1636,12 @@ fn create_bindings_map(bcx: block, pat: @ast::pat) -> BindingsMap {
// in this case, the final type of the variable will be T,
// but during matching we need to store a *T as explained
// above
let is_move = ccx.maps.moves_map.contains(&p_id);
llmatch = alloca(bcx, llvariable_ty.ptr_to());
trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
llmatch = alloca(bcx, llvariable_ty.ptr_to(), "__llmatch");
trmode = TrByValue(alloca(bcx, llvariable_ty,
bcx.ident(ident)));
}
ast::bind_by_ref(_) => {
llmatch = alloca(bcx, llvariable_ty);
llmatch = alloca(bcx, llvariable_ty, bcx.ident(ident));
trmode = TrByRef;
}
};

@ -1012,7 +1012,7 @@ pub fn get_landing_pad(bcx: block) -> BasicBlockRef {
match bcx.fcx.personality {
Some(addr) => Store(pad_bcx, llretval, addr),
None => {
let addr = alloca(pad_bcx, val_ty(llretval));
let addr = alloca(pad_bcx, val_ty(llretval), "");
bcx.fcx.personality = Some(addr);
Store(pad_bcx, llretval, addr);
}
@ -1056,7 +1056,7 @@ pub fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef {
if ty::type_is_bot(t) {
return C_null(Type::i8p());
}
let llptr = alloc_ty(bcx, t);
let llptr = alloc_ty(bcx, t, "");
Store(bcx, v, llptr);
return llptr;
}
@ -1064,7 +1064,7 @@ pub fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef {
// Since this function does *not* root, it is the caller's responsibility to
// ensure that the referent is pointed to by a root.
pub fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef {
let llptr = alloca(cx, val_ty(v));
let llptr = alloca(cx, val_ty(v), "");
Store(cx, v, llptr);
return llptr;
}
@ -1561,20 +1561,20 @@ pub fn memzero(cx: block, llptr: ValueRef, ty: Type) {
Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]);
}
pub fn alloc_ty(bcx: block, t: ty::t) -> ValueRef {
pub fn alloc_ty(bcx: block, t: ty::t, name: &str) -> ValueRef {
let _icx = push_ctxt("alloc_ty");
let ccx = bcx.ccx();
let ty = type_of::type_of(ccx, t);
assert!(!ty::type_has_params(t), "Type has params: %s", ty_to_str(ccx.tcx, t));
let val = alloca(bcx, ty);
let val = alloca(bcx, ty, name);
return val;
}
pub fn alloca(cx: block, ty: Type) -> ValueRef {
alloca_maybe_zeroed(cx, ty, false)
pub fn alloca(cx: block, ty: Type, name: &str) -> ValueRef {
alloca_maybe_zeroed(cx, ty, name, false)
}
pub fn alloca_maybe_zeroed(cx: block, ty: Type, zero: bool) -> ValueRef {
pub fn alloca_maybe_zeroed(cx: block, ty: Type, name: &str, zero: bool) -> ValueRef {
let _icx = push_ctxt("alloca");
if cx.unreachable {
unsafe {
@ -1582,7 +1582,7 @@ pub fn alloca_maybe_zeroed(cx: block, ty: Type, zero: bool) -> ValueRef {
}
}
let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas);
let p = Alloca(initcx, ty);
let p = Alloca(initcx, ty, name);
if zero { memzero(initcx, p, ty); }
p
}
@ -1623,7 +1623,8 @@ pub fn make_return_pointer(fcx: fn_ctxt, output_type: ty::t) -> ValueRef {
llvm::LLVMGetParam(fcx.llfn, 0)
} else {
let lloutputtype = type_of::type_of(fcx.ccx, output_type);
alloca(raw_block(fcx, false, fcx.llstaticallocas), lloutputtype)
alloca(raw_block(fcx, false, fcx.llstaticallocas), lloutputtype,
"__make_return_pointer")
}
}
}

@ -505,11 +505,17 @@ pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef {
}
}
pub fn Alloca(cx: block, Ty: Type) -> ValueRef {
pub fn Alloca(cx: block, Ty: Type, name: &str) -> ValueRef {
unsafe {
if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); }
count_insn(cx, "alloca");
return llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname());
if name.is_empty() {
llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname())
} else {
str::as_c_str(
name,
|c| llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), c))
}
}
}

@ -130,10 +130,10 @@ impl FnType {
j = 1u;
get_param(llwrapfn, 0u)
} else if self.ret_ty.cast {
let retptr = alloca(bcx, self.ret_ty.ty);
let retptr = alloca(bcx, self.ret_ty.ty, "");
BitCast(bcx, retptr, ret_ty.ptr_to())
} else {
alloca(bcx, ret_ty)
alloca(bcx, ret_ty, "")
};
let mut i = 0u;

@ -600,7 +600,7 @@ pub fn trans_call_inner(in_cx: block,
let mut bcx = callee.bcx;
let ccx = cx.ccx();
let ret_flag = if ret_in_loop {
let flag = alloca(bcx, Type::bool());
let flag = alloca(bcx, Type::bool(), "__ret_flag");
Store(bcx, C_bool(false), flag);
Some(flag)
} else {
@ -675,7 +675,7 @@ pub fn trans_call_inner(in_cx: block,
unsafe {
if ty::type_needs_drop(bcx.tcx(), ret_ty) {
if ty::type_is_immediate(bcx.tcx(), ret_ty) {
let llscratchptr = alloc_ty(bcx, ret_ty);
let llscratchptr = alloc_ty(bcx, ret_ty, "__ret");
Store(bcx, llresult, llscratchptr);
bcx = glue::drop_ty(bcx, llscratchptr, ret_ty);
} else {
@ -733,7 +733,7 @@ pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: Option<expr::Dest>)
llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref())
}
} else {
alloc_ty(bcx, retty)
alloc_ty(bcx, retty, "__trans_ret_slot")
}
}
}
@ -823,7 +823,7 @@ pub fn trans_arg_expr(bcx: block,
_
}) => {
let scratch_ty = expr_ty(bcx, arg_expr);
let scratch = alloc_ty(bcx, scratch_ty);
let scratch = alloc_ty(bcx, scratch_ty, "__ret_flag");
let arg_ty = expr_ty(bcx, arg_expr);
let sigil = ty::ty_closure_sigil(arg_ty);
let bcx = closure::trans_expr_fn(
@ -895,7 +895,8 @@ pub fn trans_arg_expr(bcx: block,
arg_datum.appropriate_mode(bcx.tcx()).is_by_ref() {
debug!("by copy arg with type %s, storing to scratch",
bcx.ty_to_str(arg_datum.ty));
let scratch = scratch_datum(bcx, arg_datum.ty, false);
let scratch = scratch_datum(bcx, arg_datum.ty,
"__arg", false);
arg_datum.store_to_datum(bcx,
arg_expr.id,

@ -193,7 +193,7 @@ pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t)
}
ast::BorrowedSigil => {
let cbox_ty = tuplify_box_ty(tcx, cdata_ty);
let llbox = alloc_ty(bcx, cbox_ty);
let llbox = alloc_ty(bcx, cbox_ty, "__closure");
nuke_ref_count(bcx, llbox);
rslt(bcx, llbox)
}

@ -608,6 +608,10 @@ impl block_ {
pub fn tcx(&self) -> ty::ctxt { self.fcx.ccx.tcx }
pub fn sess(&self) -> Session { self.fcx.ccx.sess }
pub fn ident(&self, ident: ident) -> @str {
token::ident_to_str(&ident)
}
pub fn node_id_to_str(&self, id: ast::node_id) -> ~str {
ast_map::node_id_to_str(self.tcx().items, id, self.sess().intr())
}

@ -173,19 +173,19 @@ pub fn immediate_rvalue_bcx(bcx: block,
return DatumBlock {bcx: bcx, datum: immediate_rvalue(val, ty)};
}
pub fn scratch_datum(bcx: block, ty: ty::t, zero: bool) -> Datum {
pub fn scratch_datum(bcx: block, ty: ty::t, name: &str, zero: bool) -> Datum {
/*!
*
* Allocates temporary space on the stack using alloca() and
* returns a by-ref Datum pointing to it. If `zero` is true, the
* space will be zeroed when it is allocated; this is normally not
* necessary, but in the case of automatic rooting in match
* statements it is possible to have temporaries that may not get
* initialized if a certain arm is not taken, so we must zero
* them. You must arrange any cleanups etc yourself! */
* them. You must arrange any cleanups etc yourself!
*/
let llty = type_of::type_of(bcx.ccx(), ty);
let scratch = alloca_maybe_zeroed(bcx, llty, zero);
let scratch = alloca_maybe_zeroed(bcx, llty, name, zero);
Datum { val: scratch, ty: ty, mode: ByRef(RevokeClean) }
}
@ -476,7 +476,7 @@ impl Datum {
if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) {
C_null(type_of::type_of(bcx.ccx(), self.ty).ptr_to())
} else {
let slot = alloc_ty(bcx, self.ty);
let slot = alloc_ty(bcx, self.ty, "");
Store(bcx, self.val, slot);
slot
}

@ -274,7 +274,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
ty::mt { ty: unit_ty, mutbl: ast::m_imm },
ty::vstore_slice(ty::re_static));
let scratch = scratch_datum(bcx, slice_ty, false);
let scratch = scratch_datum(bcx, slice_ty, "__adjust", false);
Store(bcx, base, GEPi(bcx, scratch.val, [0u, abi::slice_elt_base]));
Store(bcx, len, GEPi(bcx, scratch.val, [0u, abi::slice_elt_len]));
DatumBlock {bcx: bcx, datum: scratch}
@ -290,7 +290,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
let tcx = bcx.tcx();
let closure_ty = expr_ty_adjusted(bcx, expr);
debug!("add_env(closure_ty=%s)", closure_ty.repr(tcx));
let scratch = scratch_datum(bcx, closure_ty, false);
let scratch = scratch_datum(bcx, closure_ty, "__adjust", false);
let llfn = GEPi(bcx, scratch.val, [0u, abi::fn_field_code]);
assert_eq!(datum.appropriate_mode(tcx), ByValue);
Store(bcx, datum.to_appropriate_llval(bcx), llfn);
@ -423,7 +423,7 @@ fn trans_to_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock {
bcx = trans_rvalue_dps_unadjusted(bcx, expr, Ignore);
return nil(bcx, ty);
} else {
let scratch = scratch_datum(bcx, ty, false);
let scratch = scratch_datum(bcx, ty, "", false);
bcx = trans_rvalue_dps_unadjusted(
bcx, expr, SaveIn(scratch.val));
@ -1687,7 +1687,7 @@ fn trans_assign_op(bcx: block,
// A user-defined operator method
if bcx.ccx().maps.method_map.find(&expr.id).is_some() {
// FIXME(#2528) evaluates the receiver twice!!
let scratch = scratch_datum(bcx, dst_datum.ty, false);
let scratch = scratch_datum(bcx, dst_datum.ty, "__assign_op", false);
let bcx = trans_overloaded_op(bcx,
expr,
callee_id,

@ -195,14 +195,15 @@ fn build_wrap_fn_(ccx: @mut CrateContext,
if needs_c_return && !ty::type_is_immediate(ccx.tcx, tys.fn_sig.output) {
let lloutputtype = type_of::type_of(fcx.ccx, tys.fn_sig.output);
fcx.llretptr = Some(alloca(raw_block(fcx, false, fcx.llstaticallocas),
lloutputtype));
lloutputtype,
""));
}
let bcx = top_scope_block(fcx, None);
let lltop = bcx.llbb;
// Allocate the struct and write the arguments into it.
let llargbundle = alloca(bcx, tys.bundle_ty);
let llargbundle = alloca(bcx, tys.bundle_ty, "__llargbundle");
arg_builder(bcx, tys, llwrapfn, llargbundle);
// Create call itself.
@ -732,7 +733,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext,
let llsrcval = get_param(decl, first_real_arg);
let llsrcptr = if ty::type_is_immediate(ccx.tcx, in_type) {
let llsrcptr = alloca(bcx, llintype);
let llsrcptr = alloca(bcx, llintype, "__llsrcptr");
Store(bcx, llsrcval, llsrcptr);
llsrcptr
} else {

@ -132,7 +132,7 @@ pub fn free_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block {
ty::ty_evec(_, ty::vstore_box) |
ty::ty_estr(ty::vstore_box) |
ty::ty_opaque_closure_ptr(_) => {
let vp = alloca(bcx, type_of(bcx.ccx(), t));
let vp = alloca(bcx, type_of(bcx.ccx(), t), "");
Store(bcx, v, vp);
free_ty(bcx, vp, t)
}

@ -57,7 +57,7 @@ impl Reflector {
let bcx = self.bcx;
let str_vstore = ty::vstore_slice(ty::re_static);
let str_ty = ty::mk_estr(bcx.tcx(), str_vstore);
let scratch = scratch_datum(bcx, str_ty, false);
let scratch = scratch_datum(bcx, str_ty, "", false);
let len = C_uint(bcx.ccx(), s.len() + 1);
let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), Type::i8p());
Store(bcx, c_str, GEPi(bcx, scratch.val, [ 0, 0 ]));

@ -332,7 +332,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::e
let llptrval = PointerCast(bcx, llptrval, Type::i8p());
let llsizeval = C_uint(bcx.ccx(), s.len());
let typ = ty::mk_estr(bcx.tcx(), ty::vstore_uniq);
let lldestval = scratch_datum(bcx, typ, false);
let lldestval = scratch_datum(bcx, typ, "", false);
let bcx = callee::trans_lang_call(
bcx,
bcx.tcx().lang_items.strdup_uniq_fn(),
@ -454,7 +454,7 @@ pub fn write_content(bcx: block,
let loop_counter = {
// i = 0
let i = alloca(loop_bcx, bcx.ccx().int_type);
let i = alloca(loop_bcx, bcx.ccx().int_type, "__i");
Store(loop_bcx, C_uint(bcx.ccx(), 0), i);
Br(loop_bcx, cond_bcx.llbb);

@ -120,7 +120,7 @@ fn root(datum: &Datum,
// First, root the datum. Note that we must zero this value,
// because sometimes we root on one path but not another.
// See e.g. #4904.
let scratch = scratch_datum(bcx, datum.ty, true);
let scratch = scratch_datum(bcx, datum.ty, "__write_guard", true);
datum.copy_to_datum(bcx, INIT, scratch);
let cleanup_bcx = find_bcx_for_scope(bcx, root_info.scope);
add_clean_temp_mem_in_scope(cleanup_bcx, root_info.scope, scratch.val, scratch.ty);
@ -135,7 +135,8 @@ fn root(datum: &Datum,
// scratch.val will be NULL should the cleanup get
// called without the freezing actually occurring, and
// return_to_mut checks for this condition.
let scratch_bits = scratch_datum(bcx, ty::mk_uint(), false);
let scratch_bits = scratch_datum(bcx, ty::mk_uint(),
"__write_guard_bits", false);
let freeze_did = match freeze_kind {
DynaImm => bcx.tcx().lang_items.borrow_as_imm_fn(),