Permalink
Browse files

Remove function/basic block params from the SSA initializers.

  • Loading branch information...
whitequark committed Mar 20, 2013
1 parent 2b904df commit 046b10f30afeed2c364ac5b78b521faeb264b96f
@@ -2,22 +2,30 @@ module Furnace
class SSA::Argument < SSA::NamedValue
attr_reader :type
- def initialize(function, type, name)
- super(function, name)
+ def initialize(type, name)
+ super(name)
+
self.type = type
end
def type=(type)
@type = type.to_type
+
+ instrument { |i| i.set_arguments @function.arguments }
end
def replace_type_with(type, replacement)
- self.type = self.type.replace_type_with(type, replacement)
+ self.type = self.type.
+ replace_type_with(type, replacement)
end
def awesome_print(p=AwesomePrinter.new)
p.nest(@type).
name(name)
end
+
+ def instrument(&block)
+ @function.instrument(&block) if @function
+ end
end
end
@@ -1,7 +1,8 @@
module Furnace
class SSA::BasicBlock < SSA::NamedValue
- def initialize(function, name=nil, insns=[])
- super(function, name)
+ def initialize(insns=[], name=nil)
+ super(name)
+
@instructions = insns.to_a
end
@@ -15,6 +16,14 @@ def to_a
@instructions.dup
end
+ def function=(function)
+ if @function && @function != function
+ @function.remove self
+ end
+
+ super
+ end
+
def include?(instruction)
@instructions.include? instruction
end
@@ -36,12 +45,14 @@ def each(*types, &proc)
alias each_instruction each
def prepend(instruction)
+ instruction.basic_block = self
@instructions.unshift instruction
instrument { |i| i.add instruction }
end
def append(instruction)
+ instruction.basic_block = self
@instructions.push instruction
instrument { |i| i.add instruction }
@@ -58,6 +69,7 @@ def insert(before, instruction)
raise ArgumentError, "Instruction #{before} is not found"
end
+ instruction.basic_block = self
@instructions.insert idx, instruction
instrument { |i| i.add instruction }
@@ -69,9 +81,10 @@ def replace(instruction, replace_with)
end
def remove(instruction)
- @instructions.delete instruction
-
instrument { |i| i.remove instruction }
+
+ @instructions.delete instruction
+ instruction.detach
end
def splice(after)
@@ -14,7 +14,7 @@ def initialize(name, arguments=[], return_type=nil, options={})
@function = SSA::Function.new(name, [], return_type, instrumentation)
@function.arguments = arguments.map do |(type, name)|
- SSA::Argument.new(@function, type, name)
+ SSA::Argument.new(type, name)
end
@block = @function.entry = add_block
@@ -25,7 +25,7 @@ def lookup_insn(opcode)
end
def add_block
- block = SSA::BasicBlock.new(@function)
+ block = SSA::BasicBlock.new
@function.add block
if block_given?
@@ -39,7 +39,7 @@ def add_block
end
def append(instruction, *args)
- insn = lookup_insn(instruction).new(@block, *args)
+ insn = lookup_insn(instruction).new(*args)
@block.append insn
insn
@@ -18,6 +18,8 @@ def add(object)
basic_block: object.basic_block.name,
index: object.basic_block.index(object))
+ update_instruction(object)
+
when SSA::BasicBlock
emit("add_basic_block",
name: object.name)
@@ -35,7 +35,6 @@ def initialize_copy(original)
value_map[value] = new_value
if new_value.is_a? SSA::User
- new_value.function = self
new_value.operands = value.translate_operands(value_map)
end
@@ -81,11 +80,17 @@ def name=(name)
def arguments=(arguments)
@arguments = sanitize_arguments(arguments)
+
+ @arguments.each do |arg|
+ arg.function = self
+ end
+
instrument { |i| i.set_arguments @arguments }
end
def return_type=(return_type)
- @return_type = return_type.to_type if return_type
+ @return_type = return_type.to_type
+
instrument { |i| i.set_return_type @return_type }
end
@@ -127,6 +132,7 @@ def find(name)
end
def add(block)
+ block.function = self
@basic_blocks.add block
instrument { |i| i.add block }
@@ -138,7 +144,7 @@ def remove(block)
instrument { |i| i.remove block }
@basic_blocks.delete block
- block.function = nil
+ block.detach
end
def each_instruction(*types, &proc)
@@ -153,15 +159,14 @@ def replace_type_with(type, replacement)
@arguments.each do |arg|
arg.replace_type_with(type, replacement)
end
- instrument { |i| i.set_arguments @arguments }
each_instruction do |insn|
insn.replace_type_with(type, replacement)
end
self.return_type = return_type.replace_type_with(type, replacement)
- nil
+ self
end
def predecessors_for(name)
@@ -210,7 +215,7 @@ def sanitize_arguments(arguments)
if !argument.is_a?(SSA::Argument)
raise ArgumentError, "function #{@name} arguments: #{argument.inspect} (at #{index}) is not an Argument"
end
- end
+ end.dup.freeze
end
end
end
@@ -2,16 +2,16 @@ module Furnace
class SSA::GenericInstruction < SSA::Instruction
attr_reader :type
- def initialize(basic_block, type=nil, uses=[], name=basic_block.function.make_name)
- @type = type.to_type
+ def initialize(type, operands=[], name=nil)
+ super(operands, name)
- super(basic_block, uses, name)
+ self.type = type
end
def type=(type)
- @type = type.to_type
+ @type = type.to_type
- instrument_update
+ instrument { |i| i.update_instruction(self) }
end
def replace_type_with(type, replacement)
@@ -8,11 +8,10 @@ def self.syntax(&block)
SSA::InstructionSyntax.new(self).evaluate(&block)
end
- attr_accessor :basic_block
+ attr_reader :basic_block
- def initialize(basic_block, operands=[], name=nil)
- super(basic_block.function, operands, name)
- @basic_block = basic_block
+ def initialize(operands=[], name=nil)
+ super(operands, name)
end
def initialize_copy(original)
@@ -21,27 +20,52 @@ def initialize_copy(original)
@operands = nil
end
+ def opcode
+ self.class.opcode
+ end
+
def name=(name)
old_name = @name
+
super
- @function.instrument { |i| i.rename(self, old_name) }
+
+ instrument { |i| i.rename(self, old_name) }
+
+ name
end
- def opcode
- self.class.opcode
+ def basic_block=(basic_block)
+ if @basic_block && @basic_block != basic_block
+ @basic_block.remove self
+ end
+
+ if basic_block
+ self.function = basic_block.function
+ end
+
+ @basic_block = basic_block
+ end
+
+ def detach
+ @basic_block = nil
+
+ super
end
def remove
- @basic_block.remove self
- detach
+ @basic_block.remove self if @basic_block
+ end
+
+ def erase
+ remove
+ drop_references
end
def replace_with(value)
replace_all_uses_with value
if value.is_a? SSA::Instruction
@basic_block.replace self, value
- detach
else
remove
end
@@ -82,6 +106,7 @@ def inspect_as_value(p=AwesomePrinter.new)
end
def pretty_parameters(p=AwesomePrinter.new)
+ p
end
def pretty_operands(p=AwesomePrinter.new)
@@ -94,10 +119,10 @@ def pretty_operands(p=AwesomePrinter.new)
end
end
- protected
-
- def instrument_update
- @function.instrument { |i| i.update_instruction(self) }
+ def instrument(&block)
+ @function.instrument(&block) if @function
end
+
+ protected :function=
end
end
@@ -2,7 +2,7 @@ module Furnace
class SSA::InstructionSyntax
def initialize(klass)
@klass = klass
- @operands = {}
+ @operands = []
@splat = nil
end
@@ -12,11 +12,10 @@ def evaluate
codegen
end
- def operand(name, type=Type::Top.new)
+ def operand(name)
check_for_splat
- type = type.to_type unless type.nil?
- @operands[name.to_sym] = type
+ @operands << name.to_sym
end
def splat(name)
@@ -37,7 +36,7 @@ def codegen
operands, splat = @operands, @splat
@klass.class_eval do
- operands.each_with_index do |(operand, type), index|
+ operands.each_with_index do |operand, index|
define_method(operand) do
@operands[index]
end
@@ -85,24 +84,8 @@ def codegen
@operands = values
end
- verify!
-
values
end
-
- define_method(:verify!) do
- return if @operands.nil?
-
- operands.each_with_index do |(operand, type), index|
- value = send operand
-
- if !value.type.subtype_of?(type)
- raise TypeError, "Wrong type for operand ##{index + 1} `#{operand}' of #{self.class}: #{type} is expected, #{value.type} is present"
- end
- end
-
- nil
- end
end
end
end
@@ -1,11 +1,11 @@
module Furnace
class SSA::BranchInsn < SSA::TerminatorInstruction
syntax do |s|
- s.operand :target, SSA::BasicBlock
+ s.operand :target
end
def exits?
false
end
end
-end
+end
Oops, something went wrong.

0 comments on commit 046b10f

Please sign in to comment.