@@ -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