]> git.lizzy.rs Git - rust.git/commitdiff
reorder liveness to bring the more significant code up top
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 24 Oct 2017 19:39:08 +0000 (15:39 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 31 Oct 2017 16:41:38 +0000 (12:41 -0400)
src/librustc_mir/util/liveness.rs

index df7ba3c62faeabe10821bd3814fb6fe783a26b8c..514ff2ab830caed227ae3ea78bac2aa7db1ca7c3 100644 (file)
 
 pub type LocalSet = IdxSetBuf<Local>;
 
+// This gives the result of the liveness analysis at the boundary of basic blocks
+pub struct LivenessResult {
+    pub ins: IndexVec<BasicBlock, LocalSet>,
+    pub outs: IndexVec<BasicBlock, LocalSet>,
+}
+
+pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>) -> LivenessResult {
+    let locals = mir.local_decls.len();
+    let def_use: IndexVec<_, _> = mir.basic_blocks().iter().map(|b| {
+        block(b, locals)
+    }).collect();
+
+    let mut ins: IndexVec<_, _> = mir.basic_blocks()
+        .indices()
+        .map(|_| LocalSet::new_empty(locals))
+        .collect();
+    let mut outs = ins.clone();
+
+    let mut changed = true;
+    let mut bits = LocalSet::new_empty(locals);
+    while changed {
+        changed = false;
+
+        for b in mir.basic_blocks().indices().rev() {
+            // outs[b] = ∪ {ins of successors}
+            bits.clear();
+            for &successor in mir.basic_blocks()[b].terminator().successors().into_iter() {
+                bits.union(&ins[successor]);
+            }
+            outs[b].clone_from(&bits);
+
+            // bits = use ∪ (bits - def)
+            def_use[b].apply(&mut bits);
+
+            // update bits on entry and flag if they have changed
+            if ins[b] != bits {
+                ins[b].clone_from(&bits);
+                changed = true;
+            }
+        }
+    }
+
+    LivenessResult {
+        ins,
+        outs,
+    }
+}
+
+impl LivenessResult {
+    /// Walks backwards through the statements/terminator in the given
+    /// basic block `block`.  At each point within `block`, invokes
+    /// the callback `op` with the current location and the set of
+    /// variables that are live on entry to that location.
+    pub fn simulate_block<'tcx, OP>(&self,
+                                    mir: &Mir<'tcx>,
+                                    block: BasicBlock,
+                                    mut callback: OP)
+        where OP: FnMut(Location, &LocalSet)
+    {
+        let data = &mir[block];
+
+        // Get a copy of the bits on exit from the block.
+        let mut bits = self.outs[block].clone();
+
+        // Start with the maximal statement index -- i.e., right before
+        // the terminator executes.
+        let mut statement_index = data.statements.len();
+
+        // Compute liveness right before terminator and invoke callback.
+        let terminator_location = Location { block, statement_index };
+        let terminator_defs_uses = self.defs_uses(mir, terminator_location, &data.terminator);
+        terminator_defs_uses.apply(&mut bits);
+        callback(terminator_location, &bits);
+
+        // Compute liveness before each statement (in rev order) and invoke callback.
+        for statement in data.statements.iter().rev() {
+            statement_index -= 1;
+            let statement_location = Location { block, statement_index };
+            let statement_defs_uses = self.defs_uses(mir, statement_location, statement);
+            statement_defs_uses.apply(&mut bits);
+            callback(statement_location, &bits);
+        }
+
+        assert_eq!(bits, self.ins[block]);
+    }
+
+    fn defs_uses<'tcx, V>(&self,
+                          mir: &Mir<'tcx>,
+                          location: Location,
+                          thing: &V)
+                          -> DefsUses
+        where V: MirVisitable<'tcx>,
+    {
+        let locals = mir.local_decls.len();
+        let mut visitor = DefsUses {
+            defs: LocalSet::new_empty(locals),
+            uses: LocalSet::new_empty(locals),
+        };
+
+        // Visit the various parts of the basic block in reverse. If we go
+        // forward, the logic in `add_def` and `add_use` would be wrong.
+        thing.apply(location, &mut visitor);
+
+        visitor
+    }
+}
+
 #[derive(Eq, PartialEq, Clone)]
 struct DefsUses {
     defs: LocalSet,
@@ -159,113 +266,6 @@ fn block<'tcx>(b: &BasicBlockData<'tcx>, locals: usize) -> DefsUses {
     visitor
 }
 
-// This gives the result of the liveness analysis at the boundary of basic blocks
-pub struct LivenessResult {
-    pub ins: IndexVec<BasicBlock, LocalSet>,
-    pub outs: IndexVec<BasicBlock, LocalSet>,
-}
-
-pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>) -> LivenessResult {
-    let locals = mir.local_decls.len();
-    let def_use: IndexVec<_, _> = mir.basic_blocks().iter().map(|b| {
-        block(b, locals)
-    }).collect();
-
-    let mut ins: IndexVec<_, _> = mir.basic_blocks()
-        .indices()
-        .map(|_| LocalSet::new_empty(locals))
-        .collect();
-    let mut outs = ins.clone();
-
-    let mut changed = true;
-    let mut bits = LocalSet::new_empty(locals);
-    while changed {
-        changed = false;
-
-        for b in mir.basic_blocks().indices().rev() {
-            // outs[b] = ∪ {ins of successors}
-            bits.clear();
-            for &successor in mir.basic_blocks()[b].terminator().successors().into_iter() {
-                bits.union(&ins[successor]);
-            }
-            outs[b].clone_from(&bits);
-
-            // bits = use ∪ (bits - def)
-            def_use[b].apply(&mut bits);
-
-            // update bits on entry and flag if they have changed
-            if ins[b] != bits {
-                ins[b].clone_from(&bits);
-                changed = true;
-            }
-        }
-    }
-
-    LivenessResult {
-        ins,
-        outs,
-    }
-}
-
-impl LivenessResult {
-    /// Walks backwards through the statements/terminator in the given
-    /// basic block `block`.  At each point within `block`, invokes
-    /// the callback `op` with the current location and the set of
-    /// variables that are live on entry to that location.
-    pub fn simulate_block<'tcx, OP>(&self,
-                                    mir: &Mir<'tcx>,
-                                    block: BasicBlock,
-                                    mut callback: OP)
-        where OP: FnMut(Location, &LocalSet)
-    {
-        let data = &mir[block];
-
-        // Get a copy of the bits on exit from the block.
-        let mut bits = self.outs[block].clone();
-
-        // Start with the maximal statement index -- i.e., right before
-        // the terminator executes.
-        let mut statement_index = data.statements.len();
-
-        // Compute liveness right before terminator and invoke callback.
-        let terminator_location = Location { block, statement_index };
-        let terminator_defs_uses = self.defs_uses(mir, terminator_location, &data.terminator);
-        terminator_defs_uses.apply(&mut bits);
-        callback(terminator_location, &bits);
-
-        // Compute liveness before each statement (in rev order) and invoke callback.
-        for statement in data.statements.iter().rev() {
-            statement_index -= 1;
-            let statement_location = Location { block, statement_index };
-            let statement_defs_uses = self.defs_uses(mir, statement_location, statement);
-            statement_defs_uses.apply(&mut bits);
-            callback(statement_location, &bits);
-        }
-
-        assert_eq!(bits, self.ins[block]);
-    }
-
-    fn defs_uses<'tcx, V>(&self,
-                          mir: &Mir<'tcx>,
-                          location: Location,
-                          thing: &V)
-                          -> DefsUses
-        where V: MirVisitable<'tcx>,
-    {
-        let locals = mir.local_decls.len();
-        let mut visitor = DefsUses {
-            defs: LocalSet::new_empty(locals),
-            uses: LocalSet::new_empty(locals),
-        };
-
-        // Visit the various parts of the basic block in reverse. If we go
-        // forward, the logic in `add_def` and `add_use` would be wrong.
-        thing.apply(location, &mut visitor);
-
-        visitor
-    }
-}
-
 trait MirVisitable<'tcx> {
     fn apply<V>(&self, location: Location, visitor: &mut V)
         where V: Visitor<'tcx>;