//! generator yield points, all pre-existing references are invalidated, so this
//! doesn't matter).
+use crate::transform::MirSource;
+use crate::util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
use rustc::mir::visit::{
- PlaceContext, Visitor, MutatingUseContext, NonMutatingUseContext, NonUseContext,
+ MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext, Visitor,
};
use rustc::mir::Local;
use rustc::mir::*;
use rustc::ty::{self, TyCtxt};
+use rustc_data_structures::work_queue::WorkQueue;
use rustc_index::bit_set::BitSet;
use rustc_index::vec::{Idx, IndexVec};
-use rustc_data_structures::work_queue::WorkQueue;
use std::fs;
-use std::io::{self, Write};
+use std::io::{self, BufWriter, Write};
use std::path::{Path, PathBuf};
-use crate::transform::MirSource;
-use crate::util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
pub type LiveVarSet = BitSet<Local>;
/// 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 num_live_vars = body.local_decls.len();
- 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();
let mut bits = LiveVarSet::new_empty(num_live_vars);
// 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.
- let mut dirty_queue: WorkQueue<BasicBlock>
- = WorkQueue::with_none(body.basic_blocks().len());
+ let mut dirty_queue: WorkQueue<BasicBlock> = WorkQueue::with_none(body.basic_blocks().len());
for (bb, _) in traversal::postorder(&body) {
dirty_queue.insert(bb);
}
}
}
-struct DefsUsesVisitor
-{
+struct DefsUsesVisitor {
defs_uses: DefsUses,
}
}
}
-impl<'tcx> Visitor<'tcx> for DefsUsesVisitor
-{
+impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
fn visit_local(&mut self, &local: &Local, context: PlaceContext, _: Location) {
match categorize(context) {
Some(DefUse::Def) => self.defs_uses.add_def(local),
}
}
-fn block(
- b: &BasicBlockData<'_>,
- locals: usize,
-) -> DefsUses {
+fn block(b: &BasicBlockData<'_>, locals: usize) -> DefsUses {
let mut visitor = DefsUsesVisitor {
defs_uses: DefsUses {
defs: LiveVarSet::new_empty(locals),
},
};
- let dummy_location = Location {
- block: BasicBlock::new(0),
- statement_index: 0,
- };
+ let dummy_location = Location { block: BasicBlock::new(0), statement_index: 0 };
// 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 _ = fs::File::create(&file_path).and_then(|mut file| {
+ let _ = fs::File::create(&file_path).and_then(|file| {
+ let mut file = BufWriter::new(file);
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>| {
- 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)?;