Skip to content

Instantly share code, notes, and snippets.

@ishikawa
Created February 18, 2011 07:19
Show Gist options
  • Save ishikawa/833372 to your computer and use it in GitHub Desktop.
Save ishikawa/833372 to your computer and use it in GitHub Desktop.
A Simple, Fast Dominance Algorithm
# Cooper, Keith D.; Harvey, Timothy J.; and Kennedy, Ken (2001). A Simple, Fast Dominance Algorithm
# http://www.cs.rice.edu/~keith/EMBED/dom.pdf
#
# Computing minimal SSA using dominance frontiers
# http://en.wikipedia.org/wiki/Static_single_assignment_form#Computing_minimal_SSA_using_dominance_frontiers
#
# Dominator (graph theory)
# http://en.wikipedia.org/wiki/Dominator_(graph_theory)
#
require 'set'
class Node
attr_reader :name,
:predecessors, :successors,
:dominance_frontiers
attr_accessor :immediate_dominator
def initialize(name)
@name = name
@immediate_dominator = nil
@predecessors = []
@successors = []
@dominance_frontiers = Set.new
end
def <<(node)
@predecessors << node
node.successors << self
node
end
def >>(node)
@successors << node
node.predecessors << self
node
end
def ==(other)
case other
when self.class
self.name == other.name
else
false
end
end
def eql?(other)
other.instance_of?(self.class) && self == other
end
end
def simple_fast_dominance_algorithm(node)
return unless node.predecessors.size >= 2
node.predecessors.each do |p|
runner = p
while runner != node.immediate_dominator
runner.dominance_frontiers << node
runner = runner.immediate_dominator
end
end
end
# 1 -----+
# | |
# 2 <--+ |
# 2 | |
# +--- 2 ---+ |
# | | |
# | 3 <----+
# | |
# +--> 4
node1 = Node.new(:node1)
node2 = Node.new(:node2)
node3 = Node.new(:node3)
node4 = Node.new(:node4)
# Connection
node1 >> node2 >> node3 >> node4
node1 >> node3
node2 >> node2
node2 >> node4
# Immediate dominator
node1.immediate_dominator = nil
node2.immediate_dominator = node1
node3.immediate_dominator = node1
node4.immediate_dominator = node1
# Dominance frontiers
[ node1, node2, node3, node4].each do |node|
simple_fast_dominance_algorithm(node)
end
[ node1, node2, node3, node4].each do |node|
simple_fast_dominance_algorithm(node)
printf "%s --> %s\n", node.name, node.dominance_frontiers.map(&:name)
end
# node1 --> []
# node2 --> [:node2, :node3, :node4]
# node3 --> [:node4]
# node4 --> []
@Leedehai
Copy link

Leedehai commented Nov 7, 2018

Hi - is this correct? :) because I might want to use it as my guide to implement in another language.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment