setting registers in the allocator

unfortunately the reg instances are spread across instructions
this causes problems when setting them
This commit is contained in:
Torsten 2020-03-20 16:15:11 +02:00
parent c890e8402b
commit d2e7c647d0
3 changed files with 44 additions and 7 deletions

View File

@ -39,6 +39,7 @@ module Risc
# and give us the chance to reclaim any unsued machine regs # and give us the chance to reclaim any unsued machine regs
# (via the precalculated release_points) # (via the precalculated release_points)
def release_after(instruction , ssa_name) def release_after(instruction , ssa_name)
#puts "release request for #{ssa_name}"
release = @release_points[instruction] release = @release_points[instruction]
return unless release return unless release
return unless release.include?(ssa_name) return unless release.include?(ssa_name)
@ -51,8 +52,13 @@ module Risc
names = instruction.register_names names = instruction.register_names
#puts "AT #{instruction}" #puts "AT #{instruction}"
names.each do |ssa_name| names.each do |ssa_name|
# BUG: clearly we do NOT do ssa, because some of the instances of
# RegisterValue are the same. This causes the symbols/names to
# have changed through the previous assign. Hence without next line check
# we assign risc regs to risc reg names. Easily avoided, but not clean
next if @reg_names.include?(ssa_name)
new_reg = get_reg(ssa_name) new_reg = get_reg(ssa_name)
# swap name out instruction.set_registers( ssa_name , new_reg)
#puts "Assign #{new_reg} for #{ssa_name}" #puts "Assign #{new_reg} for #{ssa_name}"
end end
names names
@ -69,11 +75,11 @@ module Risc
released = [] released = []
released = walk_and_mark(instruction.next) if instruction.next released = walk_and_mark(instruction.next) if instruction.next
#puts "Walking #{instruction}" #puts "Walking #{instruction}"
instruction.register_names.each do |name| instruction.register_names.each do |ssa_name|
next if released.include?(name) next if released.include?(ssa_name)
@release_points[instruction] << name @release_points[instruction] << ssa_name
#puts "ADDING #{name}" #puts "ADDING #{ssa_name}"
released << name released << ssa_name
end end
released released
end end

View File

@ -21,4 +21,26 @@ module Risc
assert_equal "Integer_Type" , risc(1).register.type.name assert_equal "Integer_Type" , risc(1).register.type.name
end end
end end
# following tests are really Instruction tests, but would require mocking there
class TestInstructionProtocol < MiniTest::Test
def setup
Parfait.boot!({})
@load = Risc.load_data("source" , 1)
end
def test_reg_names
assert_equal 1 , @load.register_names.length
end
def test_reg_get
reg = @load.register_names.first
assert_equal :fix_1 , reg
end
def test_reg_set
@load.set_registers(:fix_1 , :r10)
assert_equal :r10 , @load.get_register(:register)
end
def test_reg_ssa
value = @load.set_registers(:register , :r10)
assert_equal :fix_1 , @load.get_register(:register)
end
end
end end

View File

@ -13,11 +13,20 @@ 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)
assert_equal 10 , live.length assert_equal 10 , live.length
end end
def test_ssa
instruction = @compiler.risc_instructions.next(2)
assert_equal :"message.next_message" , instruction.register.symbol
end
def est_risc
assert_nil @allocator.allocate_regs
instruction = @compiler.risc_instructions.next(2)
assert_equal :"message.next_message" , instruction.register.symbol
end
end end
end end