about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-04-23 19:39:40 +0000
committerbors <bors@rust-lang.org>2015-04-23 19:39:40 +0000
commit24e4e60ae8579d674c1eebb0298ee61471ddb6e6 (patch)
tree740bc17e709da1239bb8a3054fb9b62c5560c187
parent69e47c77b257360ec64e714eb97abf6c51475f27 (diff)
parent94a1b266f9b3688d8fb6ff382e7b846a8d4eb38d (diff)
downloadrust-24e4e60ae8579d674c1eebb0298ee61471ddb6e6.tar.gz
rust-24e4e60ae8579d674c1eebb0298ee61471ddb6e6.zip
Auto merge of #24615 - arielb1:rapid-reject, r=nikomatsakis
skolemize_late_bound_regions essentially copies the entire type (most of the times it shouldn't, but it does), and match_impl runs millions of times.

Times compiling rustc, tested with
$ make -j4 rustc-stage1
$ ( time RUSTFLAGS=-Z time-passes make -j4 rustc-stage2 ) # need LLVM time for calibration

Before:
real	21m44.960s
user	29m38.812s
sys	0m14.944s

After:
real	19m31.445s
user	26m47.260s
sys	0m14.952s

Making this is a 10% performance improvement.

LLVM passes took 867 seconds before, 862 seconds after.
-rw-r--r--src/librustc/middle/traits/select.rs47
1 files changed, 20 insertions, 27 deletions
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index ed8a6fb0200..153ec0ab2b3 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -532,11 +532,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                obligation.repr(self.tcx()));
 
         self.infcx.probe(|snapshot| {
-            let (skol_obligation_trait_ref, skol_map) =
-                self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
-            match self.match_impl(impl_def_id, obligation, snapshot,
-                                  &skol_map, skol_obligation_trait_ref.trait_ref.clone()) {
-                Ok(substs) => {
+            match self.match_impl(impl_def_id, obligation, snapshot) {
+                Ok((substs, skol_map)) => {
                     let vtable_impl = self.vtable_impl(impl_def_id,
                                                        substs,
                                                        obligation.cause.clone(),
@@ -1160,10 +1157,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let all_impls = self.all_impls(def_id);
         for &impl_def_id in &all_impls {
             self.infcx.probe(|snapshot| {
-                let (skol_obligation_trait_pred, skol_map) =
-                    self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
-                match self.match_impl(impl_def_id, obligation, snapshot,
-                                      &skol_map, skol_obligation_trait_pred.trait_ref.clone()) {
+                match self.match_impl(impl_def_id, obligation, snapshot) {
                     Ok(_) => {
                         candidates.vec.push(ImplCandidate(impl_def_id));
                     }
@@ -2115,11 +2109,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // First, create the substitutions by matching the impl again,
         // this time not in a probe.
         self.infcx.commit_if_ok(|snapshot| {
-            let (skol_obligation_trait_ref, skol_map) =
-                self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
-            let substs =
+            let (substs, skol_map) =
                 self.rematch_impl(impl_def_id, obligation,
-                                  snapshot, &skol_map, skol_obligation_trait_ref.trait_ref);
+                                  snapshot);
             debug!("confirm_impl_candidate substs={}", substs.repr(self.tcx()));
             Ok(self.vtable_impl(impl_def_id, substs, obligation.cause.clone(),
                                 obligation.recursion_depth + 1, skol_map, snapshot))
@@ -2306,14 +2298,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn rematch_impl(&mut self,
                     impl_def_id: ast::DefId,
                     obligation: &TraitObligation<'tcx>,
-                    snapshot: &infer::CombinedSnapshot,
-                    skol_map: &infer::SkolemizationMap,
-                    skol_obligation_trait_ref: Rc<ty::TraitRef<'tcx>>)
-                    -> Normalized<'tcx, Substs<'tcx>>
+                    snapshot: &infer::CombinedSnapshot)
+                    -> (Normalized<'tcx, Substs<'tcx>>, infer::SkolemizationMap)
     {
-        match self.match_impl(impl_def_id, obligation, snapshot,
-                              skol_map, skol_obligation_trait_ref) {
-            Ok(substs) => substs,
+        match self.match_impl(impl_def_id, obligation, snapshot) {
+            Ok((substs, skol_map)) => (substs, skol_map),
             Err(()) => {
                 self.tcx().sess.bug(
                     &format!("Impl {} was matchable against {} but now is not",
@@ -2326,10 +2315,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn match_impl(&mut self,
                   impl_def_id: ast::DefId,
                   obligation: &TraitObligation<'tcx>,
-                  snapshot: &infer::CombinedSnapshot,
-                  skol_map: &infer::SkolemizationMap,
-                  skol_obligation_trait_ref: Rc<ty::TraitRef<'tcx>>)
-                  -> Result<Normalized<'tcx, Substs<'tcx>>, ()>
+                  snapshot: &infer::CombinedSnapshot)
+                  -> Result<(Normalized<'tcx, Substs<'tcx>>,
+                             infer::SkolemizationMap), ()>
     {
         let impl_trait_ref = ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap();
 
@@ -2340,6 +2328,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return Err(());
         }
 
+        let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions(
+            &obligation.predicate,
+            snapshot);
+        let skol_obligation_trait_ref = skol_obligation.trait_ref;
+
         let impl_substs = util::fresh_type_vars_for_impl(self.infcx,
                                                          obligation.cause.span,
                                                          impl_def_id);
@@ -2370,17 +2363,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return Err(());
         }
 
-        if let Err(e) = self.infcx.leak_check(skol_map, snapshot) {
+        if let Err(e) = self.infcx.leak_check(&skol_map, snapshot) {
             debug!("match_impl: failed leak check due to `{}`",
                    ty::type_err_to_str(self.tcx(), &e));
             return Err(());
         }
 
         debug!("match_impl: success impl_substs={}", impl_substs.repr(self.tcx()));
-        Ok(Normalized {
+        Ok((Normalized {
             value: impl_substs,
             obligations: impl_trait_ref.obligations
-        })
+        }, skol_map))
     }
 
     fn fast_reject_trait_refs(&mut self,