Commit c04159ca authored by qinsoon's avatar qinsoon

[wip] make compiler passes a linear pipeline

we never go back to previous passes, since it is not necessary
parent 451d4887
......@@ -236,14 +236,8 @@ lazy_static! {
map
};
// put callee saved regs first
// put caller saved regs first (they imposes no overhead if there is no call instruction)
pub static ref ALL_USABLE_MACHINE_REGs : Vec<P<Value>> = vec![
RBX.clone(),
R12.clone(),
R13.clone(),
R14.clone(),
R15.clone(),
RAX.clone(),
RCX.clone(),
RDX.clone(),
......@@ -253,6 +247,13 @@ lazy_static! {
R9.clone(),
R10.clone(),
R11.clone(),
RBX.clone(),
R12.clone(),
R13.clone(),
R14.clone(),
R15.clone(),
XMM0.clone(),
XMM1.clone(),
XMM2.clone(),
......
......@@ -3,7 +3,6 @@ use compiler::backend;
use compiler::backend::reg_alloc::graph_coloring;
use compiler::backend::reg_alloc::graph_coloring::liveness::InterferenceGraph;
use compiler::backend::reg_alloc::graph_coloring::liveness::{Node, Move};
use compiler::backend::reg_alloc::RegAllocFailure;
use compiler::machine_code::CompiledFunction;
use vm::VM;
......@@ -49,13 +48,13 @@ pub struct GraphColoring<'a> {
}
impl <'a> GraphColoring<'a> {
pub fn start (func: &'a mut MuFunctionVersion, cf: &'a mut CompiledFunction, vm: &'a VM) -> Result<GraphColoring<'a>, RegAllocFailure> {
pub fn start (func: &'a mut MuFunctionVersion, cf: &'a mut CompiledFunction, vm: &'a VM) -> GraphColoring<'a> {
trace!("Initializing coloring allocator...");
cf.mc().trace_mc();
let ig = graph_coloring::build_inteference_graph(cf, func);
let mut coloring = GraphColoring {
let coloring = GraphColoring {
func: func,
cf: cf,
vm: vm,
......@@ -109,7 +108,7 @@ impl <'a> GraphColoring<'a> {
format!("Move: {} -> {}", self.display_node(m.from), self.display_node(m.to))
}
fn regalloc(mut self) -> Result<GraphColoring<'a>, RegAllocFailure> {
fn regalloc(mut self) -> GraphColoring<'a> {
trace!("---InterenceGraph---");
self.ig.print(&self.func.context);
......@@ -173,7 +172,7 @@ impl <'a> GraphColoring<'a> {
return GraphColoring::start(self.func, self.cf, self.vm);
}
Ok(self)
self
}
fn build(&mut self) {
......@@ -583,7 +582,7 @@ impl <'a> GraphColoring<'a> {
self.freeze_moves(m);
}
fn assign_colors(&mut self) -> Result<(), ()> {
fn assign_colors(&mut self) {
trace!("---coloring done---");
while !self.select_stack.is_empty() {
let n = self.select_stack.pop().unwrap();
......@@ -624,8 +623,6 @@ impl <'a> GraphColoring<'a> {
trace!("Color {} as {}", self.display_node(n), alias_color);
self.ig.color_node(n, alias_color);
}
Ok(())
}
fn rewrite_program(&mut self) {
......
......@@ -263,14 +263,6 @@ impl InterferenceGraph {
}
}
pub fn is_machine_reg(reg: MuID) -> bool {
if reg < MACHINE_ID_END {
true
} else {
false
}
}
#[allow(unused_variables)]
fn build_live_set(cf: &mut CompiledFunction, func: &MuFunctionVersion) {
let n_insts = cf.mc().number_of_insts();
......
......@@ -8,14 +8,8 @@ pub use compiler::backend::reg_alloc::graph_coloring::coloring::GraphColoring;
use ast::ir::*;
use vm::VM;
use compiler;
use compiler::CompilerPass;
use compiler::PassExecutionResult;
use compiler::backend::init_machine_regs_for_func;
use compiler::backend;
use compiler::backend::reg_alloc::RegAllocFailure;
use std::collections::HashMap;
use std::any::Any;
pub struct RegisterAllocation {
......@@ -30,17 +24,14 @@ impl RegisterAllocation {
}
#[allow(unused_variables)]
fn coloring(&mut self, vm: &VM, func: &mut MuFunctionVersion) -> Result<(), RegAllocFailure> {
fn coloring(&mut self, vm: &VM, func: &mut MuFunctionVersion) {
let compiled_funcs = vm.compiled_funcs().read().unwrap();
let mut cf = compiled_funcs.get(&func.id()).unwrap().write().unwrap();
// initialize machine registers for the function context
init_machine_regs_for_func(&mut func.context);
let coloring = match GraphColoring::start(func, &mut cf, vm) {
Ok(coloring) => coloring,
Err(_) => panic!("error during coloring - unexpected")
};
let coloring = GraphColoring::start(func, &mut cf, vm);
// replace regs
trace!("Replacing Registers...");
......@@ -68,8 +59,6 @@ impl RegisterAllocation {
}
coloring.cf.mc().trace_mc();
Ok(())
}
}
......@@ -82,15 +71,7 @@ impl CompilerPass for RegisterAllocation {
self
}
fn execute(&mut self, vm: &VM, func: &mut MuFunctionVersion) -> PassExecutionResult {
debug!("---CompilerPass {} for {}---", self.name(), func);
match self.coloring(vm, func) {
// skip slow path
Ok(_) => PassExecutionResult::ProceedTo(compiler::PASS_PEEPHOLE),
// go back to instruction selection for spilled operands
Err(RegAllocFailure::FailedForSpilling) => PassExecutionResult::GoBackTo(compiler::PASS_INST_SEL),
}
fn visit_function(&mut self, vm: &VM, func: &mut MuFunctionVersion) {
self.coloring(vm, func);
}
}
pub mod graph_coloring;
pub enum RegAllocFailure {
FailedForSpilling,
}
pub use compiler::backend::reg_alloc::graph_coloring::RegisterAllocation;
\ No newline at end of file
......@@ -12,16 +12,6 @@ pub mod frame;
pub mod machine_code;
pub use compiler::passes::CompilerPass;
pub use compiler::passes::PassExecutionResult;
pub use compiler::passes::PASS_IR_CHECK;
pub use compiler::passes::PASS_DEF_USE;
pub use compiler::passes::PASS_TREE_GEN;
pub use compiler::passes::PASS_CFA;
pub use compiler::passes::PASS_TRACE_GEN;
pub use compiler::passes::PASS_INST_SEL;
pub use compiler::passes::PASS_REG_ALLOC;
pub use compiler::passes::PASS_PEEPHOLE;
pub use compiler::passes::PASS_CODE_EMIT;
pub struct Compiler {
policy: RefCell<CompilerPolicy>,
......@@ -42,20 +32,12 @@ impl Compiler {
// FIXME: should use function name here (however hprof::enter only accept &'static str)
let _p = hprof::enter("Function Compilation");
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 _p = hprof::enter(passes[cur_pass].name());
let result = passes[cur_pass].execute(&self.vm, func);
for pass in passes.iter_mut() {
let _p = hprof::enter(pass.name());
match result {
PassExecutionResult::ProceedToNext => cur_pass += 1,
PassExecutionResult::ProceedTo(next)
| PassExecutionResult::GoBackTo(next) => cur_pass = next.get()
}
pass.execute(&self.vm, func);
drop(_p);
}
......
......@@ -6,32 +6,11 @@ mod tree_gen;
mod control_flow;
mod trace_gen;
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
pub struct PassID(usize);
impl PassID {pub fn get(&self) -> usize{self.0}}
pub use compiler::passes::def_use::DefUse;
pub use compiler::passes::tree_gen::TreeGen;
pub use compiler::passes::control_flow::ControlFlowAnalysis;
pub use compiler::passes::trace_gen::TraceGen;
// make sure the pass IDs are sequential
pub const PASS_IR_CHECK : PassID = PassID(0);
pub const PASS_DEF_USE : PassID = PassID(1);
pub const PASS_TREE_GEN : PassID = PassID(2);
pub const PASS_CFA : PassID = PassID(3);
pub const PASS_TRACE_GEN : PassID = PassID(4);
pub const PASS_INST_SEL : PassID = PassID(5);
pub const PASS_REG_ALLOC : PassID = PassID(6);
pub const PASS_PEEPHOLE : PassID = PassID(7);
pub const PASS_CODE_EMIT : PassID = PassID(8);
pub enum PassExecutionResult {
ProceedToNext,
ProceedTo(PassID),
GoBackTo(PassID)
}
use std::any::Any;
#[allow(unused_variables)]
......@@ -39,7 +18,7 @@ pub trait CompilerPass {
fn name(&self) -> &'static str;
fn as_any(&self) -> &Any;
fn execute(&mut self, vm: &VM, func: &mut MuFunctionVersion) -> PassExecutionResult {
fn execute(&mut self, vm: &VM, func: &mut MuFunctionVersion) {
debug!("---CompilerPass {} for {}---", self.name(), func);
self.start_function(vm, func);
......@@ -47,8 +26,6 @@ pub trait CompilerPass {
self.finish_function(vm, func);
debug!("---finish---");
PassExecutionResult::ProceedToNext
}
fn visit_function(&mut self, vm: &VM, func: &mut MuFunctionVersion) {
......
......@@ -4,7 +4,6 @@ use ast::ir_semantics::*;
use vm::VM;
use compiler::CompilerPass;
use compiler::PassExecutionResult;
use std::any::Any;
......@@ -31,7 +30,7 @@ impl CompilerPass for TreeGen {
self
}
fn execute(&mut self, vm: &VM, func: &mut MuFunctionVersion) -> PassExecutionResult {
fn execute(&mut self, vm: &VM, func: &mut MuFunctionVersion) {
debug!("---CompilerPass {} for {}---", self.name(), func);
{
......@@ -123,8 +122,6 @@ impl CompilerPass for TreeGen {
self.finish_function(vm, 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