use rustc_data_structures::indexed_vec::Idx;
use std::collections::BTreeSet;
use std::fmt;
-use util::liveness::{self, LivenessResult, LivenessMode};
+use util::liveness::{self, LivenessMode, LivenessResult, LocalSet};
use util as mir_util;
use self::mir_util::PassWhere;
// Compute what is live where.
let liveness = &LivenessResults {
- regular: liveness::liveness_of_locals(mir, LivenessMode {
- include_regular_use: true,
- include_drops: false,
- }),
-
- drop: liveness::liveness_of_locals(mir, LivenessMode {
- include_regular_use: false,
- include_drops: true,
- })
+ regular: liveness::liveness_of_locals(
+ mir,
+ LivenessMode {
+ include_regular_use: true,
+ include_drops: false,
+ },
+ ),
+
+ drop: liveness::liveness_of_locals(
+ mir,
+ LivenessMode {
+ include_regular_use: false,
+ include_drops: true,
+ },
+ ),
};
// Create the region inference context, generate the constraints,
.indices()
.flat_map(|bb| {
let mut results = vec![];
- liveness.regular.simulate_block(&mir, bb, |location, local_set| {
- results.push((location, local_set.clone()));
- });
+ liveness
+ .regular
+ .simulate_block(&mir, bb, |location, local_set| {
+ results.push((location, local_set.clone()));
+ });
results
})
.collect();
.indices()
.flat_map(|bb| {
let mut results = vec![];
- liveness.drop.simulate_block(&mir, bb, |location, local_set| {
- results.push((location, local_set.clone()));
- });
+ liveness
+ .drop
+ .simulate_block(&mir, bb, |location, local_set| {
+ results.push((location, local_set.clone()));
+ });
results
})
.collect();
// Before each basic block, dump out the values
// that are live on entry to the basic block.
PassWhere::BeforeBlock(bb) => {
- writeln!(out, " | Variables regular-live on entry to the block {:?}: {:?}",
- bb, liveness.regular.ins[bb])?;
- writeln!(out, " | Variables drop-live on entry to the block {:?}: {:?}",
- bb, liveness.drop.ins[bb])?;
+ let s = live_variable_set(&liveness.regular.ins[bb], &liveness.drop.ins[bb]);
+ writeln!(out, " | Live variables on entry to {:?}: {}", bb, s)?;
}
PassWhere::InCFG(location) => {
- let local_set = ®ular_liveness_per_location[&location];
- writeln!(out, " | Regular-Live variables here: {:?}", local_set)?;
- let local_set = &drop_liveness_per_location[&location];
- writeln!(out, " | Drop-Live variables here: {:?}", local_set)?;
+ let s = live_variable_set(
+ ®ular_liveness_per_location[&location],
+ &drop_liveness_per_location[&location],
+ );
+ writeln!(
+ out,
+ " | Live variables at {:?}: {}",
+ location,
+ s
+ )?;
}
PassWhere::AfterCFG => {}
}
}
}
+
+fn live_variable_set(regular: &LocalSet, drops: &LocalSet) -> String {
+ // sort and deduplicate:
+ let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();
+
+ // construct a string with each local, including `(drop)` if it is
+ // only dropped, versus a regular use.
+ let mut string = String::new();
+ for local in all_locals {
+ string.push_str(&format!("{:?}", local));
+
+ if !regular.contains(&local) {
+ assert!(drops.contains(&local));
+ string.push_str(" (drop)");
+ }
+
+ string.push_str(", ");
+ }
+
+ let len = if string.is_empty() { 0 } else { string.len() - 2 };
+
+ format!("[{}]", &string[..len])
+}
//
// END RUST SOURCE
// START rustc.node12.nll.0.mir
-// | Variables regular-live on entry to the block bb0: []
-// | Variables drop-live on entry to the block bb0: []
+// | Live variables on entry to bb0: []
// bb0: {
-// | Regular-Live variables here: []
-// | Drop-Live variables here: []
+// | Live variables at bb0[0]: []
// StorageLive(_1);
-// | Regular-Live variables here: []
-// | Drop-Live variables here: []
+// | Live variables at bb0[1]: []
// _1 = const <std::boxed::Box<T>>::new(const 22usize) -> bb1;
// }
// END rustc.node12.nll.0.mir
// START rustc.node12.nll.0.mir
-// | Variables regular-live on entry to the block bb1: []
-// | Variables drop-live on entry to the block bb1: [_1]
+// | Live variables on entry to bb1: [_1 (drop)]
// bb1: {
-// | Regular-Live variables here: []
-// | Drop-Live variables here: [_1]
+// | Live variables at bb1[0]: [_1 (drop)]
// StorageLive(_2);
-// | Regular-Live variables here: []
-// | Drop-Live variables here: [_1]
+// | Live variables at bb1[1]: [_1 (drop)]
// _2 = const can_panic() -> [return: bb2, unwind: bb4];
// }
// END rustc.node12.nll.0.mir
// END RUST SOURCE
// START rustc.node12.nll.0.mir
-// | Variables regular-live on entry to the block bb1: []
-// | Variables drop-live on entry to the block bb1: []
+// | Live variables on entry to bb1: []
// bb1: {
-// | Regular-Live variables here: []
-// | Drop-Live variables here: []
+// | Live variables at bb1[0]: []
// _1 = const 55usize;
-// | Regular-Live variables here: [_1]
-// | Drop-Live variables here: []
+// | Live variables at bb1[1]: [_1]
// StorageLive(_3);
-// | Regular-Live variables here: [_1]
-// | Drop-Live variables here: []
+// | Live variables at bb1[2]: [_1]
// StorageLive(_4);
-// | Regular-Live variables here: [_1]
-// | Drop-Live variables here: []
+// | Live variables at bb1[3]: [_1]
// _4 = _1;
-// | Regular-Live variables here: [_4]
-// | Drop-Live variables here: []
+// | Live variables at bb1[4]: [_4]
// _3 = const use_x(_4) -> bb2;
// }
// END rustc.node12.nll.0.mir
// END RUST SOURCE
// START rustc.node18.nll.0.mir
-// | Variables regular-live on entry to the block bb2: [_1]
-// | Variables drop-live on entry to the block bb2: []
+// | Live variables on entry to bb2: [_1]
// bb2: {
-// | Regular-Live variables here: [_1]
-// | Drop-Live variables here: []
+// | Live variables at bb2[0]: [_1]
// StorageLive(_4);
-// | Regular-Live variables here: [_1]
-// | Drop-Live variables here: []
+// | Live variables at bb2[1]: [_1]
// _4 = _1;
-// | Regular-Live variables here: [_4]
-// | Drop-Live variables here: []
+// | Live variables at bb2[2]: [_4]
// _3 = const make_live(_4) -> bb4;
// }
// END rustc.node18.nll.0.mir
// START rustc.node18.nll.0.mir
-// | Variables regular-live on entry to the block bb3: []
-// | Variables drop-live on entry to the block bb3: []
+// | Live variables on entry to bb3: []
// bb3: {
-// | Regular-Live variables here: []
-// | Drop-Live variables here: []
+// | Live variables at bb3[0]: []
// _5 = const make_dead() -> bb5;
// }
// END rustc.node18.nll.0.mir
// END rustc.node12.nll.0.mir
// START rustc.node12.nll.0.mir
// bb1: {
-// | Regular-Live variables here: [_1, _3]
-// | Drop-Live variables here: []
+// | Live variables at bb1[0]: [_1, _3]
// _2 = &'_#0r _1[_3];
-// | Regular-Live variables here: [_2]
-// | Drop-Live variables here: []
+// | Live variables at bb1[1]: [_2]
// switchInt(const true) -> [0u8: bb3, otherwise: bb2];
// }
// END rustc.node12.nll.0.mir
// START rustc.node12.nll.0.mir
// bb2: {
-// | Regular-Live variables here: [_2]
-// | Drop-Live variables here: []
+// | Live variables at bb2[0]: [_2]
// StorageLive(_7);
-// | Regular-Live variables here: [_2]
-// | Drop-Live variables here: []
+// | Live variables at bb2[1]: [_2]
// _7 = (*_2);
-// | Regular-Live variables here: [_7]
-// | Drop-Live variables here: []
+// | Live variables at bb2[2]: [_7]
// _6 = const use_x(_7) -> bb4;
// }
// END rustc.node12.nll.0.mir