Commit 55466779 authored by qinsoon's avatar qinsoon

refactoring and added time profiling

parent 250d61a8
......@@ -10,3 +10,4 @@ log = "0.3.5"
simple_logger = "0.4.0"
nalgebra = "0.8.2"
linked-hash-map = "0.0.10"
hprof = "0.1.3"
......@@ -2,7 +2,7 @@ use ast::ir::*;
use ast::ptr::*;
use ast::types::*;
use ast::op::*;
use common::vector_as_str;
use utils::vec_utils::as_str as vector_as_str;
use std::fmt;
use std::cell::RefCell;
......
......@@ -2,7 +2,7 @@ use ast::ptr::P;
use ast::types::*;
use ast::inst::*;
use ast::op::*;
use common::vector_as_str;
use utils::vec_utils::as_str as vector_as_str;
use std::collections::HashMap;
use std::fmt;
......
use ast::ptr::P;
use ast::ir::*;
use common::vector_as_str;
use utils::vec_utils::as_str as vector_as_str;
use std::fmt;
use std::collections::HashMap;
......
use std::fmt;
macro_rules! select_value {
($cond: expr, $res1 : expr, $res2 : expr) => {
if $cond {
$res1
} else {
$res2
}
}
}
pub fn vector_as_str<T: fmt::Display>(vec: &Vec<T>) -> String {
let mut ret = String::new();
for i in 0..vec.len() {
ret.push_str(format!("{}", vec[i]).as_str());
if i != vec.len() - 1 {
ret.push_str(", ");
}
}
ret
}
\ No newline at end of file
#![allow(dead_code)]
use compiler::CompilerPass;
use compiler::PassExecutionResult;
use compiler;
use ast::ir::*;
use vm::context::VMContext;
......@@ -29,7 +27,7 @@ impl CompilerPass for CodeEmission {
use std::fs;
let compiled_funcs = vm_context.compiled_funcs().read().unwrap();
let mut cf = compiled_funcs.get(func.fn_name).unwrap().borrow();
let cf = compiled_funcs.get(func.fn_name).unwrap().borrow();
let code = cf.mc.emit();
......@@ -40,7 +38,7 @@ impl CompilerPass for CodeEmission {
// Err(_) => {}
// }
match fs::create_dir(EMIT_DIR) {
Ok(dir) => {},
Ok(_) => {},
Err(_) => {}
}
......
extern crate hprof;
use ast::ir::*;
use vm::context::VMContext;
......@@ -7,6 +9,16 @@ use std::sync::Arc;
pub mod passes;
pub mod backend;
pub use compiler::passes::CompilerPass;
pub use compiler::passes::PassExecutionResult;
pub use compiler::passes::PASS0_DEF_USE;
pub use compiler::passes::PASS1_TREE_GEN;
pub use compiler::passes::PASS2_CFA;
pub use compiler::passes::PASS3_TRACE_GEN;
pub use compiler::passes::PASS4_INST_SEL;
pub use compiler::passes::PASS5_REG_ALLOC;
pub use compiler::passes::PASS6_CODE_EMIT;
pub struct Compiler {
policy: RefCell<CompilerPolicy>,
vm: Arc<VMContext>
......@@ -21,19 +33,27 @@ impl Compiler {
}
pub fn compile(&self, func: &mut MuFunction) {
let _p = hprof::enter(func.fn_name);
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);
match result {
PassExecutionResult::ProceedToNext => cur_pass += 1,
PassExecutionResult::GoBackTo(next) => cur_pass = next
}
drop(_p);
}
drop(_p);
hprof::profiler().print_timing();
}
}
......@@ -41,13 +61,6 @@ 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![];
......@@ -65,51 +78,3 @@ impl CompilerPolicy {
CompilerPolicy{passes: passes}
}
}
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) -> PassExecutionResult {
debug!("---CompilerPass {} for {}---", self.name(), func.fn_name);
self.start_function(vm_context, func);
self.visit_function(vm_context, func);
self.finish_function(vm_context, func);
debug!("---finish---");
PassExecutionResult::ProceedToNext
}
fn visit_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
for (label, ref mut block) in func.content.as_mut().unwrap().blocks.iter_mut() {
debug!("block: {}", label);
self.start_block(vm_context, &mut func.context, block);
self.visit_block(vm_context, &mut func.context, block);
self.finish_block(vm_context, &mut func.context, block);
}
}
fn visit_block(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, block: &mut Block) {
for inst in block.content.as_mut().unwrap().body.iter_mut() {
debug!("{}", inst);
self.visit_inst(vm_context, func_context, inst);
}
}
fn start_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {}
fn finish_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {}
fn start_block(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, block: &mut Block) {}
fn finish_block(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, block: &mut Block) {}
fn visit_inst(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, node: &mut TreeNode) {}
}
use ast::ir::*;
use ast::inst::Instruction_::*;
use common::vector_as_str;
use utils::vec_utils::as_str as vector_as_str;
use vm::context::VMContext;
use compiler::CompilerPass;
......
use ast::ir::*;
use vm::context::VMContext;
mod def_use;
mod tree_gen;
mod control_flow;
......@@ -7,3 +10,59 @@ 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;
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;
pub const PASS6_CODE_EMIT : usize = 6;
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) -> PassExecutionResult {
debug!("---CompilerPass {} for {}---", self.name(), func.fn_name);
self.start_function(vm_context, func);
self.visit_function(vm_context, func);
self.finish_function(vm_context, func);
debug!("---finish---");
PassExecutionResult::ProceedToNext
}
fn visit_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
for (label, ref mut block) in func.content.as_mut().unwrap().blocks.iter_mut() {
debug!("block: {}", label);
self.start_block(vm_context, &mut func.context, block);
self.visit_block(vm_context, &mut func.context, block);
self.finish_block(vm_context, &mut func.context, block);
}
}
fn visit_block(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, block: &mut Block) {
for inst in block.content.as_mut().unwrap().body.iter_mut() {
debug!("{}", inst);
self.visit_inst(vm_context, func_context, inst);
}
}
fn start_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {}
fn finish_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {}
fn start_block(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, block: &mut Block) {}
fn finish_block(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, block: &mut Block) {}
fn visit_inst(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, node: &mut TreeNode) {}
}
......@@ -4,14 +4,7 @@ extern crate lazy_static;
extern crate log;
#[macro_use]
mod common;
mod utils;
pub mod ast;
pub mod vm;
pub mod compiler;
mod utils;
#[allow(dead_code)]
fn main() {
println!("Hello, world!");
}
......@@ -4,10 +4,33 @@ mod linked_hashset;
pub use utils::linked_hashset::LinkedHashSet;
pub use utils::linked_hashset::LinkedHashMap;
macro_rules! select_value {
($cond: expr, $res1 : expr, $res2 : expr) => {
if $cond {
$res1
} else {
$res2
}
}
}
// This porvides some missing operations on Vec.
// They are not included in the standard libarary.
// (because they are likely inefficient?)
pub mod vec_utils {
use std::fmt;
pub fn as_str<T: fmt::Display>(vec: &Vec<T>) -> String {
let mut ret = String::new();
for i in 0..vec.len() {
ret.push_str(format!("{}", vec[i]).as_str());
if i != vec.len() - 1 {
ret.push_str(", ");
}
}
ret
}
pub fn add_all<T: Copy + PartialEq> (vec: &mut Vec<T>, vec2: &Vec<T>) -> bool {
let mut is_changed = false;
......
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