Skip to content

Commit cbc577f

Browse files
committed
Reduce TypedArena creations in check_match.
`check_match` creates a new `TypedArena` for every call to `create_and_enter`. DHAT tells me that each `TypedArena` typically is barely used, with typically a single allocation per arena. This commit moves the `TypedArena` creation outwards a bit, into `check_match`, and then passes it into `create_and_enter`. This reduces the number of arenas created by about 4-5x, for a very small perf win. (Moving the arena creation further outwards is hard because `check_match` is a query.)
1 parent a0c61a9 commit cbc577f

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

src/librustc_mir_build/hair/pattern/_match.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -588,12 +588,11 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
588588
crate fn create_and_enter<R>(
589589
tcx: TyCtxt<'tcx>,
590590
param_env: ty::ParamEnv<'tcx>,
591+
pattern_arena: &'a TypedArena<Pat<'tcx>>,
591592
module: DefId,
592-
f: impl FnOnce(MatchCheckCtxt<'_, 'tcx>) -> R,
593+
f: impl FnOnce(MatchCheckCtxt<'a, 'tcx>) -> R,
593594
) -> R {
594-
let pattern_arena = TypedArena::default();
595-
596-
f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena })
595+
f(MatchCheckCtxt { tcx, param_env, module, pattern_arena })
597596
}
598597

599598
fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {

src/librustc_mir_build/hair/pattern/check_match.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use super::_match::Usefulness::*;
22
use super::_match::WitnessPreference::*;
33
use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack};
4-
54
use super::{PatCtxt, PatKind, PatternError};
65

6+
use arena::TypedArena;
77
use rustc_ast::ast::Mutability;
88
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
99
use rustc_hir as hir;
@@ -17,7 +17,6 @@ use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERN
1717
use rustc_session::parse::feature_err;
1818
use rustc_session::Session;
1919
use rustc_span::{sym, Span};
20-
2120
use std::slice;
2221

2322
crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
@@ -26,8 +25,12 @@ crate fn check_match(tcx: TyCtxt<'_>, def_id: DefId) {
2625
Some(id) => tcx.hir().body_owned_by(tcx.hir().as_local_hir_id(id)),
2726
};
2827

29-
let mut visitor =
30-
MatchVisitor { tcx, tables: tcx.body_tables(body_id), param_env: tcx.param_env(def_id) };
28+
let mut visitor = MatchVisitor {
29+
tcx,
30+
tables: tcx.body_tables(body_id),
31+
param_env: tcx.param_env(def_id),
32+
pattern_arena: TypedArena::default(),
33+
};
3134
visitor.visit_body(tcx.hir().body(body_id));
3235
}
3336

@@ -39,6 +42,7 @@ struct MatchVisitor<'a, 'tcx> {
3942
tcx: TyCtxt<'tcx>,
4043
tables: &'a ty::TypeckTables<'tcx>,
4144
param_env: ty::ParamEnv<'tcx>,
45+
pattern_arena: TypedArena<super::Pat<'tcx>>,
4246
}
4347

4448
impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
@@ -145,7 +149,13 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
145149

146150
fn check_in_cx(&self, hir_id: HirId, f: impl FnOnce(MatchCheckCtxt<'_, 'tcx>)) {
147151
let module = self.tcx.parent_module(hir_id);
148-
MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module.to_def_id(), |cx| f(cx));
152+
MatchCheckCtxt::create_and_enter(
153+
self.tcx,
154+
self.param_env,
155+
&self.pattern_arena,
156+
module.to_def_id(),
157+
f,
158+
);
149159
}
150160

151161
fn check_match(

0 commit comments

Comments
 (0)