@@ -19,6 +19,33 @@ pub struct SsaLocals {
19
19
copy_classes: IndexVec<Local, Local>,
20
20
}
21
21
22
+ /// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to
23
+ /// actually compute dominators, we can just compare block indices because bb0 is always the first
24
+ /// block, and in any body all other blocks are always always dominated by bb0.
25
+ struct SmallDominators {
26
+ inner: Option<Dominators<BasicBlock>>,
27
+ }
28
+
29
+ trait DomExt {
30
+ fn dominates(self, _other: Self, dominators: &SmallDominators) -> bool;
31
+ }
32
+
33
+ impl DomExt for Location {
34
+ fn dominates(self, other: Location, dominators: &SmallDominators) -> bool {
35
+ if self.block == other.block {
36
+ self.statement_index <= other.statement_index
37
+ } else {
38
+ dominators.dominates(self.block, other.block)
39
+ }
40
+ }
41
+ }
42
+
43
+ impl SmallDominators {
44
+ fn dominates(&self, dom: BasicBlock, node: BasicBlock) -> bool {
45
+ if let Some(inner) = &self.inner { inner.dominates(dom, node) } else { dom < node }
46
+ }
47
+ }
48
+
22
49
impl SsaLocals {
23
50
pub fn new<'tcx>(
24
51
tcx: TyCtxt<'tcx>,
@@ -29,7 +56,9 @@ impl SsaLocals {
29
56
let assignment_order = Vec::new();
30
57
31
58
let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls);
32
- let dominators = body.basic_blocks.dominators();
59
+ let dominators =
60
+ if body.basic_blocks.len() > 2 { Some(body.basic_blocks.dominators()) } else { None };
61
+ let dominators = SmallDominators { inner: dominators };
33
62
let mut visitor = SsaVisitor { assignments, assignment_order, dominators };
34
63
35
64
for (local, decl) in body.local_decls.iter_enumerated() {
@@ -41,8 +70,14 @@ impl SsaLocals {
41
70
}
42
71
}
43
72
44
- for (bb, data) in traversal::reverse_postorder(body) {
45
- visitor.visit_basic_block_data(bb, data);
73
+ if body.basic_blocks.len() > 2 {
74
+ for (bb, data) in traversal::reverse_postorder(body) {
75
+ visitor.visit_basic_block_data(bb, data);
76
+ }
77
+ } else {
78
+ for (bb, data) in body.basic_blocks.iter_enumerated() {
79
+ visitor.visit_basic_block_data(bb, data);
80
+ }
46
81
}
47
82
48
83
for var_debug_info in &body.var_debug_info {
@@ -139,7 +174,7 @@ enum LocationExtended {
139
174
}
140
175
141
176
struct SsaVisitor {
142
- dominators: Dominators<BasicBlock> ,
177
+ dominators: SmallDominators ,
143
178
assignments: IndexVec<Local, Set1<LocationExtended>>,
144
179
assignment_order: Vec<Local>,
145
180
}
0 commit comments