aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Translation/Dominance.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Translation/Dominance.cs')
-rw-r--r--ARMeilleure/Translation/Dominance.cs95
1 files changed, 95 insertions, 0 deletions
diff --git a/ARMeilleure/Translation/Dominance.cs b/ARMeilleure/Translation/Dominance.cs
new file mode 100644
index 00000000..bb55169e
--- /dev/null
+++ b/ARMeilleure/Translation/Dominance.cs
@@ -0,0 +1,95 @@
+using ARMeilleure.IntermediateRepresentation;
+using System.Diagnostics;
+
+namespace ARMeilleure.Translation
+{
+ static class Dominance
+ {
+ // Those methods are an implementation of the algorithms on "A Simple, Fast Dominance Algorithm".
+ // https://www.cs.rice.edu/~keith/EMBED/dom.pdf
+ public static void FindDominators(ControlFlowGraph cfg)
+ {
+ BasicBlock Intersect(BasicBlock block1, BasicBlock block2)
+ {
+ while (block1 != block2)
+ {
+ while (cfg.PostOrderMap[block1.Index] < cfg.PostOrderMap[block2.Index])
+ {
+ block1 = block1.ImmediateDominator;
+ }
+
+ while (cfg.PostOrderMap[block2.Index] < cfg.PostOrderMap[block1.Index])
+ {
+ block2 = block2.ImmediateDominator;
+ }
+ }
+
+ return block1;
+ }
+
+ cfg.Entry.ImmediateDominator = cfg.Entry;
+
+ Debug.Assert(cfg.Entry == cfg.PostOrderBlocks[cfg.PostOrderBlocks.Length - 1]);
+
+ bool modified;
+
+ do
+ {
+ modified = false;
+
+ for (int blkIndex = cfg.PostOrderBlocks.Length - 2; blkIndex >= 0; blkIndex--)
+ {
+ BasicBlock block = cfg.PostOrderBlocks[blkIndex];
+
+ BasicBlock newIDom = null;
+
+ foreach (BasicBlock predecessor in block.Predecessors)
+ {
+ if (predecessor.ImmediateDominator != null)
+ {
+ if (newIDom != null)
+ {
+ newIDom = Intersect(predecessor, newIDom);
+ }
+ else
+ {
+ newIDom = predecessor;
+ }
+ }
+ }
+
+ if (block.ImmediateDominator != newIDom)
+ {
+ block.ImmediateDominator = newIDom;
+
+ modified = true;
+ }
+ }
+ }
+ while (modified);
+ }
+
+ public static void FindDominanceFrontiers(ControlFlowGraph cfg)
+ {
+ foreach (BasicBlock block in cfg.Blocks)
+ {
+ if (block.Predecessors.Count < 2)
+ {
+ continue;
+ }
+
+ for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
+ {
+ BasicBlock current = block.Predecessors[pBlkIndex];
+
+ while (current != block.ImmediateDominator)
+ {
+ current.DominanceFrontiers.Add(block);
+
+ current = current.ImmediateDominator;
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file