Commit 850d7f80 authored by qinsoon's avatar qinsoon

some refactoring: 1. allows reg alloc using other allocators (other than graph...

some refactoring: 1. allows reg alloc using other allocators (other than graph coloring), 2. allows retreat to a previous compilation pass
parent a5014bc4
use ast::ir::MuID;
use compiler::backend::reg_alloc::liveness::InterferenceGraph;
use compiler::backend::reg_alloc::liveness::{Node, Move};
use compiler::backend::reg_alloc::graph_coloring::liveness::InterferenceGraph;
use compiler::backend::reg_alloc::graph_coloring::liveness::{Node, Move};
use compiler::backend;
use utils::vec_utils;
......
mod liveness;
mod coloring;
pub use compiler::backend::reg_alloc::graph_coloring::liveness::InterferenceGraph;
pub use compiler::backend::reg_alloc::graph_coloring::liveness::build as build_inteference_graph;
pub use compiler::backend::reg_alloc::graph_coloring::coloring::GraphColoring;
\ No newline at end of file
#![allow(dead_code)]
use compiler::CompilerPass;
use compiler::PassExecutionResult;
use compiler;
use ast::ir::*;
use vm::context::VMContext;
use compiler::backend::init_machine_regs_for_func;
mod liveness;
mod coloring;
mod graph_coloring;
pub struct RegisterAllocation {
name: &'static str
......@@ -19,15 +20,9 @@ impl RegisterAllocation {
name: "Register Allcoation"
}
}
}
impl CompilerPass for RegisterAllocation {
fn name(&self) -> &'static str {
self.name
}
#[allow(unused_variables)]
fn visit_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
fn coloring(&mut self, vm_context: &VMContext, func: &mut MuFunction) -> bool {
let compiled_funcs = vm_context.compiled_funcs().read().unwrap();
let mut cf = compiled_funcs.get(func.fn_name).unwrap().borrow_mut();
......@@ -36,14 +31,14 @@ impl CompilerPass for RegisterAllocation {
// initialize machine registers for the function context
init_machine_regs_for_func(&mut func.context);
let liveness = liveness::build(&mut cf, func);
let liveness = graph_coloring::build_inteference_graph(&mut cf, func);
liveness.print();
let coloring = coloring::GraphColoring::start(liveness);
let coloring = graph_coloring::GraphColoring::start(liveness);
let spills = coloring.spills();
if !spills.is_empty() {
unimplemented!();
return false;
}
// replace regs
......@@ -64,5 +59,25 @@ impl CompilerPass for RegisterAllocation {
}
cf.mc.print();
true
}
}
impl CompilerPass for RegisterAllocation {
fn name(&self) -> &'static str {
self.name
}
fn execute(&mut self, vm_context: &VMContext, func: &mut MuFunction) -> PassExecutionResult {
debug!("---CompilerPass {} for {}---", self.name(), func.fn_name);
if self.coloring(vm_context, func) {
debug!("---finish---");
PassExecutionResult::ProceedToNext
} else {
PassExecutionResult::GoBackTo(compiler::PASS4_INST_SEL)
}
}
}
\ No newline at end of file
......@@ -21,8 +21,18 @@ impl Compiler {
}
pub fn compile(&self, func: &mut MuFunction) {
for pass in self.policy.borrow_mut().passes.iter_mut() {
pass.execute(&self.vm, func);
let mut cur_pass = 0;
let n_passes = self.policy.borrow().passes.len();
let ref mut passes = self.policy.borrow_mut().passes;
while cur_pass < n_passes {
let result = passes[cur_pass].execute(&self.vm, func);
match result {
PassExecutionResult::ProceedToNext => cur_pass += 1,
PassExecutionResult::GoBackTo(next) => cur_pass = next
}
}
}
}
......@@ -31,6 +41,13 @@ pub struct CompilerPolicy {
passes: Vec<Box<CompilerPass>>
}
pub const PASS0_DEF_USE : usize = 0;
pub const PASS1_TREE_GEN : usize = 1;
pub const PASS2_CFA : usize = 2;
pub const PASS3_TRACE_GEN : usize = 3;
pub const PASS4_INST_SEL : usize = 4;
pub const PASS5_REG_ALLOC : usize = 5;
impl CompilerPolicy {
pub fn default() -> CompilerPolicy {
let mut passes : Vec<Box<CompilerPass>> = vec![];
......@@ -39,6 +56,7 @@ impl CompilerPolicy {
passes.push(Box::new(passes::ControlFlowAnalysis::new()));
passes.push(Box::new(passes::TraceGen::new()));
passes.push(Box::new(backend::inst_sel::InstructionSelection::new()));
passes.push(Box::new(backend::reg_alloc::RegisterAllocation::new()));
CompilerPolicy{passes: passes}
}
......@@ -48,11 +66,16 @@ impl CompilerPolicy {
}
}
pub enum PassExecutionResult {
ProceedToNext,
GoBackTo(usize)
}
#[allow(unused_variables)]
pub trait CompilerPass {
fn name(&self) -> &'static str;
fn execute(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
fn execute(&mut self, vm_context: &VMContext, func: &mut MuFunction) -> PassExecutionResult {
debug!("---CompilerPass {} for {}---", self.name(), func.fn_name);
self.start_function(vm_context, func);
......@@ -60,6 +83,8 @@ pub trait CompilerPass {
self.finish_function(vm_context, func);
debug!("---finish---");
PassExecutionResult::ProceedToNext
}
fn visit_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
......
......@@ -4,6 +4,7 @@ use ast::ir_semantics::*;
use vm::context::VMContext;
use compiler::CompilerPass;
use compiler::PassExecutionResult;
pub struct TreeGen {
name: &'static str
......@@ -24,7 +25,7 @@ impl CompilerPass for TreeGen {
self.name
}
fn execute(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
fn execute(&mut self, vm_context: &VMContext, func: &mut MuFunction) -> PassExecutionResult {
debug!("---CompilerPass {} for {}---", self.name(), func.fn_name);
{
......@@ -119,6 +120,8 @@ impl CompilerPass for TreeGen {
self.finish_function(vm_context, func);
debug!("---finish---");
PassExecutionResult::ProceedToNext
}
#[allow(unused_variables)]
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment