From 98258e3edffbf7ec149145023b03eb9ad76c1e95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Steinbrink?= Date: Wed, 12 Aug 2015 07:33:17 +0200 Subject: [PATCH] Never create allocas for indirect function arguments The assertion that argument debuginfo always has to be assigned to allocas only exists in rustc, not in LLVM. The reason for that assertion might have been that we used to created bad debuginfo for closures which did indeed lead to errors when we skipped the alloca, but this was fixed in commit 218eccf "Fix de-deduplication for closure debuginfo". So now we can always skip the alloca for indirect arguments, even when generating debuginfo. --- src/librustc_trans/trans/base.rs | 17 +++++++++-------- .../trans/debuginfo/metadata.rs | 19 ++++++++++++------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 716b129081724..e3d4b6b7ff899 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -43,7 +43,7 @@ use middle::pat_util::simple_identifier; use middle::subst::Substs; use middle::ty::{self, Ty, HasTypeFlags}; use rustc::ast_map; -use session::config::{self, NoDebugInfo, FullDebugInfo}; +use session::config::{self, NoDebugInfo}; use session::Session; use trans::_match; use trans::adt; @@ -1370,12 +1370,11 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>, // the event it's not truly needed. let mut idx = fcx.arg_offset() as c_uint; for (i, &arg_ty) in arg_tys.iter().enumerate() { + let mut indirect_arg = type_of::arg_is_indirect(bcx.ccx(), arg_ty); let arg_datum = if !has_tupled_arg || i < arg_tys.len() - 1 { - if type_of::arg_is_indirect(bcx.ccx(), arg_ty) - && bcx.sess().opts.debuginfo != FullDebugInfo { + if indirect_arg { // Don't copy an indirect argument to an alloca, the caller - // already put it in a temporary alloca and gave it up, unless - // we emit extra-debug-info, which requires local allocas :(. + // already put it in a temporary alloca and gave it up let llarg = get_param(fcx.llfn, idx); idx += 1; bcx.fcx.schedule_lifetime_end(arg_scope_id, llarg); @@ -1450,11 +1449,13 @@ pub fn create_datums_for_fn_args<'a, 'tcx>(mut bcx: Block<'a, 'tcx>, bcx.fcx.lllocals.borrow_mut().insert(pat.id, arg_datum); bcx } else { - // General path. Copy out the values that are used in the - // pattern. + // General path. Copy out the values that are used in the pattern. + // Since we're copying the values out, the argument is not indirect + // as far as debug info is concerned + indirect_arg = false; _match::bind_irrefutable_pat(bcx, pat, arg_datum.match_input(), arg_scope_id) }; - debuginfo::create_argument_metadata(bcx, &args[i]); + debuginfo::create_argument_metadata(bcx, &args[i], indirect_arg); } bcx diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 0be155b772738..63d120d2b09f9 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -2078,7 +2078,7 @@ pub fn create_match_binding_metadata<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, /// This function assumes that there's a datum for each pattern component of the /// argument in `bcx.fcx.lllocals`. /// Adds the created metadata nodes directly to the crate's IR. -pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { +pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg, indirect: bool) { if bcx.unreachable.get() || fn_should_be_ignored(bcx.fcx) || bcx.sess().opts.debuginfo != FullDebugInfo { @@ -2103,11 +2103,6 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { } }; - if unsafe { llvm::LLVMIsAAllocaInst(datum.val) } == ptr::null_mut() { - bcx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \ - Referenced variable location is not an alloca!"); - } - let argument_index = { let counter = &bcx .fcx @@ -2119,11 +2114,21 @@ pub fn create_argument_metadata(bcx: Block, arg: &ast::Arg) { argument_index }; + let deref = unsafe { [llvm::LLVMDIBuilderCreateOpDeref()] }; + let access = if indirect { + VariableAccess::IndirectVariable { + alloca: datum.val, + address_operations: &deref, + } + } else { + VariableAccess::DirectVariable { alloca: datum.val } + }; + declare_local(bcx, var_ident.node.name, datum.ty, scope_metadata, - VariableAccess::DirectVariable { alloca: datum.val }, + access, VariableKind::ArgumentVariable(argument_index), span); })