- PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext, NonUseContext,
+ MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor,
use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
/// Computes which local variables are live within the given function
/// `mir`, including drops.
/// Computes which local variables are live within the given function
/// `mir`, including drops.
-pub fn liveness_of_locals(
- body: ReadOnlyBodyAndCache<'_, '_>,
-) -> LivenessResult {
+pub fn liveness_of_locals(body: ReadOnlyBodyAndCache<'_, '_>) -> LivenessResult {
- let def_use: IndexVec<_, DefsUses> = body
- .basic_blocks()
- .iter()
- .map(|b| block(b, num_live_vars))
- .collect();
+ let def_use: IndexVec<_, DefsUses> =
+ body.basic_blocks().iter().map(|b| block(b, num_live_vars)).collect();
- let mut outs: IndexVec<_, LiveVarSet> = body
- .basic_blocks()
- .indices()
- .map(|_| LiveVarSet::new_empty(num_live_vars))
- .collect();
+ let mut outs: IndexVec<_, LiveVarSet> =
+ body.basic_blocks().indices().map(|_| LiveVarSet::new_empty(num_live_vars)).collect();
// FIXME(ecstaticmorse): Reverse post-order on the reverse CFG may generate a better iteration
// order when cycles are present, but the overhead of computing the reverse CFG may outweigh
// any benefits. Benchmark this and find out.
// FIXME(ecstaticmorse): Reverse post-order on the reverse CFG may generate a better iteration
// order when cycles are present, but the overhead of computing the reverse CFG may outweigh
// any benefits. Benchmark this and find out.
fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
match categorize(context) {
Some(DefUse::Def) => self.defs_uses.add_def(local),
fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
match categorize(context) {
Some(DefUse::Def) => self.defs_uses.add_def(local),
let mut visitor = DefsUsesVisitor {
defs_uses: DefsUses {
defs: LiveVarSet::new_empty(locals),
let mut visitor = DefsUsesVisitor {
defs_uses: DefsUses {
defs: LiveVarSet::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.
// 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.
let item_id = tcx.hir().as_local_hir_id(source.def_id()).unwrap();
let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name);
file_path.push(&file_name);
let item_id = tcx.hir().as_local_hir_id(source.def_id()).unwrap();
let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name);
file_path.push(&file_name);
writeln!(file, "// MIR local liveness analysis for `{}`", node_path)?;
writeln!(file, "// source = {:?}", source)?;
writeln!(file, "// pass_name = {}", pass_name)?;
writeln!(file, "// MIR local liveness analysis for `{}`", node_path)?;
writeln!(file, "// source = {:?}", source)?;
writeln!(file, "// pass_name = {}", pass_name)?;
write_mir_intro(tcx, src, body, w)?;
for block in body.basic_blocks().indices() {
let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LiveVarSet>| {
write_mir_intro(tcx, src, body, w)?;
for block in body.basic_blocks().indices() {
let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LiveVarSet>| {
- let live: Vec<String> = result[block]
- .iter()
- .map(|local| format!("{:?}", local))
- .collect();
+ let live: Vec<String> =
+ result[block].iter().map(|local| format!("{:?}", local)).collect();
writeln!(w, "{} {{{}}}", prefix, live.join(", "))
};
write_basic_block(tcx, block, body, &mut |_, _| Ok(()), w)?;
writeln!(w, "{} {{{}}}", prefix, live.join(", "))
};
write_basic_block(tcx, block, body, &mut |_, _| Ok(()), w)?;