@@ -27,49 +27,12 @@ pub struct SsaLocals {
2727 direct_uses : IndexVec < Local , u32 > ,
2828}
2929
30- /// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to
31- /// actually compute dominators, we can just compare block indices because bb0 is always the first
32- /// block, and in any body all other blocks are always dominated by bb0.
33- struct SmallDominators < ' a > {
34- inner : Option < & ' a Dominators < BasicBlock > > ,
35- }
36-
37- impl SmallDominators < ' _ > {
38- fn dominates ( & self , first : Location , second : Location ) -> bool {
39- if first. block == second. block {
40- first. statement_index <= second. statement_index
41- } else if let Some ( inner) = & self . inner {
42- inner. dominates ( first. block , second. block )
43- } else {
44- first. block < second. block
45- }
46- }
47-
48- fn check_dominates ( & mut self , set : & mut Set1 < LocationExtended > , loc : Location ) {
49- let assign_dominates = match * set {
50- Set1 :: Empty | Set1 :: Many => false ,
51- Set1 :: One ( LocationExtended :: Arg ) => true ,
52- Set1 :: One ( LocationExtended :: Plain ( assign) ) => {
53- self . dominates ( assign. successor_within_block ( ) , loc)
54- }
55- } ;
56- // We are visiting a use that is not dominated by an assignment.
57- // Either there is a cycle involved, or we are reading for uninitialized local.
58- // Bail out.
59- if !assign_dominates {
60- * set = Set1 :: Many ;
61- }
62- }
63- }
64-
6530impl SsaLocals {
6631 pub fn new < ' tcx > ( body : & Body < ' tcx > ) -> SsaLocals {
6732 let assignment_order = Vec :: with_capacity ( body. local_decls . len ( ) ) ;
6833
6934 let assignments = IndexVec :: from_elem ( Set1 :: Empty , & body. local_decls ) ;
70- let dominators =
71- if body. basic_blocks . len ( ) > 2 { Some ( body. basic_blocks . dominators ( ) ) } else { None } ;
72- let dominators = SmallDominators { inner : dominators } ;
35+ let dominators = body. basic_blocks . dominators ( ) ;
7336
7437 let direct_uses = IndexVec :: from_elem ( 0 , & body. local_decls ) ;
7538 let mut visitor = SsaVisitor { assignments, assignment_order, dominators, direct_uses } ;
@@ -231,12 +194,31 @@ enum LocationExtended {
231194}
232195
233196struct SsaVisitor < ' a > {
234- dominators : SmallDominators < ' a > ,
197+ dominators : & ' a Dominators < BasicBlock > ,
235198 assignments : IndexVec < Local , Set1 < LocationExtended > > ,
236199 assignment_order : Vec < Local > ,
237200 direct_uses : IndexVec < Local , u32 > ,
238201}
239202
203+ impl SsaVisitor < ' _ > {
204+ fn check_dominates ( & mut self , local : Local , loc : Location ) {
205+ let set = & mut self . assignments [ local] ;
206+ let assign_dominates = match * set {
207+ Set1 :: Empty | Set1 :: Many => false ,
208+ Set1 :: One ( LocationExtended :: Arg ) => true ,
209+ Set1 :: One ( LocationExtended :: Plain ( assign) ) => {
210+ assign. successor_within_block ( ) . dominates ( loc, self . dominators )
211+ }
212+ } ;
213+ // We are visiting a use that is not dominated by an assignment.
214+ // Either there is a cycle involved, or we are reading for uninitialized local.
215+ // Bail out.
216+ if !assign_dominates {
217+ * set = Set1 :: Many ;
218+ }
219+ }
220+ }
221+
240222impl < ' tcx > Visitor < ' tcx > for SsaVisitor < ' _ > {
241223 fn visit_local ( & mut self , local : Local , ctxt : PlaceContext , loc : Location ) {
242224 match ctxt {
@@ -254,7 +236,7 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
254236 self . assignments [ local] = Set1 :: Many ;
255237 }
256238 PlaceContext :: NonMutatingUse ( _) => {
257- self . dominators . check_dominates ( & mut self . assignments [ local] , loc) ;
239+ self . check_dominates ( local, loc) ;
258240 self . direct_uses [ local] += 1 ;
259241 }
260242 PlaceContext :: NonUse ( _) => { }
@@ -269,7 +251,7 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
269251 let new_ctxt = PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Copy ) ;
270252
271253 self . visit_projection ( place. as_ref ( ) , new_ctxt, loc) ;
272- self . dominators . check_dominates ( & mut self . assignments [ place. local ] , loc) ;
254+ self . check_dominates ( place. local , loc) ;
273255 }
274256 return ;
275257 } else {
0 commit comments