From be0e77837a1abaf5668bd247ed683ccabb293f16 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 29 Jun 2018 06:38:56 -0400 Subject: [PATCH] use `WorkQueue` to track dirty bits in liveness --- src/librustc_mir/util/liveness.rs | 39 ++++++++++++++++++------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/librustc_mir/util/liveness.rs b/src/librustc_mir/util/liveness.rs index 34f8141141d2..938eb72654ab 100644 --- a/src/librustc_mir/util/liveness.rs +++ b/src/librustc_mir/util/liveness.rs @@ -37,6 +37,7 @@ use rustc::mir::*; use rustc::mir::visit::{PlaceContext, Visitor}; use rustc_data_structures::indexed_vec::{Idx, IndexVec}; use rustc_data_structures::indexed_set::IdxSetBuf; +use rustc_data_structures::work_queue::WorkQueue; use util::pretty::{dump_enabled, write_basic_block, write_mir_intro}; use rustc::ty::item_path; use rustc::mir::visit::MirVisitable; @@ -130,26 +131,32 @@ pub fn liveness_of_locals<'tcx>(mir: &Mir<'tcx>, mode: LivenessMode) -> Liveness .collect(); let mut outs = ins.clone(); - let mut changed = true; let mut bits = LocalSet::new_empty(locals); - while changed { - changed = false; - for b in mir.basic_blocks().indices().rev() { - // outs[b] = ∪ {ins of successors} - bits.clear(); - for &successor in mir.basic_blocks()[b].terminator().successors() { - bits.union(&ins[successor]); - } - outs[b].overwrite(&bits); + // queue of things that need to be re-processed, and a set containing + // the things currently in the queue + let mut dirty_queue: WorkQueue = WorkQueue::with_all(mir.basic_blocks().len()); - // bits = use ∪ (bits - def) - def_use[b].apply(&mut bits); + let predecessors = mir.predecessors(); - // update bits on entry and flag if they have changed - if ins[b] != bits { - ins[b].overwrite(&bits); - changed = true; + while let Some(bb) = dirty_queue.pop() { + // outs[b] = ∪ {ins of successors} + bits.clear(); + for &successor in mir[bb].terminator().successors() { + bits.union(&ins[successor]); + } + outs[bb].overwrite(&bits); + + // bits = use ∪ (bits - def) + def_use[bb].apply(&mut bits); + + // update bits on entry and, if they have changed, enqueue all + // of our predecessors, since their inputs have now changed + if ins[bb] != bits { + ins[bb].overwrite(&bits); + + for &pred_bb in &predecessors[bb] { + dirty_queue.insert(pred_bb); } } }