Skip to content

Commit 02ad572

Browse files
author
Ariel Ben-Yehuda
committed
avoid calling mk_region unnecessarily
this improves typeck & trans performance by 1%. This looked hotter on callgrind than it is on a CPU.
1 parent 64c6978 commit 02ad572

File tree

27 files changed

+85
-55
lines changed

27 files changed

+85
-55
lines changed

src/librustc/infer/freshen.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for TypeFreshener<'a, 'gcx, 'tcx> {
9999
ty::ReEmpty |
100100
ty::ReErased => {
101101
// replace all free regions with 'erased
102-
self.tcx().mk_region(ty::ReErased)
102+
self.tcx().types.re_erased
103103
}
104104
}
105105
}

src/librustc/infer/region_inference/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -948,7 +948,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
948948
} else {
949949
// otherwise, we don't know what the free region is,
950950
// so we must conservatively say the LUB is static:
951-
self.tcx.mk_region(ReStatic)
951+
self.tcx.types.re_static
952952
}
953953
}
954954

@@ -971,7 +971,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
971971
if a == b {
972972
a
973973
} else {
974-
self.tcx.mk_region(ReStatic)
974+
self.tcx.types.re_static
975975
}
976976
}
977977
}
@@ -1018,7 +1018,7 @@ impl<'a, 'gcx, 'tcx> RegionVarBindings<'a, 'gcx, 'tcx> {
10181018

10191019
fn construct_var_data(&self) -> Vec<VarValue<'tcx>> {
10201020
(0..self.num_vars() as usize)
1021-
.map(|_| Value(self.tcx.mk_region(ty::ReEmpty)))
1021+
.map(|_| Value(self.tcx.types.re_empty))
10221022
.collect()
10231023
}
10241024

@@ -1493,7 +1493,7 @@ fn lookup<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
14931493
-> &'tcx ty::Region {
14941494
match values[rid.index as usize] {
14951495
Value(r) => r,
1496-
ErrorValue => tcx.mk_region(ReStatic), // Previously reported error.
1496+
ErrorValue => tcx.types.re_static, // Previously reported error.
14971497
}
14981498
}
14991499

src/librustc/middle/expr_use_visitor.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
426426

427427
hir::ExprMatch(ref discr, ref arms, _) => {
428428
let discr_cmt = return_if_err!(self.mc.cat_expr(&discr));
429-
let r = self.tcx().mk_region(ty::ReEmpty);
429+
let r = self.tcx().types.re_empty;
430430
self.borrow_expr(&discr, r, ty::ImmBorrow, MatchDiscriminant);
431431

432432
// treatment of the discriminant is handled while walking the arms.

src/librustc/middle/mem_categorization.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -871,8 +871,8 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
871871
// we can promote to a constant, otherwise equal to enclosing temp
872872
// lifetime.
873873
let (re, old_re) = if promotable {
874-
(self.tcx().mk_region(ty::ReStatic),
875-
self.tcx().mk_region(ty::ReStatic))
874+
(self.tcx().types.re_static,
875+
self.tcx().types.re_static)
876876
} else {
877877
self.temporary_scope(id)
878878
};

src/librustc/traits/fulfill.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ fn process_predicate<'a, 'gcx, 'tcx>(
433433
// Otherwise, we have something of the form
434434
// `for<'a> T: 'a where 'a not in T`, which we can treat as `T: 'static`.
435435
Some(t_a) => {
436-
let r_static = selcx.tcx().mk_region(ty::ReStatic);
436+
let r_static = selcx.tcx().types.re_static;
437437
register_region_obligation(t_a, r_static,
438438
obligation.cause.clone(),
439439
region_obligations);

src/librustc/traits/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -628,7 +628,7 @@ pub fn get_vtable_methods<'a, 'tcx>(
628628
// the method may have some early-bound lifetimes, add
629629
// regions for those
630630
let substs = Substs::for_item(tcx, def_id,
631-
|_, _| tcx.mk_region(ty::ReErased),
631+
|_, _| tcx.types.re_erased,
632632
|def, _| trait_ref.substs().type_for_def(def));
633633

634634
// the trait type may have higher-ranked lifetimes in it;

src/librustc/ty/context.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ pub struct CommonTypes<'tcx> {
190190
pub f64: Ty<'tcx>,
191191
pub never: Ty<'tcx>,
192192
pub err: Ty<'tcx>,
193+
194+
pub re_empty: &'tcx Region,
195+
pub re_static: &'tcx Region,
196+
pub re_erased: &'tcx Region,
193197
}
194198

195199
#[derive(RustcEncodable, RustcDecodable)]
@@ -360,6 +364,14 @@ impl<'tcx> TypeckTables<'tcx> {
360364
impl<'tcx> CommonTypes<'tcx> {
361365
fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
362366
let mk = |sty| interners.intern_ty(sty, None);
367+
let mk_region = |r| {
368+
if let Some(r) = interners.region.borrow().get(&r) {
369+
return r.0;
370+
}
371+
let r = interners.arena.alloc(r);
372+
interners.region.borrow_mut().insert(Interned(r));
373+
&*r
374+
};
363375
CommonTypes {
364376
bool: mk(TyBool),
365377
char: mk(TyChar),
@@ -379,6 +391,10 @@ impl<'tcx> CommonTypes<'tcx> {
379391
u128: mk(TyUint(ast::UintTy::U128)),
380392
f32: mk(TyFloat(ast::FloatTy::F32)),
381393
f64: mk(TyFloat(ast::FloatTy::F64)),
394+
395+
re_empty: mk_region(Region::ReEmpty),
396+
re_static: mk_region(Region::ReStatic),
397+
re_erased: mk_region(Region::ReErased),
382398
}
383399
}
384400
}
@@ -1233,7 +1249,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
12331249
}
12341250

12351251
pub fn mk_static_str(self) -> Ty<'tcx> {
1236-
self.mk_imm_ref(self.mk_region(ty::ReStatic), self.mk_str())
1252+
self.mk_imm_ref(self.types.re_static, self.mk_str())
12371253
}
12381254

12391255
pub fn mk_adt(self, def: &'tcx AdtDef, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {

src/librustc/ty/fold.rs

+19-3
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
410410
pub fn erase_late_bound_regions<T>(self, value: &Binder<T>) -> T
411411
where T : TypeFoldable<'tcx>
412412
{
413-
self.replace_late_bound_regions(value, |_| self.mk_region(ty::ReErased)).0
413+
self.replace_late_bound_regions(value, |_| self.types.re_erased).0
414414
}
415415

416416
/// Rewrite any late-bound regions so that they are anonymous. Region numbers are
@@ -538,7 +538,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
538538
// whenever a substitution occurs.
539539
match *r {
540540
ty::ReLateBound(..) => r,
541-
_ => self.tcx().mk_region(ty::ReErased)
541+
_ => self.tcx().types.re_erased
542542
}
543543
}
544544
}
@@ -565,6 +565,22 @@ pub fn shift_region(region: ty::Region, amount: u32) -> ty::Region {
565565
}
566566
}
567567

568+
pub fn shift_region_ref<'a, 'gcx, 'tcx>(
569+
tcx: TyCtxt<'a, 'gcx, 'tcx>,
570+
region: &'tcx ty::Region,
571+
amount: u32)
572+
-> &'tcx ty::Region
573+
{
574+
match region {
575+
&ty::ReLateBound(debruijn, br) if amount > 0 => {
576+
tcx.mk_region(ty::ReLateBound(debruijn.shifted(amount), br))
577+
}
578+
_ => {
579+
region
580+
}
581+
}
582+
}
583+
568584
pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
569585
amount: u32, value: &T) -> T
570586
where T: TypeFoldable<'tcx>
@@ -573,7 +589,7 @@ pub fn shift_regions<'a, 'gcx, 'tcx, T>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
573589
value, amount);
574590

575591
value.fold_with(&mut RegionFolder::new(tcx, &mut false, &mut |region, _current_depth| {
576-
tcx.mk_region(shift_region(*region, amount))
592+
shift_region_ref(tcx, region, amount)
577593
}))
578594
}
579595

src/librustc/ty/mod.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -2520,15 +2520,13 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
25202520
/// Construct a parameter environment suitable for static contexts or other contexts where there
25212521
/// are no free type/lifetime parameters in scope.
25222522
pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> {
2523-
2524-
// for an empty parameter environment, there ARE no free
2525-
// regions, so it shouldn't matter what we use for the free id
2526-
let free_id_outlive = self.region_maps.node_extent(ast::DUMMY_NODE_ID);
25272523
ty::ParameterEnvironment {
25282524
free_substs: self.intern_substs(&[]),
25292525
caller_bounds: Vec::new(),
2530-
implicit_region_bound: self.mk_region(ty::ReEmpty),
2531-
free_id_outlive: free_id_outlive,
2526+
implicit_region_bound: self.types.re_empty,
2527+
// for an empty parameter environment, there ARE no free
2528+
// regions, so it shouldn't matter what we use for the free id
2529+
free_id_outlive: ROOT_CODE_EXTENT,
25322530
is_copy_cache: RefCell::new(FxHashMap()),
25332531
is_sized_cache: RefCell::new(FxHashMap()),
25342532
}
@@ -2779,4 +2777,3 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
27792777
pub struct CrateInherentImpls {
27802778
pub inherent_impls: DefIdMap<Rc<Vec<DefId>>>,
27812779
}
2782-

src/librustc/ty/subst.rs

+3
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,9 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> {
539539
}
540540

541541
fn shift_region_through_binders(&self, region: &'tcx ty::Region) -> &'tcx ty::Region {
542+
if self.region_binders_passed == 0 || !region.has_escaping_regions() {
543+
return region;
544+
}
542545
self.tcx().mk_region(ty::fold::shift_region(*region, self.region_binders_passed))
543546
}
544547
}

src/librustc/ty/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
412412
/// a suitable "empty substs" for it.
413413
pub fn empty_substs_for_def_id(self, item_def_id: DefId) -> &'tcx ty::Substs<'tcx> {
414414
ty::Substs::for_item(self, item_def_id,
415-
|_, _| self.mk_region(ty::ReErased),
415+
|_, _| self.types.re_erased,
416416
|_, _| {
417417
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
418418
})

src/librustc_borrowck/borrowck/gather_loans/lifetime.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> {
120120
}
121121
Categorization::StaticItem |
122122
Categorization::Deref(.., mc::UnsafePtr(..)) => {
123-
self.bccx.tcx.mk_region(ty::ReStatic)
123+
self.bccx.tcx.types.re_static
124124
}
125125
Categorization::Deref(.., mc::BorrowedPtr(_, r)) |
126126
Categorization::Deref(.., mc::Implicit(_, r)) => {

src/librustc_driver/test.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,12 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> {
343343
}
344344

345345
pub fn t_rptr_static(&self) -> Ty<'tcx> {
346-
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(ty::ReStatic),
346+
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.types.re_static,
347347
self.tcx().types.isize)
348348
}
349349

350350
pub fn t_rptr_empty(&self) -> Ty<'tcx> {
351-
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.mk_region(ty::ReEmpty),
351+
self.infcx.tcx.mk_imm_ref(self.infcx.tcx.types.re_empty,
352352
self.tcx().types.isize)
353353
}
354354

src/librustc_mir/build/matches/test.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
280280
assert!(ty.is_slice());
281281

282282
let array_ty = tcx.mk_array(tcx.types.u8, bytes.len());
283-
let array_ref = tcx.mk_imm_ref(tcx.mk_region(ty::ReStatic), array_ty);
283+
let array_ref = tcx.mk_imm_ref(tcx.types.re_static, array_ty);
284284
let array = self.literal_operand(test.span, array_ref, Literal::Value {
285285
value: value.clone()
286286
});

src/librustc_mir/shim.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,9 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
308308
Adjustment::Deref => Operand::Consume(rcvr_l.deref()),
309309
Adjustment::RefMut => {
310310
// let rcvr = &mut rcvr;
311-
let re_erased = tcx.mk_region(ty::ReErased);
312311
let ref_rcvr = local_decls.push(temp_decl(
313312
Mutability::Not,
314-
tcx.mk_ref(re_erased, ty::TypeAndMut {
313+
tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut {
315314
ty: sig.inputs()[0],
316315
mutbl: hir::Mutability::MutMutable
317316
}),
@@ -321,7 +320,7 @@ fn build_call_shim<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>,
321320
source_info: source_info,
322321
kind: StatementKind::Assign(
323322
Lvalue::Local(ref_rcvr),
324-
Rvalue::Ref(re_erased, BorrowKind::Mut, rcvr_l)
323+
Rvalue::Ref(tcx.types.re_erased, BorrowKind::Mut, rcvr_l)
325324
)
326325
});
327326
Operand::Consume(Lvalue::Local(ref_rcvr))

src/librustc_mir/transform/erase_regions.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//! care erasing regions all over the place.
1414
1515
use rustc::ty::subst::Substs;
16-
use rustc::ty::{Ty, TyCtxt, ReErased, ClosureSubsts};
16+
use rustc::ty::{Ty, TyCtxt, ClosureSubsts};
1717
use rustc::mir::*;
1818
use rustc::mir::visit::MutVisitor;
1919
use rustc::mir::transform::{MirPass, MirSource, Pass};
@@ -43,7 +43,7 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
4343
fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
4444
match *rvalue {
4545
Rvalue::Ref(ref mut r, _, _) => {
46-
*r = self.tcx.mk_region(ReErased);
46+
*r = self.tcx.types.re_erased;
4747
}
4848
Rvalue::Use(..) |
4949
Rvalue::Repeat(..) |

src/librustc_mir/transform/inline.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
497497
let dest = if dest_needs_borrow(&destination.0) {
498498
debug!("Creating temp for return destination");
499499
let dest = Rvalue::Ref(
500-
self.tcx.mk_region(ty::ReErased),
500+
self.tcx.types.re_erased,
501501
BorrowKind::Mut,
502502
destination.0);
503503

@@ -582,7 +582,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
582582
fn cast_box_free_arg(&self, arg: Lvalue<'tcx>, ptr_ty: Ty<'tcx>,
583583
callsite: &CallSite<'tcx>, caller_mir: &mut Mir<'tcx>) -> Operand<'tcx> {
584584
let arg = Rvalue::Ref(
585-
self.tcx.mk_region(ty::ReErased),
585+
self.tcx.types.re_erased,
586586
BorrowKind::Mut,
587587
arg.deref());
588588

src/librustc_mir/util/elaborate_drops.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
507507
let ty = self.lvalue_ty(self.lvalue);
508508
let substs = tcx.mk_substs(iter::once(Kind::from(ty)));
509509

510-
let re_erased = tcx.mk_region(ty::ReErased);
511-
let ref_ty = tcx.mk_ref(re_erased, ty::TypeAndMut {
510+
let ref_ty = tcx.mk_ref(tcx.types.re_erased, ty::TypeAndMut {
512511
ty: ty,
513512
mutbl: hir::Mutability::MutMutable
514513
});
@@ -520,7 +519,7 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
520519
source_info: self.source_info,
521520
kind: StatementKind::Assign(
522521
Lvalue::Local(ref_lvalue),
523-
Rvalue::Ref(re_erased, BorrowKind::Mut, self.lvalue.clone())
522+
Rvalue::Ref(tcx.types.re_erased, BorrowKind::Mut, self.lvalue.clone())
524523
)
525524
}],
526525
terminator: Some(Terminator {

src/librustc_trans/mir/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
710710
let tr_lvalue = self.const_lvalue(lvalue, span)?;
711711

712712
let ty = tr_lvalue.ty;
713-
let ref_ty = tcx.mk_ref(tcx.mk_region(ty::ReErased),
713+
let ref_ty = tcx.mk_ref(tcx.types.re_erased,
714714
ty::TypeAndMut { ty: ty, mutbl: bk.to_mutbl_lossy() });
715715

716716
let base = match tr_lvalue.base {

src/librustc_trans/mir/rvalue.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,7 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
331331

332332
let ty = tr_lvalue.ty.to_ty(bcx.tcx());
333333
let ref_ty = bcx.tcx().mk_ref(
334-
bcx.tcx().mk_region(ty::ReErased),
334+
bcx.tcx().types.re_erased,
335335
ty::TypeAndMut { ty: ty, mutbl: bk.to_mutbl_lossy() }
336336
);
337337

src/librustc_typeck/astconv.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
109109
let tcx = self.tcx();
110110
let r = match tcx.named_region_map.defs.get(&lifetime.id) {
111111
Some(&rl::Region::Static) => {
112-
tcx.mk_region(ty::ReStatic)
112+
tcx.types.re_static
113113
}
114114

115115
Some(&rl::Region::LateBound(debruijn, id)) => {
@@ -171,7 +171,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
171171
.emit();
172172

173173
return Substs::for_item(tcx, def_id, |_, _| {
174-
tcx.mk_region(ty::ReStatic)
174+
tcx.types.re_static
175175
}, |_, _| {
176176
tcx.types.err
177177
});
@@ -254,7 +254,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
254254
if let Some(lifetime) = lifetimes.get(i) {
255255
self.ast_region_to_region(lifetime, Some(def))
256256
} else {
257-
tcx.mk_region(ty::ReStatic)
257+
tcx.types.re_static
258258
}
259259
}, |def, substs| {
260260
let i = def.index as usize;
@@ -715,7 +715,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
715715
span_err!(tcx.sess, span, E0228,
716716
"the lifetime bound for this object type cannot be deduced \
717717
from context; please supply an explicit bound");
718-
tcx.mk_region(ty::ReStatic)
718+
tcx.types.re_static
719719
})
720720
}
721721
})
@@ -1357,7 +1357,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
13571357
// If any of the derived region bounds are 'static, that is always
13581358
// the best choice.
13591359
if derived_region_bounds.iter().any(|&r| ty::ReStatic == *r) {
1360-
return Some(tcx.mk_region(ty::ReStatic));
1360+
return Some(tcx.types.re_static);
13611361
}
13621362

13631363
// Determine whether there is exactly one unique region in the set

0 commit comments

Comments
 (0)