1use std::collections::BinaryHeap;
2
3use rustc_index::{IndexVec, bit_set::DenseBitSet};
4use rustc_middle::mir::BasicBlock;
5
6struct Item<'a> {
7 bb: BasicBlock,
8 dominator_order_rank: &'a IndexVec<BasicBlock, u32>,
9}
10
11pub(crate) struct WorkQueue<'a> {
12 heap: BinaryHeap<Item<'a>>,
13 set: DenseBitSet<BasicBlock>,
14 dominator_order_rank: &'a IndexVec<BasicBlock, u32>,
15}
16
17impl<'a> WorkQueue<'a> {
18 pub(crate) fn empty(len: usize, dominator_order_rank: &'a IndexVec<BasicBlock, u32>) -> Self {
19 Self {
20 heap: BinaryHeap::with_capacity(len),
21 set: DenseBitSet::new_empty(len),
22 dominator_order_rank,
23 }
24 }
25
26 pub(crate) fn insert(&mut self, bb: BasicBlock) -> bool {
27 if self.set.insert(bb) {
28 self.heap
29 .push(Item { bb, dominator_order_rank: self.dominator_order_rank });
30 true
31 } else {
32 false
33 }
34 }
35
36 pub(crate) fn pop(&mut self) -> Option<BasicBlock> {
37 if let Some(Item { bb, .. }) = self.heap.pop() {
38 self.set.remove(bb);
39 Some(bb)
40 } else {
41 None
42 }
43 }
44}
45
46impl PartialEq for Item<'_> {
47 fn eq(&self, other: &Self) -> bool {
48 self.bb == other.bb
49 }
50}
51
52impl PartialOrd for Item<'_> {
53 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
54 Some(self.cmp(other))
55 }
56}
57
58impl Eq for Item<'_> {}
59
60impl Ord for Item<'_> {
61 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
62 self.dominator_order_rank[other.bb].cmp(&self.dominator_order_rank[self.bb])
63 }
64}