Auto merge of #52438 - ljedrz:rustc_vec_capacity, r=eddyb

Calculate Vec capacities in librustc

Calculate the required capacity of a few vectors in rustc based on the number of elements they are populated with.
This commit is contained in:
bors 2018-07-21 00:55:46 +00:00
commit bf7afee52a
4 changed files with 48 additions and 58 deletions

View file

@ -562,36 +562,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub fn unsolved_variables(&self) -> Vec<Ty<'tcx>> {
let mut variables = Vec::new();
let mut type_variables = self.type_variables.borrow_mut();
let mut int_unification_table = self.int_unification_table.borrow_mut();
let mut float_unification_table = self.float_unification_table.borrow_mut();
{
let mut type_variables = self.type_variables.borrow_mut();
variables.extend(
type_variables
.unsolved_variables()
.into_iter()
.map(|t| self.tcx.mk_var(t)));
}
{
let mut int_unification_table = self.int_unification_table.borrow_mut();
variables.extend(
type_variables
.unsolved_variables()
.into_iter()
.map(|t| self.tcx.mk_var(t))
.chain(
(0..int_unification_table.len())
.map(|i| ty::IntVid { index: i as u32 })
.filter(|&vid| int_unification_table.probe_value(vid).is_none())
.map(|v| self.tcx.mk_int_var(v)));
}
{
let mut float_unification_table = self.float_unification_table.borrow_mut();
variables.extend(
.map(|v| self.tcx.mk_int_var(v))
).chain(
(0..float_unification_table.len())
.map(|i| ty::FloatVid { index: i as u32 })
.filter(|&vid| float_unification_table.probe_value(vid).is_none())
.map(|v| self.tcx.mk_float_var(v)));
}
return variables;
.map(|v| self.tcx.mk_float_var(v))
).collect()
}
fn combine_fields(&'a self, trace: TypeTrace<'tcx>, param_env: ty::ParamEnv<'tcx>)

View file

@ -391,16 +391,12 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> {
fn create_and_seed_worklist<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
access_levels: &privacy::AccessLevels,
krate: &hir::Crate)
-> Vec<ast::NodeId> {
let mut worklist = Vec::new();
for (id, _) in &access_levels.map {
worklist.push(*id);
}
// Seed entry point
if let Some((id, _, _)) = *tcx.sess.entry_fn.borrow() {
worklist.push(id);
}
-> Vec<ast::NodeId>
{
let worklist = access_levels.map.iter().map(|(&id, _)| id).chain(
// Seed entry point
tcx.sess.entry_fn.borrow().map(|(id, _, _)| id)
).collect::<Vec<_>>();
// Seed implemented trait items
let mut life_seeder = LifeSeeder {

View file

@ -565,7 +565,13 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
}
fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
let mut llargument_tys = Vec::new();
let args_capacity: usize = self.args.iter().map(|arg|
if arg.pad.is_some() { 1 } else { 0 } +
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
).sum();
let mut llargument_tys = Vec::with_capacity(
if let PassMode::Indirect(_) = self.ret.mode { 1 } else { 0 } + args_capacity
);
let llreturn_ty = match self.ret.mode {
PassMode::Ignore => Type::void(cx),

View file

@ -1473,35 +1473,34 @@ impl<'a, 'gcx, 'tcx> Bounds<'tcx> {
pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>)
-> Vec<ty::Predicate<'tcx>>
{
let mut vec = Vec::new();
// If it could be sized, and is, add the sized predicate
if self.implicitly_sized {
if let Some(sized) = tcx.lang_items().sized_trait() {
let sized_predicate = if self.implicitly_sized {
tcx.lang_items().sized_trait().map(|sized| {
let trait_ref = ty::TraitRef {
def_id: sized,
substs: tcx.mk_substs_trait(param_ty, &[])
};
vec.push(trait_ref.to_predicate());
}
}
trait_ref.to_predicate()
})
} else {
None
};
for &region_bound in &self.region_bounds {
// account for the binder being introduced below; no need to shift `param_ty`
// because, at present at least, it can only refer to early-bound regions
let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
vec.push(
ty::Binder::dummy(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate());
}
for bound_trait_ref in &self.trait_bounds {
vec.push(bound_trait_ref.to_predicate());
}
for projection in &self.projection_bounds {
vec.push(projection.to_predicate());
}
vec
sized_predicate.into_iter().chain(
self.region_bounds.iter().map(|&region_bound| {
// account for the binder being introduced below; no need to shift `param_ty`
// because, at present at least, it can only refer to early-bound regions
let region_bound = tcx.mk_region(ty::fold::shift_region(*region_bound, 1));
ty::Binder::dummy(ty::OutlivesPredicate(param_ty, region_bound)).to_predicate()
}).chain(
self.trait_bounds.iter().map(|bound_trait_ref| {
bound_trait_ref.to_predicate()
})
).chain(
self.projection_bounds.iter().map(|projection| {
projection.to_predicate()
})
)
).collect()
}
}