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<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`).
This commit is contained in:
parent
d6ede9192d
commit
ae5f7224b5
2 changed files with 41 additions and 97 deletions
|
|
@ -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<BasicBlock>,
|
||||
storage_liveness: liveness::LiveVarSet<Local>,
|
||||
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<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>,
|
||||
|
|
@ -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,
|
||||
|
|
@ -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();
|
||||
|
|
@ -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<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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
@ -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))
|
||||
|
|
@ -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.
|
||||
//
|
||||
|
|
@ -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:
|
||||
|
|
@ -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),
|
||||
|
|
@ -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;
|
||||
|
|
@ -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));
|
||||
|
|
@ -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(", "))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue