11pub use super :: * ;
22
3- use crate :: dataflow:: generic:: { Results , ResultsRefCursor } ;
4- use crate :: dataflow:: BitDenotation ;
5- use crate :: dataflow:: MaybeBorrowedLocals ;
3+ use crate :: dataflow:: generic:: { self as dataflow, GenKill , Results , ResultsRefCursor } ;
4+ use crate :: dataflow:: BottomValue ;
65use rustc:: mir:: visit:: { NonMutatingUseContext , PlaceContext , Visitor } ;
76use rustc:: mir:: * ;
87use std:: cell:: RefCell ;
98
109#[ derive( Copy , Clone ) ]
11- pub struct MaybeStorageLive < ' a , ' tcx > {
12- body : & ' a Body < ' tcx > ,
13- }
10+ pub struct MaybeStorageLive ;
1411
15- impl < ' a , ' tcx > MaybeStorageLive < ' a , ' tcx > {
16- pub fn new ( body : & ' a Body < ' tcx > ) -> Self {
17- MaybeStorageLive { body }
18- }
12+ impl dataflow:: AnalysisDomain < ' tcx > for MaybeStorageLive {
13+ type Idx = Local ;
1914
20- pub fn body ( & self ) -> & Body < ' tcx > {
21- self . body
22- }
23- }
15+ const NAME : & ' static str = "maybe_storage_live" ;
2416
25- impl < ' a , ' tcx > BitDenotation < ' tcx > for MaybeStorageLive < ' a , ' tcx > {
26- type Idx = Local ;
27- fn name ( ) -> & ' static str {
28- "maybe_storage_live"
29- }
30- fn bits_per_block ( & self ) -> usize {
31- self . body . local_decls . len ( )
17+ fn bits_per_block ( & self , body : & mir:: Body < ' tcx > ) -> usize {
18+ body. local_decls . len ( )
3219 }
3320
34- fn start_block_effect ( & self , on_entry : & mut BitSet < Local > ) {
21+ fn initialize_start_block ( & self , body : & mir :: Body < ' tcx > , on_entry : & mut BitSet < Self :: Idx > ) {
3522 // The resume argument is live on function entry (we don't care about
3623 // the `self` argument)
37- for arg in self . body . args_iter ( ) . skip ( 1 ) {
24+ for arg in body. args_iter ( ) . skip ( 1 ) {
3825 on_entry. insert ( arg) ;
3926 }
4027 }
28+ }
4129
42- fn statement_effect ( & self , trans : & mut GenKillSet < Local > , loc : Location ) {
43- let stmt = & self . body [ loc. block ] . statements [ loc. statement_index ] ;
44-
30+ impl dataflow:: GenKillAnalysis < ' tcx > for MaybeStorageLive {
31+ fn statement_effect (
32+ & self ,
33+ trans : & mut impl GenKill < Self :: Idx > ,
34+ stmt : & mir:: Statement < ' tcx > ,
35+ _: Location ,
36+ ) {
4537 match stmt. kind {
4638 StatementKind :: StorageLive ( l) => trans. gen ( l) ,
4739 StatementKind :: StorageDead ( l) => trans. kill ( l) ,
4840 _ => ( ) ,
4941 }
5042 }
5143
52- fn terminator_effect ( & self , _trans : & mut GenKillSet < Local > , _loc : Location ) {
44+ fn terminator_effect (
45+ & self ,
46+ _trans : & mut impl GenKill < Self :: Idx > ,
47+ _: & mir:: Terminator < ' tcx > ,
48+ _: Location ,
49+ ) {
5350 // Terminators have no effect
5451 }
5552
56- fn propagate_call_return (
53+ fn call_return_effect (
5754 & self ,
58- _in_out : & mut BitSet < Local > ,
59- _call_bb : mir:: BasicBlock ,
60- _dest_bb : mir:: BasicBlock ,
61- _dest_place : & mir:: Place < ' tcx > ,
55+ _trans : & mut impl GenKill < Self :: Idx > ,
56+ _block : BasicBlock ,
57+ _func : & mir:: Operand < ' tcx > ,
58+ _args : & [ mir:: Operand < ' tcx > ] ,
59+ _return_place : & mir:: Place < ' tcx > ,
6260 ) {
6361 // Nothing to do when a call returns successfully
6462 }
6563}
6664
67- impl < ' a , ' tcx > BottomValue for MaybeStorageLive < ' a , ' tcx > {
65+ impl BottomValue for MaybeStorageLive {
6866 /// bottom = dead
6967 const BOTTOM_VALUE : bool = false ;
7068}
@@ -73,60 +71,62 @@ type BorrowedLocalsResults<'a, 'tcx> = ResultsRefCursor<'a, 'a, 'tcx, MaybeBorro
7371
7472/// Dataflow analysis that determines whether each local requires storage at a
7573/// given location; i.e. whether its storage can go away without being observed.
76- pub struct RequiresStorage < ' mir , ' tcx > {
74+ pub struct MaybeRequiresStorage < ' mir , ' tcx > {
7775 body : ReadOnlyBodyAndCache < ' mir , ' tcx > ,
7876 borrowed_locals : RefCell < BorrowedLocalsResults < ' mir , ' tcx > > ,
7977}
8078
81- impl < ' mir , ' tcx : ' mir > RequiresStorage < ' mir , ' tcx > {
79+ impl < ' mir , ' tcx > MaybeRequiresStorage < ' mir , ' tcx > {
8280 pub fn new (
8381 body : ReadOnlyBodyAndCache < ' mir , ' tcx > ,
8482 borrowed_locals : & ' mir Results < ' tcx , MaybeBorrowedLocals > ,
8583 ) -> Self {
86- RequiresStorage {
84+ MaybeRequiresStorage {
8785 body,
8886 borrowed_locals : RefCell :: new ( ResultsRefCursor :: new ( * body, borrowed_locals) ) ,
8987 }
9088 }
91-
92- pub fn body ( & self ) -> & Body < ' tcx > {
93- & self . body
94- }
9589}
9690
97- impl < ' mir , ' tcx > BitDenotation < ' tcx > for RequiresStorage < ' mir , ' tcx > {
91+ impl < ' mir , ' tcx > dataflow :: AnalysisDomain < ' tcx > for MaybeRequiresStorage < ' mir , ' tcx > {
9892 type Idx = Local ;
99- fn name ( ) -> & ' static str {
100- "requires_storage"
101- }
102- fn bits_per_block ( & self ) -> usize {
103- self . body . local_decls . len ( )
93+
94+ const NAME : & ' static str = "requires_storage" ;
95+
96+ fn bits_per_block ( & self , body : & mir :: Body < ' tcx > ) -> usize {
97+ body. local_decls . len ( )
10498 }
10599
106- fn start_block_effect ( & self , on_entry : & mut BitSet < Local > ) {
100+ fn initialize_start_block ( & self , body : & mir :: Body < ' tcx > , on_entry : & mut BitSet < Self :: Idx > ) {
107101 // The resume argument is live on function entry (we don't care about
108102 // the `self` argument)
109- for arg in self . body . args_iter ( ) . skip ( 1 ) {
103+ for arg in body. args_iter ( ) . skip ( 1 ) {
110104 on_entry. insert ( arg) ;
111105 }
112106 }
107+ }
113108
114- fn before_statement_effect ( & self , sets : & mut GenKillSet < Self :: Idx > , loc : Location ) {
115- let stmt = & self . body [ loc. block ] . statements [ loc. statement_index ] ;
116-
109+ impl < ' mir , ' tcx > dataflow:: GenKillAnalysis < ' tcx > for MaybeRequiresStorage < ' mir , ' tcx > {
110+ fn before_statement_effect (
111+ & self ,
112+ trans : & mut impl GenKill < Self :: Idx > ,
113+ stmt : & mir:: Statement < ' tcx > ,
114+ loc : Location ,
115+ ) {
117116 // If a place is borrowed in a statement, it needs storage for that statement.
118- self . borrowed_locals . borrow ( ) . analysis ( ) . statement_effect ( sets , stmt, loc) ;
117+ self . borrowed_locals . borrow ( ) . analysis ( ) . statement_effect ( trans , stmt, loc) ;
119118
120- // If a place is assigned to in a statement, it needs storage for that statement.
121119 match & stmt. kind {
122- StatementKind :: StorageDead ( l) => sets. kill ( * l) ,
120+ StatementKind :: StorageDead ( l) => trans. kill ( * l) ,
121+
122+ // If a place is assigned to in a statement, it needs storage for that statement.
123123 StatementKind :: Assign ( box ( place, _) )
124124 | StatementKind :: SetDiscriminant { box place, .. } => {
125- sets . gen ( place. local ) ;
125+ trans . gen ( place. local ) ;
126126 }
127- StatementKind :: InlineAsm ( box InlineAsm { outputs , .. } ) => {
128- for place in & * * outputs {
129- sets . gen ( place. local ) ;
127+ StatementKind :: InlineAsm ( asm ) => {
128+ for place in & * asm . outputs {
129+ trans . gen ( place. local ) ;
130130 }
131131 }
132132
@@ -140,22 +140,30 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
140140 }
141141 }
142142
143- fn statement_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
143+ fn statement_effect (
144+ & self ,
145+ trans : & mut impl GenKill < Self :: Idx > ,
146+ _: & mir:: Statement < ' tcx > ,
147+ loc : Location ,
148+ ) {
144149 // If we move from a place then only stops needing storage *after*
145150 // that statement.
146- self . check_for_move ( sets , loc) ;
151+ self . check_for_move ( trans , loc) ;
147152 }
148153
149- fn before_terminator_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
150- let terminator = self . body [ loc. block ] . terminator ( ) ;
151-
154+ fn before_terminator_effect (
155+ & self ,
156+ trans : & mut impl GenKill < Self :: Idx > ,
157+ terminator : & mir:: Terminator < ' tcx > ,
158+ loc : Location ,
159+ ) {
152160 // If a place is borrowed in a terminator, it needs storage for that terminator.
153- self . borrowed_locals . borrow ( ) . analysis ( ) . terminator_effect ( sets , terminator, loc) ;
161+ self . borrowed_locals . borrow ( ) . analysis ( ) . terminator_effect ( trans , terminator, loc) ;
154162
155163 match & terminator. kind {
156- TerminatorKind :: Call { destination : Some ( ( Place { local , .. } , _) ) , .. }
157- | TerminatorKind :: Yield { resume_arg : Place { local , .. } , .. } => {
158- sets . gen ( * local) ;
164+ TerminatorKind :: Call { destination : Some ( ( place , _) ) , .. }
165+ | TerminatorKind :: Yield { resume_arg : place , .. } => {
166+ trans . gen ( place . local ) ;
159167 }
160168
161169 // Nothing to do for these. Match exhaustively so this fails to compile when new
@@ -176,14 +184,19 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
176184 }
177185 }
178186
179- fn terminator_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
180- match & self . body [ loc. block ] . terminator ( ) . kind {
187+ fn terminator_effect (
188+ & self ,
189+ trans : & mut impl GenKill < Self :: Idx > ,
190+ terminator : & mir:: Terminator < ' tcx > ,
191+ loc : Location ,
192+ ) {
193+ match & terminator. kind {
181194 // For call terminators the destination requires storage for the call
182195 // and after the call returns successfully, but not after a panic.
183196 // Since `propagate_call_unwind` doesn't exist, we have to kill the
184- // destination here, and then gen it again in `propagate_call_return `.
185- TerminatorKind :: Call { destination : Some ( ( Place { local , .. } , _) ) , .. } => {
186- sets . kill ( * local) ;
197+ // destination here, and then gen it again in `call_return_effect `.
198+ TerminatorKind :: Call { destination : Some ( ( place , _) ) , .. } => {
199+ trans . kill ( place . local ) ;
187200 }
188201
189202 // Nothing to do for these. Match exhaustively so this fails to compile when new
@@ -204,45 +217,49 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
204217 | TerminatorKind :: Unreachable => { }
205218 }
206219
207- self . check_for_move ( sets , loc) ;
220+ self . check_for_move ( trans , loc) ;
208221 }
209222
210- fn propagate_call_return (
223+ fn call_return_effect (
211224 & self ,
212- in_out : & mut BitSet < Local > ,
213- _call_bb : mir:: BasicBlock ,
214- _dest_bb : mir:: BasicBlock ,
215- dest_place : & mir:: Place < ' tcx > ,
225+ trans : & mut impl GenKill < Self :: Idx > ,
226+ _block : BasicBlock ,
227+ _func : & mir:: Operand < ' tcx > ,
228+ _args : & [ mir:: Operand < ' tcx > ] ,
229+ return_place : & mir:: Place < ' tcx > ,
216230 ) {
217- in_out . insert ( dest_place . local ) ;
231+ trans . gen ( return_place . local ) ;
218232 }
219233}
220234
221- impl < ' mir , ' tcx > RequiresStorage < ' mir , ' tcx > {
235+ impl < ' mir , ' tcx > MaybeRequiresStorage < ' mir , ' tcx > {
222236 /// Kill locals that are fully moved and have not been borrowed.
223- fn check_for_move ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
224- let mut visitor = MoveVisitor { sets , borrowed_locals : & self . borrowed_locals } ;
237+ fn check_for_move ( & self , trans : & mut impl GenKill < Local > , loc : Location ) {
238+ let mut visitor = MoveVisitor { trans , borrowed_locals : & self . borrowed_locals } ;
225239 visitor. visit_location ( self . body , loc) ;
226240 }
227241}
228242
229- impl < ' mir , ' tcx > BottomValue for RequiresStorage < ' mir , ' tcx > {
243+ impl < ' mir , ' tcx > BottomValue for MaybeRequiresStorage < ' mir , ' tcx > {
230244 /// bottom = dead
231245 const BOTTOM_VALUE : bool = false ;
232246}
233247
234- struct MoveVisitor < ' a , ' mir , ' tcx > {
248+ struct MoveVisitor < ' a , ' mir , ' tcx , T > {
235249 borrowed_locals : & ' a RefCell < BorrowedLocalsResults < ' mir , ' tcx > > ,
236- sets : & ' a mut GenKillSet < Local > ,
250+ trans : & ' a mut T ,
237251}
238252
239- impl < ' a , ' mir : ' a , ' tcx > Visitor < ' tcx > for MoveVisitor < ' a , ' mir , ' tcx > {
253+ impl < ' a , ' mir , ' tcx , T > Visitor < ' tcx > for MoveVisitor < ' a , ' mir , ' tcx , T >
254+ where
255+ T : GenKill < Local > ,
256+ {
240257 fn visit_local ( & mut self , local : & Local , context : PlaceContext , loc : Location ) {
241258 if PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Move ) == context {
242259 let mut borrowed_locals = self . borrowed_locals . borrow_mut ( ) ;
243260 borrowed_locals. seek_before ( loc) ;
244261 if !borrowed_locals. contains ( * local) {
245- self . sets . kill ( * local) ;
262+ self . trans . kill ( * local) ;
246263 }
247264 }
248265 }
0 commit comments