@@ -19,6 +19,33 @@ pub struct SsaLocals {
1919 copy_classes : IndexVec < Local , Local > ,
2020}
2121
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+
2249impl SsaLocals {
2350 pub fn new < ' tcx > (
2451 tcx : TyCtxt < ' tcx > ,
@@ -29,7 +56,9 @@ impl SsaLocals {
2956 let assignment_order = Vec :: new ( ) ;
3057
3158 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 } ;
3362 let mut visitor = SsaVisitor { assignments, assignment_order, dominators } ;
3463
3564 for ( local, decl) in body. local_decls . iter_enumerated ( ) {
@@ -41,8 +70,14 @@ impl SsaLocals {
4170 }
4271 }
4372
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+ }
4681 }
4782
4883 for var_debug_info in & body. var_debug_info {
@@ -139,7 +174,7 @@ enum LocationExtended {
139174}
140175
141176struct SsaVisitor {
142- dominators : Dominators < BasicBlock > ,
177+ dominators : SmallDominators ,
143178 assignments : IndexVec < Local , Set1 < LocationExtended > > ,
144179 assignment_order : Vec < Local > ,
145180}
0 commit comments