Skip to content

Commit 7c085ac

Browse files
authored
Rollup merge of #155026 - nnethercote:mv-maybe_loop_headers, r=dianqk
Move `maybe_loop_headers` out of `rustc_middle`. `rustc_middle` is enormous and it's always good to move things out of it where possible. `maybe_loop_headers` is easy to move because it has a single use in `jump_threading.rs`. r? @WaffleLapkin
2 parents a2d7d8c + 6352e82 commit 7c085ac

3 files changed

Lines changed: 27 additions & 32 deletions

File tree

compiler/rustc_middle/src/mir/loops.rs

Lines changed: 0 additions & 29 deletions
This file was deleted.

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ mod query;
4848
mod statement;
4949
mod syntax;
5050
mod terminator;
51-
52-
pub mod loops;
5351
pub mod traversal;
5452
pub mod visit;
5553

compiler/rustc_mir_transform/src/jump_threading.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
9797
ecx: InterpCx::new(tcx, DUMMY_SP, typing_env, DummyMachine),
9898
body,
9999
map: Map::new(tcx, body, PlaceCollectionMode::OnDemand),
100-
maybe_loop_headers: loops::maybe_loop_headers(body),
100+
maybe_loop_headers: maybe_loop_headers(body),
101101
entry_states: IndexVec::from_elem(ConditionSet::default(), &body.basic_blocks),
102102
};
103103

@@ -1100,3 +1100,29 @@ impl<'a, 'tcx> OpportunitySet<'a, 'tcx> {
11001100
Some(new_target)
11011101
}
11021102
}
1103+
1104+
/// Compute the set of loop headers in the given body. A loop header is usually defined as a block
1105+
/// which dominates one of its predecessors. This definition is only correct for reducible CFGs.
1106+
/// However, computing dominators is expensive, so we approximate according to the post-order
1107+
/// traversal order. A loop header for us is a block which is visited after its predecessor in
1108+
/// post-order. This is ok as we mostly need a heuristic.
1109+
fn maybe_loop_headers(body: &Body<'_>) -> DenseBitSet<BasicBlock> {
1110+
let mut maybe_loop_headers = DenseBitSet::new_empty(body.basic_blocks.len());
1111+
let mut visited = DenseBitSet::new_empty(body.basic_blocks.len());
1112+
for (bb, bbdata) in traversal::postorder(body) {
1113+
// Post-order means we visit successors before the block for acyclic CFGs.
1114+
// If the successor is not visited yet, consider it a loop header.
1115+
for succ in bbdata.terminator().successors() {
1116+
if !visited.contains(succ) {
1117+
maybe_loop_headers.insert(succ);
1118+
}
1119+
}
1120+
1121+
// Only mark `bb` as visited after we checked the successors, in case we have a self-loop.
1122+
// bb1: goto -> bb1;
1123+
let _new = visited.insert(bb);
1124+
debug_assert!(_new);
1125+
}
1126+
1127+
maybe_loop_headers
1128+
}

0 commit comments

Comments
 (0)