Skip to content

Commit 9f38792

Browse files
committed
librustc: Fold rt items into lang items. Shaves another 10% or so off hello world compile time.
1 parent d2d1d98 commit 9f38792

File tree

8 files changed

+105
-147
lines changed

8 files changed

+105
-147
lines changed

src/libcore/rt.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,14 @@ extern mod rustrt {
3838
fn rust_upcall_free(ptr: *c_char);
3939
}
4040

41-
// FIXME (#2861): This needs both the attribute, and the name prefixed with
42-
// 'rt_', otherwise the compiler won't find it. To fix this, see
43-
// gather_rust_rtcalls.
4441
#[rt(fail_)]
42+
#[lang="fail_"]
4543
pub fn rt_fail_(expr: *c_char, file: *c_char, line: size_t) -> ! {
4644
sys::begin_unwind_(expr, file, line);
4745
}
4846

4947
#[rt(fail_bounds_check)]
48+
#[lang="fail_bounds_check"]
5049
pub fn rt_fail_bounds_check(file: *c_char, line: size_t,
5150
index: size_t, len: size_t) {
5251
let msg = fmt!("index out of bounds: the len is %d but the index is %d",
@@ -57,6 +56,7 @@ pub fn rt_fail_bounds_check(file: *c_char, line: size_t,
5756
}
5857

5958
#[rt(exchange_malloc)]
59+
#[lang="exchange_malloc"]
6060
pub fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
6161
return rustrt::rust_upcall_exchange_malloc(td, size);
6262
}
@@ -65,11 +65,13 @@ pub fn rt_exchange_malloc(td: *c_char, size: uintptr_t) -> *c_char {
6565
// inside a landing pad may corrupt the state of the exception handler. If a
6666
// problem occurs, call exit instead.
6767
#[rt(exchange_free)]
68+
#[lang="exchange_free"]
6869
pub fn rt_exchange_free(ptr: *c_char) {
6970
rustrt::rust_upcall_exchange_free(ptr);
7071
}
7172

7273
#[rt(malloc)]
74+
#[lang="malloc"]
7375
pub fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
7476
return rustrt::rust_upcall_malloc(td, size);
7577
}
@@ -78,6 +80,7 @@ pub fn rt_malloc(td: *c_char, size: uintptr_t) -> *c_char {
7880
// inside a landing pad may corrupt the state of the exception handler. If a
7981
// problem occurs, call exit instead.
8082
#[rt(free)]
83+
#[lang="free"]
8184
pub fn rt_free(ptr: *c_char) {
8285
rustrt::rust_upcall_free(ptr);
8386
}

src/librustc/middle/lang_items.rs

Lines changed: 65 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -34,43 +34,49 @@ use std::map::HashMap;
3434
use str_eq = str::eq;
3535

3636
pub enum LangItem {
37-
ConstTraitLangItem, // 0
38-
CopyTraitLangItem, // 1
39-
OwnedTraitLangItem, // 2
40-
DurableTraitLangItem, // 3
41-
42-
DropTraitLangItem, // 4
43-
44-
AddTraitLangItem, // 5
45-
SubTraitLangItem, // 6
46-
MulTraitLangItem, // 7
47-
DivTraitLangItem, // 8
48-
ModuloTraitLangItem, // 9
49-
NegTraitLangItem, // 10
50-
BitXorTraitLangItem, // 11
51-
BitAndTraitLangItem, // 12
52-
BitOrTraitLangItem, // 13
53-
ShlTraitLangItem, // 14
54-
ShrTraitLangItem, // 15
55-
IndexTraitLangItem, // 16
56-
57-
EqTraitLangItem, // 17
58-
OrdTraitLangItem, // 18
59-
60-
StrEqFnLangItem, // 19
61-
UniqStrEqFnLangItem, // 20
62-
AnnihilateFnLangItem, // 21
63-
LogTypeFnLangItem, // 22
37+
ConstTraitLangItem, // 0
38+
CopyTraitLangItem, // 1
39+
OwnedTraitLangItem, // 2
40+
DurableTraitLangItem, // 3
41+
42+
DropTraitLangItem, // 4
43+
44+
AddTraitLangItem, // 5
45+
SubTraitLangItem, // 6
46+
MulTraitLangItem, // 7
47+
DivTraitLangItem, // 8
48+
ModuloTraitLangItem, // 9
49+
NegTraitLangItem, // 10
50+
BitXorTraitLangItem, // 11
51+
BitAndTraitLangItem, // 12
52+
BitOrTraitLangItem, // 13
53+
ShlTraitLangItem, // 14
54+
ShrTraitLangItem, // 15
55+
IndexTraitLangItem, // 16
56+
57+
EqTraitLangItem, // 17
58+
OrdTraitLangItem, // 18
59+
60+
StrEqFnLangItem, // 19
61+
UniqStrEqFnLangItem, // 20
62+
AnnihilateFnLangItem, // 21
63+
LogTypeFnLangItem, // 22
64+
FailFnLangItem, // 23
65+
FailBoundsCheckFnLangItem, // 24
66+
ExchangeMallocFnLangItem, // 25
67+
ExchangeFreeFnLangItem, // 26
68+
MallocFnLangItem, // 27
69+
FreeFnLangItem, // 28
6470
}
6571

6672
struct LanguageItems {
67-
items: [ Option<def_id> * 23 ]
73+
items: [ Option<def_id> * 29 ]
6874
}
6975

7076
impl LanguageItems {
7177
static pub fn new() -> LanguageItems {
7278
LanguageItems {
73-
items: [ None, ..23 ]
79+
items: [ None, ..29 ]
7480
}
7581
}
7682

@@ -110,6 +116,12 @@ impl LanguageItems {
110116
20 => "uniq_str_eq",
111117
21 => "annihilate",
112118
22 => "log_type",
119+
23 => "fail_",
120+
24 => "fail_bounds_check",
121+
25 => "exchange_malloc",
122+
26 => "exchange_free",
123+
27 => "malloc",
124+
28 => "free",
113125

114126
_ => "???"
115127
}
@@ -190,6 +202,24 @@ impl LanguageItems {
190202
pub fn log_type_fn(&const self) -> def_id {
191203
self.items[LogTypeFnLangItem as uint].get()
192204
}
205+
pub fn fail_fn(&const self) -> def_id {
206+
self.items[FailFnLangItem as uint].get()
207+
}
208+
pub fn fail_bounds_check_fn(&const self) -> def_id {
209+
self.items[FailBoundsCheckFnLangItem as uint].get()
210+
}
211+
pub fn exchange_malloc_fn(&const self) -> def_id {
212+
self.items[ExchangeMallocFnLangItem as uint].get()
213+
}
214+
pub fn exchange_free_fn(&const self) -> def_id {
215+
self.items[ExchangeFreeFnLangItem as uint].get()
216+
}
217+
pub fn malloc_fn(&const self) -> def_id {
218+
self.items[MallocFnLangItem as uint].get()
219+
}
220+
pub fn free_fn(&const self) -> def_id {
221+
self.items[FreeFnLangItem as uint].get()
222+
}
193223
}
194224

195225
fn LanguageItemCollector(crate: @crate,
@@ -225,6 +255,12 @@ fn LanguageItemCollector(crate: @crate,
225255
item_refs.insert(~"uniq_str_eq", UniqStrEqFnLangItem as uint);
226256
item_refs.insert(~"annihilate", AnnihilateFnLangItem as uint);
227257
item_refs.insert(~"log_type", LogTypeFnLangItem as uint);
258+
item_refs.insert(~"fail_", FailFnLangItem as uint);
259+
item_refs.insert(~"fail_bounds_check", FailBoundsCheckFnLangItem as uint);
260+
item_refs.insert(~"exchange_malloc", ExchangeMallocFnLangItem as uint);
261+
item_refs.insert(~"exchange_free", ExchangeFreeFnLangItem as uint);
262+
item_refs.insert(~"malloc", MallocFnLangItem as uint);
263+
item_refs.insert(~"free", FreeFnLangItem as uint);
228264

229265
LanguageItemCollector {
230266
crate: crate,

src/librustc/middle/trans/base.rs

Lines changed: 16 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,20 @@ fn opaque_box_body(bcx: block,
262262

263263
// malloc_raw_dyn: allocates a box to contain a given type, but with a
264264
// potentially dynamic size.
265-
fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap,
265+
fn malloc_raw_dyn(bcx: block,
266+
t: ty::t,
267+
heap: heap,
266268
size: ValueRef) -> Result {
267269
let _icx = bcx.insn_ctxt("malloc_raw");
268270
let ccx = bcx.ccx();
269271

270-
let (mk_fn, rtcall) = match heap {
271-
heap_shared => (ty::mk_imm_box, ~"malloc"),
272-
heap_exchange => (ty::mk_imm_uniq, ~"exchange_malloc")
272+
let (mk_fn, langcall) = match heap {
273+
heap_shared => {
274+
(ty::mk_imm_box, bcx.tcx().lang_items.malloc_fn())
275+
}
276+
heap_exchange => {
277+
(ty::mk_imm_uniq, bcx.tcx().lang_items.exchange_malloc_fn())
278+
}
273279
};
274280

275281
// Grab the TypeRef type of box_ptr_ty.
@@ -283,8 +289,11 @@ fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap,
283289
// Allocate space:
284290
let tydesc = PointerCast(bcx, static_ti.tydesc, T_ptr(T_i8()));
285291
let rval = alloca_zeroed(bcx, T_ptr(T_i8()));
286-
let bcx = callee::trans_rtcall(bcx, rtcall, ~[tydesc, size],
287-
expr::SaveIn(rval));
292+
let bcx = callee::trans_rtcall_or_lang_call(
293+
bcx,
294+
langcall,
295+
~[tydesc, size],
296+
expr::SaveIn(rval));
288297
return rslt(bcx, PointerCast(bcx, Load(bcx, rval), llty));
289298
}
290299

@@ -2539,92 +2548,6 @@ fn trap(bcx: block) {
25392548
}
25402549
}
25412550

2542-
fn push_rtcall(ccx: @crate_ctxt, name: ~str, did: ast::def_id) {
2543-
match ccx.rtcalls.find(name) {
2544-
Some(existing_did) if did != existing_did => {
2545-
ccx.sess.fatal(fmt!("multiple definitions for runtime call %s",
2546-
name));
2547-
}
2548-
Some(_) | None => {
2549-
ccx.rtcalls.insert(name, did);
2550-
}
2551-
}
2552-
}
2553-
2554-
fn gather_local_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) {
2555-
visit::visit_crate(*crate, (), visit::mk_simple_visitor(@{
2556-
visit_item: |item| match item.node {
2557-
ast::item_fn(*) => {
2558-
let attr_metas = attr::attr_metas(
2559-
attr::find_attrs_by_name(item.attrs, ~"rt"));
2560-
for vec::each(attr_metas) |attr_meta| {
2561-
match attr::get_meta_item_list(*attr_meta) {
2562-
Some(list) => {
2563-
let head = vec::head(list);
2564-
let name = attr::get_meta_item_name(head);
2565-
push_rtcall(ccx, name, {crate: ast::local_crate,
2566-
node: item.id});
2567-
}
2568-
None => ()
2569-
}
2570-
}
2571-
}
2572-
_ => ()
2573-
},
2574-
..*visit::default_simple_visitor()
2575-
}));
2576-
}
2577-
2578-
fn gather_external_rtcalls(ccx: @crate_ctxt) {
2579-
do cstore::iter_crate_data(ccx.sess.cstore) |_cnum, cmeta| {
2580-
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
2581-
cstore::get_crate_data(ccx.sess.cstore, cnum)
2582-
};
2583-
do decoder::each_path(ccx.sess.intr(), cmeta, get_crate_data) |path| {
2584-
let pathname = path.path_string;
2585-
match path.def_like {
2586-
decoder::dl_def(d) => {
2587-
match d {
2588-
ast::def_fn(did, _) => {
2589-
// FIXME (#2861): This should really iterate attributes
2590-
// like gather_local_rtcalls, but we'll need to
2591-
// export attributes in metadata/encoder before we can do
2592-
// that.
2593-
let sentinel = ~"rt::rt_";
2594-
let slen = str::len(sentinel);
2595-
if str::starts_with(pathname, sentinel) {
2596-
let name = str::substr(pathname,
2597-
slen, str::len(pathname)-slen);
2598-
push_rtcall(ccx, name, did);
2599-
}
2600-
}
2601-
_ => ()
2602-
}
2603-
}
2604-
_ => ()
2605-
}
2606-
true
2607-
}
2608-
}
2609-
}
2610-
2611-
fn gather_rtcalls(ccx: @crate_ctxt, crate: @ast::crate) {
2612-
gather_local_rtcalls(ccx, crate);
2613-
gather_external_rtcalls(ccx);
2614-
2615-
// FIXME (#2861): Check for other rtcalls too, once they are
2616-
// supported. Also probably want to check type signature so we don't crash
2617-
// in some obscure place in LLVM if the user provides the wrong signature
2618-
// for an rtcall.
2619-
let expected_rtcalls =
2620-
~[~"exchange_free", ~"exchange_malloc", ~"fail_", ~"free", ~"malloc"];
2621-
for vec::each(expected_rtcalls) |name| {
2622-
if !ccx.rtcalls.contains_key(*name) {
2623-
fail fmt!("no definition for runtime call %s", *name);
2624-
}
2625-
}
2626-
}
2627-
26282551
fn decl_gc_metadata(ccx: @crate_ctxt, llmod_id: ~str) {
26292552
if !ccx.sess.opts.gc || !ccx.uses_gc {
26302553
return;
@@ -2869,9 +2792,7 @@ fn trans_crate(sess: session::Session,
28692792
llvm_insn_ctxt: @mut ~[],
28702793
llvm_insns: HashMap(),
28712794
fn_times: @mut ~[]},
2872-
upcalls:
2873-
upcall::declare_upcalls(targ_cfg, llmod),
2874-
rtcalls: HashMap(),
2795+
upcalls: upcall::declare_upcalls(targ_cfg, llmod),
28752796
tydesc_type: tydesc_type,
28762797
int_type: int_type,
28772798
float_type: float_type,
@@ -2885,8 +2806,6 @@ fn trans_crate(sess: session::Session,
28852806
mut do_not_commit_warning_issued: false
28862807
};
28872808

2888-
gather_rtcalls(ccx, crate);
2889-
28902809
{
28912810
let _icx = ccx.insn_ctxt("data");
28922811
trans_constants(ccx, crate);

src/librustc/middle/trans/callee.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -333,13 +333,6 @@ fn trans_method_call(in_cx: block,
333333
DontAutorefArg)
334334
}
335335

336-
fn trans_rtcall(bcx: block, name: ~str, args: ~[ValueRef], dest: expr::Dest)
337-
-> block
338-
{
339-
let did = bcx.ccx().rtcalls[name];
340-
return trans_rtcall_or_lang_call(bcx, did, args, dest);
341-
}
342-
343336
fn trans_rtcall_or_lang_call(bcx: block, did: ast::def_id, args: ~[ValueRef],
344337
dest: expr::Dest) -> block {
345338
let fty = if did.crate == ast::local_crate {

src/librustc/middle/trans/closure.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,11 +492,13 @@ fn make_opaque_cbox_take_glue(
492492
let sz = Add(bcx, sz, shape::llsize_of(ccx, T_box_header(ccx)));
493493

494494
// Allocate memory, update original ptr, and copy existing data
495-
let malloc = ~"exchange_malloc";
496495
let opaque_tydesc = PointerCast(bcx, tydesc, T_ptr(T_i8()));
497496
let rval = alloca_zeroed(bcx, T_ptr(T_i8()));
498-
let bcx = callee::trans_rtcall(bcx, malloc, ~[opaque_tydesc, sz],
499-
expr::SaveIn(rval));
497+
let bcx = callee::trans_rtcall_or_lang_call(
498+
bcx,
499+
bcx.tcx().lang_items.exchange_malloc_fn(),
500+
~[opaque_tydesc, sz],
501+
expr::SaveIn(rval));
500502
let cbox_out = PointerCast(bcx, Load(bcx, rval), llopaquecboxty);
501503
call_memcpy(bcx, cbox_out, cbox_in, sz);
502504
Store(bcx, cbox_out, cboxptr);

src/librustc/middle/trans/common.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,6 @@ struct crate_ctxt {
197197
maps: astencode::maps,
198198
stats: stats,
199199
upcalls: @upcall::upcalls,
200-
rtcalls: HashMap<~str, ast::def_id>,
201200
tydesc_type: TypeRef,
202201
int_type: TypeRef,
203202
float_type: TypeRef,

src/librustc/middle/trans/controlflow.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ fn trans_fail_value(bcx: block, sp_opt: Option<span>, V_fail_str: ValueRef)
368368
let V_str = PointerCast(bcx, V_fail_str, T_ptr(T_i8()));
369369
let V_filename = PointerCast(bcx, V_filename, T_ptr(T_i8()));
370370
let args = ~[V_str, V_filename, C_int(ccx, V_line)];
371-
let bcx = callee::trans_rtcall(bcx, ~"fail_", args, expr::Ignore);
371+
let bcx = callee::trans_rtcall_or_lang_call(
372+
bcx, bcx.tcx().lang_items.fail_fn(), args, expr::Ignore);
372373
Unreachable(bcx);
373374
return bcx;
374375
}
@@ -384,8 +385,8 @@ fn trans_fail_bounds_check(bcx: block, sp: span,
384385
let filename = PointerCast(bcx, filename_cstr, T_ptr(T_i8()));
385386

386387
let args = ~[filename, line, index, len];
387-
let bcx = callee::trans_rtcall(bcx, ~"fail_bounds_check", args,
388-
expr::Ignore);
388+
let bcx = callee::trans_rtcall_or_lang_call(
389+
bcx, bcx.tcx().lang_items.fail_bounds_check_fn(), args, expr::Ignore);
389390
Unreachable(bcx);
390391
return bcx;
391392
}

0 commit comments

Comments
 (0)