Emit "no-frame-pointer-elim" attribute for closures, shims, and glue.
This commit is contained in:
parent
36d5dc7c9b
commit
4f7ab0e16b
@ -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)
|
||||
|
@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_frame_pointer_elimination(ccx: &CrateContext, llfn: ValueRef) {
|
||||
// FIXME: #11906: Omitting frame pointers breaks retrieving the value of a
|
||||
// parameter.
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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));
|
||||
|
||||
// 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 {
|
||||
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);
|
||||
}
|
||||
}
|
||||
set_frame_pointer_elimination(ccx, llfn);
|
||||
|
||||
for attr in attrs {
|
||||
if attr.check_name("cold") {
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user