33
33
//! generator yield points, all pre-existing references are invalidated, so this
34
34
//! doesn't matter).
35
35
36
- use rustc:: mir:: visit:: MirVisitable ;
37
36
use rustc:: mir:: visit:: { PlaceContext , Visitor } ;
38
37
use rustc:: mir:: Local ;
39
38
use rustc:: mir:: * ;
@@ -50,17 +49,13 @@ use util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
50
49
pub type LiveVarSet < V > = IdxSet < V > ;
51
50
52
51
/// This gives the result of the liveness analysis at the boundary of
53
- /// basic blocks. You can use `simulate_block` to obtain the
54
- /// intra-block results.
52
+ /// basic blocks.
55
53
///
56
54
/// The `V` type defines the set of variables that we computed
57
55
/// liveness for. This is often `Local`, in which case we computed
58
56
/// liveness for all variables -- but it can also be some other type,
59
57
/// which indicates a subset of the variables within the graph.
60
58
pub struct LivenessResult < V : Idx > {
61
- /// Liveness mode in use when these results were computed.
62
- pub mode : LivenessMode ,
63
-
64
59
/// Live variables on exit to each basic block. This is equal to
65
60
/// the union of the `ins` for each successor.
66
61
pub outs : IndexVec < BasicBlock , LiveVarSet < V > > ,
@@ -104,78 +99,23 @@ impl<'a, 'tcx> LiveVariableMap for IdentityMap<'a, 'tcx> {
104
99
}
105
100
}
106
101
107
- #[ derive( Copy , Clone , Debug ) ]
108
- pub struct LivenessMode {
109
- /// If true, then we will consider "regular uses" of a variable to be live.
110
- /// For example, if the user writes `foo(x)`, then this is a regular use of
111
- /// the variable `x`.
112
- pub include_regular_use : bool ,
113
-
114
- /// If true, then we will consider (implicit) drops of a variable
115
- /// to be live. For example, if the user writes `{ let x =
116
- /// vec![...]; .. }`, then the drop at the end of the block is an
117
- /// implicit drop.
118
- ///
119
- /// NB. Despite its name, a call like `::std::mem::drop(x)` is
120
- /// **not** considered a drop for this purposes, but rather a
121
- /// regular use.
122
- pub include_drops : bool ,
123
- }
124
-
125
- /// A combination of liveness results, used in NLL.
126
- pub struct LivenessResults < V : Idx > {
127
- /// Liveness results where a regular use makes a variable X live,
128
- /// but not a drop.
129
- pub regular : LivenessResult < V > ,
130
-
131
- /// Liveness results where a drop makes a variable X live,
132
- /// but not a regular use.
133
- pub drop : LivenessResult < V > ,
134
- }
135
-
136
- impl < V : Idx > LivenessResults < V > {
137
- pub fn compute < ' tcx > (
138
- mir : & Mir < ' tcx > ,
139
- map : & impl LiveVariableMap < LiveVar = V > ,
140
- ) -> LivenessResults < V > {
141
- LivenessResults {
142
- regular : liveness_of_locals (
143
- & mir,
144
- LivenessMode {
145
- include_regular_use : true ,
146
- include_drops : false ,
147
- } ,
148
- map,
149
- ) ,
150
-
151
- drop : liveness_of_locals (
152
- & mir,
153
- LivenessMode {
154
- include_regular_use : false ,
155
- include_drops : true ,
156
- } ,
157
- map,
158
- ) ,
159
- }
160
- }
161
- }
162
-
163
102
/// Compute which local variables are live within the given function
164
103
/// `mir`. The liveness mode `mode` determines what sorts of uses are
165
104
/// considered to make a variable live (e.g., do drops count?).
166
105
pub fn liveness_of_locals < ' tcx , V : Idx > (
167
106
mir : & Mir < ' tcx > ,
168
- mode : LivenessMode ,
169
107
map : & impl LiveVariableMap < LiveVar = V > ,
170
108
) -> LivenessResult < V > {
171
109
let num_live_vars = map. num_variables ( ) ;
172
110
173
- let def_use: IndexVec < _ , DefsUses < V > > = mir. basic_blocks ( )
111
+ let def_use: IndexVec < _ , DefsUses < V > > = mir
112
+ . basic_blocks ( )
174
113
. iter ( )
175
- . map ( |b| block ( mode , map, b, num_live_vars) )
114
+ . map ( |b| block ( map, b, num_live_vars) )
176
115
. collect ( ) ;
177
116
178
- let mut outs: IndexVec < _ , LiveVarSet < V > > = mir. basic_blocks ( )
117
+ let mut outs: IndexVec < _ , LiveVarSet < V > > = mir
118
+ . basic_blocks ( )
179
119
. indices ( )
180
120
. map ( |_| LiveVarSet :: new_empty ( num_live_vars) )
181
121
. collect ( ) ;
@@ -206,71 +146,7 @@ pub fn liveness_of_locals<'tcx, V: Idx>(
206
146
}
207
147
}
208
148
209
- LivenessResult { mode, outs }
210
- }
211
-
212
- impl < V : Idx > LivenessResult < V > {
213
- /// Walks backwards through the statements/terminator in the given
214
- /// basic block `block`. At each point within `block`, invokes
215
- /// the callback `op` with the current location and the set of
216
- /// variables that are live on entry to that location.
217
- pub fn simulate_block < ' tcx , OP > (
218
- & self ,
219
- mir : & Mir < ' tcx > ,
220
- block : BasicBlock ,
221
- map : & impl LiveVariableMap < LiveVar = V > ,
222
- mut callback : OP ,
223
- ) where
224
- OP : FnMut ( Location , & LiveVarSet < V > ) ,
225
- {
226
- let data = & mir[ block] ;
227
-
228
- // Get a copy of the bits on exit from the block.
229
- let mut bits = self . outs [ block] . clone ( ) ;
230
-
231
- // Start with the maximal statement index -- i.e., right before
232
- // the terminator executes.
233
- let mut statement_index = data. statements . len ( ) ;
234
-
235
- // Compute liveness right before terminator and invoke callback.
236
- let terminator_location = Location {
237
- block,
238
- statement_index,
239
- } ;
240
- let num_live_vars = map. num_variables ( ) ;
241
- let mut visitor = DefsUsesVisitor {
242
- mode : self . mode ,
243
- map,
244
- defs_uses : DefsUses {
245
- defs : LiveVarSet :: new_empty ( num_live_vars) ,
246
- uses : LiveVarSet :: new_empty ( num_live_vars) ,
247
- } ,
248
- } ;
249
- // Visit the various parts of the basic block in reverse. If we go
250
- // forward, the logic in `add_def` and `add_use` would be wrong.
251
- visitor. update_bits_and_do_callback (
252
- terminator_location,
253
- & data. terminator ,
254
- & mut bits,
255
- & mut callback,
256
- ) ;
257
-
258
- // Compute liveness before each statement (in rev order) and invoke callback.
259
- for statement in data. statements . iter ( ) . rev ( ) {
260
- statement_index -= 1 ;
261
- let statement_location = Location {
262
- block,
263
- statement_index,
264
- } ;
265
- visitor. defs_uses . clear ( ) ;
266
- visitor. update_bits_and_do_callback (
267
- statement_location,
268
- statement,
269
- & mut bits,
270
- & mut callback,
271
- ) ;
272
- }
273
- }
149
+ LivenessResult { outs }
274
150
}
275
151
276
152
#[ derive( Eq , PartialEq , Clone ) ]
@@ -342,7 +218,6 @@ where
342
218
V : Idx ,
343
219
M : LiveVariableMap < LiveVar = V > + ' lv ,
344
220
{
345
- mode : LivenessMode ,
346
221
map : & ' lv M ,
347
222
defs_uses : DefsUses < V > ,
348
223
}
@@ -354,11 +229,6 @@ struct DefsUses<V: Idx> {
354
229
}
355
230
356
231
impl < V : Idx > DefsUses < V > {
357
- fn clear ( & mut self ) {
358
- self . uses . clear ( ) ;
359
- self . defs . clear ( ) ;
360
- }
361
-
362
232
fn apply ( & self , bits : & mut LiveVarSet < V > ) -> bool {
363
233
bits. subtract ( & self . defs ) | bits. union ( & self . uses )
364
234
}
@@ -393,29 +263,6 @@ impl<V: Idx> DefsUses<V> {
393
263
}
394
264
}
395
265
396
- impl < ' lv , V , M > DefsUsesVisitor < ' lv , V , M >
397
- where
398
- V : Idx ,
399
- M : LiveVariableMap < LiveVar = V > ,
400
- {
401
- /// Update `bits` with the effects of `value` and call `callback`. We
402
- /// should always visit in reverse order. This method assumes that we have
403
- /// not visited anything before; if you have, clear `bits` first.
404
- fn update_bits_and_do_callback < ' tcx , OP > (
405
- & mut self ,
406
- location : Location ,
407
- value : & impl MirVisitable < ' tcx > ,
408
- bits : & mut LiveVarSet < V > ,
409
- callback : & mut OP ,
410
- ) where
411
- OP : FnMut ( Location , & LiveVarSet < V > ) ,
412
- {
413
- value. apply ( location, self ) ;
414
- self . defs_uses . apply ( bits) ;
415
- callback ( location, bits) ;
416
- }
417
- }
418
-
419
266
impl < ' tcx , ' lv , V , M > Visitor < ' tcx > for DefsUsesVisitor < ' lv , V , M >
420
267
where
421
268
V : Idx ,
@@ -425,24 +272,19 @@ where
425
272
if let Some ( v_index) = self . map . from_local ( local) {
426
273
match categorize ( context) {
427
274
Some ( DefUse :: Def ) => self . defs_uses . add_def ( v_index) ,
428
- Some ( DefUse :: Use ) if self . mode . include_regular_use => {
429
- self . defs_uses . add_use ( v_index)
430
- }
431
- Some ( DefUse :: Drop ) if self . mode . include_drops => self . defs_uses . add_use ( v_index) ,
275
+ Some ( DefUse :: Use ) | Some ( DefUse :: Drop ) => self . defs_uses . add_use ( v_index) ,
432
276
_ => ( ) ,
433
277
}
434
278
}
435
279
}
436
280
}
437
281
438
282
fn block < ' tcx , V : Idx > (
439
- mode : LivenessMode ,
440
283
map : & impl LiveVariableMap < LiveVar = V > ,
441
284
b : & BasicBlockData < ' tcx > ,
442
285
locals : usize ,
443
286
) -> DefsUses < V > {
444
287
let mut visitor = DefsUsesVisitor {
445
- mode,
446
288
map,
447
289
defs_uses : DefsUses {
448
290
defs : LiveVarSet :: new_empty ( locals) ,
0 commit comments