From ae5f7224b5ee08f9762befb26eccb8ad26cdbcbc Mon Sep 17 00:00:00 2001 From: Lucas Molas Date: Fri, 15 Feb 2019 02:01:29 -0300 Subject: [PATCH] nll: remove `IdentityMap` and `LiveVariableMap` With `NllLivenessMap` and `LiveVar` removed, the `IdentityMap` (remaining structure implementing the `LiveVariableMap` trait) loses its meaning. Specialize the `LiveVarSet` to a `BitSet` removing the `V` and related parameters. The `LiveVarSet` was only being used as `LiveVarSet` so this commit doesn't bring any change to the logic, it just removes an unused parameter (that without `LiveVar` now, it couldn't have been specialized to anything but `Local`). --- src/librustc_mir/transform/generator.rs | 16 ++-- src/librustc_mir/util/liveness.rs | 122 +++++++----------------- 2 files changed, 41 insertions(+), 97 deletions(-) diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs index 0866b87cf17e6..2c305197328ad 100644 --- a/src/librustc_mir/transform/generator.rs +++ b/src/librustc_mir/transform/generator.rs @@ -68,7 +68,7 @@ use crate::transform::no_landing_pads::no_landing_pads; use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location}; use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals}; use crate::util::dump_mir; -use crate::util::liveness::{self, IdentityMap}; +use crate::util::liveness; pub struct StateTransform; @@ -148,7 +148,7 @@ struct SuspensionPoint { state: u32, resume: BasicBlock, drop: Option, - storage_liveness: liveness::LiveVarSet, + storage_liveness: liveness::LiveVarSet, } struct TransformVisitor<'a, 'tcx: 'a> { @@ -165,7 +165,7 @@ struct TransformVisitor<'a, 'tcx: 'a> { // A map from a suspension point in a block to the locals which have live storage at that point // FIXME(eddyb) This should use `IndexVec>`. - storage_liveness: FxHashMap>, + storage_liveness: FxHashMap, // A list of suspension points, generated during the transform suspension_points: Vec, @@ -358,7 +358,7 @@ fn replace_result_variable<'tcx>( new_ret_local } -struct StorageIgnored(liveness::LiveVarSet); +struct StorageIgnored(liveness::LiveVarSet); impl<'tcx> Visitor<'tcx> for StorageIgnored { fn visit_statement(&mut self, @@ -379,8 +379,8 @@ fn locals_live_across_suspend_points( source: MirSource<'tcx>, movable: bool, ) -> ( - liveness::LiveVarSet, - FxHashMap>, + liveness::LiveVarSet, + FxHashMap, ) { let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len()); let node_id = tcx.hir().as_local_node_id(source.def_id()).unwrap(); @@ -414,14 +414,12 @@ fn locals_live_across_suspend_points( let mut set = liveness::LiveVarSet::new_empty(mir.local_decls.len()); let mut liveness = liveness::liveness_of_locals( mir, - &IdentityMap::new(mir), ); liveness::dump_mir( tcx, "generator_liveness", source, mir, - &IdentityMap::new(mir), &liveness, ); @@ -491,7 +489,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx>) -> (FxHashMap, usize)>, GeneratorLayout<'tcx>, - FxHashMap>) + FxHashMap) { // Use a liveness analysis to compute locals which are live across a suspension point let (live_locals, storage_liveness) = locals_live_across_suspend_points(tcx, diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index dcbd9aa9af225..9cda6cfdacbe3 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -39,7 +39,7 @@ 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; +pub type LiveVarSet = BitSet; /// This gives the result of the liveness analysis at the boundary of /// basic blocks. @@ -48,66 +48,27 @@ pub type LiveVarSet = BitSet; /// liveness for. This is often `Local`, in which case we computed /// liveness for all variables -- but it can also be some other type, /// which indicates a subset of the variables within the graph. -pub struct LivenessResult { +pub struct LivenessResult { /// Live variables on exit to each basic block. This is equal to /// the union of the `ins` for each successor. - pub outs: IndexVec>, -} - -/// Defines the mapping to/from the MIR local variables (`Local`) to -/// the "live variable indices" we are using in a particular -/// computation. -pub trait LiveVariableMap { - type LiveVar; - - fn from_local(&self, local: Local) -> Option; - fn from_live_var(&self, local: Self::LiveVar) -> Local; - fn num_variables(&self) -> usize; -} - -#[derive(Debug)] -pub struct IdentityMap<'a, 'tcx: 'a> { - mir: &'a Mir<'tcx>, -} - -impl<'a, 'tcx> IdentityMap<'a, 'tcx> { - pub fn new(mir: &'a Mir<'tcx>) -> Self { - Self { mir } - } -} - -impl<'a, 'tcx> LiveVariableMap for IdentityMap<'a, 'tcx> { - type LiveVar = Local; - - fn from_local(&self, local: Local) -> Option { - Some(local) - } - - fn from_live_var(&self, local: Self::LiveVar) -> Local { - local - } - - fn num_variables(&self) -> usize { - self.mir.local_decls.len() - } + pub outs: IndexVec, } /// Computes which local variables are live within the given function /// `mir`. The liveness mode `mode` determines what sorts of uses are /// considered to make a variable live (e.g., do drops count?). -pub fn liveness_of_locals<'tcx, V: Idx>( +pub fn liveness_of_locals<'tcx>( mir: &Mir<'tcx>, - map: &impl LiveVariableMap, -) -> LivenessResult { - let num_live_vars = map.num_variables(); +) -> LivenessResult { + let num_live_vars = mir.local_decls.len(); - let def_use: IndexVec<_, DefsUses> = mir + let def_use: IndexVec<_, DefsUses> = mir .basic_blocks() .iter() - .map(|b| block(map, b, num_live_vars)) + .map(|b| block(b, num_live_vars)) .collect(); - let mut outs: IndexVec<_, LiveVarSet> = mir + let mut outs: IndexVec<_, LiveVarSet> = mir .basic_blocks() .indices() .map(|_| LiveVarSet::new_empty(num_live_vars)) @@ -211,27 +172,23 @@ pub fn categorize<'tcx>(context: PlaceContext<'tcx>) -> Option { } } -struct DefsUsesVisitor<'lv, V, M> -where - V: Idx, - M: LiveVariableMap + 'lv, +struct DefsUsesVisitor { - map: &'lv M, - defs_uses: DefsUses, + defs_uses: DefsUses, } #[derive(Eq, PartialEq, Clone)] -struct DefsUses { - defs: LiveVarSet, - uses: LiveVarSet, +struct DefsUses { + defs: LiveVarSet, + uses: LiveVarSet, } -impl DefsUses { - fn apply(&self, bits: &mut LiveVarSet) -> bool { +impl DefsUses { + fn apply(&self, bits: &mut LiveVarSet) -> bool { bits.subtract(&self.defs) | bits.union(&self.uses) } - fn add_def(&mut self, index: V) { + fn add_def(&mut self, index: Local) { // If it was used already in the block, remove that use // now that we found a definition. // @@ -245,7 +202,7 @@ impl DefsUses { self.defs.insert(index); } - fn add_use(&mut self, index: V) { + fn add_use(&mut self, index: Local) { // Inverse of above. // // Example: @@ -261,29 +218,22 @@ impl DefsUses { } } -impl<'tcx, 'lv, V, M> Visitor<'tcx> for DefsUsesVisitor<'lv, V, M> -where - V: Idx, - M: LiveVariableMap, +impl<'tcx> Visitor<'tcx> for DefsUsesVisitor { fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) { - if let Some(v_index) = self.map.from_local(local) { - match categorize(context) { - Some(DefUse::Def) => self.defs_uses.add_def(v_index), - Some(DefUse::Use) | Some(DefUse::Drop) => self.defs_uses.add_use(v_index), - _ => (), - } + match categorize(context) { + Some(DefUse::Def) => self.defs_uses.add_def(local), + Some(DefUse::Use) | Some(DefUse::Drop) => self.defs_uses.add_use(local), + _ => (), } } } -fn block<'tcx, V: Idx>( - map: &impl LiveVariableMap, +fn block<'tcx>( b: &BasicBlockData<'tcx>, locals: usize, -) -> DefsUses { +) -> DefsUses { let mut visitor = DefsUsesVisitor { - map, defs_uses: DefsUses { defs: LiveVarSet::new_empty(locals), uses: LiveVarSet::new_empty(locals), @@ -305,13 +255,12 @@ fn block<'tcx, V: Idx>( visitor.defs_uses } -pub fn dump_mir<'a, 'tcx, V: Idx>( +pub fn dump_mir<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, pass_name: &str, source: MirSource<'tcx>, mir: &Mir<'tcx>, - map: &impl LiveVariableMap, - result: &LivenessResult, + result: &LivenessResult, ) { if !dump_enabled(tcx, pass_name, source) { return; @@ -320,17 +269,16 @@ pub fn dump_mir<'a, 'tcx, V: Idx>( // see notes on #41697 below tcx.item_path_str(source.def_id()) }); - dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, map, result); + dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result); } -fn dump_matched_mir_node<'a, 'tcx, V: Idx>( +fn dump_matched_mir_node<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, pass_name: &str, node_path: &str, source: MirSource<'tcx>, mir: &Mir<'tcx>, - map: &dyn LiveVariableMap, - result: &LivenessResult, + result: &LivenessResult, ) { let mut file_path = PathBuf::new(); file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir)); @@ -342,25 +290,23 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>( writeln!(file, "// source = {:?}", source)?; writeln!(file, "// pass_name = {}", pass_name)?; writeln!(file, "")?; - write_mir_fn(tcx, source, mir, map, &mut file, result)?; + write_mir_fn(tcx, source, mir, &mut file, result)?; Ok(()) }); } -pub fn write_mir_fn<'a, 'tcx, V: Idx>( +pub fn write_mir_fn<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource<'tcx>, mir: &Mir<'tcx>, - map: &dyn LiveVariableMap, w: &mut dyn Write, - result: &LivenessResult, + result: &LivenessResult, ) -> io::Result<()> { write_mir_intro(tcx, src, mir, w)?; for block in mir.basic_blocks().indices() { - let print = |w: &mut dyn Write, prefix, result: &IndexVec>| { + let print = |w: &mut dyn Write, prefix, result: &IndexVec| { let live: Vec = result[block] .iter() - .map(|v| map.from_live_var(v)) .map(|local| format!("{:?}", local)) .collect(); writeln!(w, "{} {{{}}}", prefix, live.join(", "))