Add some monomorphizing instrumentation, simplify types before emitting glue.

This commit is contained in:
Graydon Hoare 2012-09-12 14:48:13 -07:00
parent 4ce2ee12be
commit 719a4750ba
6 changed files with 135 additions and 4 deletions

View File

@ -1554,6 +1554,7 @@ fn trans_closure(ccx: @crate_ctxt, path: path, decl: ast::fn_decl,
id: ast::node_id,
maybe_load_env: fn(fn_ctxt),
finish: fn(block)) {
ccx.stats.n_closures += 1;
let _icx = ccx.insn_ctxt("trans_closure");
set_uwtable(llfndecl);
@ -1619,6 +1620,7 @@ fn trans_fn(ccx: @crate_ctxt,
let start = if do_time { time::get_time() }
else { {sec: 0i64, nsec: 0i32} };
let _icx = ccx.insn_ctxt("trans_fn");
ccx.stats.n_fns += 1;
trans_closure(ccx, path, decl, body, llfndecl, ty_self,
param_substs, id,
|fcx| {
@ -2651,6 +2653,10 @@ fn trans_crate(sess: session::session,
mut n_glues_created: 0u,
mut n_null_glues: 0u,
mut n_real_glues: 0u,
mut n_fns: 0u,
mut n_monos: 0u,
mut n_inlines: 0u,
mut n_closures: 0u,
llvm_insn_ctxt: @mut ~[],
llvm_insns: str_hash(),
fn_times: @mut ~[]},
@ -2704,13 +2710,20 @@ fn trans_crate(sess: session::session,
io::println(fmt!("n_null_glues: %u", ccx.stats.n_null_glues));
io::println(fmt!("n_real_glues: %u", ccx.stats.n_real_glues));
io::println(fmt!("n_fns: %u", ccx.stats.n_fns));
io::println(fmt!("n_monos: %u", ccx.stats.n_monos));
io::println(fmt!("n_inlines: %u", ccx.stats.n_inlines));
io::println(fmt!("n_closures: %u", ccx.stats.n_closures));
// FIXME (#2280): this temporary shouldn't be
// necessary, but seems to be, for borrowing.
/*
let times = copy *ccx.stats.fn_times;
for vec::each(times) |timing| {
io::println(fmt!("time: %s took %d ms", timing.ident,
timing.time));
}
*/
}
if ccx.sess.count_llvm_insns() {

View File

@ -89,6 +89,10 @@ type stats =
mut n_glues_created: uint,
mut n_null_glues: uint,
mut n_real_glues: uint,
mut n_fns: uint,
mut n_monos: uint,
mut n_inlines: uint,
mut n_closures: uint,
llvm_insn_ctxt: @mut ~[~str],
llvm_insns: HashMap<~str, uint>,
fn_times: @mut ~[{ident: ~str, time: int}]};

View File

@ -121,10 +121,103 @@ fn lazily_emit_all_tydesc_glue(ccx: @crate_ctxt,
lazily_emit_tydesc_glue(ccx, abi::tydesc_field_visit_glue, static_ti);
}
fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
if (field == abi::tydesc_field_take_glue ||
field == abi::tydesc_field_drop_glue ||
field == abi::tydesc_field_free_glue) &&
! ty::type_needs_drop(tcx, t) {
return ty::mk_u32(tcx);
}
if field == abi::tydesc_field_take_glue {
match ty::get(t).sty {
ty::ty_unboxed_vec(*) => { return ty::mk_u32(tcx); }
_ => ()
}
}
if field == abi::tydesc_field_take_glue &&
ty::type_is_boxed(t) {
return ty::mk_imm_box(tcx, ty::mk_u32(tcx));
}
if field == abi::tydesc_field_free_glue {
match ty::get(t).sty {
ty::ty_fn(*) |
ty::ty_box(*) |
ty::ty_opaque_box |
ty::ty_uniq(*) |
ty::ty_evec(_, ty::vstore_uniq) | ty::ty_estr(ty::vstore_uniq) |
ty::ty_evec(_, ty::vstore_box) | ty::ty_estr(ty::vstore_box) |
ty::ty_opaque_closure_ptr(*) => (),
_ => { return ty::mk_u32(tcx); }
}
}
if (field == abi::tydesc_field_free_glue ||
field == abi::tydesc_field_drop_glue) {
match ty::get(t).sty {
ty::ty_box(mt) |
ty::ty_evec(mt, ty::vstore_box)
if ! ty::type_needs_drop(tcx, mt.ty) =>
return ty::mk_imm_box(tcx, ty::mk_u32(tcx)),
ty::ty_uniq(mt) |
ty::ty_evec(mt, ty::vstore_uniq)
if ! ty::type_needs_drop(tcx, mt.ty) =>
return ty::mk_imm_uniq(tcx, ty::mk_u32(tcx)),
_ => ()
}
}
return t;
}
pure fn cast_glue(ccx: @crate_ctxt, ti: @tydesc_info, v: ValueRef)
-> ValueRef {
unchecked {
let llfnty = type_of_glue_fn(ccx, ti.ty);
llvm::LLVMConstPointerCast(v, T_ptr(llfnty))
}
}
fn lazily_emit_simplified_tydesc_glue(ccx: @crate_ctxt, field: uint,
ti: @tydesc_info) -> bool {
let _icx = ccx.insn_ctxt("lazily_emit_simplified_tydesc_glue");
let simpl = simplified_glue_type(ccx.tcx, field, ti.ty);
if simpl != ti.ty {
let simpl_ti = base::get_tydesc(ccx, simpl);
lazily_emit_tydesc_glue(ccx, field, simpl_ti);
if field == abi::tydesc_field_take_glue {
ti.take_glue =
simpl_ti.take_glue.map(|v| cast_glue(ccx, ti, v));
} else if field == abi::tydesc_field_drop_glue {
ti.drop_glue =
simpl_ti.drop_glue.map(|v| cast_glue(ccx, ti, v));
} else if field == abi::tydesc_field_free_glue {
ti.free_glue =
simpl_ti.free_glue.map(|v| cast_glue(ccx, ti, v));
} else if field == abi::tydesc_field_visit_glue {
ti.visit_glue =
simpl_ti.visit_glue.map(|v| cast_glue(ccx, ti, v));
}
return true;
}
return false;
}
fn lazily_emit_tydesc_glue(ccx: @crate_ctxt, field: uint,
ti: @tydesc_info) {
let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue");
let llfnty = type_of_glue_fn(ccx, ti.ty);
if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
return;
}
if field == abi::tydesc_field_take_glue {
match ti.take_glue {
Some(_) => (),
@ -502,7 +595,9 @@ fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
//XXX this triggers duplicate LLVM symbols
let name = if false /*ccx.sess.opts.debuginfo*/ {
mangle_internal_name_by_type_only(ccx, t, ~"tydesc")
} else { mangle_internal_name_by_seq(ccx, ~"tydesc") };
} else {
mangle_internal_name_by_seq(ccx, ~"tydesc")
};
note_unique_llvm_symbol(ccx, name);
log(debug, fmt!("+++ declare_tydesc %s %s", ty_to_str(ccx.tcx, t), name));
let gvar = str::as_c_str(name, |buf| {
@ -535,6 +630,7 @@ fn declare_generic_glue(ccx: @crate_ctxt, t: ty::t, llfnty: TypeRef,
} else {
fn_nm = mangle_internal_name_by_seq(ccx, (~"glue_" + name));
}
debug!("%s is for type %s", fn_nm, ty_to_str(ccx.tcx, t));
note_unique_llvm_symbol(ccx, fn_nm);
let llfn = decl_cdecl_fn(ccx.llmod, fn_nm, llfnty);
set_glue_inlining(llfn, t);

View File

@ -30,6 +30,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
}
csearch::found(ast::ii_item(item)) => {
ccx.external.insert(fn_id, Some(item.id));
ccx.stats.n_inlines += 1;
trans_item(ccx, *item);
local_def(item.id)
}
@ -64,6 +65,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
with a non-item parent");
}
csearch::found(ast::ii_method(impl_did, mth)) => {
ccx.stats.n_inlines += 1;
ccx.external.insert(fn_id, Some(mth.id));
let {bounds: impl_bnds, region_param: _, ty: impl_ty} =
ty::lookup_item_type(ccx.tcx, impl_did);

View File

@ -97,6 +97,8 @@ fn monomorphic_fn(ccx: @crate_ctxt,
let mono_ty = ty::subst_tps(ccx.tcx, substs, llitem_ty);
let llfty = type_of_fn_from_ty(ccx, mono_ty);
ccx.stats.n_monos += 1;
let depth = option::get_default(ccx.monomorphizing.find(fn_id), 0u);
// Random cut-off -- code that needs to instantiate the same function
// recursively more than ten times can probably safely be assumed to be

View File

@ -1546,6 +1546,7 @@ fn type_is_immediate(ty: t) -> bool {
type_is_unique(ty) || type_is_region_ptr(ty);
}
fn type_needs_drop(cx: ctxt, ty: t) -> bool {
match cx.needs_drop_cache.find(ty) {
Some(result) => return result,
@ -1557,8 +1558,22 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
// scalar types
ty_nil | ty_bot | ty_bool | ty_int(_) | ty_float(_) | ty_uint(_) |
ty_type | ty_ptr(_) | ty_rptr(_, _) |
ty_estr(vstore_fixed(_)) | ty_estr(vstore_slice(_)) |
ty_evec(_, vstore_slice(_)) => false,
ty_estr(vstore_fixed(_)) |
ty_estr(vstore_slice(_)) |
ty_evec(_, vstore_slice(_)) |
ty_self => false,
ty_box(_) | ty_uniq(_) |
ty_opaque_box | ty_opaque_closure_ptr(*) |
ty_estr(vstore_uniq) |
ty_estr(vstore_box) |
ty_evec(_, vstore_uniq) |
ty_evec(_, vstore_box) => true,
ty_trait(*) => true,
ty_param(*) | ty_infer(*) => true,
ty_evec(mt, vstore_fixed(_)) => type_needs_drop(cx, mt.ty),
ty_unboxed_vec(mt) => type_needs_drop(cx, mt.ty),
ty_rec(flds) => {
@ -1598,7 +1613,6 @@ fn type_needs_drop(cx: ctxt, ty: t) -> bool {
_ => true
}
}
_ => true
};
cx.needs_drop_cache.insert(ty, result);