Fix non ssa issue

register instances were being shared across instructions
causing the setting to have side-effects
Fixed this by copying the register on write
(fixing the symptom rather than the cause, i'll make an issue)
This commit is contained in:
Torsten 2020-03-20 18:33:37 +02:00
parent d2e7c647d0
commit 06ade75593
5 changed files with 19 additions and 23 deletions

View File

@ -60,12 +60,13 @@ module Risc
# set all registers that has the name "name" # set all registers that has the name "name"
# going through the register_names and setting all where the # going through the register_names and setting all where the
# get_register would return name # get_register would return name
# Set to the value given as second arg. # Create new RegisterValue with new name and swap the variable out
def set_registers(name , value) def set_registers(name , value)
register_attributes.each do |attr| register_attributes.each do |attr|
reg = instance_variable_get("@#{attr}".to_sym) reg = instance_variable_get("@#{attr}".to_sym)
next unless reg.symbol == name next unless reg.symbol == name
reg.set_name(value) new_reg = reg.dup(value)
instance_variable_set("@#{attr}".to_sym , new_reg)
end end
end end

View File

@ -23,13 +23,14 @@ module Risc
# A third value may give extra information. This is a hash, where keys may # A third value may give extra information. This is a hash, where keys may
# be :value, or :value_XX or :type_XX to indicate value or type information # be :value, or :value_XX or :type_XX to indicate value or type information
# for an XX instance # for an XX instance
def initialize( reg , type , extra = {}) def initialize( reg , type , extra = {} , ssa = nil)
extra = {} unless extra extra = {} unless extra
@extra = extra
@symbol = reg
raise "not Symbol #{symbol}:#{symbol.class}" unless symbol.is_a?(Symbol)
raise "Not Hash #{extra}" unless extra.is_a?(Hash) raise "Not Hash #{extra}" unless extra.is_a?(Hash)
@extra = extra
raise "not Symbol #{reg}:#{reg.class}" unless reg.is_a?(Symbol)
@symbol = reg
known_type(type) known_type(type)
@ssa = ssa
end end
def class_name def class_name
@ -37,17 +38,13 @@ module Risc
@type.class_name @type.class_name
end end
# During initial creation ssa-like names are given to the registers. # make a copy with a new register name (given arg)
# Later the name is changed, with set_name. When that happens # the copy will have the ssa set to the old name
# the original is retained as ssa attttribute for debugging. def dup( reg )
def set_name( symbol ) RegisterValue.new(reg , @type , @extra , @symbol)
raise "not Symbol #{symbol}:#{symbol.class}" unless symbol.is_a?(Symbol)
old = @symbol
@ssa = @symbol
@symbol = symbol
old
end end
# allows to set the compiler, which is mainly done by the compiler # allows to set the compiler, which is mainly done by the compiler
# but sometimes, eg in exit, one nneds to create the reg by hand and set # but sometimes, eg in exit, one nneds to create the reg by hand and set
# return the RegisterValue for chaining in assignment # return the RegisterValue for chaining in assignment

View File

@ -24,6 +24,11 @@ module Risc
def test_r0 def test_r0
assert_equal :message , @r0.symbol assert_equal :message , @r0.symbol
end end
def test_dup
copy = @r0.dup( :r0 )
assert_equal :r0 , copy.symbol
assert_equal :message , copy.ssa
end
def test_load_label def test_load_label
label = Risc::Label.new("HI","ho" , FakeAddress.new(0)) label = Risc::Label.new("HI","ho" , FakeAddress.new(0))
move = @r1 << label move = @r1 << label

View File

@ -53,12 +53,5 @@ module Risc
def test_has_ssa def test_has_ssa
assert_nil @r0.ssa assert_nil @r0.ssa
end end
def test_set_name
assert_equal :message , @r0.set_name(:r0)
end
def test_set_ssa
@r0.set_name(:r0)
assert_equal :message , @r0.ssa
end
end end
end end

View File

@ -13,7 +13,7 @@ module Risc
end end
def test_allocate_runs def test_allocate_runs
assert_nil @allocator.allocate_regs assert_nil @allocator.allocate_regs
#assert_equal 0 , @allocator.used_regs.length assert_equal 0 , @allocator.used_regs.length
end end
def test_live_length def test_live_length
live = @allocator.walk_and_mark(@compiler.risc_instructions) live = @allocator.walk_and_mark(@compiler.risc_instructions)