Skip to content

Commit fb97bb5

Browse files
committed
Auto merge of #51900 - PramodBisht:51813_b, r=nikomatsakis
introduce dirty list to dataflow @nikomatsakis my naive implementation never worked, So, I decided to implement using `work_queue` data structure. This PR also includes your commits from `nll-liveness-dirty-list` branch. Those commits should not visible once your branch is merged. r? @nikomatsakis
2 parents 739320a + 09df6a0 commit fb97bb5

File tree

1 file changed

+44
-44
lines changed
  • src/librustc_mir/dataflow

1 file changed

+44
-44
lines changed

src/librustc_mir/dataflow/mod.rs

+44-44
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use syntax::ast::{self, MetaItem};
1313
use rustc_data_structures::indexed_set::{IdxSet, IdxSetBuf};
1414
use rustc_data_structures::indexed_vec::Idx;
1515
use rustc_data_structures::bitslice::{bitwise, BitwiseOperator};
16+
use rustc_data_structures::work_queue::WorkQueue;
1617

1718
use rustc::ty::{self, TyCtxt};
1819
use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
@@ -176,7 +177,6 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitD
176177
struct PropagationContext<'b, 'a: 'b, 'tcx: 'a, O> where O: 'b + BitDenotation
177178
{
178179
builder: &'b mut DataflowAnalysis<'a, 'tcx, O>,
179-
changed: bool,
180180
}
181181

182182
impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
@@ -185,12 +185,9 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
185185
let mut temp = IdxSetBuf::new_empty(self.flow_state.sets.bits_per_block);
186186
let mut propcx = PropagationContext {
187187
builder: self,
188-
changed: true,
189188
};
190-
while propcx.changed {
191-
propcx.changed = false;
192-
propcx.walk_cfg(&mut temp);
193-
}
189+
propcx.walk_cfg(&mut temp);
190+
194191
}
195192

196193
fn build_sets(&mut self) {
@@ -236,18 +233,20 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD> where BD: BitDenotation
236233
impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD> where BD: BitDenotation
237234
{
238235
fn walk_cfg(&mut self, in_out: &mut IdxSet<BD::Idx>) {
236+
let mut dirty_queue: WorkQueue<mir::BasicBlock> =
237+
WorkQueue::with_all(self.builder.mir.basic_blocks().len());
239238
let mir = self.builder.mir;
240-
for (bb_idx, bb_data) in mir.basic_blocks().iter().enumerate() {
241-
let builder = &mut self.builder;
239+
while let Some(bb) = dirty_queue.pop() {
240+
let bb_data = &mir[bb];
242241
{
243-
let sets = builder.flow_state.sets.for_block(bb_idx);
242+
let sets = self.builder.flow_state.sets.for_block(bb.index());
244243
debug_assert!(in_out.words().len() == sets.on_entry.words().len());
245244
in_out.overwrite(sets.on_entry);
246245
in_out.union(sets.gen_set);
247246
in_out.subtract(sets.kill_set);
248247
}
249-
builder.propagate_bits_into_graph_successors_of(
250-
in_out, &mut self.changed, (mir::BasicBlock::new(bb_idx), bb_data));
248+
self.builder.propagate_bits_into_graph_successors_of(
249+
in_out, (bb, bb_data), &mut dirty_queue);
251250
}
252251
}
253252
}
@@ -806,68 +805,68 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
806805
fn propagate_bits_into_graph_successors_of(
807806
&mut self,
808807
in_out: &mut IdxSet<D::Idx>,
809-
changed: &mut bool,
810-
(bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData))
808+
(bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData),
809+
dirty_list: &mut WorkQueue<mir::BasicBlock>)
811810
{
812811
match bb_data.terminator().kind {
813812
mir::TerminatorKind::Return |
814813
mir::TerminatorKind::Resume |
815814
mir::TerminatorKind::Abort |
816815
mir::TerminatorKind::GeneratorDrop |
817816
mir::TerminatorKind::Unreachable => {}
818-
mir::TerminatorKind::Goto { ref target } |
819-
mir::TerminatorKind::Assert { ref target, cleanup: None, .. } |
820-
mir::TerminatorKind::Yield { resume: ref target, drop: None, .. } |
821-
mir::TerminatorKind::Drop { ref target, location: _, unwind: None } |
817+
mir::TerminatorKind::Goto { target } |
818+
mir::TerminatorKind::Assert { target, cleanup: None, .. } |
819+
mir::TerminatorKind::Yield { resume: target, drop: None, .. } |
820+
mir::TerminatorKind::Drop { target, location: _, unwind: None } |
822821
mir::TerminatorKind::DropAndReplace {
823-
ref target, value: _, location: _, unwind: None
822+
target, value: _, location: _, unwind: None
824823
} => {
825-
self.propagate_bits_into_entry_set_for(in_out, changed, target);
824+
self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
826825
}
827-
mir::TerminatorKind::Yield { resume: ref target, drop: Some(ref drop), .. } => {
828-
self.propagate_bits_into_entry_set_for(in_out, changed, target);
829-
self.propagate_bits_into_entry_set_for(in_out, changed, drop);
826+
mir::TerminatorKind::Yield { resume: target, drop: Some(drop), .. } => {
827+
self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
828+
self.propagate_bits_into_entry_set_for(in_out, drop, dirty_list);
830829
}
831-
mir::TerminatorKind::Assert { ref target, cleanup: Some(ref unwind), .. } |
832-
mir::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } |
830+
mir::TerminatorKind::Assert { target, cleanup: Some(unwind), .. } |
831+
mir::TerminatorKind::Drop { target, location: _, unwind: Some(unwind) } |
833832
mir::TerminatorKind::DropAndReplace {
834-
ref target, value: _, location: _, unwind: Some(ref unwind)
833+
target, value: _, location: _, unwind: Some(unwind)
835834
} => {
836-
self.propagate_bits_into_entry_set_for(in_out, changed, target);
835+
self.propagate_bits_into_entry_set_for(in_out, target, dirty_list);
837836
if !self.dead_unwinds.contains(&bb) {
838-
self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
837+
self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
839838
}
840839
}
841840
mir::TerminatorKind::SwitchInt { ref targets, .. } => {
842841
for target in targets {
843-
self.propagate_bits_into_entry_set_for(in_out, changed, target);
842+
self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list);
844843
}
845844
}
846-
mir::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => {
847-
if let Some(ref unwind) = *cleanup {
845+
mir::TerminatorKind::Call { cleanup, ref destination, func: _, args: _ } => {
846+
if let Some(unwind) = cleanup {
848847
if !self.dead_unwinds.contains(&bb) {
849-
self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
848+
self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
850849
}
851850
}
852-
if let Some((ref dest_place, ref dest_bb)) = *destination {
851+
if let Some((ref dest_place, dest_bb)) = *destination {
853852
// N.B.: This must be done *last*, after all other
854853
// propagation, as documented in comment above.
855854
self.flow_state.operator.propagate_call_return(
856-
in_out, bb, *dest_bb, dest_place);
857-
self.propagate_bits_into_entry_set_for(in_out, changed, dest_bb);
855+
in_out, bb, dest_bb, dest_place);
856+
self.propagate_bits_into_entry_set_for(in_out, dest_bb, dirty_list);
858857
}
859858
}
860-
mir::TerminatorKind::FalseEdges { ref real_target, ref imaginary_targets } => {
861-
self.propagate_bits_into_entry_set_for(in_out, changed, real_target);
859+
mir::TerminatorKind::FalseEdges { real_target, ref imaginary_targets } => {
860+
self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list);
862861
for target in imaginary_targets {
863-
self.propagate_bits_into_entry_set_for(in_out, changed, target);
862+
self.propagate_bits_into_entry_set_for(in_out, *target, dirty_list);
864863
}
865864
}
866-
mir::TerminatorKind::FalseUnwind { ref real_target, unwind } => {
867-
self.propagate_bits_into_entry_set_for(in_out, changed, real_target);
868-
if let Some(ref unwind) = unwind {
865+
mir::TerminatorKind::FalseUnwind { real_target, unwind } => {
866+
self.propagate_bits_into_entry_set_for(in_out, real_target, dirty_list);
867+
if let Some(unwind) = unwind {
869868
if !self.dead_unwinds.contains(&bb) {
870-
self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
869+
self.propagate_bits_into_entry_set_for(in_out, unwind, dirty_list);
871870
}
872871
}
873872
}
@@ -876,14 +875,15 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
876875

877876
fn propagate_bits_into_entry_set_for(&mut self,
878877
in_out: &IdxSet<D::Idx>,
879-
changed: &mut bool,
880-
bb: &mir::BasicBlock) {
878+
bb: mir::BasicBlock,
879+
dirty_queue: &mut WorkQueue<mir::BasicBlock>) {
881880
let entry_set = self.flow_state.sets.for_block(bb.index()).on_entry;
882881
let set_changed = bitwise(entry_set.words_mut(),
883882
in_out.words(),
884883
&self.flow_state.operator);
885884
if set_changed {
886-
*changed = true;
885+
dirty_queue.insert(bb);
887886
}
888887
}
888+
889889
}

0 commit comments

Comments
 (0)