auto merge of #10127 : thestinger/rust/cold, r=pcwalton
This allows a function to marked as infrequently called, resulting in any branch calling it to be considered colder.
This commit is contained in:
commit
671ab42a3b
|
@ -693,6 +693,8 @@ pub mod llvm {
|
||||||
pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint);
|
pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint);
|
||||||
pub fn LLVMRemoveReturnAttribute(Fn: ValueRef, PA: c_uint);
|
pub fn LLVMRemoveReturnAttribute(Fn: ValueRef, PA: c_uint);
|
||||||
|
|
||||||
|
pub fn LLVMAddColdAttribute(Fn: ValueRef);
|
||||||
|
|
||||||
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef,
|
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef,
|
||||||
PA: c_ulonglong,
|
PA: c_ulonglong,
|
||||||
HighPA: c_ulonglong);
|
HighPA: c_ulonglong);
|
||||||
|
|
|
@ -202,19 +202,21 @@ pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
|
||||||
f
|
f
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_extern_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
|
fn get_extern_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
|
||||||
name: &str) -> ValueRef {
|
name: &str, did: ast::DefId) -> ValueRef {
|
||||||
match ccx.externs.find_equiv(&name) {
|
match ccx.externs.find_equiv(&name) {
|
||||||
Some(n) => return *n,
|
Some(n) => return *n,
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
let f = decl_rust_fn(ccx, inputs, output, name);
|
let f = decl_rust_fn(ccx, inputs, output, name);
|
||||||
|
do csearch::get_item_attrs(ccx.tcx.cstore, did) |meta_items| {
|
||||||
|
set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x)).to_owned_vec(), f)
|
||||||
|
}
|
||||||
ccx.externs.insert(name.to_owned(), f);
|
ccx.externs.insert(name.to_owned(), f);
|
||||||
f
|
f
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decl_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
|
fn decl_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t, name: &str) -> ValueRef {
|
||||||
name: &str) -> ValueRef {
|
|
||||||
let llfty = type_of_rust_fn(ccx, inputs, output);
|
let llfty = type_of_rust_fn(ccx, inputs, output);
|
||||||
let llfn = decl_cdecl_fn(ccx.llmod, name, llfty);
|
let llfn = decl_cdecl_fn(ccx.llmod, name, llfty);
|
||||||
|
|
||||||
|
@ -481,6 +483,10 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
|
||||||
if contains_name(attrs, "no_split_stack") {
|
if contains_name(attrs, "no_split_stack") {
|
||||||
set_no_split_stack(llfn);
|
set_no_split_stack(llfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if contains_name(attrs, "cold") {
|
||||||
|
unsafe { llvm::LLVMAddColdAttribute(llfn) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_always_inline(f: ValueRef) {
|
pub fn set_always_inline(f: ValueRef) {
|
||||||
|
@ -840,7 +846,7 @@ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t) ->
|
||||||
ty::ty_bare_fn(ref fn_ty) => {
|
ty::ty_bare_fn(ref fn_ty) => {
|
||||||
match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
|
match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
|
||||||
Some(Rust) | Some(RustIntrinsic) => {
|
Some(Rust) | Some(RustIntrinsic) => {
|
||||||
get_extern_rust_fn(ccx, fn_ty.sig.inputs, fn_ty.sig.output, name)
|
get_extern_rust_fn(ccx, fn_ty.sig.inputs, fn_ty.sig.output, name, did)
|
||||||
}
|
}
|
||||||
Some(*) | None => {
|
Some(*) | None => {
|
||||||
let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
|
let c = foreign::llvm_calling_convention(ccx, fn_ty.abis);
|
||||||
|
@ -851,7 +857,7 @@ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::DefId, t: ty::t) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ty_closure(ref f) => {
|
ty::ty_closure(ref f) => {
|
||||||
get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name)
|
get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name, did)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let llty = type_of(ccx, t);
|
let llty = type_of(ccx, t);
|
||||||
|
|
|
@ -57,6 +57,7 @@ pub fn clear_task_borrow_list() {
|
||||||
let _ = try_take_task_borrow_list();
|
let _ = try_take_task_borrow_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) -> ! {
|
unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) -> ! {
|
||||||
debug_borrow("fail_borrowed: ", box, 0, 0, file, line);
|
debug_borrow("fail_borrowed: ", box, 0, 0, file, line);
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,13 @@ use libc::{c_char, size_t, uintptr_t};
|
||||||
use rt::task;
|
use rt::task;
|
||||||
use rt::borrowck;
|
use rt::borrowck;
|
||||||
|
|
||||||
|
#[cold]
|
||||||
#[lang="fail_"]
|
#[lang="fail_"]
|
||||||
pub fn fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
|
pub fn fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
|
||||||
task::begin_unwind(expr, file, line);
|
task::begin_unwind(expr, file, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
#[lang="fail_bounds_check"]
|
#[lang="fail_bounds_check"]
|
||||||
pub fn fail_bounds_check(file: *c_char, line: size_t, index: size_t, len: size_t) -> ! {
|
pub fn fail_bounds_check(file: *c_char, line: size_t, index: size_t, len: size_t) -> ! {
|
||||||
let msg = format!("index out of bounds: the len is {} but the index is {}",
|
let msg = format!("index out of bounds: the len is {} but the index is {}",
|
||||||
|
|
|
@ -365,6 +365,11 @@ extern "C" void LLVMRemoveReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
|
||||||
AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
|
AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {
|
||||||
|
Function *A = unwrap<Function>(Fn);
|
||||||
|
A->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
|
extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
|
||||||
LLVMValueRef source,
|
LLVMValueRef source,
|
||||||
const char* Name,
|
const char* Name,
|
||||||
|
|
|
@ -629,3 +629,4 @@ LLVMRustAddAlwaysInlinePass
|
||||||
LLVMAddReturnAttribute
|
LLVMAddReturnAttribute
|
||||||
LLVMRemoveReturnAttribute
|
LLVMRemoveReturnAttribute
|
||||||
LLVMTypeToString
|
LLVMTypeToString
|
||||||
|
LLVMAddColdAttribute
|
||||||
|
|
Loading…
Reference in New Issue