Auto merge of #142821 - cjgillot:jump-threading-single, r=saethlin

Compute jump threading opportunities in a single pass

The current implementation of jump threading walks MIR CFG backwards from each `SwitchInt` terminator. This PR replaces this by a single postorder traversal of MIR. In theory, we could do a full fixpoint dataflow analysis, but this has low returns as we forbid threading through a loop header.

The second commit in this PR modifies the carried state to a lighter data structure. The current implementation uses some kind of `IndexVec<ValueIndex, &[Condition]>`. This is needlessly heavy, as the state rarely ever carries more than a few `Condition`s. The first commit replaces this state with a simpler `&[Condition]`, and puts the corresponding `ValueIndex` inside `Condition`.

The three later commits are perf tweaks.

The sixth commit is the main change. Instead of carrying the goto target inside the condition, we maintain a set of conditions associated with each block, and their consequences in following blocks. Think: if this condition is fulfilled in this block, then that condition is fulfilled in that block. This makes the threading algorithm much easier to implement, without the extra bookkeeping of `ThreadingOpportunity` we had.

Later commits modify that algorithm to shrink the set of duplicated blocks. By propagating fulfilled conditions down the CFG, and trimming costly threads.
This commit is contained in:
bors 2025-12-01 23:44:49 +00:00
commit 4ad239f415
27 changed files with 1839 additions and 808 deletions

View file

@ -24,9 +24,7 @@ rustc_index::newtype_index!(
rustc_index::newtype_index!(
/// This index uniquely identifies a tracked place and therefore a slot in [`State`].
///
/// It is an implementation detail of this module.
struct ValueIndex {}
pub struct ValueIndex {}
);
/// See [`State`].
@ -211,22 +209,9 @@ impl<V: Clone + HasBottom> State<V> {
/// The target place must have been flooded before calling this method.
pub fn insert_place_idx(&mut self, target: PlaceIndex, source: PlaceIndex, map: &Map<'_>) {
let State::Reachable(values) = self else { return };
// If both places are tracked, we copy the value to the target.
// If the target is tracked, but the source is not, we do nothing, as invalidation has
// already been performed.
if let Some(target_value) = map.places[target].value_index
&& let Some(source_value) = map.places[source].value_index
{
values.insert(target_value, values.get(source_value).clone());
}
for target_child in map.children(target) {
// Try to find corresponding child and recurse. Reasoning is similar as above.
let projection = map.places[target_child].proj_elem.unwrap();
if let Some(source_child) = map.projections.get(&(source, projection)) {
self.insert_place_idx(target_child, *source_child, map);
}
}
map.for_each_value_pair(target, source, &mut |target, source| {
values.insert(target, values.get(source).clone());
});
}
/// Helper method to interpret `target = result`.
@ -677,6 +662,26 @@ impl<'tcx> Map<'tcx> {
self.find_extra(place, [TrackElem::DerefLen])
}
/// Locates the value corresponding to the given place.
pub fn value(&self, place: PlaceIndex) -> Option<ValueIndex> {
self.places[place].value_index
}
/// Locates the value corresponding to the given place.
pub fn find_value(&self, place: PlaceRef<'_>) -> Option<ValueIndex> {
self.value(self.find(place)?)
}
/// Locates the value corresponding to the given discriminant.
pub fn find_discr_value(&self, place: PlaceRef<'_>) -> Option<ValueIndex> {
self.value(self.find_discr(place)?)
}
/// Locates the value corresponding to the given length.
pub fn find_len_value(&self, place: PlaceRef<'_>) -> Option<ValueIndex> {
self.value(self.find_len(place)?)
}
/// Iterate over all direct children.
fn children(&self, parent: PlaceIndex) -> impl Iterator<Item = PlaceIndex> {
Children::new(self, parent)
@ -689,7 +694,7 @@ impl<'tcx> Map<'tcx> {
///
/// `tail_elem` allows to support discriminants that are not a place in MIR, but that we track
/// as such.
fn for_each_aliasing_place(
pub fn for_each_aliasing_place(
&self,
place: PlaceRef<'_>,
tail_elem: Option<TrackElem>,
@ -745,11 +750,15 @@ impl<'tcx> Map<'tcx> {
}
}
/// Return the range of value indices inside this place.
pub fn values_inside(&self, root: PlaceIndex) -> &[ValueIndex] {
let range = self.inner_values[root].clone();
&self.inner_values_buffer[range]
}
/// Invoke a function on each value in the given place and all descendants.
fn for_each_value_inside(&self, root: PlaceIndex, f: &mut impl FnMut(ValueIndex)) {
let range = self.inner_values[root].clone();
let values = &self.inner_values_buffer[range];
for &v in values {
for &v in self.values_inside(root) {
f(v)
}
}
@ -778,6 +787,31 @@ impl<'tcx> Map<'tcx> {
}
}
}
/// Recursively iterates on each value contained in `target`, paired with matching projection
/// inside `source`.
pub fn for_each_value_pair(
&self,
target: PlaceIndex,
source: PlaceIndex,
f: &mut impl FnMut(ValueIndex, ValueIndex),
) {
// If both places are tracked, we copy the value to the target.
// If the target is tracked, but the source is not, we do nothing, as invalidation has
// already been performed.
if let Some(target_value) = self.places[target].value_index
&& let Some(source_value) = self.places[source].value_index
{
f(target_value, source_value)
}
for target_child in self.children(target) {
// Try to find corresponding child and recurse. Reasoning is similar as above.
let projection = self.places[target_child].proj_elem.unwrap();
if let Some(source_child) = self.projections.get(&(source, projection)) {
self.for_each_value_pair(target_child, *source_child, f);
}
}
}
}
/// This is the information tracked for every [`PlaceIndex`] and is stored by [`Map`].

File diff suppressed because it is too large Load diff

View file

@ -1,92 +1,72 @@
Function name: conditions::main
Raw bytes (642): 0x[01, 01, 54, 05, 09, 01, 05, 09, 5d, 09, 27, 5d, 61, 27, 65, 5d, 61, 09, 23, 27, 65, 5d, 61, 01, 03, 03, 0d, 11, 51, 11, 4f, 51, 55, 4f, 59, 51, 55, 11, 4b, 4f, 59, 51, 55, 03, 9f, 01, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 9f, 01, 15, 0d, 11, 19, 45, 19, 97, 01, 45, 49, 97, 01, 4d, 45, 49, 19, 93, 01, 97, 01, 4d, 45, 49, 9f, 01, 8f, 02, 0d, 11, 15, 19, 15, 19, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, 8f, 02, 1d, 15, 19, 21, 39, 21, e3, 01, 39, 3d, e3, 01, 41, 39, 3d, 21, df, 01, e3, 01, 41, 39, 3d, 8f, 02, cb, 02, 15, 19, 1d, 21, 8f, 02, cb, 02, 15, 19, 1d, 21, 8f, 02, cb, 02, 15, 19, 1d, 21, 8f, 02, cb, 02, 15, 19, 1d, 21, 25, 29, 1d, 21, cb, 02, 25, 1d, 21, 29, 2d, 29, c3, 02, 2d, 31, c3, 02, 35, 2d, 31, 29, bf, 02, c3, 02, 35, 2d, 31, cb, 02, cf, 02, 1d, 21, 25, 29, 52, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0c, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 00, 17, 05, 01, 09, 00, 0a, 06, 01, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 23, 00, 3d, 02, 0a, 1e, 02, 09, 00, 0a, 09, 01, 09, 00, 17, 09, 01, 09, 00, 12, 2a, 02, 09, 00, 0f, 03, 03, 09, 00, 16, 03, 00, 19, 00, 1a, 03, 01, 08, 00, 0c, 03, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 2e, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 32, 00, 1d, 00, 2a, 36, 00, 2e, 00, 3c, 4b, 00, 3d, 02, 0a, 46, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 52, 02, 09, 00, 0f, 9f, 01, 03, 08, 00, 0c, 9f, 01, 01, 0d, 00, 1a, 9f, 01, 00, 1d, 00, 1e, 9f, 01, 01, 0c, 00, 10, 9f, 01, 00, 11, 02, 0a, 00, 02, 09, 00, 0a, 9f, 01, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 72, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 7a, 00, 21, 00, 2e, 7e, 00, 32, 00, 40, 93, 01, 00, 41, 02, 0e, 8e, 01, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 9a, 01, 02, 0d, 00, 13, 00, 02, 05, 00, 06, 8f, 02, 02, 09, 00, 16, 8f, 02, 00, 19, 00, 1a, 8f, 02, 01, 08, 00, 0c, 8f, 02, 00, 0d, 02, 06, 00, 02, 05, 00, 06, cb, 02, 02, 09, 00, 0a, 8f, 02, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, be, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, c6, 01, 00, 1d, 00, 2a, ca, 01, 00, 2e, 00, 3c, df, 01, 00, 3d, 02, 0a, da, 01, 02, 09, 00, 0a, 21, 01, 09, 00, 17, 8a, 02, 02, 0d, 00, 20, 8a, 02, 00, 23, 00, 2c, 8a, 02, 01, 09, 00, 11, 8a, 02, 01, 09, 00, 0f, cf, 02, 03, 09, 00, 0a, cb, 02, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, 9e, 02, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, a6, 02, 00, 1d, 00, 2a, aa, 02, 00, 2e, 00, 3c, bf, 02, 00, 3d, 02, 0a, ba, 02, 02, 09, 00, 0a, 29, 01, 09, 00, 17, c6, 02, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
Raw bytes (581): 0x[01, 01, 40, 05, 09, 01, 05, 09, 51, 09, 13, 51, 55, 01, 03, 03, 0d, 11, 49, 11, 27, 49, 4d, 03, 63, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 0d, 11, 63, 15, 0d, 11, 19, 41, 19, 5b, 41, 45, 63, bf, 01, 0d, 11, 15, 19, 15, 19, 15, 19, 15, 19, 15, 19, 1d, 21, 15, 19, bf, 01, 1d, 15, 19, 21, 39, 21, 93, 01, 39, 3d, bf, 01, fb, 01, 15, 19, 1d, 21, bf, 01, fb, 01, 15, 19, 1d, 21, bf, 01, fb, 01, 15, 19, 1d, 21, bf, 01, fb, 01, 15, 19, 1d, 21, 25, 29, 1d, 21, fb, 01, 25, 1d, 21, 29, 2d, 29, f3, 01, 2d, 31, f3, 01, 35, 2d, 31, 29, ef, 01, f3, 01, 35, 2d, 31, fb, 01, ff, 01, 1d, 21, 25, 29, 52, 01, 03, 01, 00, 0a, 01, 01, 09, 00, 16, 01, 00, 19, 00, 1a, 01, 01, 08, 00, 0c, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 03, 09, 00, 0a, 01, 00, 10, 00, 1d, 05, 01, 09, 00, 17, 05, 01, 09, 00, 0a, 06, 01, 0f, 00, 1c, 09, 01, 0c, 00, 19, 0a, 00, 1d, 00, 2a, 0e, 00, 2e, 00, 3c, 09, 00, 3d, 02, 0a, 00, 02, 09, 00, 0a, 09, 01, 09, 00, 17, 09, 01, 09, 00, 12, 16, 02, 09, 00, 0f, 03, 03, 09, 00, 16, 03, 00, 19, 00, 1a, 03, 01, 08, 00, 0c, 03, 00, 0d, 02, 06, 00, 02, 05, 00, 06, 03, 02, 08, 00, 15, 0d, 00, 16, 02, 06, 1a, 02, 0f, 00, 1c, 11, 01, 0c, 00, 19, 1e, 00, 1d, 00, 2a, 22, 00, 2e, 00, 3c, 11, 00, 3d, 02, 0a, 00, 02, 09, 00, 0a, 11, 01, 09, 00, 17, 2a, 02, 09, 00, 0f, 63, 03, 08, 00, 0c, 63, 01, 0d, 00, 1a, 63, 00, 1d, 00, 1e, 63, 01, 0c, 00, 10, 63, 00, 11, 02, 0a, 00, 02, 09, 00, 0a, 63, 02, 0c, 00, 19, 15, 00, 1a, 02, 0a, 4a, 04, 11, 00, 1e, 19, 01, 10, 00, 1d, 52, 00, 21, 00, 2e, 56, 00, 32, 00, 40, 19, 00, 41, 02, 0e, 00, 02, 0d, 00, 0e, 19, 01, 0d, 00, 1b, 5e, 02, 0d, 00, 13, 00, 02, 05, 00, 06, bf, 01, 02, 09, 00, 16, bf, 01, 00, 19, 00, 1a, bf, 01, 01, 08, 00, 0c, bf, 01, 00, 0d, 02, 06, 00, 02, 05, 00, 06, fb, 01, 02, 09, 00, 0a, bf, 01, 00, 10, 00, 1d, 1d, 00, 1e, 02, 06, 82, 01, 02, 0f, 00, 1c, 21, 01, 0c, 00, 19, 8a, 01, 00, 1d, 00, 2a, 8e, 01, 00, 2e, 00, 3c, 21, 00, 3d, 02, 0a, 00, 02, 09, 00, 0a, 21, 01, 09, 00, 17, ba, 01, 02, 0d, 00, 20, ba, 01, 00, 23, 00, 2c, ba, 01, 01, 09, 00, 11, ba, 01, 01, 09, 00, 0f, ff, 01, 03, 09, 00, 0a, fb, 01, 00, 10, 00, 1d, 25, 00, 1e, 02, 06, ce, 01, 02, 0f, 00, 1c, 29, 01, 0c, 00, 19, d6, 01, 00, 1d, 00, 2a, da, 01, 00, 2e, 00, 3c, ef, 01, 00, 3d, 02, 0a, ea, 01, 02, 09, 00, 0a, 29, 01, 09, 00, 17, f6, 01, 02, 09, 00, 0f, 01, 02, 01, 00, 02]
Number of files: 1
- file 0 => $DIR/conditions.rs
Number of expressions: 84
Number of expressions: 64
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
- expression 1 operands: lhs = Counter(0), rhs = Counter(1)
- expression 2 operands: lhs = Counter(2), rhs = Counter(23)
- expression 3 operands: lhs = Counter(2), rhs = Expression(9, Add)
- expression 4 operands: lhs = Counter(23), rhs = Counter(24)
- expression 5 operands: lhs = Expression(9, Add), rhs = Counter(25)
- expression 6 operands: lhs = Counter(23), rhs = Counter(24)
- expression 7 operands: lhs = Counter(2), rhs = Expression(8, Add)
- expression 8 operands: lhs = Expression(9, Add), rhs = Counter(25)
- expression 9 operands: lhs = Counter(23), rhs = Counter(24)
- expression 10 operands: lhs = Counter(0), rhs = Expression(0, Add)
- expression 11 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 12 operands: lhs = Counter(4), rhs = Counter(20)
- expression 13 operands: lhs = Counter(4), rhs = Expression(19, Add)
- expression 14 operands: lhs = Counter(20), rhs = Counter(21)
- expression 15 operands: lhs = Expression(19, Add), rhs = Counter(22)
- expression 16 operands: lhs = Counter(20), rhs = Counter(21)
- expression 17 operands: lhs = Counter(4), rhs = Expression(18, Add)
- expression 18 operands: lhs = Expression(19, Add), rhs = Counter(22)
- expression 19 operands: lhs = Counter(20), rhs = Counter(21)
- expression 20 operands: lhs = Expression(0, Add), rhs = Expression(39, Add)
- expression 21 operands: lhs = Counter(3), rhs = Counter(4)
- expression 22 operands: lhs = Counter(3), rhs = Counter(4)
- expression 23 operands: lhs = Counter(3), rhs = Counter(4)
- expression 2 operands: lhs = Counter(2), rhs = Counter(20)
- expression 3 operands: lhs = Counter(2), rhs = Expression(4, Add)
- expression 4 operands: lhs = Counter(20), rhs = Counter(21)
- expression 5 operands: lhs = Counter(0), rhs = Expression(0, Add)
- expression 6 operands: lhs = Expression(0, Add), rhs = Counter(3)
- expression 7 operands: lhs = Counter(4), rhs = Counter(18)
- expression 8 operands: lhs = Counter(4), rhs = Expression(9, Add)
- expression 9 operands: lhs = Counter(18), rhs = Counter(19)
- expression 10 operands: lhs = Expression(0, Add), rhs = Expression(24, Add)
- expression 11 operands: lhs = Counter(3), rhs = Counter(4)
- expression 12 operands: lhs = Counter(3), rhs = Counter(4)
- expression 13 operands: lhs = Counter(3), rhs = Counter(4)
- expression 14 operands: lhs = Counter(3), rhs = Counter(4)
- expression 15 operands: lhs = Counter(3), rhs = Counter(4)
- expression 16 operands: lhs = Counter(3), rhs = Counter(4)
- expression 17 operands: lhs = Counter(3), rhs = Counter(4)
- expression 18 operands: lhs = Expression(24, Add), rhs = Counter(5)
- expression 19 operands: lhs = Counter(3), rhs = Counter(4)
- expression 20 operands: lhs = Counter(6), rhs = Counter(16)
- expression 21 operands: lhs = Counter(6), rhs = Expression(22, Add)
- expression 22 operands: lhs = Counter(16), rhs = Counter(17)
- expression 23 operands: lhs = Expression(24, Add), rhs = Expression(47, Add)
- expression 24 operands: lhs = Counter(3), rhs = Counter(4)
- expression 25 operands: lhs = Counter(3), rhs = Counter(4)
- expression 26 operands: lhs = Counter(3), rhs = Counter(4)
- expression 27 operands: lhs = Counter(3), rhs = Counter(4)
- expression 28 operands: lhs = Expression(39, Add), rhs = Counter(5)
- expression 29 operands: lhs = Counter(3), rhs = Counter(4)
- expression 30 operands: lhs = Counter(6), rhs = Counter(17)
- expression 31 operands: lhs = Counter(6), rhs = Expression(37, Add)
- expression 32 operands: lhs = Counter(17), rhs = Counter(18)
- expression 33 operands: lhs = Expression(37, Add), rhs = Counter(19)
- expression 34 operands: lhs = Counter(17), rhs = Counter(18)
- expression 35 operands: lhs = Counter(6), rhs = Expression(36, Add)
- expression 36 operands: lhs = Expression(37, Add), rhs = Counter(19)
- expression 37 operands: lhs = Counter(17), rhs = Counter(18)
- expression 38 operands: lhs = Expression(39, Add), rhs = Expression(67, Add)
- expression 39 operands: lhs = Counter(3), rhs = Counter(4)
- expression 40 operands: lhs = Counter(5), rhs = Counter(6)
- expression 25 operands: lhs = Counter(5), rhs = Counter(6)
- expression 26 operands: lhs = Counter(5), rhs = Counter(6)
- expression 27 operands: lhs = Counter(5), rhs = Counter(6)
- expression 28 operands: lhs = Counter(5), rhs = Counter(6)
- expression 29 operands: lhs = Counter(5), rhs = Counter(6)
- expression 30 operands: lhs = Counter(7), rhs = Counter(8)
- expression 31 operands: lhs = Counter(5), rhs = Counter(6)
- expression 32 operands: lhs = Expression(47, Add), rhs = Counter(7)
- expression 33 operands: lhs = Counter(5), rhs = Counter(6)
- expression 34 operands: lhs = Counter(8), rhs = Counter(14)
- expression 35 operands: lhs = Counter(8), rhs = Expression(36, Add)
- expression 36 operands: lhs = Counter(14), rhs = Counter(15)
- expression 37 operands: lhs = Expression(47, Add), rhs = Expression(62, Add)
- expression 38 operands: lhs = Counter(5), rhs = Counter(6)
- expression 39 operands: lhs = Counter(7), rhs = Counter(8)
- expression 40 operands: lhs = Expression(47, Add), rhs = Expression(62, Add)
- expression 41 operands: lhs = Counter(5), rhs = Counter(6)
- expression 42 operands: lhs = Counter(5), rhs = Counter(6)
- expression 43 operands: lhs = Counter(5), rhs = Counter(6)
- expression 42 operands: lhs = Counter(7), rhs = Counter(8)
- expression 43 operands: lhs = Expression(47, Add), rhs = Expression(62, Add)
- expression 44 operands: lhs = Counter(5), rhs = Counter(6)
- expression 45 operands: lhs = Counter(7), rhs = Counter(8)
- expression 46 operands: lhs = Counter(5), rhs = Counter(6)
- expression 47 operands: lhs = Expression(67, Add), rhs = Counter(7)
- expression 48 operands: lhs = Counter(5), rhs = Counter(6)
- expression 49 operands: lhs = Counter(8), rhs = Counter(14)
- expression 50 operands: lhs = Counter(8), rhs = Expression(56, Add)
- expression 51 operands: lhs = Counter(14), rhs = Counter(15)
- expression 52 operands: lhs = Expression(56, Add), rhs = Counter(16)
- expression 53 operands: lhs = Counter(14), rhs = Counter(15)
- expression 54 operands: lhs = Counter(8), rhs = Expression(55, Add)
- expression 55 operands: lhs = Expression(56, Add), rhs = Counter(16)
- expression 56 operands: lhs = Counter(14), rhs = Counter(15)
- expression 57 operands: lhs = Expression(67, Add), rhs = Expression(82, Add)
- expression 58 operands: lhs = Counter(5), rhs = Counter(6)
- expression 59 operands: lhs = Counter(7), rhs = Counter(8)
- expression 60 operands: lhs = Expression(67, Add), rhs = Expression(82, Add)
- expression 61 operands: lhs = Counter(5), rhs = Counter(6)
- expression 46 operands: lhs = Expression(47, Add), rhs = Expression(62, Add)
- expression 47 operands: lhs = Counter(5), rhs = Counter(6)
- expression 48 operands: lhs = Counter(7), rhs = Counter(8)
- expression 49 operands: lhs = Counter(9), rhs = Counter(10)
- expression 50 operands: lhs = Counter(7), rhs = Counter(8)
- expression 51 operands: lhs = Expression(62, Add), rhs = Counter(9)
- expression 52 operands: lhs = Counter(7), rhs = Counter(8)
- expression 53 operands: lhs = Counter(10), rhs = Counter(11)
- expression 54 operands: lhs = Counter(10), rhs = Expression(60, Add)
- expression 55 operands: lhs = Counter(11), rhs = Counter(12)
- expression 56 operands: lhs = Expression(60, Add), rhs = Counter(13)
- expression 57 operands: lhs = Counter(11), rhs = Counter(12)
- expression 58 operands: lhs = Counter(10), rhs = Expression(59, Add)
- expression 59 operands: lhs = Expression(60, Add), rhs = Counter(13)
- expression 60 operands: lhs = Counter(11), rhs = Counter(12)
- expression 61 operands: lhs = Expression(62, Add), rhs = Expression(63, Add)
- expression 62 operands: lhs = Counter(7), rhs = Counter(8)
- expression 63 operands: lhs = Expression(67, Add), rhs = Expression(82, Add)
- expression 64 operands: lhs = Counter(5), rhs = Counter(6)
- expression 65 operands: lhs = Counter(7), rhs = Counter(8)
- expression 66 operands: lhs = Expression(67, Add), rhs = Expression(82, Add)
- expression 67 operands: lhs = Counter(5), rhs = Counter(6)
- expression 68 operands: lhs = Counter(7), rhs = Counter(8)
- expression 69 operands: lhs = Counter(9), rhs = Counter(10)
- expression 70 operands: lhs = Counter(7), rhs = Counter(8)
- expression 71 operands: lhs = Expression(82, Add), rhs = Counter(9)
- expression 72 operands: lhs = Counter(7), rhs = Counter(8)
- expression 73 operands: lhs = Counter(10), rhs = Counter(11)
- expression 74 operands: lhs = Counter(10), rhs = Expression(80, Add)
- expression 75 operands: lhs = Counter(11), rhs = Counter(12)
- expression 76 operands: lhs = Expression(80, Add), rhs = Counter(13)
- expression 77 operands: lhs = Counter(11), rhs = Counter(12)
- expression 78 operands: lhs = Counter(10), rhs = Expression(79, Add)
- expression 79 operands: lhs = Expression(80, Add), rhs = Counter(13)
- expression 80 operands: lhs = Counter(11), rhs = Counter(12)
- expression 81 operands: lhs = Expression(82, Add), rhs = Expression(83, Add)
- expression 82 operands: lhs = Counter(7), rhs = Counter(8)
- expression 83 operands: lhs = Counter(9), rhs = Counter(10)
- expression 63 operands: lhs = Counter(9), rhs = Counter(10)
Number of file 0 mappings: 82
- Code(Counter(0)) at (prev + 3, 1) to (start + 0, 10)
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
@ -103,16 +83,14 @@ Number of file 0 mappings: 82
= (c0 - c1)
- Code(Counter(2)) at (prev + 1, 12) to (start + 0, 25)
- Code(Expression(2, Sub)) at (prev + 0, 29) to (start + 0, 42)
= (c2 - c23)
= (c2 - c20)
- Code(Expression(3, Sub)) at (prev + 0, 46) to (start + 0, 60)
= (c2 - (c23 + c24))
- Code(Expression(8, Add)) at (prev + 0, 61) to (start + 2, 10)
= ((c23 + c24) + c25)
- Code(Expression(7, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c2 - ((c23 + c24) + c25))
= (c2 - (c20 + c21))
- Code(Counter(2)) at (prev + 0, 61) to (start + 2, 10)
- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 23)
- Code(Counter(2)) at (prev + 1, 9) to (start + 0, 18)
- Code(Expression(10, Sub)) at (prev + 2, 9) to (start + 0, 15)
- Code(Expression(5, Sub)) at (prev + 2, 9) to (start + 0, 15)
= (c0 - (c1 + c2))
- Code(Expression(0, Add)) at (prev + 3, 9) to (start + 0, 22)
= (c1 + c2)
@ -126,101 +104,95 @@ Number of file 0 mappings: 82
- Code(Expression(0, Add)) at (prev + 2, 8) to (start + 0, 21)
= (c1 + c2)
- Code(Counter(3)) at (prev + 0, 22) to (start + 2, 6)
- Code(Expression(11, Sub)) at (prev + 2, 15) to (start + 0, 28)
- Code(Expression(6, Sub)) at (prev + 2, 15) to (start + 0, 28)
= ((c1 + c2) - c3)
- Code(Counter(4)) at (prev + 1, 12) to (start + 0, 25)
- Code(Expression(12, Sub)) at (prev + 0, 29) to (start + 0, 42)
= (c4 - c20)
- Code(Expression(13, Sub)) at (prev + 0, 46) to (start + 0, 60)
= (c4 - (c20 + c21))
- Code(Expression(18, Add)) at (prev + 0, 61) to (start + 2, 10)
= ((c20 + c21) + c22)
- Code(Expression(17, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c4 - ((c20 + c21) + c22))
- Code(Expression(7, Sub)) at (prev + 0, 29) to (start + 0, 42)
= (c4 - c18)
- Code(Expression(8, Sub)) at (prev + 0, 46) to (start + 0, 60)
= (c4 - (c18 + c19))
- Code(Counter(4)) at (prev + 0, 61) to (start + 2, 10)
- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
- Code(Counter(4)) at (prev + 1, 9) to (start + 0, 23)
- Code(Expression(20, Sub)) at (prev + 2, 9) to (start + 0, 15)
- Code(Expression(10, Sub)) at (prev + 2, 9) to (start + 0, 15)
= ((c1 + c2) - (c3 + c4))
- Code(Expression(39, Add)) at (prev + 3, 8) to (start + 0, 12)
- Code(Expression(24, Add)) at (prev + 3, 8) to (start + 0, 12)
= (c3 + c4)
- Code(Expression(39, Add)) at (prev + 1, 13) to (start + 0, 26)
- Code(Expression(24, Add)) at (prev + 1, 13) to (start + 0, 26)
= (c3 + c4)
- Code(Expression(39, Add)) at (prev + 0, 29) to (start + 0, 30)
- Code(Expression(24, Add)) at (prev + 0, 29) to (start + 0, 30)
= (c3 + c4)
- Code(Expression(39, Add)) at (prev + 1, 12) to (start + 0, 16)
- Code(Expression(24, Add)) at (prev + 1, 12) to (start + 0, 16)
= (c3 + c4)
- Code(Expression(39, Add)) at (prev + 0, 17) to (start + 2, 10)
- Code(Expression(24, Add)) at (prev + 0, 17) to (start + 2, 10)
= (c3 + c4)
- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
- Code(Expression(39, Add)) at (prev + 2, 12) to (start + 0, 25)
- Code(Expression(24, Add)) at (prev + 2, 12) to (start + 0, 25)
= (c3 + c4)
- Code(Counter(5)) at (prev + 0, 26) to (start + 2, 10)
- Code(Expression(28, Sub)) at (prev + 4, 17) to (start + 0, 30)
- Code(Expression(18, Sub)) at (prev + 4, 17) to (start + 0, 30)
= ((c3 + c4) - c5)
- Code(Counter(6)) at (prev + 1, 16) to (start + 0, 29)
- Code(Expression(30, Sub)) at (prev + 0, 33) to (start + 0, 46)
= (c6 - c17)
- Code(Expression(31, Sub)) at (prev + 0, 50) to (start + 0, 64)
= (c6 - (c17 + c18))
- Code(Expression(36, Add)) at (prev + 0, 65) to (start + 2, 14)
= ((c17 + c18) + c19)
- Code(Expression(35, Sub)) at (prev + 2, 13) to (start + 0, 14)
= (c6 - ((c17 + c18) + c19))
- Code(Expression(20, Sub)) at (prev + 0, 33) to (start + 0, 46)
= (c6 - c16)
- Code(Expression(21, Sub)) at (prev + 0, 50) to (start + 0, 64)
= (c6 - (c16 + c17))
- Code(Counter(6)) at (prev + 0, 65) to (start + 2, 14)
- Code(Zero) at (prev + 2, 13) to (start + 0, 14)
- Code(Counter(6)) at (prev + 1, 13) to (start + 0, 27)
- Code(Expression(38, Sub)) at (prev + 2, 13) to (start + 0, 19)
- Code(Expression(23, Sub)) at (prev + 2, 13) to (start + 0, 19)
= ((c3 + c4) - (c5 + c6))
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Expression(67, Add)) at (prev + 2, 9) to (start + 0, 22)
- Code(Expression(47, Add)) at (prev + 2, 9) to (start + 0, 22)
= (c5 + c6)
- Code(Expression(67, Add)) at (prev + 0, 25) to (start + 0, 26)
- Code(Expression(47, Add)) at (prev + 0, 25) to (start + 0, 26)
= (c5 + c6)
- Code(Expression(67, Add)) at (prev + 1, 8) to (start + 0, 12)
- Code(Expression(47, Add)) at (prev + 1, 8) to (start + 0, 12)
= (c5 + c6)
- Code(Expression(67, Add)) at (prev + 0, 13) to (start + 2, 6)
- Code(Expression(47, Add)) at (prev + 0, 13) to (start + 2, 6)
= (c5 + c6)
- Code(Zero) at (prev + 2, 5) to (start + 0, 6)
- Code(Expression(82, Add)) at (prev + 2, 9) to (start + 0, 10)
- Code(Expression(62, Add)) at (prev + 2, 9) to (start + 0, 10)
= (c7 + c8)
- Code(Expression(67, Add)) at (prev + 0, 16) to (start + 0, 29)
- Code(Expression(47, Add)) at (prev + 0, 16) to (start + 0, 29)
= (c5 + c6)
- Code(Counter(7)) at (prev + 0, 30) to (start + 2, 6)
- Code(Expression(47, Sub)) at (prev + 2, 15) to (start + 0, 28)
- Code(Expression(32, Sub)) at (prev + 2, 15) to (start + 0, 28)
= ((c5 + c6) - c7)
- Code(Counter(8)) at (prev + 1, 12) to (start + 0, 25)
- Code(Expression(49, Sub)) at (prev + 0, 29) to (start + 0, 42)
- Code(Expression(34, Sub)) at (prev + 0, 29) to (start + 0, 42)
= (c8 - c14)
- Code(Expression(50, Sub)) at (prev + 0, 46) to (start + 0, 60)
- Code(Expression(35, Sub)) at (prev + 0, 46) to (start + 0, 60)
= (c8 - (c14 + c15))
- Code(Expression(55, Add)) at (prev + 0, 61) to (start + 2, 10)
= ((c14 + c15) + c16)
- Code(Expression(54, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c8 - ((c14 + c15) + c16))
- Code(Counter(8)) at (prev + 0, 61) to (start + 2, 10)
- Code(Zero) at (prev + 2, 9) to (start + 0, 10)
- Code(Counter(8)) at (prev + 1, 9) to (start + 0, 23)
- Code(Expression(66, Sub)) at (prev + 2, 13) to (start + 0, 32)
- Code(Expression(46, Sub)) at (prev + 2, 13) to (start + 0, 32)
= ((c5 + c6) - (c7 + c8))
- Code(Expression(66, Sub)) at (prev + 0, 35) to (start + 0, 44)
- Code(Expression(46, Sub)) at (prev + 0, 35) to (start + 0, 44)
= ((c5 + c6) - (c7 + c8))
- Code(Expression(66, Sub)) at (prev + 1, 9) to (start + 0, 17)
- Code(Expression(46, Sub)) at (prev + 1, 9) to (start + 0, 17)
= ((c5 + c6) - (c7 + c8))
- Code(Expression(66, Sub)) at (prev + 1, 9) to (start + 0, 15)
- Code(Expression(46, Sub)) at (prev + 1, 9) to (start + 0, 15)
= ((c5 + c6) - (c7 + c8))
- Code(Expression(83, Add)) at (prev + 3, 9) to (start + 0, 10)
- Code(Expression(63, Add)) at (prev + 3, 9) to (start + 0, 10)
= (c9 + c10)
- Code(Expression(82, Add)) at (prev + 0, 16) to (start + 0, 29)
- Code(Expression(62, Add)) at (prev + 0, 16) to (start + 0, 29)
= (c7 + c8)
- Code(Counter(9)) at (prev + 0, 30) to (start + 2, 6)
- Code(Expression(71, Sub)) at (prev + 2, 15) to (start + 0, 28)
- Code(Expression(51, Sub)) at (prev + 2, 15) to (start + 0, 28)
= ((c7 + c8) - c9)
- Code(Counter(10)) at (prev + 1, 12) to (start + 0, 25)
- Code(Expression(73, Sub)) at (prev + 0, 29) to (start + 0, 42)
- Code(Expression(53, Sub)) at (prev + 0, 29) to (start + 0, 42)
= (c10 - c11)
- Code(Expression(74, Sub)) at (prev + 0, 46) to (start + 0, 60)
- Code(Expression(54, Sub)) at (prev + 0, 46) to (start + 0, 60)
= (c10 - (c11 + c12))
- Code(Expression(79, Add)) at (prev + 0, 61) to (start + 2, 10)
- Code(Expression(59, Add)) at (prev + 0, 61) to (start + 2, 10)
= ((c11 + c12) + c13)
- Code(Expression(78, Sub)) at (prev + 2, 9) to (start + 0, 10)
- Code(Expression(58, Sub)) at (prev + 2, 9) to (start + 0, 10)
= (c10 - ((c11 + c12) + c13))
- Code(Counter(10)) at (prev + 1, 9) to (start + 0, 23)
- Code(Expression(81, Sub)) at (prev + 2, 9) to (start + 0, 15)
- Code(Expression(61, Sub)) at (prev + 2, 9) to (start + 0, 15)
= ((c7 + c8) - (c9 + c10))
- Code(Counter(0)) at (prev + 2, 1) to (start + 0, 2)
Highest counter ID seen: c10

View file

@ -1,51 +1,50 @@
- // MIR for `aggregate` before JumpThreading
+ // MIR for `aggregate` after JumpThreading
fn aggregate(_1: u8) -> u8 {
debug x => _1;
fn aggregate() -> u8 {
let mut _0: u8;
let _1: u8;
let _2: u8;
let _3: u8;
let mut _4: (u8, u8);
let mut _5: bool;
let mut _6: u8;
let mut _3: (u8, u8);
let mut _4: bool;
let mut _5: u8;
scope 1 {
debug a => _2;
debug b => _3;
debug a => _1;
debug b => _2;
}
bb0: {
StorageLive(_4);
_4 = const aggregate::FOO;
StorageLive(_2);
_2 = copy (_4.0: u8);
StorageLive(_3);
_3 = copy (_4.1: u8);
StorageDead(_4);
_3 = const aggregate::FOO;
StorageLive(_1);
_1 = copy (_3.0: u8);
StorageLive(_2);
_2 = copy (_3.1: u8);
StorageDead(_3);
StorageLive(_4);
StorageLive(_5);
StorageLive(_6);
_6 = copy _2;
_5 = Eq(move _6, const 7_u8);
- switchInt(move _5) -> [0: bb2, otherwise: bb1];
_5 = copy _1;
_4 = Eq(move _5, const 7_u8);
- switchInt(move _4) -> [0: bb2, otherwise: bb1];
+ goto -> bb2;
}
bb1: {
StorageDead(_6);
_0 = copy _3;
goto -> bb3;
}
bb2: {
StorageDead(_6);
StorageDead(_5);
_0 = copy _2;
goto -> bb3;
}
bb3: {
bb2: {
StorageDead(_5);
StorageDead(_3);
_0 = copy _1;
goto -> bb3;
}
bb3: {
StorageDead(_4);
StorageDead(_2);
StorageDead(_1);
return;
}
}

View file

@ -1,51 +1,50 @@
- // MIR for `aggregate` before JumpThreading
+ // MIR for `aggregate` after JumpThreading
fn aggregate(_1: u8) -> u8 {
debug x => _1;
fn aggregate() -> u8 {
let mut _0: u8;
let _1: u8;
let _2: u8;
let _3: u8;
let mut _4: (u8, u8);
let mut _5: bool;
let mut _6: u8;
let mut _3: (u8, u8);
let mut _4: bool;
let mut _5: u8;
scope 1 {
debug a => _2;
debug b => _3;
debug a => _1;
debug b => _2;
}
bb0: {
StorageLive(_4);
_4 = const aggregate::FOO;
StorageLive(_2);
_2 = copy (_4.0: u8);
StorageLive(_3);
_3 = copy (_4.1: u8);
StorageDead(_4);
_3 = const aggregate::FOO;
StorageLive(_1);
_1 = copy (_3.0: u8);
StorageLive(_2);
_2 = copy (_3.1: u8);
StorageDead(_3);
StorageLive(_4);
StorageLive(_5);
StorageLive(_6);
_6 = copy _2;
_5 = Eq(move _6, const 7_u8);
- switchInt(move _5) -> [0: bb2, otherwise: bb1];
_5 = copy _1;
_4 = Eq(move _5, const 7_u8);
- switchInt(move _4) -> [0: bb2, otherwise: bb1];
+ goto -> bb2;
}
bb1: {
StorageDead(_6);
_0 = copy _3;
goto -> bb3;
}
bb2: {
StorageDead(_6);
StorageDead(_5);
_0 = copy _2;
goto -> bb3;
}
bb3: {
bb2: {
StorageDead(_5);
StorageDead(_3);
_0 = copy _1;
goto -> bb3;
}
bb3: {
StorageDead(_4);
StorageDead(_2);
StorageDead(_1);
return;
}
}

View file

@ -0,0 +1,238 @@
- // MIR for `chained_conditions` before JumpThreading
+ // MIR for `chained_conditions` after JumpThreading
fn chained_conditions() -> u8 {
let mut _0: u8;
let _1: chained_conditions::BacktraceStyle;
let mut _2: std::option::Option<std::string::String>;
let mut _3: &std::option::Option<std::string::String>;
let mut _4: isize;
let _5: std::string::String;
let _6: &std::string::String;
let mut _7: bool;
let mut _8: &&std::string::String;
let _9: &std::string::String;
let mut _10: &&str;
let _11: &str;
let _12: std::string::String;
let _13: &std::string::String;
let mut _14: bool;
let mut _15: &&std::string::String;
let _16: &std::string::String;
let mut _17: &&str;
let _18: &str;
let mut _19: isize;
let mut _20: &&str;
let mut _21: &&str;
let mut _22: bool;
let mut _23: bool;
let mut _24: isize;
let mut _25: isize;
let mut _26: isize;
scope 1 {
debug format => _1;
}
scope 2 {
debug x => _5;
debug x => _6;
}
scope 3 {
debug x => _12;
debug x => _13;
}
scope 4 (inlined std::cmp::impls::<impl PartialEq<&str> for &String>::eq) {
let mut _27: &std::string::String;
let mut _28: &str;
}
scope 5 (inlined std::cmp::impls::<impl PartialEq<&str> for &String>::eq) {
let mut _29: &std::string::String;
let mut _30: &str;
}
bb0: {
_22 = const false;
_23 = const false;
StorageLive(_1);
StorageLive(_2);
_2 = env_var() -> [return: bb1, unwind unreachable];
}
bb1: {
_22 = const true;
_23 = const true;
_4 = discriminant(_2);
switchInt(move _4) -> [0: bb3, 1: bb4, otherwise: bb2];
}
bb2: {
unreachable;
}
bb3: {
_1 = chained_conditions::BacktraceStyle::Off;
- goto -> bb18;
+ goto -> bb23;
}
bb4: {
StorageLive(_6);
_6 = &((_2 as Some).0: std::string::String);
StorageLive(_7);
StorageLive(_8);
StorageLive(_9);
_9 = &(*_6);
_8 = &_9;
StorageLive(_10);
_21 = const chained_conditions::promoted[1];
_10 = &(*_21);
StorageLive(_27);
StorageLive(_28);
_27 = copy (*_8);
_28 = copy (*_10);
_7 = <String as PartialEq<str>>::eq(move _27, move _28) -> [return: bb19, unwind unreachable];
}
bb5: {
StorageDead(_10);
StorageDead(_9);
StorageDead(_8);
StorageDead(_7);
StorageLive(_5);
_23 = const false;
_5 = move ((_2 as Some).0: std::string::String);
_1 = chained_conditions::BacktraceStyle::Full;
drop(_5) -> [return: bb7, unwind unreachable];
}
bb6: {
StorageDead(_10);
StorageDead(_9);
StorageDead(_8);
StorageDead(_7);
StorageDead(_6);
StorageLive(_13);
_13 = &((_2 as Some).0: std::string::String);
StorageLive(_14);
StorageLive(_15);
StorageLive(_16);
_16 = &(*_13);
_15 = &_16;
StorageLive(_17);
_20 = const chained_conditions::promoted[0];
_17 = &(*_20);
StorageLive(_29);
StorageLive(_30);
_29 = copy (*_15);
_30 = copy (*_17);
_14 = <String as PartialEq<str>>::eq(move _29, move _30) -> [return: bb20, unwind unreachable];
}
bb7: {
StorageDead(_5);
StorageDead(_6);
- goto -> bb18;
+ goto -> bb21;
}
bb8: {
StorageDead(_17);
StorageDead(_16);
StorageDead(_15);
StorageDead(_14);
StorageLive(_12);
_23 = const false;
_12 = move ((_2 as Some).0: std::string::String);
_1 = chained_conditions::BacktraceStyle::Off;
drop(_12) -> [return: bb10, unwind unreachable];
}
bb9: {
StorageDead(_17);
StorageDead(_16);
StorageDead(_15);
StorageDead(_14);
StorageDead(_13);
_1 = chained_conditions::BacktraceStyle::Short;
- goto -> bb18;
+ goto -> bb23;
}
bb10: {
StorageDead(_12);
StorageDead(_13);
- goto -> bb18;
+ goto -> bb21;
}
bb11: {
_0 = const 3_u8;
goto -> bb14;
}
bb12: {
_0 = const 2_u8;
goto -> bb14;
}
bb13: {
_0 = const 1_u8;
goto -> bb14;
}
bb14: {
StorageDead(_1);
return;
}
bb15: {
_22 = const false;
_23 = const false;
StorageDead(_2);
_19 = discriminant(_1);
switchInt(move _19) -> [0: bb13, 1: bb12, 2: bb11, otherwise: bb2];
}
bb16: {
switchInt(copy _23) -> [0: bb15, otherwise: bb17];
}
bb17: {
drop(((_2 as Some).0: std::string::String)) -> [return: bb15, unwind unreachable];
}
bb18: {
_24 = discriminant(_2);
switchInt(move _24) -> [1: bb16, otherwise: bb15];
}
bb19: {
StorageDead(_28);
StorageDead(_27);
switchInt(move _7) -> [0: bb6, otherwise: bb5];
}
bb20: {
StorageDead(_30);
StorageDead(_29);
switchInt(move _14) -> [0: bb9, otherwise: bb8];
+ }
+
+ bb21: {
+ _24 = discriminant(_2);
+ switchInt(move _24) -> [1: bb22, otherwise: bb15];
+ }
+
+ bb22: {
+ goto -> bb15;
+ }
+
+ bb23: {
+ _24 = discriminant(_2);
+ switchInt(move _24) -> [1: bb24, otherwise: bb15];
+ }
+
+ bb24: {
+ goto -> bb17;
}
}

View file

@ -0,0 +1,255 @@
- // MIR for `chained_conditions` before JumpThreading
+ // MIR for `chained_conditions` after JumpThreading
fn chained_conditions() -> u8 {
let mut _0: u8;
let _1: chained_conditions::BacktraceStyle;
let mut _2: std::option::Option<std::string::String>;
let mut _3: &std::option::Option<std::string::String>;
let mut _4: isize;
let _5: std::string::String;
let _6: &std::string::String;
let mut _7: bool;
let mut _8: &&std::string::String;
let _9: &std::string::String;
let mut _10: &&str;
let _11: &str;
let _12: std::string::String;
let _13: &std::string::String;
let mut _14: bool;
let mut _15: &&std::string::String;
let _16: &std::string::String;
let mut _17: &&str;
let _18: &str;
let mut _19: isize;
let mut _20: &&str;
let mut _21: &&str;
let mut _22: bool;
let mut _23: bool;
let mut _24: isize;
let mut _25: isize;
let mut _26: isize;
scope 1 {
debug format => _1;
}
scope 2 {
debug x => _5;
debug x => _6;
}
scope 3 {
debug x => _12;
debug x => _13;
}
scope 4 (inlined std::cmp::impls::<impl PartialEq<&str> for &String>::eq) {
let mut _27: &std::string::String;
let mut _28: &str;
}
scope 5 (inlined std::cmp::impls::<impl PartialEq<&str> for &String>::eq) {
let mut _29: &std::string::String;
let mut _30: &str;
}
bb0: {
_22 = const false;
_23 = const false;
StorageLive(_1);
StorageLive(_2);
_22 = const true;
_23 = const true;
_2 = env_var() -> [return: bb1, unwind continue];
}
bb1: {
_4 = discriminant(_2);
switchInt(move _4) -> [0: bb3, 1: bb4, otherwise: bb2];
}
bb2: {
unreachable;
}
bb3: {
_1 = chained_conditions::BacktraceStyle::Off;
- goto -> bb19;
+ goto -> bb27;
}
bb4: {
StorageLive(_6);
_6 = &((_2 as Some).0: std::string::String);
StorageLive(_7);
StorageLive(_8);
StorageLive(_9);
_9 = &(*_6);
_8 = &_9;
StorageLive(_10);
_21 = const chained_conditions::promoted[1];
_10 = &(*_21);
StorageLive(_27);
StorageLive(_28);
_27 = copy (*_8);
_28 = copy (*_10);
_7 = <String as PartialEq<str>>::eq(move _27, move _28) -> [return: bb23, unwind: bb22];
}
bb5: {
StorageDead(_10);
StorageDead(_9);
StorageDead(_8);
StorageDead(_7);
StorageLive(_5);
_23 = const false;
_5 = move ((_2 as Some).0: std::string::String);
_1 = chained_conditions::BacktraceStyle::Full;
drop(_5) -> [return: bb7, unwind: bb22];
}
bb6: {
StorageDead(_10);
StorageDead(_9);
StorageDead(_8);
StorageDead(_7);
StorageDead(_6);
StorageLive(_13);
_13 = &((_2 as Some).0: std::string::String);
StorageLive(_14);
StorageLive(_15);
StorageLive(_16);
_16 = &(*_13);
_15 = &_16;
StorageLive(_17);
_20 = const chained_conditions::promoted[0];
_17 = &(*_20);
StorageLive(_29);
StorageLive(_30);
_29 = copy (*_15);
_30 = copy (*_17);
_14 = <String as PartialEq<str>>::eq(move _29, move _30) -> [return: bb24, unwind: bb22];
}
bb7: {
StorageDead(_5);
StorageDead(_6);
- goto -> bb19;
+ goto -> bb25;
}
bb8: {
StorageDead(_17);
StorageDead(_16);
StorageDead(_15);
StorageDead(_14);
StorageLive(_12);
_23 = const false;
_12 = move ((_2 as Some).0: std::string::String);
_1 = chained_conditions::BacktraceStyle::Off;
drop(_12) -> [return: bb10, unwind: bb22];
}
bb9: {
StorageDead(_17);
StorageDead(_16);
StorageDead(_15);
StorageDead(_14);
StorageDead(_13);
_1 = chained_conditions::BacktraceStyle::Short;
- goto -> bb19;
+ goto -> bb27;
}
bb10: {
StorageDead(_12);
StorageDead(_13);
- goto -> bb19;
+ goto -> bb25;
}
bb11: {
_0 = const 3_u8;
goto -> bb14;
}
bb12: {
_0 = const 2_u8;
goto -> bb14;
}
bb13: {
_0 = const 1_u8;
goto -> bb14;
}
bb14: {
StorageDead(_1);
return;
}
bb15 (cleanup): {
resume;
}
bb16: {
_22 = const false;
_23 = const false;
StorageDead(_2);
_19 = discriminant(_1);
switchInt(move _19) -> [0: bb13, 1: bb12, 2: bb11, otherwise: bb2];
}
bb17: {
switchInt(copy _23) -> [0: bb16, otherwise: bb18];
}
bb18: {
drop(((_2 as Some).0: std::string::String)) -> [return: bb16, unwind: bb15];
}
bb19: {
_24 = discriminant(_2);
switchInt(move _24) -> [1: bb17, otherwise: bb16];
}
bb20 (cleanup): {
switchInt(copy _23) -> [0: bb15, otherwise: bb21];
}
bb21 (cleanup): {
drop(((_2 as Some).0: std::string::String)) -> [return: bb15, unwind terminate(cleanup)];
}
bb22 (cleanup): {
_26 = discriminant(_2);
switchInt(move _26) -> [1: bb20, otherwise: bb15];
}
bb23: {
StorageDead(_28);
StorageDead(_27);
switchInt(move _7) -> [0: bb6, otherwise: bb5];
}
bb24: {
StorageDead(_30);
StorageDead(_29);
switchInt(move _14) -> [0: bb9, otherwise: bb8];
+ }
+
+ bb25: {
+ _24 = discriminant(_2);
+ switchInt(move _24) -> [1: bb26, otherwise: bb16];
+ }
+
+ bb26: {
+ goto -> bb16;
+ }
+
+ bb27: {
+ _24 = discriminant(_2);
+ switchInt(move _24) -> [1: bb28, otherwise: bb16];
+ }
+
+ bb28: {
+ goto -> bb18;
}
}

View file

@ -23,14 +23,14 @@
bb2: {
_2 = CustomDiscr::B;
goto -> bb3;
- goto -> bb3;
+ goto -> bb8;
}
bb3: {
StorageDead(_3);
_4 = discriminant(_2);
- switchInt(move _4) -> [35: bb5, otherwise: bb4];
+ goto -> bb4;
switchInt(move _4) -> [35: bb5, otherwise: bb4];
}
bb4: {
@ -52,6 +52,12 @@
+ StorageDead(_3);
+ _4 = discriminant(_2);
+ goto -> bb5;
+ }
+
+ bb8: {
+ StorageDead(_3);
+ _4 = discriminant(_2);
+ goto -> bb4;
}
}

View file

@ -23,14 +23,14 @@
bb2: {
_2 = CustomDiscr::B;
goto -> bb3;
- goto -> bb3;
+ goto -> bb8;
}
bb3: {
StorageDead(_3);
_4 = discriminant(_2);
- switchInt(move _4) -> [35: bb5, otherwise: bb4];
+ goto -> bb4;
switchInt(move _4) -> [35: bb5, otherwise: bb4];
}
bb4: {
@ -52,6 +52,12 @@
+ StorageDead(_3);
+ _4 = discriminant(_2);
+ goto -> bb5;
+ }
+
+ bb8: {
+ StorageDead(_3);
+ _4 = discriminant(_2);
+ goto -> bb4;
}
}

View file

@ -15,7 +15,7 @@
bb1: {
_3 = const false;
- goto -> bb4;
+ goto -> bb9;
+ goto -> bb10;
}
bb2: {
@ -24,7 +24,8 @@
bb3: {
_2 = const false;
goto -> bb4;
- goto -> bb4;
+ goto -> bb13;
}
bb4: {
@ -40,8 +41,7 @@
}
bb7: {
- goto -> bb5;
+ goto -> bb10;
goto -> bb5;
}
bb8: {
@ -49,10 +49,30 @@
+ }
+
+ bb9: {
+ goto -> bb5;
+ switchInt(copy _3) -> [0: bb5, otherwise: bb7];
+ }
+
+ bb10: {
+ goto -> bb11;
+ }
+
+ bb11: {
+ goto -> bb8;
+ }
+
+ bb12: {
+ switchInt(copy _3) -> [0: bb5, otherwise: bb7];
+ }
+
+ bb13: {
+ goto -> bb14;
+ }
+
+ bb14: {
+ goto -> bb15;
+ }
+
+ bb15: {
goto -> bb6;
}
}

View file

@ -15,7 +15,7 @@
bb1: {
_3 = const false;
- goto -> bb4;
+ goto -> bb9;
+ goto -> bb10;
}
bb2: {
@ -24,7 +24,8 @@
bb3: {
_2 = const false;
goto -> bb4;
- goto -> bb4;
+ goto -> bb13;
}
bb4: {
@ -40,8 +41,7 @@
}
bb7: {
- goto -> bb5;
+ goto -> bb10;
goto -> bb5;
}
bb8: {
@ -49,10 +49,30 @@
+ }
+
+ bb9: {
+ goto -> bb5;
+ switchInt(copy _3) -> [0: bb5, otherwise: bb7];
+ }
+
+ bb10: {
+ goto -> bb11;
+ }
+
+ bb11: {
+ goto -> bb8;
+ }
+
+ bb12: {
+ switchInt(copy _3) -> [0: bb5, otherwise: bb7];
+ }
+
+ bb13: {
+ goto -> bb14;
+ }
+
+ bb14: {
+ goto -> bb15;
+ }
+
+ bb15: {
goto -> bb6;
}
}

View file

@ -97,8 +97,7 @@
StorageDead(_10);
StorageDead(_4);
_5 = discriminant(_3);
- switchInt(move _5) -> [0: bb2, 1: bb3, otherwise: bb1];
+ goto -> bb2;
switchInt(move _5) -> [0: bb2, 1: bb3, otherwise: bb1];
}
bb6: {
@ -114,7 +113,8 @@
bb7: {
_11 = move ((_4 as Ok).0: i32);
_3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(copy _11);
goto -> bb5;
- goto -> bb5;
+ goto -> bb9;
+ }
+
+ bb8: {
@ -124,6 +124,15 @@
+ StorageDead(_4);
+ _5 = discriminant(_3);
+ goto -> bb3;
+ }
+
+ bb9: {
+ StorageDead(_12);
+ StorageDead(_11);
+ StorageDead(_10);
+ StorageDead(_4);
+ _5 = discriminant(_3);
+ goto -> bb2;
}
}

View file

@ -97,8 +97,7 @@
StorageDead(_10);
StorageDead(_4);
_5 = discriminant(_3);
- switchInt(move _5) -> [0: bb2, 1: bb3, otherwise: bb1];
+ goto -> bb2;
switchInt(move _5) -> [0: bb2, 1: bb3, otherwise: bb1];
}
bb6: {
@ -114,7 +113,8 @@
bb7: {
_11 = move ((_4 as Ok).0: i32);
_3 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(copy _11);
goto -> bb5;
- goto -> bb5;
+ goto -> bb9;
+ }
+
+ bb8: {
@ -124,6 +124,15 @@
+ StorageDead(_4);
+ _5 = discriminant(_3);
+ goto -> bb3;
+ }
+
+ bb9: {
+ StorageDead(_12);
+ StorageDead(_11);
+ StorageDead(_10);
+ StorageDead(_4);
+ _5 = discriminant(_3);
+ goto -> bb2;
}
}

View file

@ -14,7 +14,7 @@
bb1: {
_2 = const false;
- goto -> bb3;
+ goto -> bb8;
+ goto -> bb9;
}
bb2: {
@ -47,10 +47,14 @@
+ }
+
+ bb8: {
+ goto -> bb9;
+ switchInt(copy _2) -> [0: bb4, otherwise: bb5];
+ }
+
+ bb9: {
+ goto -> bb10;
+ }
+
+ bb10: {
+ goto -> bb6;
}
}

View file

@ -14,7 +14,7 @@
bb1: {
_2 = const false;
- goto -> bb3;
+ goto -> bb8;
+ goto -> bb9;
}
bb2: {
@ -47,10 +47,14 @@
+ }
+
+ bb8: {
+ goto -> bb9;
+ switchInt(copy _2) -> [0: bb4, otherwise: bb5];
+ }
+
+ bb9: {
+ goto -> bb10;
+ }
+
+ bb10: {
+ goto -> bb6;
}
}

View file

@ -19,9 +19,9 @@ fn too_complex(x: Result<i32, usize>) -> Option<i32> {
// CHECK: goto -> bb8;
// CHECK: bb3: {
// CHECK: [[controlflow]] = ControlFlow::<usize, i32>::Continue(
// CHECK: goto -> bb4;
// CHECK: goto -> bb9;
// CHECK: bb4: {
// CHECK: goto -> bb6;
// CHECK: switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1];
// CHECK: bb5: {
// CHECK: {{_.*}} = copy (([[controlflow]] as Break).0: usize);
// CHECK: _0 = Option::<i32>::None;
@ -34,6 +34,8 @@ fn too_complex(x: Result<i32, usize>) -> Option<i32> {
// CHECK: return;
// CHECK: bb8: {
// CHECK: goto -> bb5;
// CHECK: bb9: {
// CHECK: goto -> bb6;
match {
match x {
Ok(v) => ControlFlow::Continue(v),
@ -63,7 +65,7 @@ fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
// CHECK: bb4: {
// CHECK: return;
// CHECK: bb5: {
// CHECK: goto -> bb2;
// CHECK: switchInt(move _5) -> [0: bb2, 1: bb3, otherwise: bb1];
// CHECK: bb6: {
// CHECK: {{_.*}} = move (([[x]] as Err).0: i32);
// CHECK: [[controlflow]] = ControlFlow::<Result<Infallible, i32>, i32>::Break(
@ -71,12 +73,40 @@ fn identity(x: Result<i32, i32>) -> Result<i32, i32> {
// CHECK: bb7: {
// CHECK: {{_.*}} = move (([[x]] as Ok).0: i32);
// CHECK: [[controlflow]] = ControlFlow::<Result<Infallible, i32>, i32>::Continue(
// CHECK: goto -> bb5;
// CHECK: goto -> bb9;
// CHECK: bb8: {
// CHECK: goto -> bb3;
// CHECK: bb9: {
// CHECK: goto -> bb2;
Ok(x?)
}
fn two_reads() -> i32 {
// CHECK-LABEL: fn two_reads(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug b => [[b:_.*]];
// CHECK: debug c => [[c:_.*]];
// CHECK: bb0: {
// CHECK: [[a]] = const 2_i32;
// CHECK: [[b]] = copy [[a]];
// CHECK: [[c]] = copy [[a]];
// CHECK: [[tmp:_.*]] = copy [[c]];
// CHECK: [[eq:_.*]] = Eq(move [[tmp]], const 2_i32);
// CHECK: goto -> bb1;
// CHECK: bb1: {
// CHECK: _0 = const 0_i32;
// CHECK: goto -> bb3;
// CHECK: bb2: {
// CHECK: _0 = const 1_i32;
// CHECK: goto -> bb3;
// CHECK: bb3: {
// CHECK: return;
let a = 2;
let b = a;
let c = a;
if c == 2 { 0 } else { 1 }
}
enum DFA {
A,
B,
@ -134,9 +164,9 @@ fn custom_discr(x: bool) -> u8 {
// CHECK: goto -> bb7;
// CHECK: bb2: {
// CHECK: {{_.*}} = CustomDiscr::B;
// CHECK: goto -> bb3;
// CHECK: goto -> bb8;
// CHECK: bb3: {
// CHECK: goto -> bb4;
// CHECK: switchInt(move _4) -> [35: bb5, otherwise: bb4];
// CHECK: bb4: {
// CHECK: _0 = const 13_u8;
// CHECK: goto -> bb6;
@ -147,6 +177,8 @@ fn custom_discr(x: bool) -> u8 {
// CHECK: return;
// CHECK: bb7: {
// CHECK: goto -> bb5;
// CHECK: bb8: {
// CHECK: goto -> bb4;
match if x { CustomDiscr::A } else { CustomDiscr::B } {
CustomDiscr::A => 5,
_ => 13,
@ -258,7 +290,6 @@ fn duplicate_chain(x: bool) -> u8 {
bb4 = {
// CHECK: bb4: {
// CHECK: {{_.*}} = const 15_i32;
// CHECK-NOT: switchInt(
// CHECK: goto -> bb5;
let c = 15;
match a { 5 => bb5, _ => bb6 }
@ -348,7 +379,7 @@ fn renumbered_bb(x: bool) -> u8 {
}
bb1 = {
// CHECK: bb1: {
// CHECK: goto -> bb8;
// CHECK: goto -> bb9;
a = false;
Goto(bb3)
}
@ -389,10 +420,13 @@ fn renumbered_bb(x: bool) -> u8 {
}
// Duplicate of bb3.
// CHECK: bb8: {
// CHECK-NEXT: goto -> bb9;
// Duplicate of bb4.
// CHECK: switchInt(copy _2) -> [0: bb4, otherwise: bb5];
// Duplicate of bb8.
// CHECK: bb9: {
// CHECK-NEXT: goto -> bb6;
// CHECK: goto -> bb10;
// Duplicate of bb4.
// CHECK: bb10: {
// CHECK: goto -> bb6;
}
}
@ -407,22 +441,26 @@ fn disappearing_bb(x: u8) -> u8 {
let a: bool;
let b: bool;
{
// CHECK: bb0: {
a = true;
b = true;
// CHECK: switchInt({{.*}}) -> [0: bb3, 1: bb3, 2: bb1, otherwise: bb2];
match x { 0 => bb3, 1 => bb3, 2 => bb1, _ => bb2 }
}
bb1 = {
// CHECK: bb1: {
// CHECK: goto -> bb9;
// CHECK: goto -> bb10;
b = false;
Goto(bb4)
}
bb2 = {
// CHECK: bb2: {
// CHECK: unreachable;
Unreachable()
}
bb3 = {
// CHECK: bb3: {
// CHECK: goto -> bb10;
// CHECK: goto -> bb13;
a = false;
Goto(bb4)
}
@ -442,16 +480,34 @@ fn disappearing_bb(x: u8) -> u8 {
Goto(bb6)
}
// CHECK: bb9: {
// CHECK: goto -> bb5;
// CHECK: switchInt(copy _3) -> [0: bb5, otherwise: bb7];
// CHECK: bb10: {
// CHECK: goto -> bb6;
// CHECK: goto -> bb11;
// CHECK: bb11: {
// CHECK: goto -> bb8;
// CHECK: bb12: {
// CHECK: switchInt(copy _3) -> [0: bb5, otherwise: bb7];
// CHECK: bb13: {
// CHECK: goto -> bb14;
// CHECK: bb14: {
// CHECK: goto -> bb15;
// CHECK: bb15: {
// CHECK: goto -> bb6;
}
}
/// Verify that we can thread jumps when we assign from an aggregate constant.
fn aggregate(x: u8) -> u8 {
fn aggregate() -> u8 {
// CHECK-LABEL: fn aggregate(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug b => [[b:_.*]];
// CHECK-NOT: switchInt(
// CHECK: [[a2:_.*]] = copy [[a]];
// CHECK: {{_.*}} = Eq(move [[a2]], const 7_u8);
// CHECK-NEXT: goto -> [[bb:bb.*]];
// CHECK: [[bb]]: {
// CHECK-NOT: }
// CHECK: _0 = copy [[a]];
const FOO: (u8, u8) = (5, 13);
@ -508,7 +564,16 @@ fn assume(a: u8, b: bool) -> u8 {
/// Verify that jump threading succeeds seeing through copies of aggregates.
fn aggregate_copy() -> u32 {
// CHECK-LABEL: fn aggregate_copy(
// CHECK: debug a => [[a:_.*]];
// CHECK: debug b => [[b:_.*]];
// CHECK: debug c => [[c:_.*]];
// CHECK-NOT: switchInt(
// CHECK: [[c2:_.*]] = copy [[c]];
// CHECK: {{_.*}} = Eq(move [[c2]], const 2_u32);
// CHECK-NEXT: goto -> [[bb:bb.*]];
// CHECK: [[bb]]: {
// CHECK-NOT: }
// CHECK: _0 = const 13_u32;
const Foo: (u32, u32) = (5, 3);
@ -532,6 +597,14 @@ fn floats() -> u32 {
pub fn bitwise_not() -> i32 {
// CHECK-LABEL: fn bitwise_not(
// CHECK: debug a => [[a:_.*]];
// CHECK: [[a2:_.*]] = copy [[a]];
// CHECK: [[not:_.*]] = Not(move [[a2]]);
// CHECK: {{_.*}} = Eq(move [[not]], const 0_i32);
// CHECK-NEXT: goto -> [[bb:bb.*]];
// CHECK: [[bb]]: {
// CHECK-NOT: }
// CHECK: _0 = const 0_i32;
// Test for #131195, which was optimizing `!a == b` into `a != b`.
let a = 1;
@ -540,11 +613,49 @@ pub fn bitwise_not() -> i32 {
pub fn logical_not() -> i32 {
// CHECK-LABEL: fn logical_not(
// CHECK: debug a => [[a:_.*]];
// CHECK: [[a2:_.*]] = copy [[a]];
// CHECK: [[not:_.*]] = Not(move [[a2]]);
// CHECK: {{_.*}} = Eq(move [[not]], const true);
// CHECK-NEXT: goto -> [[bb:bb.*]];
// CHECK: [[bb]]: {
// CHECK-NOT: }
// CHECK: _0 = const 1_i32;
let a = false;
if !a == true { 1 } else { 0 }
}
/// Verify that we correctly handle threading multiple conditions on the same bb.
/// One version of the implementation was buggy and mutated a bb that would be duplicated later.
fn chained_conditions() -> u8 {
// CHECK-LABEL: fn chained_conditions(
#[inline(never)]
fn env_var() -> Option<String> {
None
}
enum BacktraceStyle {
Off,
Short,
Full,
};
let format = match env_var() {
Some(x) if &x == "full" => BacktraceStyle::Full,
Some(x) if &x == "0" => BacktraceStyle::Off,
Some(_) => BacktraceStyle::Short,
None => BacktraceStyle::Off,
};
match format {
BacktraceStyle::Off => 1,
BacktraceStyle::Short => 2,
BacktraceStyle::Full => 3,
}
}
fn main() {
// CHECK-LABEL: fn main(
too_complex(Ok(0));
@ -557,7 +668,7 @@ fn main() {
mutable_ref();
renumbered_bb(true);
disappearing_bb(7);
aggregate(7);
aggregate();
assume(7, false);
floats();
bitwise_not();
@ -566,6 +677,7 @@ fn main() {
// EMIT_MIR jump_threading.too_complex.JumpThreading.diff
// EMIT_MIR jump_threading.identity.JumpThreading.diff
// EMIT_MIR jump_threading.two_reads.JumpThreading.diff
// EMIT_MIR jump_threading.custom_discr.JumpThreading.diff
// EMIT_MIR jump_threading.dfa.JumpThreading.diff
// EMIT_MIR jump_threading.multiple_match.JumpThreading.diff
@ -580,3 +692,4 @@ fn main() {
// EMIT_MIR jump_threading.floats.JumpThreading.diff
// EMIT_MIR jump_threading.bitwise_not.JumpThreading.diff
// EMIT_MIR jump_threading.logical_not.JumpThreading.diff
// EMIT_MIR jump_threading.chained_conditions.JumpThreading.diff

View file

@ -57,13 +57,13 @@
_2 = ControlFlow::<usize, i32>::Continue(move _5);
StorageDead(_5);
StorageDead(_4);
goto -> bb4;
- goto -> bb4;
+ goto -> bb9;
}
bb4: {
_8 = discriminant(_2);
- switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1];
+ goto -> bb6;
switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1];
}
bb5: {
@ -93,6 +93,11 @@
+ bb8: {
+ _8 = discriminant(_2);
+ goto -> bb5;
+ }
+
+ bb9: {
+ _8 = discriminant(_2);
+ goto -> bb6;
}
}

View file

@ -57,13 +57,13 @@
_2 = ControlFlow::<usize, i32>::Continue(move _5);
StorageDead(_5);
StorageDead(_4);
goto -> bb4;
- goto -> bb4;
+ goto -> bb9;
}
bb4: {
_8 = discriminant(_2);
- switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1];
+ goto -> bb6;
switchInt(move _8) -> [0: bb6, 1: bb5, otherwise: bb1];
}
bb5: {
@ -93,6 +93,11 @@
+ bb8: {
+ _8 = discriminant(_2);
+ goto -> bb5;
+ }
+
+ bb9: {
+ _8 = discriminant(_2);
+ goto -> bb6;
}
}

View file

@ -0,0 +1,56 @@
- // MIR for `two_reads` before JumpThreading
+ // MIR for `two_reads` after JumpThreading
fn two_reads() -> i32 {
let mut _0: i32;
let _1: i32;
let mut _4: bool;
let mut _5: i32;
scope 1 {
debug a => _1;
let _2: i32;
scope 2 {
debug b => _2;
let _3: i32;
scope 3 {
debug c => _3;
}
}
}
bb0: {
StorageLive(_1);
_1 = const 2_i32;
StorageLive(_2);
_2 = copy _1;
StorageLive(_3);
_3 = copy _1;
StorageLive(_4);
StorageLive(_5);
_5 = copy _3;
_4 = Eq(move _5, const 2_i32);
- switchInt(move _4) -> [0: bb2, otherwise: bb1];
+ goto -> bb1;
}
bb1: {
StorageDead(_5);
_0 = const 0_i32;
goto -> bb3;
}
bb2: {
StorageDead(_5);
_0 = const 1_i32;
goto -> bb3;
}
bb3: {
StorageDead(_4);
StorageDead(_3);
StorageDead(_2);
StorageDead(_1);
return;
}
}

View file

@ -0,0 +1,56 @@
- // MIR for `two_reads` before JumpThreading
+ // MIR for `two_reads` after JumpThreading
fn two_reads() -> i32 {
let mut _0: i32;
let _1: i32;
let mut _4: bool;
let mut _5: i32;
scope 1 {
debug a => _1;
let _2: i32;
scope 2 {
debug b => _2;
let _3: i32;
scope 3 {
debug c => _3;
}
}
}
bb0: {
StorageLive(_1);
_1 = const 2_i32;
StorageLive(_2);
_2 = copy _1;
StorageLive(_3);
_3 = copy _1;
StorageLive(_4);
StorageLive(_5);
_5 = copy _3;
_4 = Eq(move _5, const 2_i32);
- switchInt(move _4) -> [0: bb2, otherwise: bb1];
+ goto -> bb1;
}
bb1: {
StorageDead(_5);
_0 = const 0_i32;
goto -> bb3;
}
bb2: {
StorageDead(_5);
_0 = const 1_i32;
goto -> bb3;
}
bb3: {
StorageDead(_4);
StorageDead(_3);
StorageDead(_2);
StorageDead(_1);
return;
}
}

View file

@ -7,12 +7,11 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
scope 1 (inlined <MultiField as PartialOrd>::le) {
let mut _6: std::option::Option<std::cmp::Ordering>;
scope 2 (inlined Option::<std::cmp::Ordering>::is_some_and::<fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le}>) {
let mut _11: isize;
let _12: std::cmp::Ordering;
let _11: std::cmp::Ordering;
scope 3 {
scope 4 (inlined <fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le} as FnOnce<(std::cmp::Ordering,)>>::call_once - shim(fn(std::cmp::Ordering) -> bool {std::cmp::Ordering::is_le})) {
scope 5 (inlined std::cmp::Ordering::is_le) {
let mut _13: i8;
let mut _12: i8;
scope 6 (inlined std::cmp::Ordering::as_raw) {
}
}
@ -37,7 +36,7 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
}
bb0: {
StorageLive(_12);
StorageLive(_11);
StorageLive(_6);
StorageLive(_5);
StorageLive(_7);
@ -64,42 +63,19 @@ fn demo_le(_1: &MultiField, _2: &MultiField) -> bool {
StorageDead(_8);
_6 = Option::<std::cmp::Ordering>::Some(move _10);
StorageDead(_10);
StorageDead(_7);
StorageDead(_5);
StorageLive(_11);
goto -> bb4;
goto -> bb2;
}
bb2: {
StorageDead(_7);
StorageDead(_5);
StorageLive(_11);
_11 = discriminant(_6);
switchInt(move _11) -> [0: bb3, 1: bb4, otherwise: bb6];
}
bb3: {
_0 = const false;
goto -> bb5;
}
bb4: {
_12 = move ((_6 as Some).0: std::cmp::Ordering);
StorageLive(_13);
_13 = discriminant(_12);
_0 = Le(move _13, const 0_i8);
StorageDead(_13);
goto -> bb5;
}
bb5: {
StorageDead(_11);
StorageDead(_6);
_11 = move ((_6 as Some).0: std::cmp::Ordering);
StorageLive(_12);
_12 = discriminant(_11);
_0 = Le(move _12, const 0_i8);
StorageDead(_12);
StorageDead(_6);
StorageDead(_11);
return;
}
bb6: {
unreachable;
}
}

View file

@ -13,22 +13,23 @@ pub fn demo_le(a: &MultiField, b: &MultiField) -> bool {
// CHECK: inlined{{.+}}is_some_and
// CHECK: inlined <MultiField as PartialOrd>::partial_cmp
// CHECK: [[A0:_[0-9]+]] = copy ((*_1).0: char);
// CHECK: [[B0:_[0-9]+]] = copy ((*_2).0: char);
// CHECK: Cmp(move [[A0]], move [[B0]]);
// CHECK: bb0: {
// CHECK: [[A0:_[0-9]+]] = copy ((*_1).0: char);
// CHECK: [[B0:_[0-9]+]] = copy ((*_2).0: char);
// CHECK: Cmp(move [[A0]], move [[B0]]);
// CHECK: [[D0:_[0-9]+]] = discriminant({{.+}});
// CHECK: switchInt(move [[D0]]) -> [0: bb1, otherwise: bb2];
// CHECK: [[D0:_[0-9]+]] = discriminant({{.+}});
// CHECK: switchInt(move [[D0]]) -> [0: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}];
// CHECK: bb1: {
// CHECK: [[A1:_[0-9]+]] = copy ((*_1).1: i16);
// CHECK: [[B1:_[0-9]+]] = copy ((*_2).1: i16);
// CHECK: Cmp(move [[A1]], move [[B1]]);
// CHECK: goto -> bb2;
// CHECK: [[A1:_[0-9]+]] = copy ((*_1).1: i16);
// CHECK: [[B1:_[0-9]+]] = copy ((*_2).1: i16);
// CHECK: Cmp(move [[A1]], move [[B1]]);
// CHECK: [[D1:_[0-9]+]] = discriminant({{.+}});
// CHECK: switchInt(move [[D1]]) -> [0: bb{{[0-9]+}}, 1: bb{{[0-9]+}}, otherwise: bb{{[0-9]+}}];
// CHECK: [[D2:_[0-9]+]] = discriminant({{.+}});
// CHECK: _0 = Le(move [[D2]], const 0_i8);
// CHECK: bb2: {
// CHECK: [[D2:_[0-9]+]] = discriminant({{.+}});
// CHECK: _0 = Le(move [[D2]], const 0_i8);
// CHECK: return;
*a <= *b
}

View file

@ -211,12 +211,6 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
bb7: {
StorageDead(_16);
StorageDead(_22);
StorageDead(_13);
StorageDead(_20);
StorageDead(_19);
StorageDead(_12);
StorageDead(_11);
goto -> bb10;
}
@ -226,16 +220,16 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
}
bb9: {
goto -> bb10;
}
bb10: {
StorageDead(_22);
StorageDead(_13);
StorageDead(_20);
StorageDead(_19);
StorageDead(_12);
StorageDead(_11);
goto -> bb10;
}
bb10: {
StorageDead(_23);
StorageDead(_26);
StorageDead(_25);

View file

@ -173,12 +173,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb7: {
StorageDead(_15);
StorageDead(_21);
StorageDead(_12);
StorageDead(_19);
StorageDead(_18);
StorageDead(_11);
StorageDead(_10);
goto -> bb10;
}
@ -188,16 +182,16 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb9: {
goto -> bb10;
}
bb10: {
StorageDead(_21);
StorageDead(_12);
StorageDead(_19);
StorageDead(_18);
StorageDead(_11);
StorageDead(_10);
goto -> bb10;
}
bb10: {
StorageDead(_22);
drop(_2) -> [return: bb11, unwind unreachable];
}

View file

@ -173,12 +173,6 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
bb7: {
StorageDead(_15);
StorageDead(_21);
StorageDead(_12);
StorageDead(_19);
StorageDead(_18);
StorageDead(_11);
StorageDead(_10);
goto -> bb10;
}
@ -188,16 +182,16 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
}
bb9: {
goto -> bb10;
}
bb10: {
StorageDead(_21);
StorageDead(_12);
StorageDead(_19);
StorageDead(_18);
StorageDead(_11);
StorageDead(_10);
goto -> bb10;
}
bb10: {
StorageDead(_22);
drop(_2) -> [return: bb11, unwind continue];
}

View file

@ -69,8 +69,7 @@
StorageDead(_7);
StorageDead(_6);
_3 = discriminant(_2);
- switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
+ goto -> bb2;
switchInt(move _3) -> [0: bb2, 1: bb3, otherwise: bb1];
}
bb5: {
@ -86,7 +85,8 @@
bb6: {
_7 = copy ((_1 as Ok).0: i32);
_2 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(copy _7);
goto -> bb4;
- goto -> bb4;
+ goto -> bb8;
+ }
+
+ bb7: {
@ -95,6 +95,14 @@
+ StorageDead(_6);
+ _3 = discriminant(_2);
+ goto -> bb3;
+ }
+
+ bb8: {
+ StorageDead(_8);
+ StorageDead(_7);
+ StorageDead(_6);
+ _3 = discriminant(_2);
+ goto -> bb2;
}
}

View file

@ -44,13 +44,13 @@
bb3: {
_4 = copy ((_1 as Ok).0: i32);
_2 = ControlFlow::<usize, i32>::Continue(copy _4);
goto -> bb4;
- goto -> bb4;
+ goto -> bb9;
}
bb4: {
_6 = discriminant(_2);
- switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb1];
+ goto -> bb6;
switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb1];
}
bb5: {
@ -75,6 +75,11 @@
+ bb8: {
+ _6 = discriminant(_2);
+ goto -> bb5;
+ }
+
+ bb9: {
+ _6 = discriminant(_2);
+ goto -> bb6;
}
}