Skip to content

Commit

Permalink
boots: Clean up dominator analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Jan 26, 2025
1 parent 7bad2df commit b6e2ea9
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 26 deletions.
53 changes: 32 additions & 21 deletions pkgs/boots/dominator.dora
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@ pub fn computePostOrder(graph: Graph) {
}

fn computeDominators(graph: Graph) {
let blocks = graph.blockCount().toInt64();
let filled = BitSet::new(blocks);
let dominators = Array[Option[Block]]::fill(blocks, None[Block]);

let entry = graph.getEntryBlock().id().toInt64();
filled.insert(entry);

// Algorithm from paper "A Simple, Fast Dominance Algorithm".
for block in graph.reversePostOrderIterator() {
if block.isEntryBlock() {
Expand All @@ -148,19 +155,26 @@ fn computeDominators(graph: Graph) {
for predEdge in block.predecessors {
let pred = predEdge.source;

if predEdge.isBackward() {
continue;
}
if filled.contains(pred.id().toInt64()) {
let block = if newIdom is Some(newIdom) {
commonDominator(dominators, newIdom, pred)
} else {
pred
};

if newIdom.isNone() {
newIdom = Some(pred);
continue;
newIdom = Some(block);
}

newIdom = Some(commonDominator(newIdom.getOrPanic(), pred));
}

block.setDominator(newIdom.getOrPanic());
assert(newIdom.isSome());
let blockId = block.id().toInt64();
dominators(blockId) = newIdom;
filled.insert(blockId);
}

for block in graph.insertionOrderIterator() {
block.setDominator(dominators(block.id().toInt64()));
block.clearDominatedBlocks();
}

// Assert that we have a reducible graph.
Expand Down Expand Up @@ -188,16 +202,13 @@ fn computeDominators(graph: Graph) {
for pred in block.predecessors {
let pred = pred.source;

if newIdom.isNone() {
newIdom = Some(pred);
continue;
}

if pred.getDominator().isNone() {
continue;
}
let block = if newIdom is Some(newIdom) {
commonDominator(dominators, newIdom, pred)
} else {
pred
};

newIdom = Some(commonDominator(newIdom.getOrPanic(), pred));
newIdom = Some(block);
}

assert(block.getDominator().getOrPanic() === newIdom.getOrPanic());
Expand All @@ -213,17 +224,17 @@ fn computeDominators(graph: Graph) {
}
}

fn commonDominator(b1: Block, b2: Block): Block {
fn commonDominator(dominators: Array[Option[Block]], b1: Block, b2: Block): Block {
let mut finger1 = b1;
let mut finger2 = b2;

while finger1 != finger2 {
while finger1.postOrderIdx < finger2.postOrderIdx {
finger1 = finger1.getDominator().getOrPanic();
finger1 = dominators(finger1.id().toInt64()).getOrPanic();
}

while finger2.postOrderIdx < finger1.postOrderIdx {
finger2 = finger2.getDominator().getOrPanic();
finger2 = dominators(finger2.id().toInt64()).getOrPanic();
}
}

Expand Down
14 changes: 9 additions & 5 deletions pkgs/boots/graph.dora
Original file line number Diff line number Diff line change
Expand Up @@ -492,8 +492,8 @@ impl Block {
self.dominator
}

pub fn setDominator(block: Block) {
self.dominator = Some(block);
pub fn setDominator(block: Option[Block]) {
self.dominator = block;
}

pub fn dominates(other: Block): Bool {
Expand All @@ -507,14 +507,18 @@ impl Block {
pub fn strictlyDominates(other: Block): Bool {
let mut current = other.getDominator();

while current.isSome() {
if self === current.getOrPanic() { return true; }
current = current.getOrPanic().getDominator();
while current is Some(c) {
if self === c { return true; }
current = c.getDominator();
}

false
}

pub fn clearDominatedBlocks() {
self.dominatedBlocks.clear();
}

pub fn getDominatedBlocks(): Vec[Block] {
self.dominatedBlocks
}
Expand Down

0 comments on commit b6e2ea9

Please sign in to comment.