Skip to content

Commit

Permalink
Reduce TypedArena creations in check_match.
Browse files Browse the repository at this point in the history
`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.)
  • Loading branch information
nnethercote committed May 7, 2020
1 parent a0c61a9 commit cbc577f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
7 changes: 3 additions & 4 deletions src/librustc_mir_build/hair/pattern/_match.rs
Expand Up @@ -588,12 +588,11 @@ impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
crate fn create_and_enter<R>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
pattern_arena: &'a TypedArena<Pat<'tcx>>,
module: DefId,
f: impl FnOnce(MatchCheckCtxt<'_, 'tcx>) -> R,
f: impl FnOnce(MatchCheckCtxt<'a, 'tcx>) -> R,
) -> R {
let pattern_arena = TypedArena::default();

f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena })
f(MatchCheckCtxt { tcx, param_env, module, pattern_arena })
}

fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
Expand Down
20 changes: 15 additions & 5 deletions src/librustc_mir_build/hair/pattern/check_match.rs
@@ -1,9 +1,9 @@
use super::_match::Usefulness::*;
use super::_match::WitnessPreference::*;
use super::_match::{expand_pattern, is_useful, MatchCheckCtxt, Matrix, PatStack};

use super::{PatCtxt, PatKind, PatternError};

use arena::TypedArena;
use rustc_ast::ast::Mutability;
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir;
Expand All @@ -17,7 +17,6 @@ use rustc_session::lint::builtin::{IRREFUTABLE_LET_PATTERNS, UNREACHABLE_PATTERN
use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::{sym, Span};

use std::slice;

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

let mut visitor =
MatchVisitor { tcx, tables: tcx.body_tables(body_id), param_env: tcx.param_env(def_id) };
let mut visitor = MatchVisitor {
tcx,
tables: tcx.body_tables(body_id),
param_env: tcx.param_env(def_id),
pattern_arena: TypedArena::default(),
};
visitor.visit_body(tcx.hir().body(body_id));
}

Expand All @@ -39,6 +42,7 @@ struct MatchVisitor<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
tables: &'a ty::TypeckTables<'tcx>,
param_env: ty::ParamEnv<'tcx>,
pattern_arena: TypedArena<super::Pat<'tcx>>,
}

impl<'tcx> Visitor<'tcx> for MatchVisitor<'_, 'tcx> {
Expand Down Expand Up @@ -145,7 +149,13 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {

fn check_in_cx(&self, hir_id: HirId, f: impl FnOnce(MatchCheckCtxt<'_, 'tcx>)) {
let module = self.tcx.parent_module(hir_id);
MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module.to_def_id(), |cx| f(cx));
MatchCheckCtxt::create_and_enter(
self.tcx,
self.param_env,
&self.pattern_arena,
module.to_def_id(),
f,
);
}

fn check_match(
Expand Down

0 comments on commit cbc577f

Please sign in to comment.