rustc: slightly optimize make_mono_id to not clone lots of vectors.
This commit is contained in:
parent
c709c1efc6
commit
5fa7be659c
3 changed files with 65 additions and 69 deletions
|
@ -690,6 +690,7 @@ pub fn is_null(val: ValueRef) -> bool {
|
||||||
#[deriving(Eq, TotalEq, Hash)]
|
#[deriving(Eq, TotalEq, Hash)]
|
||||||
pub struct MonoParamId {
|
pub struct MonoParamId {
|
||||||
pub subst: ty::t,
|
pub subst: ty::t,
|
||||||
|
// Do we really need the vtables to be hashed? Isn't the type enough?
|
||||||
pub vtables: Vec<mono_id>
|
pub vtables: Vec<mono_id>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -427,29 +427,6 @@ pub fn trans_trait_callee_from_llval<'a>(bcx: &'a Block<'a>,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vtable_id(ccx: &CrateContext,
|
|
||||||
origin: &typeck::vtable_origin)
|
|
||||||
-> mono_id {
|
|
||||||
match origin {
|
|
||||||
&typeck::vtable_static(impl_id, ref substs, ref sub_vtables) => {
|
|
||||||
let psubsts = param_substs {
|
|
||||||
tys: (*substs).clone(),
|
|
||||||
vtables: Some(sub_vtables.clone()),
|
|
||||||
self_ty: None,
|
|
||||||
self_vtables: None
|
|
||||||
};
|
|
||||||
|
|
||||||
monomorphize::make_mono_id(
|
|
||||||
ccx,
|
|
||||||
impl_id,
|
|
||||||
&psubsts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// can't this be checked at the callee?
|
|
||||||
_ => fail!("vtable_id")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a returns a dynamic vtable for the given type and vtable origin.
|
/// Creates a returns a dynamic vtable for the given type and vtable origin.
|
||||||
/// This is used only for objects.
|
/// This is used only for objects.
|
||||||
fn get_vtable(bcx: &Block,
|
fn get_vtable(bcx: &Block,
|
||||||
|
@ -460,7 +437,7 @@ fn get_vtable(bcx: &Block,
|
||||||
let _icx = push_ctxt("meth::get_vtable");
|
let _icx = push_ctxt("meth::get_vtable");
|
||||||
|
|
||||||
// Check the cache.
|
// Check the cache.
|
||||||
let hash_id = (self_ty, vtable_id(ccx, origins.get(0)));
|
let hash_id = (self_ty, monomorphize::make_vtable_id(ccx, origins.get(0)));
|
||||||
match ccx.vtables.borrow().find(&hash_id) {
|
match ccx.vtables.borrow().find(&hash_id) {
|
||||||
Some(&val) => { return val }
|
Some(&val) => { return val }
|
||||||
None => { }
|
None => { }
|
||||||
|
|
|
@ -47,28 +47,34 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||||
self_vtables.repr(ccx.tcx()),
|
self_vtables.repr(ccx.tcx()),
|
||||||
ref_id);
|
ref_id);
|
||||||
|
|
||||||
assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t)));
|
assert!(real_substs.tps.iter().all(|t| {
|
||||||
|
!ty::type_needs_infer(*t) && !ty::type_has_params(*t)
|
||||||
|
}));
|
||||||
|
|
||||||
let _icx = push_ctxt("monomorphic_fn");
|
let _icx = push_ctxt("monomorphic_fn");
|
||||||
|
|
||||||
let psubsts = @param_substs {
|
let substs_iter = real_substs.self_ty.iter().chain(real_substs.tps.iter());
|
||||||
tys: real_substs.tps.clone(),
|
let param_ids: Vec<MonoParamId> = match vtables {
|
||||||
vtables: vtables,
|
Some(ref vts) => {
|
||||||
self_ty: real_substs.self_ty.clone(),
|
debug!("make_mono_id vtables={} psubsts={}",
|
||||||
self_vtables: self_vtables
|
vts.repr(ccx.tcx()), real_substs.tps.repr(ccx.tcx()));
|
||||||
|
let vts_iter = self_vtables.iter().chain(vts.iter());
|
||||||
|
vts_iter.zip(substs_iter).map(|(vtable, subst)| MonoParamId {
|
||||||
|
subst: *subst,
|
||||||
|
// Do we really need the vtables to be hashed? Isn't the type enough?
|
||||||
|
vtables: vtable.iter().map(|vt| make_vtable_id(ccx, vt)).collect()
|
||||||
|
}).collect()
|
||||||
|
}
|
||||||
|
None => substs_iter.map(|subst| MonoParamId {
|
||||||
|
subst: *subst,
|
||||||
|
vtables: Vec::new()
|
||||||
|
}).collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
for s in real_substs.tps.iter() { assert!(!ty::type_has_params(*s)); }
|
let hash_id = @mono_id_ {
|
||||||
for s in psubsts.tys.iter() { assert!(!ty::type_has_params(*s)); }
|
def: fn_id,
|
||||||
|
params: param_ids
|
||||||
let hash_id = make_mono_id(ccx, fn_id, &*psubsts);
|
};
|
||||||
|
|
||||||
debug!("monomorphic_fn(\
|
|
||||||
fn_id={}, \
|
|
||||||
psubsts={}, \
|
|
||||||
hash_id={:?})",
|
|
||||||
fn_id.repr(ccx.tcx()),
|
|
||||||
psubsts.repr(ccx.tcx()),
|
|
||||||
hash_id);
|
|
||||||
|
|
||||||
match ccx.monomorphized.borrow().find(&hash_id) {
|
match ccx.monomorphized.borrow().find(&hash_id) {
|
||||||
Some(&val) => {
|
Some(&val) => {
|
||||||
|
@ -79,6 +85,21 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let psubsts = @param_substs {
|
||||||
|
tys: real_substs.tps.clone(),
|
||||||
|
vtables: vtables,
|
||||||
|
self_ty: real_substs.self_ty.clone(),
|
||||||
|
self_vtables: self_vtables
|
||||||
|
};
|
||||||
|
|
||||||
|
debug!("monomorphic_fn(\
|
||||||
|
fn_id={}, \
|
||||||
|
psubsts={}, \
|
||||||
|
hash_id={:?})",
|
||||||
|
fn_id.repr(ccx.tcx()),
|
||||||
|
psubsts.repr(ccx.tcx()),
|
||||||
|
hash_id);
|
||||||
|
|
||||||
let tpt = ty::lookup_item_type(ccx.tcx(), fn_id);
|
let tpt = ty::lookup_item_type(ccx.tcx(), fn_id);
|
||||||
let llitem_ty = tpt.ty;
|
let llitem_ty = tpt.ty;
|
||||||
|
|
||||||
|
@ -117,8 +138,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||||
|
|
||||||
debug!("monomorphic_fn about to subst into {}", llitem_ty.repr(ccx.tcx()));
|
debug!("monomorphic_fn about to subst into {}", llitem_ty.repr(ccx.tcx()));
|
||||||
let mono_ty = match is_static_provided {
|
let mono_ty = match is_static_provided {
|
||||||
None => ty::subst_tps(ccx.tcx(), psubsts.tys.as_slice(),
|
None => ty::subst_tps(ccx.tcx(), real_substs.tps.as_slice(),
|
||||||
psubsts.self_ty, llitem_ty),
|
real_substs.self_ty, llitem_ty),
|
||||||
Some(num_method_ty_params) => {
|
Some(num_method_ty_params) => {
|
||||||
// Static default methods are a little unfortunate, in
|
// Static default methods are a little unfortunate, in
|
||||||
// that the "internal" and "external" type of them differ.
|
// that the "internal" and "external" type of them differ.
|
||||||
|
@ -134,9 +155,9 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||||
// stick a substitution for the self type in.
|
// stick a substitution for the self type in.
|
||||||
// This is a bit unfortunate.
|
// This is a bit unfortunate.
|
||||||
|
|
||||||
let idx = psubsts.tys.len() - num_method_ty_params;
|
let idx = real_substs.tps.len() - num_method_ty_params;
|
||||||
let substs = psubsts.tys.slice(0, idx) +
|
let substs = real_substs.tps.slice(0, idx) +
|
||||||
&[psubsts.self_ty.unwrap()] + psubsts.tys.tailn(idx);
|
&[real_substs.self_ty.unwrap()] + real_substs.tps.tailn(idx);
|
||||||
debug!("static default: changed substitution to {}",
|
debug!("static default: changed substitution to {}",
|
||||||
substs.repr(ccx.tcx()));
|
substs.repr(ccx.tcx()));
|
||||||
|
|
||||||
|
@ -284,28 +305,25 @@ pub fn monomorphic_fn(ccx: &CrateContext,
|
||||||
(lldecl, false)
|
(lldecl, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_mono_id(ccx: &CrateContext,
|
pub fn make_vtable_id(ccx: &CrateContext,
|
||||||
item: ast::DefId,
|
origin: &typeck::vtable_origin)
|
||||||
substs: ¶m_substs) -> mono_id {
|
-> mono_id {
|
||||||
let substs_iter = substs.self_ty.iter().chain(substs.tys.iter());
|
match origin {
|
||||||
let param_ids: Vec<MonoParamId> = match substs.vtables {
|
&typeck::vtable_static(impl_id, ref substs, ref sub_vtables) => {
|
||||||
Some(ref vts) => {
|
let param_ids = sub_vtables.iter().zip(substs.iter()).map(|(vtable, subst)| {
|
||||||
debug!("make_mono_id vtables={} substs={}",
|
MonoParamId {
|
||||||
vts.repr(ccx.tcx()), substs.tys.repr(ccx.tcx()));
|
subst: *subst,
|
||||||
let vts_iter = substs.self_vtables.iter().chain(vts.iter());
|
vtables: vtable.iter().map(|vt| make_vtable_id(ccx, vt)).collect()
|
||||||
vts_iter.zip(substs_iter).map(|(vtable, subst)| MonoParamId {
|
}
|
||||||
subst: *subst,
|
}).collect();
|
||||||
vtables: vtable.iter().map(|vt| meth::vtable_id(ccx, vt)).collect()
|
|
||||||
}).collect()
|
|
||||||
}
|
|
||||||
None => substs_iter.map(|subst| MonoParamId {
|
|
||||||
subst: *subst,
|
|
||||||
vtables: Vec::new()
|
|
||||||
}).collect()
|
|
||||||
};
|
|
||||||
|
|
||||||
@mono_id_ {
|
@mono_id_ {
|
||||||
def: item,
|
def: impl_id,
|
||||||
params: param_ids
|
params: param_ids
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// can't this be checked at the callee?
|
||||||
|
_ => fail!("make_vtable_id needs vtable_static")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue