Skip to content

Commit

Permalink
nll: remove IdentityMap and LiveVariableMap
Browse files Browse the repository at this point in the history
With `NllLivenessMap` and `LiveVar` removed, the `IdentityMap` (remaining
structure implementing the `LiveVariableMap` trait) loses its meaning.

Specialize the `LiveVarSet` to a `BitSet<Local>` removing the `V` and related
parameters. The `LiveVarSet<V>` was only being used as `LiveVarSet<Local>` 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`).
  • Loading branch information
schomatis committed Feb 16, 2019
1 parent d6ede91 commit ae5f722
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 97 deletions.
16 changes: 7 additions & 9 deletions src/librustc_mir/transform/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -148,7 +148,7 @@ struct SuspensionPoint {
state: u32,
resume: BasicBlock,
drop: Option<BasicBlock>,
storage_liveness: liveness::LiveVarSet<Local>,
storage_liveness: liveness::LiveVarSet,
}

struct TransformVisitor<'a, 'tcx: 'a> {
Expand All @@ -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<BasicBlock, Option<_>>`.
storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
storage_liveness: FxHashMap<BasicBlock, liveness::LiveVarSet>,

// A list of suspension points, generated during the transform
suspension_points: Vec<SuspensionPoint>,
Expand Down Expand Up @@ -358,7 +358,7 @@ fn replace_result_variable<'tcx>(
new_ret_local
}

struct StorageIgnored(liveness::LiveVarSet<Local>);
struct StorageIgnored(liveness::LiveVarSet);

impl<'tcx> Visitor<'tcx> for StorageIgnored {
fn visit_statement(&mut self,
Expand All @@ -379,8 +379,8 @@ fn locals_live_across_suspend_points(
source: MirSource<'tcx>,
movable: bool,
) -> (
liveness::LiveVarSet<Local>,
FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
liveness::LiveVarSet,
FxHashMap<BasicBlock, liveness::LiveVarSet>,
) {
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
let node_id = tcx.hir().as_local_node_id(source.def_id()).unwrap();
Expand Down Expand Up @@ -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,
);

Expand Down Expand Up @@ -491,7 +489,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &mut Mir<'tcx>)
-> (FxHashMap<Local, (Ty<'tcx>, usize)>,
GeneratorLayout<'tcx>,
FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>)
FxHashMap<BasicBlock, liveness::LiveVarSet>)
{
// 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,
Expand Down
122 changes: 34 additions & 88 deletions src/librustc_mir/util/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<V> = BitSet<V>;
pub type LiveVarSet = BitSet<Local>;

/// This gives the result of the liveness analysis at the boundary of
/// basic blocks.
Expand All @@ -48,66 +48,27 @@ pub type LiveVarSet<V> = BitSet<V>;
/// 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<V: Idx> {
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<BasicBlock, LiveVarSet<V>>,
}

/// 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<Self::LiveVar>;
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<Self::LiveVar> {
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<BasicBlock, LiveVarSet>,
}

/// 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<LiveVar = V>,
) -> LivenessResult<V> {
let num_live_vars = map.num_variables();
) -> LivenessResult {
let num_live_vars = mir.local_decls.len();

let def_use: IndexVec<_, DefsUses<V>> = 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<V>> = mir
let mut outs: IndexVec<_, LiveVarSet> = mir
.basic_blocks()
.indices()
.map(|_| LiveVarSet::new_empty(num_live_vars))
Expand Down Expand Up @@ -211,27 +172,23 @@ pub fn categorize<'tcx>(context: PlaceContext<'tcx>) -> Option<DefUse> {
}
}

struct DefsUsesVisitor<'lv, V, M>
where
V: Idx,
M: LiveVariableMap<LiveVar = V> + 'lv,
struct DefsUsesVisitor
{
map: &'lv M,
defs_uses: DefsUses<V>,
defs_uses: DefsUses,
}

#[derive(Eq, PartialEq, Clone)]
struct DefsUses<V: Idx> {
defs: LiveVarSet<V>,
uses: LiveVarSet<V>,
struct DefsUses {
defs: LiveVarSet,
uses: LiveVarSet,
}

impl<V: Idx> DefsUses<V> {
fn apply(&self, bits: &mut LiveVarSet<V>) -> 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.
//
Expand All @@ -245,7 +202,7 @@ impl<V: Idx> DefsUses<V> {
self.defs.insert(index);
}

fn add_use(&mut self, index: V) {
fn add_use(&mut self, index: Local) {
// Inverse of above.
//
// Example:
Expand All @@ -261,29 +218,22 @@ impl<V: Idx> DefsUses<V> {
}
}

impl<'tcx, 'lv, V, M> Visitor<'tcx> for DefsUsesVisitor<'lv, V, M>
where
V: Idx,
M: LiveVariableMap<LiveVar = V>,
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<LiveVar = V>,
fn block<'tcx>(
b: &BasicBlockData<'tcx>,
locals: usize,
) -> DefsUses<V> {
) -> DefsUses {
let mut visitor = DefsUsesVisitor {
map,
defs_uses: DefsUses {
defs: LiveVarSet::new_empty(locals),
uses: LiveVarSet::new_empty(locals),
Expand All @@ -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<LiveVar = V>,
result: &LivenessResult<V>,
result: &LivenessResult,
) {
if !dump_enabled(tcx, pass_name, source) {
return;
Expand All @@ -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<LiveVar = V>,
result: &LivenessResult<V>,
result: &LivenessResult,
) {
let mut file_path = PathBuf::new();
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
Expand All @@ -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<LiveVar = V>,
w: &mut dyn Write,
result: &LivenessResult<V>,
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<BasicBlock, LiveVarSet<V>>| {
let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LiveVarSet>| {
let live: Vec<String> = result[block]
.iter()
.map(|v| map.from_live_var(v))
.map(|local| format!("{:?}", local))
.collect();
writeln!(w, "{} {{{}}}", prefix, live.join(", "))
Expand Down

0 comments on commit ae5f722

Please sign in to comment.