From 4f7ab0e16b7f424a8c93c69d36e4fa6f70ef8f26 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 27 May 2016 13:27:56 -0400 Subject: [PATCH] Emit "no-frame-pointer-elim" attribute for closures, shims, and glue. --- src/librustc/session/mod.rs | 7 ++++++- src/librustc_trans/attributes.rs | 24 +++++++++++++----------- src/librustc_trans/callee.rs | 2 +- src/librustc_trans/closure.rs | 2 ++ src/librustc_trans/glue.rs | 2 ++ src/librustc_trans/meth.rs | 2 ++ src/librustc_trans/monomorphize.rs | 1 + 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index ab9187a835dad..100b204b50135 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -15,7 +15,7 @@ use lint; use middle::cstore::CrateStore; use middle::dependency_format; use session::search_paths::PathKind; -use session::config::PanicStrategy; +use session::config::{DebugInfoLevel, PanicStrategy}; use ty::tls; use util::nodemap::{NodeMap, FnvHashMap}; use mir::transform as mir_pass; @@ -315,6 +315,11 @@ impl Session { self.opts.debugging_opts.enable_nonzeroing_move_hints } + pub fn must_not_eliminate_frame_pointers(&self) -> bool { + self.opts.debuginfo != DebugInfoLevel::NoDebugInfo || + !self.target.target.options.eliminate_frame_pointer + } + /// Returns the symbol name for the registrar function, /// given the crate Svh and the function DefIndex. pub fn generate_plugin_registrar_symbol(&self, svh: &Svh, index: DefIndex) diff --git a/src/librustc_trans/attributes.rs b/src/librustc_trans/attributes.rs index d4930f37dcd5e..01e9970dc76c3 100644 --- a/src/librustc_trans/attributes.rs +++ b/src/librustc_trans/attributes.rs @@ -11,7 +11,6 @@ use libc::c_uint; use llvm::{self, ValueRef}; -use session::config::NoDebugInfo; pub use syntax::attr::InlineAttr; use syntax::ast; use context::CrateContext; @@ -74,25 +73,28 @@ pub fn naked(val: ValueRef, is_naked: bool) { } } -/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute]) -/// attributes. -pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) { - use syntax::attr::*; - inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs)); - +pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) { // FIXME: #11906: Omitting frame pointers breaks retrieving the value of a // parameter. - let no_fp_elim = (ccx.sess().opts.debuginfo != NoDebugInfo) || - !ccx.sess().target.target.options.eliminate_frame_pointer; - if no_fp_elim { + if ccx.sess().must_not_eliminate_frame_pointers() { unsafe { let attr = "no-frame-pointer-elim\0".as_ptr() as *const _; let val = "true\0".as_ptr() as *const _; llvm::LLVMAddFunctionAttrStringValue(llfn, llvm::FunctionIndex as c_uint, - attr, val); + attr, + val); } } +} + +/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute]) +/// attributes. +pub fn from_fn_attrs(ccx: &CrateContext, attrs: &[ast::Attribute], llfn: ValueRef) { + use syntax::attr::*; + inline(llfn, find_inline_attr(Some(ccx.sess().diagnostic()), attrs)); + + set_frame_pointer_elimination(ccx, llfn); for attr in attrs { if attr.check_name("cold") { diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index d7f565a9cd449..5b2cfbe46490d 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -381,7 +381,7 @@ pub fn trans_fn_pointer_shim<'a, 'tcx>( bare_fn_ty, "fn_pointer_shim"); let llfn = declare::define_internal_fn(ccx, &function_name, tuple_fn_ty); - + attributes::set_frame_pointer_elimination(ccx, llfn); // let (block_arena, fcx): (TypedArena<_>, FunctionContext); block_arena = TypedArena::new(); diff --git a/src/librustc_trans/closure.rs b/src/librustc_trans/closure.rs index 5e0d34c2a674d..9cc5cbbbb65cb 100644 --- a/src/librustc_trans/closure.rs +++ b/src/librustc_trans/closure.rs @@ -171,6 +171,7 @@ fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, // set an inline hint for all closures attributes::inline(llfn, attributes::InlineAttr::Hint); + attributes::set_frame_pointer_elimination(ccx, llfn); debug!("get_or_create_declaration_if_closure(): inserting new \ closure {:?}: {:?}", @@ -377,6 +378,7 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>( let function_name = symbol_names::internal_name_from_type_and_suffix(ccx, llonce_fn_ty, "once_shim"); let lloncefn = declare::define_internal_fn(ccx, &function_name, llonce_fn_ty); + attributes::set_frame_pointer_elimination(ccx, lloncefn); let (block_arena, fcx): (TypedArena<_>, FunctionContext); block_arena = TypedArena::new(); diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index 64e178bf91962..9787915840109 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -14,6 +14,7 @@ use std; +use attributes; use back::symbol_names; use llvm; use llvm::{ValueRef, get_param}; @@ -272,6 +273,7 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let fn_nm = symbol_names::internal_name_from_type_and_suffix(ccx, t, suffix); assert!(declare::get_defined_value(ccx, &fn_nm).is_none()); let llfn = declare::declare_cfn(ccx, &fn_nm, llfnty); + attributes::set_frame_pointer_elimination(ccx, llfn); ccx.available_drop_glues().borrow_mut().insert(g, fn_nm); ccx.drop_glues().borrow_mut().insert(g, llfn); diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 64ee18fccef37..4b81d993e02e1 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -10,6 +10,7 @@ use std::rc::Rc; +use attributes; use arena::TypedArena; use back::symbol_names; use llvm::{ValueRef, get_params}; @@ -91,6 +92,7 @@ pub fn trans_object_shim<'a, 'tcx>(ccx: &'a CrateContext<'a, 'tcx>, let function_name = symbol_names::internal_name_from_type_and_suffix(ccx, method_ty, "object_shim"); let llfn = declare::define_internal_fn(ccx, &function_name, method_ty); + attributes::set_frame_pointer_elimination(ccx, llfn); let (block_arena, fcx): (TypedArena<_>, FunctionContext); block_arena = TypedArena::new(); diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index b0f8edac0a623..c02dd7995f1e9 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -151,6 +151,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, _ => bug!() }; attributes::inline(lldecl, attributes::InlineAttr::Hint); + attributes::set_frame_pointer_elimination(ccx, lldecl); base::trans_ctor_shim(ccx, fn_node_id, disr, psubsts, lldecl); }