diff options
| author | The 8472 <git@infinite-source.de> | 2023-03-06 15:07:02 +0100 |
|---|---|---|
| committer | The 8472 <git@infinite-source.de> | 2023-03-17 19:56:03 +0100 |
| commit | 7cce618d18c8203369d605d1ccedcfda09d58acc (patch) | |
| tree | c66fb6e99f48f923502f04644133e71654509e3f /compiler/rustc_trait_selection/src | |
| parent | 03b01c5bec658081605ab078ad3fbcdb6b30f6c2 (diff) | |
Fast path that skips over unchanged obligations in process_obligations
- only borrow the refcell once per loop - avoid complex matches to reduce branch paths in the hot loop - use a by-ref fast path that avoids mutations at the expense of having false negatives
Diffstat (limited to 'compiler/rustc_trait_selection/src')
| -rw-r--r-- | compiler/rustc_trait_selection/src/traits/fulfill.rs | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index 1aaadae12dd..23754480fcf 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -211,6 +211,29 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { type Error = FulfillmentErrorCode<'tcx>; type OUT = Outcome<Self::Obligation, Self::Error>; + /// Compared to `needs_process_obligation` this and its callees + /// contain some optimizations that come at the price of false negatives. + /// + /// They + /// - reduce branching by covering only the most common case + /// - take a read-only view of the unification tables which allows skipping undo_log + /// construction. + /// - bail out on value-cache misses in ena to avoid pointer chasing + /// - hoist RefCell locking out of the loop + #[inline] + fn skippable_obligations<'b>( + &'b self, + it: impl Iterator<Item = &'b Self::Obligation>, + ) -> usize { + let is_unchanged = self.selcx.infcx.is_ty_infer_var_definitely_unchanged(); + + it.take_while(|o| match o.stalled_on.as_slice() { + [o] => is_unchanged(*o), + _ => false, + }) + .count() + } + /// Identifies whether a predicate obligation needs processing. /// /// This is always inlined because it has a single callsite and it is |
