Skip to content

Commit 719a475

Browse files
committed
Add some monomorphizing instrumentation, simplify types before emitting glue.
1 parent 4ce2ee1 commit 719a475

File tree

6 files changed

+135
-4
lines changed

6 files changed

+135
-4
lines changed

src/rustc/middle/trans/base.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,7 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
15541554
id: ast::node_id,
15551555
maybe_load_env: fn(fn_ctxt),
15561556
finish: fn(block)) {
1557+
ccx.stats.n_closures += 1;
15571558
let _icx = ccx.insn_ctxt("trans_closure");
15581559
set_uwtable(llfndecl);
15591560

@@ -1619,6 +1620,7 @@ fn trans_fn(ccx: @crate_ctxt,
16191620
let start = if do_time { time::get_time() }
16201621
else { {sec: 0i64, nsec: 0i32} };
16211622
let _icx = ccx.insn_ctxt("trans_fn");
1623+
ccx.stats.n_fns += 1;
16221624
trans_closure(ccx, path, decl, body, llfndecl, ty_self,
16231625
param_substs, id,
16241626
|fcx| {
@@ -2651,6 +2653,10 @@ fn trans_crate(sess: session::session,
26512653
mut n_glues_created: 0u,
26522654
mut n_null_glues: 0u,
26532655
mut n_real_glues: 0u,
2656+
mut n_fns: 0u,
2657+
mut n_monos: 0u,
2658+
mut n_inlines: 0u,
2659+
mut n_closures: 0u,
26542660
llvm_insn_ctxt: @mut ~[],
26552661
llvm_insns: str_hash(),
26562662
fn_times: @mut ~[]},
@@ -2704,13 +2710,20 @@ fn trans_crate(sess: session::session,
27042710
io::println(fmt!("n_null_glues: %u", ccx.stats.n_null_glues));
27052711
io::println(fmt!("n_real_glues: %u", ccx.stats.n_real_glues));
27062712

2713+
io::println(fmt!("n_fns: %u", ccx.stats.n_fns));
2714+
io::println(fmt!("n_monos: %u", ccx.stats.n_monos));
2715+
io::println(fmt!("n_inlines: %u", ccx.stats.n_inlines));
2716+
io::println(fmt!("n_closures: %u", ccx.stats.n_closures));
2717+
27072718
// FIXME (#2280): this temporary shouldn't be
27082719
// necessary, but seems to be, for borrowing.
2720+
/*
27092721
let times = copy *ccx.stats.fn_times;
27102722
for vec::each(times) |timing| {
27112723
io::println(fmt!("time: %s took %d ms", timing.ident,
27122724
timing.time));
27132725
}
2726+
*/
27142727
}
27152728

27162729
if ccx.sess.count_llvm_insns() {

src/rustc/middle/trans/common.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ type stats =
8989
mut n_glues_created: uint,
9090
mut n_null_glues: uint,
9191
mut n_real_glues: uint,
92+
mut n_fns: uint,
93+
mut n_monos: uint,
94+
mut n_inlines: uint,
95+
mut n_closures: uint,
9296
llvm_insn_ctxt: @mut ~[~str],
9397
llvm_insns: HashMap<~str, uint>,
9498
fn_times: @mut ~[{ident: ~str, time: int}]};

src/rustc/middle/trans/glue.rs

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,103 @@ fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
121121
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_visit_glue, static_ti);
122122
}
123123

124+
fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
125+
126+
if (field == abi::tydesc_field_take_glue ||
127+
field == abi::tydesc_field_drop_glue ||
128+
field == abi::tydesc_field_free_glue) &&
129+
! ty::type_needs_drop(tcx, t) {
130+
return ty::mk_u32(tcx);
131+
}
132+
133+
if field == abi::tydesc_field_take_glue {
134+
match ty::get(t).sty {
135+
ty::ty_unboxed_vec(*) => { return ty::mk_u32(tcx); }
136+
_ => ()
137+
}
138+
}
139+
140+
if field == abi::tydesc_field_take_glue &&
141+
ty::type_is_boxed(t) {
142+
return ty::mk_imm_box(tcx, ty::mk_u32(tcx));
143+
}
144+
145+
if field == abi::tydesc_field_free_glue {
146+
match ty::get(t).sty {
147+
ty::ty_fn(*) |
148+
ty::ty_box(*) |
149+
ty::ty_opaque_box |
150+
ty::ty_uniq(*) |
151+
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) |
152+
ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) |
153+
ty::ty_opaque_closure_ptr(*) => (),
154+
_ => { return ty::mk_u32(tcx); }
155+
}
156+
}
157+
158+
if (field == abi::tydesc_field_free_glue ||
159+
field == abi::tydesc_field_drop_glue) {
160+
match ty::get(t).sty {
161+
ty::ty_box(mt) |
162+
ty::ty_evec(mt, ty::vstore_box)
163+
if ! ty::type_needs_drop(tcx, mt.ty) =>
164+
return ty::mk_imm_box(tcx, ty::mk_u32(tcx)),
165+
166+
ty::ty_uniq(mt) |
167+
ty::ty_evec(mt, ty::vstore_uniq)
168+
if ! ty::type_needs_drop(tcx, mt.ty) =>
169+
return ty::mk_imm_uniq(tcx, ty::mk_u32(tcx)),
170+
171+
_ => ()
172+
}
173+
}
174+
175+
return t;
176+
}
177+
178+
pure fn cast_glue(ccx: @crate_ctxt, ti: @tydesc_info, v: ValueRef)
179+
-> ValueRef {
180+
unchecked {
181+
let llfnty = type_of_glue_fn(ccx, ti.ty);
182+
llvm::LLVMConstPointerCast(v, T_ptr(llfnty))
183+
}
184+
}
185+
186+
fn lazily_emit_simplified_tydesc_glue(ccx: @crate_ctxt, field: uint,
187+
ti: @tydesc_info) -> bool {
188+
let _icx = ccx.insn_ctxt("lazily_emit_simplified_tydesc_glue");
189+
let simpl = simplified_glue_type(ccx.tcx, field, ti.ty);
190+
if simpl != ti.ty {
191+
let simpl_ti = base::get_tydesc(ccx, simpl);
192+
lazily_emit_tydesc_glue(ccx, field, simpl_ti);
193+
if field == abi::tydesc_field_take_glue {
194+
ti.take_glue =
195+
simpl_ti.take_glue.map(|v| cast_glue(ccx, ti, v));
196+
} else if field == abi::tydesc_field_drop_glue {
197+
ti.drop_glue =
198+
simpl_ti.drop_glue.map(|v| cast_glue(ccx, ti, v));
199+
} else if field == abi::tydesc_field_free_glue {
200+
ti.free_glue =
201+
simpl_ti.free_glue.map(|v| cast_glue(ccx, ti, v));
202+
} else if field == abi::tydesc_field_visit_glue {
203+
ti.visit_glue =
204+
simpl_ti.visit_glue.map(|v| cast_glue(ccx, ti, v));
205+
}
206+
return true;
207+
}
208+
return false;
209+
}
210+
211+
124212
fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
125213
ti: @tydesc_info) {
126214
let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue");
127215
let llfnty = type_of_glue_fn(ccx, ti.ty);
216+
217+
if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
218+
return;
219+
}
220+
128221
if field == abi::tydesc_field_take_glue {
129222
match ti.take_glue {
130223
Some(_) => (),
@@ -502,7 +595,9 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
502595
//XXX this triggers duplicate LLVM symbols
503596
let name = if false /*ccx.sess.opts.debuginfo*/ {
504597
mangle_internal_name_by_type_only(ccx, t, ~"tydesc")
505-
} else { mangle_internal_name_by_seq(ccx, ~"tydesc") };
598+
} else {
599+
mangle_internal_name_by_seq(ccx, ~"tydesc")
600+
};
506601
note_unique_llvm_symbol(ccx, name);
507602
log(debug, fmt!("+++ declare_tydesc %s %s", ty_to_str(ccx.tcx, t), name));
508603
let gvar = str::as_c_str(name, |buf| {
@@ -535,6 +630,7 @@ fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
535630
} else {
536631
fn_nm = mangle_internal_name_by_seq(ccx, (~"glue_" + name));
537632
}
633+
debug!("%s is for type %s", fn_nm, ty_to_str(ccx.tcx, t));
538634
note_unique_llvm_symbol(ccx, fn_nm);
539635
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
540636
set_glue_inlining(llfn, t);

src/rustc/middle/trans/inline.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
3030
}
3131
csearch::found(ast::ii_item(item)) => {
3232
ccx.external.insert(fn_id, Some(item.id));
33+
ccx.stats.n_inlines += 1;
3334
trans_item(ccx, *item);
3435
local_def(item.id)
3536
}
@@ -64,6 +65,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
6465
with a non-item parent");
6566
}
6667
csearch::found(ast::ii_method(impl_did, mth)) => {
68+
ccx.stats.n_inlines += 1;
6769
ccx.external.insert(fn_id, Some(mth.id));
6870
let {bounds: impl_bnds, region_param: _, ty: impl_ty} =
6971
ty::lookup_item_type(ccx.tcx, impl_did);

src/rustc/middle/trans/monomorphize.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ fn monomorphic_fn(ccx: @crate_ctxt,
9797
let mono_ty = ty::subst_tps(ccx.tcx, substs, llitem_ty);
9898
let llfty = type_of_fn_from_ty(ccx, mono_ty);
9999

100+
ccx.stats.n_monos += 1;
101+
100102
let depth = option::get_default(ccx.monomorphizing.find(fn_id), 0u);
101103
// Random cut-off -- code that needs to instantiate the same function
102104
// recursively more than ten times can probably safely be assumed to be

src/rustc/middle/ty.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,7 @@ fn type_is_immediate(ty: t) -> bool {
15461546
type_is_unique(ty) || type_is_region_ptr(ty);
15471547
}
15481548
1549+
15491550
fn type_needs_drop(cx: ctxt, ty: t) -> bool {
15501551
match cx.needs_drop_cache.find(ty) {
15511552
Some(result) => return result,
@@ -1557,8 +1558,22 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
15571558
// scalar types
15581559
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
15591560
ty_type | ty_ptr(_) | ty_rptr(_, _) |
1560-
ty_estr(vstore_fixed(_)) | ty_estr(vstore_slice(_)) |
1561-
ty_evec(_, vstore_slice(_)) => false,
1561+
ty_estr(vstore_fixed(_)) |
1562+
ty_estr(vstore_slice(_)) |
1563+
ty_evec(_, vstore_slice(_)) |
1564+
ty_self => false,
1565+
1566+
ty_box(_) | ty_uniq(_) |
1567+
ty_opaque_box | ty_opaque_closure_ptr(*) |
1568+
ty_estr(vstore_uniq) |
1569+
ty_estr(vstore_box) |
1570+
ty_evec(_, vstore_uniq) |
1571+
ty_evec(_, vstore_box) => true,
1572+
1573+
ty_trait(*) => true,
1574+
1575+
ty_param(*) | ty_infer(*) => true,
1576+
15621577
ty_evec(mt, vstore_fixed(_)) => type_needs_drop(cx, mt.ty),
15631578
ty_unboxed_vec(mt) => type_needs_drop(cx, mt.ty),
15641579
ty_rec(flds) => {
@@ -1598,7 +1613,6 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
15981613
_ => true
15991614
}
16001615
}
1601-
_ => true
16021616
};
16031617
16041618
cx.needs_drop_cache.insert(ty, result);

0 commit comments

Comments
 (0)