about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicholas Nethercote <nnethercote@mozilla.com>2020-05-07 15:03:45 +1000
committerNicholas Nethercote <nnethercote@mozilla.com>2020-05-07 15:03:45 +1000
commitcbc577fc719e00f60004c8b22db0256f4c9da4b2 (patch)
tree993d6f72f086416bec155b180a5c3e602eaf7ec4 /src
parenta0c61a904482129989f5c1e5cb9f1008efb76f7f (diff)
downloadrust-cbc577fc719e00f60004c8b22db0256f4c9da4b2.tar.gz
rust-cbc577fc719e00f60004c8b22db0256f4c9da4b2.zip
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.)
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir_build/hair/pattern/_match.rs7
-rw-r--r--src/librustc_mir_build/hair/pattern/check_match.rs20
2 files changed, 18 insertions, 9 deletions
diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs
index de3ae2e961f..4e8ec6152e3 100644
--- a/src/librustc_mir_build/hair/pattern/_match.rs
+++ b/src/librustc_mir_build/hair/pattern/_match.rs
@@ -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 {
diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs
index c90634e511b..eda694ee2cb 100644
--- a/src/librustc_mir_build/hair/pattern/check_match.rs
+++ b/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;
@@ -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) {
@@ -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));
 }
 
@@ -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> {
@@ -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(