basic liveliness for allocator
This commit is contained in:
parent
d0b734c57c
commit
4f290ee246
@ -13,6 +13,7 @@ module Risc
|
||||
@compiler = compiler
|
||||
@platform = platform
|
||||
@used_regs = {}
|
||||
@release_points = Hash.new( [] )
|
||||
@reg_names = (0 ... platform.num_registers).collect{|i| "r#{i-1}".to_sym }
|
||||
end
|
||||
attr_reader :used_regs , :compiler , :platform , :reg_names
|
||||
@ -23,7 +24,29 @@ module Risc
|
||||
# Ie on arm register names are r0 .. . r15 , so it keeps a list of unused
|
||||
# regs and frees regs according to live ranges
|
||||
def allocate_regs
|
||||
determine_liveness
|
||||
end
|
||||
|
||||
# determines when registers can be freed
|
||||
#
|
||||
# this is done by walking the instructions backwards and saving the first
|
||||
# occurence of a register name. (The last, as we walk backwards)
|
||||
def determine_liveness
|
||||
walk_and_mark(@compiler.risc_instructions)
|
||||
end
|
||||
|
||||
# First walk down, and on the way up mark register occurences, unless they
|
||||
# have been marked already
|
||||
def walk_and_mark(instruction)
|
||||
released = []
|
||||
released = walk_and_mark(instruction.next) if instruction.next
|
||||
#puts instruction.class.name
|
||||
instruction.register_names.each do |name|
|
||||
next if released.include?(name)
|
||||
@release_points[instruction] << name
|
||||
released << name
|
||||
end
|
||||
released
|
||||
end
|
||||
|
||||
def used_regs_empty?
|
||||
|
@ -26,6 +26,13 @@ module Risc
|
||||
def test_platform
|
||||
assert_equal Arm::ArmPlatform , @allocator.platform.class
|
||||
end
|
||||
def test_allocate_runs
|
||||
assert @allocator.allocate_regs
|
||||
end
|
||||
def test_live
|
||||
live = @allocator.determine_liveness
|
||||
assert_equal 0 , live.length
|
||||
end
|
||||
def test_add_ok
|
||||
assert_equal RegisterValue, @allocator.use_reg(tmp_reg).class
|
||||
end
|
||||
|
22
test/risc/test_standard_allocator1.rb
Normal file
22
test/risc/test_standard_allocator1.rb
Normal file
@ -0,0 +1,22 @@
|
||||
require_relative "../helper"
|
||||
|
||||
module Risc
|
||||
class TestStandardAllocator1 < MiniTest::Test
|
||||
include SlotMachineCompile
|
||||
def setup
|
||||
coll = compile_slot( "class Space ; def main(); main{return 'Ho'};return 'Hi'; end; end;")
|
||||
@compiler = coll.to_risc.method_compilers
|
||||
@allocator = Platform.for(:arm).allocator(@compiler)
|
||||
end
|
||||
def test_main
|
||||
assert_equal :main , @compiler.callable.name
|
||||
end
|
||||
def test_allocate_runs
|
||||
assert @allocator.allocate_regs
|
||||
end
|
||||
def test_live_length
|
||||
live = @allocator.determine_liveness
|
||||
assert_equal 10 , live.length
|
||||
end
|
||||
end
|
||||
end
|
@ -4,7 +4,7 @@ module ScopeHelper
|
||||
|
||||
def compiler_with_main(options = {})
|
||||
compiler = RubyX::RubyXCompiler.new(RubyX.default_test_options.merge(options))
|
||||
compiler.ruby_to_sol( in_Space( as_main("return")) )
|
||||
compiler.ruby_to_sol( as_main("return 5") )
|
||||
compiler
|
||||
end
|
||||
def in_Test(statements)
|
||||
|
Loading…
Reference in New Issue
Block a user