Skip to content

Commit 394cb02

Browse files
committed
Simplify condition graph.
1 parent eb8e141 commit 394cb02

10 files changed

+215
-228
lines changed

compiler/rustc_mir_transform/src/jump_threading.rs

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,8 @@ impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
134134
finder.entry_states[bb] = state;
135135
}
136136

137-
if let Some(opportunities) = OpportunitySet::new(body, finder.entry_states) {
137+
if let Some(mut opportunities) = OpportunitySet::new(body, finder.entry_states) {
138+
opportunities.simplify();
138139
opportunities.apply();
139140
}
140141
}
@@ -796,6 +797,88 @@ impl<'a, 'tcx> OpportunitySet<'a, 'tcx> {
796797
Some(OpportunitySet { basic_blocks, entry_states, duplicates })
797798
}
798799

800+
/// Propagate fulfilled conditions forward in the CFG to reduce the amount of duplication.
801+
#[instrument(level = "debug", skip(self))]
802+
fn simplify(&mut self) {
803+
let mut worklist = Vec::with_capacity(self.basic_blocks.len());
804+
worklist.push(START_BLOCK);
805+
let mut visited =
806+
FxHashSet::with_capacity_and_hasher(self.basic_blocks.len(), Default::default());
807+
808+
// Start by computing the number of reachable predecessors for each block.
809+
let mut predecessors = IndexVec::from_elem(0, &self.entry_states);
810+
predecessors[START_BLOCK] = 1; // Account for the implicit entry edge.
811+
while let Some(bb) = worklist.pop() {
812+
if visited.insert(bb) {
813+
let term = self.basic_blocks[bb].terminator();
814+
for s in term.successors() {
815+
predecessors[s] += 1;
816+
worklist.push(s);
817+
}
818+
}
819+
}
820+
821+
// Compute the number of edges into each block that carry each condition.
822+
let mut fulfill_in_pred_count = IndexVec::from_fn_n(
823+
|bb: BasicBlock| IndexVec::from_elem_n(0, self.entry_states[bb].targets.len()),
824+
self.entry_states.len(),
825+
);
826+
827+
visited.clear();
828+
worklist.push(START_BLOCK);
829+
while let Some(bb) = worklist.pop() {
830+
if !visited.insert(bb) {
831+
continue;
832+
}
833+
834+
trace!(?bb, preds = ?predecessors[bb]);
835+
debug_assert_ne!(predecessors[bb], 0);
836+
837+
if let Some((condition, _)) =
838+
fulfill_in_pred_count[bb].iter_enumerated().find(|&(_, &p)| p == predecessors[bb])
839+
{
840+
trace!(?condition);
841+
self.entry_states[bb].fulfilled.push(condition);
842+
}
843+
844+
let state = &self.entry_states[bb];
845+
trace!(?state);
846+
847+
let mut targets: Vec<_> = state
848+
.fulfilled
849+
.iter()
850+
.flat_map(|&index| state.targets[index].iter().copied())
851+
.collect();
852+
targets.sort();
853+
targets.dedup();
854+
trace!(?targets);
855+
856+
let mut successors =
857+
self.basic_blocks[bb].terminator().successors().collect::<Vec<_>>();
858+
859+
targets.reverse();
860+
while let Some(target) = targets.pop() {
861+
match target {
862+
ConditionTarget::Goto(target) => {
863+
predecessors[target] += 1;
864+
for &s in successors.iter() {
865+
predecessors[s] -= 1;
866+
}
867+
targets.retain(|t| t.block() == target);
868+
successors.clear();
869+
successors.push(target);
870+
}
871+
ConditionTarget::Chain(target, condition) => {
872+
let count = successors.iter().filter(|&&s| s == target).count();
873+
fulfill_in_pred_count[target][condition] += count;
874+
}
875+
}
876+
}
877+
878+
worklist.extend(successors);
879+
}
880+
}
881+
799882
/// Apply the opportunities on the graph.
800883
#[instrument(level = "debug", skip(self))]
801884
fn apply(mut self) {

tests/mir-opt/jump_threading.chained_conditions.JumpThreading.panic-abort.diff

Lines changed: 36 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,7 @@
6161
_22 = const true;
6262
_23 = const true;
6363
_4 = discriminant(_2);
64-
- switchInt(move _4) -> [0: bb3, 1: bb4, otherwise: bb2];
65-
+ switchInt(move _4) -> [0: bb21, 1: bb4, otherwise: bb2];
64+
switchInt(move _4) -> [0: bb3, 1: bb4, otherwise: bb2];
6665
}
6766

6867
bb2: {
@@ -71,7 +70,8 @@
7170

7271
bb3: {
7372
_1 = chained_conditions::BacktraceStyle::Off;
74-
goto -> bb18;
73+
- goto -> bb18;
74+
+ goto -> bb37;
7575
}
7676

7777
bb4: {
@@ -102,7 +102,7 @@
102102
_5 = move ((_2 as Some).0: std::string::String);
103103
_1 = chained_conditions::BacktraceStyle::Full;
104104
- drop(_5) -> [return: bb7, unwind unreachable];
105-
+ drop(_5) -> [return: bb23, unwind unreachable];
105+
+ drop(_5) -> [return: bb21, unwind unreachable];
106106
}
107107

108108
bb6: {
@@ -144,7 +144,7 @@
144144
_12 = move ((_2 as Some).0: std::string::String);
145145
_1 = chained_conditions::BacktraceStyle::Off;
146146
- drop(_12) -> [return: bb10, unwind unreachable];
147-
+ drop(_12) -> [return: bb30, unwind unreachable];
147+
+ drop(_12) -> [return: bb27, unwind unreachable];
148148
}
149149

150150
bb9: {
@@ -155,7 +155,7 @@
155155
StorageDead(_13);
156156
_1 = chained_conditions::BacktraceStyle::Short;
157157
- goto -> bb18;
158-
+ goto -> bb36;
158+
+ goto -> bb33;
159159
}
160160

161161
bb10: {
@@ -218,118 +218,101 @@
218218
+ }
219219
+
220220
+ bb21: {
221-
+ _1 = chained_conditions::BacktraceStyle::Off;
222-
+ goto -> bb40;
223-
+ }
224-
+
225-
+ bb22: {
226221
+ StorageDead(_5);
227222
+ StorageDead(_6);
228-
+ goto -> bb18;
223+
+ goto -> bb23;
229224
+ }
230225
+
231-
+ bb23: {
232-
+ StorageDead(_5);
233-
+ StorageDead(_6);
234-
+ goto -> bb25;
235-
+ }
236-
+
237-
+ bb24: {
226+
+ bb22: {
238227
+ _24 = discriminant(_2);
239228
+ switchInt(move _24) -> [1: bb16, otherwise: bb15];
240229
+ }
241230
+
242-
+ bb25: {
231+
+ bb23: {
243232
+ _24 = discriminant(_2);
244-
+ switchInt(move _24) -> [1: bb28, otherwise: bb26];
233+
+ switchInt(move _24) -> [1: bb26, otherwise: bb24];
245234
+ }
246235
+
247-
+ bb26: {
236+
+ bb24: {
248237
+ _22 = const false;
249238
+ _23 = const false;
250239
+ StorageDead(_2);
251240
+ _19 = discriminant(_1);
252241
+ goto -> bb11;
253242
+ }
254243
+
255-
+ bb27: {
244+
+ bb25: {
256245
+ switchInt(copy _23) -> [0: bb15, otherwise: bb17];
257246
+ }
258247
+
259-
+ bb28: {
260-
+ goto -> bb26;
261-
+ }
262-
+
263-
+ bb29: {
264-
+ StorageDead(_12);
265-
+ StorageDead(_13);
266-
+ goto -> bb18;
248+
+ bb26: {
249+
+ goto -> bb24;
267250
+ }
268251
+
269-
+ bb30: {
252+
+ bb27: {
270253
+ StorageDead(_12);
271254
+ StorageDead(_13);
272-
+ goto -> bb32;
255+
+ goto -> bb29;
273256
+ }
274257
+
275-
+ bb31: {
258+
+ bb28: {
276259
+ _24 = discriminant(_2);
277260
+ switchInt(move _24) -> [1: bb16, otherwise: bb15];
278261
+ }
279262
+
280-
+ bb32: {
263+
+ bb29: {
281264
+ _24 = discriminant(_2);
282-
+ switchInt(move _24) -> [1: bb35, otherwise: bb33];
265+
+ switchInt(move _24) -> [1: bb32, otherwise: bb30];
283266
+ }
284267
+
285-
+ bb33: {
268+
+ bb30: {
286269
+ _22 = const false;
287270
+ _23 = const false;
288271
+ StorageDead(_2);
289272
+ _19 = discriminant(_1);
290273
+ goto -> bb13;
291274
+ }
292275
+
293-
+ bb34: {
276+
+ bb31: {
294277
+ switchInt(copy _23) -> [0: bb15, otherwise: bb17];
295278
+ }
296279
+
297-
+ bb35: {
298-
+ goto -> bb33;
280+
+ bb32: {
281+
+ goto -> bb30;
299282
+ }
300283
+
301-
+ bb36: {
284+
+ bb33: {
302285
+ _24 = discriminant(_2);
303-
+ switchInt(move _24) -> [1: bb38, otherwise: bb37];
286+
+ switchInt(move _24) -> [1: bb35, otherwise: bb34];
304287
+ }
305288
+
306-
+ bb37: {
289+
+ bb34: {
307290
+ _22 = const false;
308291
+ _23 = const false;
309292
+ StorageDead(_2);
310293
+ _19 = discriminant(_1);
311294
+ goto -> bb12;
312295
+ }
313296
+
314-
+ bb38: {
315-
+ switchInt(copy _23) -> [0: bb37, otherwise: bb39];
297+
+ bb35: {
298+
+ switchInt(copy _23) -> [0: bb34, otherwise: bb36];
316299
+ }
317300
+
318-
+ bb39: {
319-
+ drop(((_2 as Some).0: std::string::String)) -> [return: bb37, unwind unreachable];
301+
+ bb36: {
302+
+ drop(((_2 as Some).0: std::string::String)) -> [return: bb34, unwind unreachable];
320303
+ }
321304
+
322-
+ bb40: {
305+
+ bb37: {
323306
+ _24 = discriminant(_2);
324-
+ switchInt(move _24) -> [1: bb41, otherwise: bb33];
307+
+ switchInt(move _24) -> [1: bb38, otherwise: bb30];
325308
+ }
326309
+
327-
+ bb41: {
328-
+ goto -> bb42;
310+
+ bb38: {
311+
+ goto -> bb39;
329312
+ }
330313
+
331-
+ bb42: {
332-
+ drop(((_2 as Some).0: std::string::String)) -> [return: bb33, unwind unreachable];
314+
+ bb39: {
315+
+ drop(((_2 as Some).0: std::string::String)) -> [return: bb30, unwind unreachable];
333316
}
334317
}
335318

0 commit comments

Comments
 (0)