|
8 | 8 | // option. This file may not be copied, modified, or distributed
|
9 | 9 | // except according to those terms.
|
10 | 10 |
|
11 |
| -//! Liveness analysis. |
12 |
| -
|
13 |
| -// FIXME: Make sure this analysis uses proper MIR semantics. Also find out what |
14 |
| -// the MIR semantics are. |
| 11 | +//! Liveness analysis which computes liveness of MIR local variables at the boundary of basic blocks |
15 | 12 |
|
16 | 13 | use rustc::mir::*;
|
17 | 14 | use rustc::mir::visit::{LvalueContext, Visitor};
|
@@ -47,15 +44,31 @@ impl<'tcx> Visitor<'tcx> for BlockInfoVisitor {
|
47 | 44 | if let Lvalue::Local(local) = *lvalue {
|
48 | 45 | match context {
|
49 | 46 | LvalueContext::Store |
|
| 47 | + |
| 48 | + // We let Call defined the result in both the success and unwind cases. |
| 49 | + // This may not be right. |
50 | 50 | LvalueContext::Call |
|
| 51 | + |
| 52 | + // Storage live and storage dead aren't proper defines, but we can ignore |
| 53 | + // values that come before them. |
51 | 54 | LvalueContext::StorageLive |
|
52 | 55 | LvalueContext::StorageDead => {
|
53 | 56 | self.defs.add(&local);
|
54 | 57 | }
|
55 | 58 | LvalueContext::Projection(..) |
|
| 59 | + |
| 60 | + // Borrows only consider their local used at the point of the borrow. |
| 61 | + // This won't affect the results since we use this analysis for generators |
| 62 | + // and we only care about the result at suspension points. Borrows cannot |
| 63 | + // cross suspension points so this behavoir is unproblematic. |
56 | 64 | LvalueContext::Borrow { .. } |
|
| 65 | + |
57 | 66 | LvalueContext::Inspect |
|
58 | 67 | LvalueContext::Consume |
|
| 68 | + |
| 69 | + // We consider drops to always be uses of locals. |
| 70 | + // Drop eloboration should be run before this analysis otherwise |
| 71 | + // the results might be too pessimistic. |
59 | 72 | LvalueContext::Drop => {
|
60 | 73 | // Ignore uses which are already defined in this block
|
61 | 74 | if !self.pre_defs.contains(&local) {
|
@@ -90,6 +103,7 @@ fn block<'tcx>(b: &BasicBlockData<'tcx>, locals: usize) -> BlockInfo {
|
90 | 103 | }
|
91 | 104 | }
|
92 | 105 |
|
| 106 | +// This gives the result of the liveness analysis at the boundary of basic blocks |
93 | 107 | pub struct LivenessResult {
|
94 | 108 | pub ins: IndexVec<BasicBlock, LocalSet>,
|
95 | 109 | pub outs: IndexVec<BasicBlock, LocalSet>,
|
|
0 commit comments