diff options
| author | bors <bors@rust-lang.org> | 2024-07-03 18:52:04 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-07-03 18:52:04 +0000 |
| commit | 2b90614e94cfb400820cfc10fe63b0db74f9e67a (patch) | |
| tree | a51d4dc4c105955b3a8766e7b0b471d8f8ab8c41 /compiler/rustc_mir_transform/src | |
| parent | 1cfd47fe0b78f48a04ac8fce792a406b638da40b (diff) | |
| parent | 76244d4dbc768e15e429c1f66ec021884f369f5f (diff) | |
| download | rust-2b90614e94cfb400820cfc10fe63b0db74f9e67a.tar.gz rust-2b90614e94cfb400820cfc10fe63b0db74f9e67a.zip | |
Auto merge of #127036 - cjgillot:sparse-state, r=oli-obk
Make jump threading state sparse Continuation of https://github.com/rust-lang/rust/pull/127024 Both dataflow const-prop and jump threading involve cloning the state vector a lot. This PR replaces the data structure by a sparse vector, considering: - that jump threading state is typically very sparse (at most 1 or 2 set entries); - that dataflow const-prop is disabled by default; - that place/value map is very eager, and prone to creating an overly large state. The first commit is shared with the previous PR to avoid needless conflicts. r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/jump_threading.rs | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs index 27e506a920b..85a61f95ca3 100644 --- a/compiler/rustc_mir_transform/src/jump_threading.rs +++ b/compiler/rustc_mir_transform/src/jump_threading.rs @@ -47,6 +47,7 @@ use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::ty::layout::LayoutOf; use rustc_middle::ty::{self, ScalarInt, TyCtxt}; +use rustc_mir_dataflow::lattice::HasBottom; use rustc_mir_dataflow::value_analysis::{Map, PlaceIndex, State, TrackElem}; use rustc_span::DUMMY_SP; use rustc_target::abi::{TagEncoding, Variants}; @@ -158,9 +159,17 @@ impl Condition { } } -#[derive(Copy, Clone, Debug, Default)] +#[derive(Copy, Clone, Debug)] struct ConditionSet<'a>(&'a [Condition]); +impl HasBottom for ConditionSet<'_> { + const BOTTOM: Self = ConditionSet(&[]); + + fn is_bottom(&self) -> bool { + self.0.is_empty() + } +} + impl<'a> ConditionSet<'a> { fn iter(self) -> impl Iterator<Item = Condition> + 'a { self.0.iter().copied() @@ -177,7 +186,7 @@ impl<'a> ConditionSet<'a> { impl<'tcx, 'a> TOFinder<'tcx, 'a> { fn is_empty(&self, state: &State<ConditionSet<'a>>) -> bool { - state.all(|cs| cs.0.is_empty()) + state.all_bottom() } /// Recursion entry point to find threading opportunities. @@ -198,7 +207,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { debug!(?discr); let cost = CostChecker::new(self.tcx, self.param_env, None, self.body); - let mut state = State::new(ConditionSet::default(), self.map); + let mut state = State::new_reachable(); let conds = if let Some((value, then, else_)) = targets.as_static_if() { let value = ScalarInt::try_from_uint(value, discr_layout.size)?; @@ -255,7 +264,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { // _1 = 5 // Whatever happens here, it won't change the result of a `SwitchInt`. // _1 = 6 if let Some((lhs, tail)) = self.mutated_statement(stmt) { - state.flood_with_tail_elem(lhs.as_ref(), tail, self.map, ConditionSet::default()); + state.flood_with_tail_elem(lhs.as_ref(), tail, self.map, ConditionSet::BOTTOM); } } @@ -609,7 +618,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> { // We can recurse through this terminator. let mut state = state(); if let Some(place_to_flood) = place_to_flood { - state.flood_with(place_to_flood.as_ref(), self.map, ConditionSet::default()); + state.flood_with(place_to_flood.as_ref(), self.map, ConditionSet::BOTTOM); } self.find_opportunity(bb, state, cost.clone(), depth + 1); } |
