3333//! generator yield points, all pre-existing references are invalidated, so this
3434//! doesn't matter).
3535
36- use rustc:: mir:: visit:: MirVisitable ;
3736use rustc:: mir:: visit:: { PlaceContext , Visitor } ;
3837use rustc:: mir:: Local ;
3938use rustc:: mir:: * ;
@@ -50,17 +49,13 @@ use util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
5049pub type LiveVarSet < V > = IdxSet < V > ;
5150
5251/// 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.
5553///
5654/// The `V` type defines the set of variables that we computed
5755/// liveness for. This is often `Local`, in which case we computed
5856/// liveness for all variables -- but it can also be some other type,
5957/// which indicates a subset of the variables within the graph.
6058pub struct LivenessResult < V : Idx > {
61- /// Liveness mode in use when these results were computed.
62- pub mode : LivenessMode ,
63-
6459 /// Live variables on exit to each basic block. This is equal to
6560 /// the union of the `ins` for each successor.
6661 pub outs : IndexVec < BasicBlock , LiveVarSet < V > > ,
@@ -104,78 +99,23 @@ impl<'a, 'tcx> LiveVariableMap for IdentityMap<'a, 'tcx> {
10499 }
105100}
106101
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-
163102/// Compute which local variables are live within the given function
164103/// `mir`. The liveness mode `mode` determines what sorts of uses are
165104/// considered to make a variable live (e.g., do drops count?).
166105pub fn liveness_of_locals < ' tcx , V : Idx > (
167106 mir : & Mir < ' tcx > ,
168- mode : LivenessMode ,
169107 map : & impl LiveVariableMap < LiveVar = V > ,
170108) -> LivenessResult < V > {
171109 let num_live_vars = map. num_variables ( ) ;
172110
173- let def_use: IndexVec < _ , DefsUses < V > > = mir. basic_blocks ( )
111+ let def_use: IndexVec < _ , DefsUses < V > > = mir
112+ . basic_blocks ( )
174113 . iter ( )
175- . map ( |b| block ( mode , map, b, num_live_vars) )
114+ . map ( |b| block ( map, b, num_live_vars) )
176115 . collect ( ) ;
177116
178- let mut outs: IndexVec < _ , LiveVarSet < V > > = mir. basic_blocks ( )
117+ let mut outs: IndexVec < _ , LiveVarSet < V > > = mir
118+ . basic_blocks ( )
179119 . indices ( )
180120 . map ( |_| LiveVarSet :: new_empty ( num_live_vars) )
181121 . collect ( ) ;
@@ -206,71 +146,7 @@ pub fn liveness_of_locals<'tcx, V: Idx>(
206146 }
207147 }
208148
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 }
274150}
275151
276152#[ derive( Eq , PartialEq , Clone ) ]
@@ -342,7 +218,6 @@ where
342218 V : Idx ,
343219 M : LiveVariableMap < LiveVar = V > + ' lv ,
344220{
345- mode : LivenessMode ,
346221 map : & ' lv M ,
347222 defs_uses : DefsUses < V > ,
348223}
@@ -354,11 +229,6 @@ struct DefsUses<V: Idx> {
354229}
355230
356231impl < V : Idx > DefsUses < V > {
357- fn clear ( & mut self ) {
358- self . uses . clear ( ) ;
359- self . defs . clear ( ) ;
360- }
361-
362232 fn apply ( & self , bits : & mut LiveVarSet < V > ) -> bool {
363233 bits. subtract ( & self . defs ) | bits. union ( & self . uses )
364234 }
@@ -393,29 +263,6 @@ impl<V: Idx> DefsUses<V> {
393263 }
394264}
395265
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-
419266impl < ' tcx , ' lv , V , M > Visitor < ' tcx > for DefsUsesVisitor < ' lv , V , M >
420267where
421268 V : Idx ,
@@ -425,24 +272,19 @@ where
425272 if let Some ( v_index) = self . map . from_local ( local) {
426273 match categorize ( context) {
427274 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) ,
432276 _ => ( ) ,
433277 }
434278 }
435279 }
436280}
437281
438282fn block < ' tcx , V : Idx > (
439- mode : LivenessMode ,
440283 map : & impl LiveVariableMap < LiveVar = V > ,
441284 b : & BasicBlockData < ' tcx > ,
442285 locals : usize ,
443286) -> DefsUses < V > {
444287 let mut visitor = DefsUsesVisitor {
445- mode,
446288 map,
447289 defs_uses : DefsUses {
448290 defs : LiveVarSet :: new_empty ( locals) ,
0 commit comments