GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

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