Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace state_for_location with DataflowResultsCursor #64532

Merged
merged 3 commits into from
Sep 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 2 additions & 26 deletions src/librustc_mir/dataflow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,34 +453,10 @@ where
{
self.flow_state.each_gen_bit(f)
}
}

pub fn state_for_location<'tcx, T: BitDenotation<'tcx>>(loc: Location,
analysis: &T,
result: &DataflowResults<'tcx, T>,
body: &Body<'tcx>)
-> BitSet<T::Idx> {
let mut trans = GenKill::from_elem(HybridBitSet::new_empty(analysis.bits_per_block()));

for stmt in 0..loc.statement_index {
let mut stmt_loc = loc;
stmt_loc.statement_index = stmt;
analysis.before_statement_effect(&mut trans, stmt_loc);
analysis.statement_effect(&mut trans, stmt_loc);
pub fn get(&self) -> &BitSet<BD::Idx> {
self.flow_state.as_dense()
}

// Apply the pre-statement effect of the statement we're evaluating.
if loc.statement_index == body[loc.block].statements.len() {
analysis.before_terminator_effect(&mut trans, loc);
} else {
analysis.before_statement_effect(&mut trans, loc);
}

// Apply the transfer function for all preceding statements to the fixpoint
// at the start of the block.
let mut state = result.sets().entry_set_for(loc.block.index()).to_owned();
trans.apply(&mut state);
state
}

pub struct DataflowAnalysis<'a, 'tcx, O>
Expand Down
37 changes: 15 additions & 22 deletions src/librustc_mir/transform/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ use crate::transform::{MirPass, MirSource};
use crate::transform::simplify;
use crate::transform::no_landing_pads::no_landing_pads;
use crate::dataflow::{DataflowResults, DataflowResultsConsumer, FlowAtLocation};
use crate::dataflow::{do_dataflow, DebugFormatted, state_for_location};
use crate::dataflow::{do_dataflow, DebugFormatted, DataflowResultsCursor};
use crate::dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals, RequiresStorage};
use crate::util::dump_mir;
use crate::util::liveness;
Expand Down Expand Up @@ -436,9 +436,10 @@ fn locals_live_across_suspend_points(
// Calculate when MIR locals have live storage. This gives us an upper bound of their
// lifetimes.
let storage_live_analysis = MaybeStorageLive::new(body);
let storage_live =
let storage_live_results =
do_dataflow(tcx, body, def_id, &[], &dead_unwinds, storage_live_analysis,
|bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
let mut storage_live_cursor = DataflowResultsCursor::new(&storage_live_results, body);

// Find the MIR locals which do not use StorageLive/StorageDead statements.
// The storage of these locals are always live.
Expand All @@ -448,17 +449,18 @@ fn locals_live_across_suspend_points(
// Calculate the MIR locals which have been previously
// borrowed (even if they are still active).
let borrowed_locals_analysis = HaveBeenBorrowedLocals::new(body);
let borrowed_locals_result =
let borrowed_locals_results =
do_dataflow(tcx, body, def_id, &[], &dead_unwinds, borrowed_locals_analysis,
|bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
let mut borrowed_locals_cursor = DataflowResultsCursor::new(&borrowed_locals_results, body);

// Calculate the MIR locals that we actually need to keep storage around
// for.
let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_result);
let requires_storage =
let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_results);
let requires_storage_results =
do_dataflow(tcx, body, def_id, &[], &dead_unwinds, requires_storage_analysis,
|bd, p| DebugFormatted::new(&bd.body().local_decls[p]));
let requires_storage_analysis = RequiresStorage::new(body, &borrowed_locals_result);
let mut requires_storage_cursor = DataflowResultsCursor::new(&requires_storage_results, body);

// Calculate the liveness of MIR locals ignoring borrows.
let mut live_locals = liveness::LiveVarSet::new_empty(body.local_decls.len());
Expand All @@ -484,10 +486,6 @@ fn locals_live_across_suspend_points(
};

if !movable {
let borrowed_locals = state_for_location(loc,
&borrowed_locals_analysis,
&borrowed_locals_result,
body);
// The `liveness` variable contains the liveness of MIR locals ignoring borrows.
// This is correct for movable generators since borrows cannot live across
// suspension points. However for immovable generators we need to account for
Expand All @@ -498,22 +496,19 @@ fn locals_live_across_suspend_points(
// If a borrow is converted to a raw reference, we must also assume that it lives
// forever. Note that the final liveness is still bounded by the storage liveness
// of the local, which happens using the `intersect` operation below.
liveness.outs[block].union(&borrowed_locals);
borrowed_locals_cursor.seek(loc);
liveness.outs[block].union(borrowed_locals_cursor.get());
}

let storage_liveness = state_for_location(loc,
&storage_live_analysis,
&storage_live,
body);
storage_live_cursor.seek(loc);
let storage_liveness = storage_live_cursor.get();

// Store the storage liveness for later use so we can restore the state
// after a suspension point
storage_liveness_map.insert(block, storage_liveness.clone());

let mut storage_required = state_for_location(loc,
&requires_storage_analysis,
&requires_storage,
body);
requires_storage_cursor.seek(loc);
let mut storage_required = requires_storage_cursor.get().clone();

// Mark locals without storage statements as always requiring storage
storage_required.union(&ignored.0);
Expand Down Expand Up @@ -549,8 +544,7 @@ fn locals_live_across_suspend_points(
body,
&live_locals,
&ignored,
requires_storage,
requires_storage_analysis);
requires_storage_results);

LivenessInfo {
live_locals,
Expand Down Expand Up @@ -588,7 +582,6 @@ fn compute_storage_conflicts(
stored_locals: &liveness::LiveVarSet,
ignored: &StorageIgnored,
requires_storage: DataflowResults<'tcx, RequiresStorage<'mir, 'tcx>>,
_requires_storage_analysis: RequiresStorage<'mir, 'tcx>,
) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> {
assert_eq!(body.local_decls.len(), ignored.0.domain_size());
assert_eq!(body.local_decls.len(), stored_locals.domain_size());
Expand Down