Skip to content

Commit e471c20

Browse files
committed
Auto merge of #50418 - nnethercote:cmt, r=eddyb
Avoid many `cmt` allocations. `cmt` is a ref-counted wrapper around `cmt_` The use of refcounting keeps `cmt` handling simple, but a lot of `cmt` instances are very short-lived, and heap-allocating the short-lived ones takes up time. This patch changes things in the following ways. - Most of the functions that produced `cmt` instances now produce `cmt_` instances. The `Rc::new` calls that occurred within those functions now occur at their call sites (but only when necessary, which isn't that often). - Many of the functions that took `cmt` arguments now take `&cmt_` arguments. This includes all the methods in the `Delegate` trait. As a result, the vast majority of the heap allocations are avoided. In an extreme case, the number of calls to malloc in tuple-stress drops from 9.9M to 7.9M, a drop of 20%. And the compile times for many runs of coercions, deep-vector, and tuple-stress drop by 1--2%.
2 parents fc6b2c5 + 7cf142f commit e471c20

File tree

12 files changed

+208
-209
lines changed

12 files changed

+208
-209
lines changed

src/librustc/middle/expr_use_visitor.rs

+30-30
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use ty::{self, TyCtxt, adjustment};
2828

2929
use hir::{self, PatKind};
3030
use rustc_data_structures::sync::Lrc;
31+
use std::rc::Rc;
3132
use syntax::ast;
3233
use syntax::ptr::P;
3334
use syntax_pos::Span;
@@ -44,7 +45,7 @@ pub trait Delegate<'tcx> {
4445
fn consume(&mut self,
4546
consume_id: ast::NodeId,
4647
consume_span: Span,
47-
cmt: mc::cmt<'tcx>,
48+
cmt: &mc::cmt_<'tcx>,
4849
mode: ConsumeMode);
4950

5051
// The value found at `cmt` has been determined to match the
@@ -61,22 +62,22 @@ pub trait Delegate<'tcx> {
6162
// called on a subpart of an input passed to `matched_pat).
6263
fn matched_pat(&mut self,
6364
matched_pat: &hir::Pat,
64-
cmt: mc::cmt<'tcx>,
65+
cmt: &mc::cmt_<'tcx>,
6566
mode: MatchMode);
6667

6768
// The value found at `cmt` is either copied or moved via the
6869
// pattern binding `consume_pat`, depending on mode.
6970
fn consume_pat(&mut self,
7071
consume_pat: &hir::Pat,
71-
cmt: mc::cmt<'tcx>,
72+
cmt: &mc::cmt_<'tcx>,
7273
mode: ConsumeMode);
7374

7475
// The value found at `borrow` is being borrowed at the point
7576
// `borrow_id` for the region `loan_region` with kind `bk`.
7677
fn borrow(&mut self,
7778
borrow_id: ast::NodeId,
7879
borrow_span: Span,
79-
cmt: mc::cmt<'tcx>,
80+
cmt: &mc::cmt_<'tcx>,
8081
loan_region: ty::Region<'tcx>,
8182
bk: ty::BorrowKind,
8283
loan_cause: LoanCause);
@@ -90,7 +91,7 @@ pub trait Delegate<'tcx> {
9091
fn mutate(&mut self,
9192
assignment_id: ast::NodeId,
9293
assignment_span: Span,
93-
assignee_cmt: mc::cmt<'tcx>,
94+
assignee_cmt: &mc::cmt_<'tcx>,
9495
mode: MutateMode);
9596
}
9697

@@ -316,11 +317,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
316317

317318
let fn_body_scope_r =
318319
self.tcx().mk_region(ty::ReScope(region::Scope::Node(body.value.hir_id.local_id)));
319-
let arg_cmt = self.mc.cat_rvalue(
320+
let arg_cmt = Rc::new(self.mc.cat_rvalue(
320321
arg.id,
321322
arg.pat.span,
322323
fn_body_scope_r, // Args live only as long as the fn body.
323-
arg_ty);
324+
arg_ty));
324325

325326
self.walk_irrefutable_pat(arg_cmt, &arg.pat);
326327
}
@@ -335,11 +336,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
335336
fn delegate_consume(&mut self,
336337
consume_id: ast::NodeId,
337338
consume_span: Span,
338-
cmt: mc::cmt<'tcx>) {
339+
cmt: &mc::cmt_<'tcx>) {
339340
debug!("delegate_consume(consume_id={}, cmt={:?})",
340341
consume_id, cmt);
341342

342-
let mode = copy_or_move(&self.mc, self.param_env, &cmt, DirectRefMove);
343+
let mode = copy_or_move(&self.mc, self.param_env, cmt, DirectRefMove);
343344
self.delegate.consume(consume_id, consume_span, cmt, mode);
344345
}
345346

@@ -353,7 +354,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
353354
debug!("consume_expr(expr={:?})", expr);
354355

355356
let cmt = return_if_err!(self.mc.cat_expr(expr));
356-
self.delegate_consume(expr.id, expr.span, cmt);
357+
self.delegate_consume(expr.id, expr.span, &cmt);
357358
self.walk_expr(expr);
358359
}
359360

@@ -362,7 +363,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
362363
expr: &hir::Expr,
363364
mode: MutateMode) {
364365
let cmt = return_if_err!(self.mc.cat_expr(expr));
365-
self.delegate.mutate(assignment_expr.id, assignment_expr.span, cmt, mode);
366+
self.delegate.mutate(assignment_expr.id, assignment_expr.span, &cmt, mode);
366367
self.walk_expr(expr);
367368
}
368369

@@ -375,7 +376,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
375376
expr, r, bk);
376377

377378
let cmt = return_if_err!(self.mc.cat_expr(expr));
378-
self.delegate.borrow(expr.id, expr.span, cmt, r, bk, cause);
379+
self.delegate.borrow(expr.id, expr.span, &cmt, r, bk, cause);
379380

380381
self.walk_expr(expr)
381382
}
@@ -435,7 +436,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
435436
}
436437

437438
hir::ExprMatch(ref discr, ref arms, _) => {
438-
let discr_cmt = return_if_err!(self.mc.cat_expr(&discr));
439+
let discr_cmt = Rc::new(return_if_err!(self.mc.cat_expr(&discr)));
439440
let r = self.tcx().types.re_empty;
440441
self.borrow_expr(&discr, r, ty::ImmBorrow, MatchDiscriminant);
441442

@@ -619,7 +620,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
619620
// "assigns", which is handled by
620621
// `walk_pat`:
621622
self.walk_expr(&expr);
622-
let init_cmt = return_if_err!(self.mc.cat_expr(&expr));
623+
let init_cmt = Rc::new(return_if_err!(self.mc.cat_expr(&expr)));
623624
self.walk_irrefutable_pat(init_cmt, &local.pat);
624625
}
625626
}
@@ -652,7 +653,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
652653
None => { return; }
653654
};
654655

655-
let with_cmt = return_if_err!(self.mc.cat_expr(&with_expr));
656+
let with_cmt = Rc::new(return_if_err!(self.mc.cat_expr(&with_expr)));
656657

657658
// Select just those fields of the `with`
658659
// expression that will actually be used
@@ -671,7 +672,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
671672
with_field.name,
672673
with_field.ty(self.tcx(), substs)
673674
);
674-
self.delegate_consume(with_expr.id, with_expr.span, cmt_field);
675+
self.delegate_consume(with_expr.id, with_expr.span, &cmt_field);
675676
}
676677
}
677678
}
@@ -710,7 +711,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
710711
adjustment::Adjust::Unsize => {
711712
// Creating a closure/fn-pointer or unsizing consumes
712713
// the input and stores it into the resulting rvalue.
713-
self.delegate_consume(expr.id, expr.span, cmt.clone());
714+
self.delegate_consume(expr.id, expr.span, &cmt);
714715
}
715716

716717
adjustment::Adjust::Deref(None) => {}
@@ -722,12 +723,11 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
722723
// this is an autoref of `x`.
723724
adjustment::Adjust::Deref(Some(ref deref)) => {
724725
let bk = ty::BorrowKind::from_mutbl(deref.mutbl);
725-
self.delegate.borrow(expr.id, expr.span, cmt.clone(),
726-
deref.region, bk, AutoRef);
726+
self.delegate.borrow(expr.id, expr.span, &cmt, deref.region, bk, AutoRef);
727727
}
728728

729729
adjustment::Adjust::Borrow(ref autoref) => {
730-
self.walk_autoref(expr, cmt.clone(), autoref);
730+
self.walk_autoref(expr, &cmt, autoref);
731731
}
732732
}
733733
cmt = return_if_err!(self.mc.cat_expr_adjusted(expr, cmt, &adjustment));
@@ -739,7 +739,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
739739
/// after all relevant autoderefs have occurred.
740740
fn walk_autoref(&mut self,
741741
expr: &hir::Expr,
742-
cmt_base: mc::cmt<'tcx>,
742+
cmt_base: &mc::cmt_<'tcx>,
743743
autoref: &adjustment::AutoBorrow<'tcx>) {
744744
debug!("walk_autoref(expr.id={} cmt_base={:?} autoref={:?})",
745745
expr.id,
@@ -852,7 +852,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
852852
// Each match binding is effectively an assignment to the
853853
// binding being produced.
854854
let def = Def::Local(canonical_id);
855-
if let Ok(binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) {
855+
if let Ok(ref binding_cmt) = mc.cat_def(pat.id, pat.span, pat_ty, def) {
856856
delegate.mutate(pat.id, pat.span, binding_cmt, MutateMode::Init);
857857
}
858858

@@ -861,13 +861,13 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
861861
ty::BindByReference(m) => {
862862
if let ty::TyRef(r, _) = pat_ty.sty {
863863
let bk = ty::BorrowKind::from_mutbl(m);
864-
delegate.borrow(pat.id, pat.span, cmt_pat, r, bk, RefBinding);
864+
delegate.borrow(pat.id, pat.span, &cmt_pat, r, bk, RefBinding);
865865
}
866866
}
867867
ty::BindByValue(..) => {
868868
let mode = copy_or_move(mc, param_env, &cmt_pat, PatBindingMove);
869869
debug!("walk_pat binding consuming pat");
870-
delegate.consume_pat(pat, cmt_pat, mode);
870+
delegate.consume_pat(pat, &cmt_pat, mode);
871871
}
872872
}
873873
}
@@ -891,12 +891,12 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
891891
let downcast_cmt = mc.cat_downcast_if_needed(pat, cmt_pat, variant_did);
892892

893893
debug!("variant downcast_cmt={:?} pat={:?}", downcast_cmt, pat);
894-
delegate.matched_pat(pat, downcast_cmt, match_mode);
894+
delegate.matched_pat(pat, &downcast_cmt, match_mode);
895895
}
896896
Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
897897
Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => {
898898
debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
899-
delegate.matched_pat(pat, cmt_pat, match_mode);
899+
delegate.matched_pat(pat, &cmt_pat, match_mode);
900900
}
901901
_ => {}
902902
}
@@ -924,12 +924,12 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
924924
self.param_env,
925925
&cmt_var,
926926
CaptureMove);
927-
self.delegate.consume(closure_expr.id, freevar.span, cmt_var, mode);
927+
self.delegate.consume(closure_expr.id, freevar.span, &cmt_var, mode);
928928
}
929929
ty::UpvarCapture::ByRef(upvar_borrow) => {
930930
self.delegate.borrow(closure_expr.id,
931931
fn_decl_span,
932-
cmt_var,
932+
&cmt_var,
933933
upvar_borrow.region,
934934
upvar_borrow.kind,
935935
ClosureCapture(freevar.span));
@@ -943,7 +943,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
943943
closure_id: ast::NodeId,
944944
closure_span: Span,
945945
upvar: &hir::Freevar)
946-
-> mc::McResult<mc::cmt<'tcx>> {
946+
-> mc::McResult<mc::cmt_<'tcx>> {
947947
// Create the cmt for the variable being borrowed, from the
948948
// caller's perspective
949949
let var_hir_id = self.tcx().hir.node_to_hir_id(upvar.var_id());
@@ -954,7 +954,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
954954

955955
fn copy_or_move<'a, 'gcx, 'tcx>(mc: &mc::MemCategorizationContext<'a, 'gcx, 'tcx>,
956956
param_env: ty::ParamEnv<'tcx>,
957-
cmt: &mc::cmt<'tcx>,
957+
cmt: &mc::cmt_<'tcx>,
958958
move_reason: MoveReason)
959959
-> ConsumeMode
960960
{

0 commit comments

Comments
 (0)