about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-05-30 11:01:55 -0700
committerbors <bors@rust-lang.org>2016-05-30 11:01:55 -0700
commitb522b25a41967f7aa6694767dc85745692844259 (patch)
treeae0fa31739153094496b82d5c5b7f49bc963a4dc /src
parentf3bfa313ecf557b9684568f6a2acd42cd67cc1bc (diff)
parent4f7ab0e16b7f424a8c93c69d36e4fa6f70ef8f26 (diff)
downloadrust-b522b25a41967f7aa6694767dc85745692844259.tar.gz
rust-b522b25a41967f7aa6694767dc85745692844259.zip
Auto merge of #33909 - michaelwoerister:frame-pointer-fix, r=nikomatsakis
Emit "no-frame-pointer-elim" attribute for closures, shims, and glue.

This will hopefully let `perf` give better backtraces.
r? @nikomatsakis
Diffstat (limited to 'src')
-rw-r--r--src/librustc/session/mod.rs7
-rw-r--r--src/librustc_trans/attributes.rs24
-rw-r--r--src/librustc_trans/callee.rs2
-rw-r--r--src/librustc_trans/closure.rs2
-rw-r--r--src/librustc_trans/glue.rs2
-rw-r--r--src/librustc_trans/meth.rs2
-rw-r--r--src/librustc_trans/monomorphize.rs1
7 files changed, 27 insertions, 13 deletions
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index ab9187a835d..100b204b501 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 d4930f37dcd..01e9970dc76 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 d7f565a9cd4..5b2cfbe4649 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 5e0d34c2a67..9cc5cbbbb65 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 64e178bf919..97879158401 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 64ee18fccef..4b81d993e02 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 b0f8edac0a6..c02dd7995f1 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);
         }