Skip to content

Commit 671ab42

Browse files
committed
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.
2 parents dba6070 + 541e5f8 commit 671ab42

File tree

6 files changed

+23
-6
lines changed

6 files changed

+23
-6
lines changed

src/librustc/lib/llvm.rs

+2
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,8 @@ pub mod llvm {
693693
pub fn LLVMAddReturnAttribute(Fn: ValueRef, PA: c_uint);
694694
pub fn LLVMRemoveReturnAttribute(Fn: ValueRef, PA: c_uint);
695695

696+
pub fn LLVMAddColdAttribute(Fn: ValueRef);
697+
696698
pub fn LLVMRemoveFunctionAttr(Fn: ValueRef,
697699
PA: c_ulonglong,
698700
HighPA: c_ulonglong);

src/librustc/middle/trans/base.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -202,19 +202,21 @@ pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: &str,
202202
f
203203
}
204204

205-
pub fn get_extern_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
206-
name: &str) -> ValueRef {
205+
fn get_extern_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
206+
name: &str, did: ast::DefId) -> ValueRef {
207207
match ccx.externs.find_equiv(&name) {
208208
Some(n) => return *n,
209209
None => ()
210210
}
211211
let f = decl_rust_fn(ccx, inputs, output, name);
212+
do csearch::get_item_attrs(ccx.tcx.cstore, did) |meta_items| {
213+
set_llvm_fn_attrs(meta_items.iter().map(|&x| attr::mk_attr(x)).to_owned_vec(), f)
214+
}
212215
ccx.externs.insert(name.to_owned(), f);
213216
f
214217
}
215218

216-
pub fn decl_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t,
217-
name: &str) -> ValueRef {
219+
fn decl_rust_fn(ccx: &mut CrateContext, inputs: &[ty::t], output: ty::t, name: &str) -> ValueRef {
218220
let llfty = type_of_rust_fn(ccx, inputs, output);
219221
let llfn = decl_cdecl_fn(ccx.llmod, name, llfty);
220222

@@ -481,6 +483,10 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) {
481483
if contains_name(attrs, "no_split_stack") {
482484
set_no_split_stack(llfn);
483485
}
486+
487+
if contains_name(attrs, "cold") {
488+
unsafe { llvm::LLVMAddColdAttribute(llfn) }
489+
}
484490
}
485491

486492
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) ->
840846
ty::ty_bare_fn(ref fn_ty) => {
841847
match fn_ty.abis.for_arch(ccx.sess.targ_cfg.arch) {
842848
Some(Rust) | Some(RustIntrinsic) => {
843-
get_extern_rust_fn(ccx, fn_ty.sig.inputs, fn_ty.sig.output, name)
849+
get_extern_rust_fn(ccx, fn_ty.sig.inputs, fn_ty.sig.output, name, did)
844850
}
845851
Some(*) | None => {
846852
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) ->
851857
}
852858
}
853859
ty::ty_closure(ref f) => {
854-
get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name)
860+
get_extern_rust_fn(ccx, f.sig.inputs, f.sig.output, name, did)
855861
}
856862
_ => {
857863
let llty = type_of(ccx, t);

src/libstd/rt/borrowck.rs

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub fn clear_task_borrow_list() {
5757
let _ = try_take_task_borrow_list();
5858
}
5959

60+
#[cold]
6061
unsafe fn fail_borrowed(box: *mut raw::Box<()>, file: *c_char, line: size_t) -> ! {
6162
debug_borrow("fail_borrowed: ", box, 0, 0, file, line);
6263

src/libstd/unstable/lang.rs

+2
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ use libc::{c_char, size_t, uintptr_t};
1616
use rt::task;
1717
use rt::borrowck;
1818

19+
#[cold]
1920
#[lang="fail_"]
2021
pub fn fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
2122
task::begin_unwind(expr, file, line);
2223
}
2324

25+
#[cold]
2426
#[lang="fail_bounds_check"]
2527
pub fn fail_bounds_check(file: *c_char, line: size_t, index: size_t, len: size_t) -> ! {
2628
let msg = format!("index out of bounds: the len is {} but the index is {}",

src/rustllvm/RustWrapper.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,11 @@ extern "C" void LLVMRemoveReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) {
365365
AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B));
366366
}
367367

368+
extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {
369+
Function *A = unwrap<Function>(Fn);
370+
A->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold);
371+
}
372+
368373
extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
369374
LLVMValueRef source,
370375
const char* Name,

src/rustllvm/rustllvm.def.in

+1
Original file line numberDiff line numberDiff line change
@@ -629,3 +629,4 @@ LLVMRustAddAlwaysInlinePass
629629
LLVMAddReturnAttribute
630630
LLVMRemoveReturnAttribute
631631
LLVMTypeToString
632+
LLVMAddColdAttribute

0 commit comments

Comments
 (0)