Commit b974c3b1 authored by qinsoon's avatar qinsoon

refactoring tree (part 1)

parent b9b363ec
use ast::ptr::P;
use ast::op::{BinOp, CmpOp, AtomicRMWOp};
use ast::op::*;
use ast::types::*;
use std::collections::HashMap;
......@@ -106,6 +106,7 @@ pub trait OperandIteratable {
#[derive(Clone)]
/// always use with P<TreeNode>
pub struct TreeNode {
// pub op: OpCode,
pub v: TreeNode_
}
......@@ -196,30 +197,15 @@ impl fmt::Debug for Constant {
#[derive(Clone)]
pub enum Instruction {
NonTerm(NonTermInstruction),
Term(Terminal)
}
impl fmt::Debug for Instruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Instruction::NonTerm(ref inst) => write!(f, "{:?}", inst),
&Instruction::Term(ref inst) => write!(f, "{:?}", inst)
}
}
}
impl OperandIteratable for Instruction {
fn list_operands(&self) -> Vec<P<TreeNode>> {
match self {
&Instruction::NonTerm(ref inst) => inst.list_operands(),
&Instruction::Term(ref inst) => inst.list_operands()
}
}
}
// non-terminal instruction
Assign{
left: Vec<P<TreeNode>>,
right: Expression_
},
#[derive(Clone)]
pub enum Terminal {
Fence(MemoryOrder),
// terminal instruction
Return(Vec<P<TreeNode>>),
ThreadExit, // TODO: common inst
Throw(Vec<P<TreeNode>>),
......@@ -260,15 +246,63 @@ pub enum Terminal {
branches: Vec<(P<TreeNode>, Destination)>
},
ExnInstruction{
inner: NonTermInstruction,
inner: P<Instruction>,
resume: ResumptionData
}
}
impl OperandIteratable for Terminal {
impl fmt::Debug for Instruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Instruction::Assign{ref left, ref right} => {
write!(f, "{:?} = {:?}", left, right)
},
&Instruction::Fence(order) => {
write!(f, "FENCE {:?}", order)
}
&Instruction::Return(ref vals) => write!(f, "RET {:?}", vals),
&Instruction::ThreadExit => write!(f, "THREADEXIT"),
&Instruction::Throw(ref vals) => write!(f, "THROW {:?}", vals),
&Instruction::TailCall(ref call) => write!(f, "TAILCALL {:?}", call),
&Instruction::Branch1(ref dest) => write!(f, "BRANCH {:?}", dest),
&Instruction::Branch2{ref cond, ref true_dest, ref false_dest} => {
write!(f, "BRANCH2 {:?} {:?} {:?}", cond, true_dest, false_dest)
},
&Instruction::Watchpoint{id, ref disable_dest, ref resume} => {
match id {
Some(id) => {
write!(f, "WATCHPOINT {:?} {:?} {:?}", id, disable_dest.as_ref().unwrap(), resume)
},
None => {
write!(f, "TRAP {:?}", resume)
}
}
},
&Instruction::WPBranch{wp, ref disable_dest, ref enable_dest} => {
write!(f, "WPBRANCH {:?} {:?} {:?}", wp, disable_dest, enable_dest)
},
&Instruction::Call{ref data, ref resume} => write!(f, "CALL {:?} {:?}", data, resume),
&Instruction::SwapStack{ref stack, is_exception, ref args, ref resume} => {
write!(f, "SWAPSTACK {:?} {:?} {:?} {:?}", stack, is_exception, args, resume)
},
&Instruction::Switch{ref cond, ref default, ref branches} => {
write!(f, "SWITCH {:?} {:?} {{{:?}}}", cond, default, branches)
},
&Instruction::ExnInstruction{ref inner, ref resume} => {
write!(f, "{:?} {:?}", inner, resume)
}
}
}
}
impl OperandIteratable for Instruction {
fn list_operands(&self) -> Vec<P<TreeNode>> {
use ast::ir::Terminal::*;
use ast::ir::Instruction::*;
match self {
&Assign{ref right, ..} => right.list_operands(),
&Fence(_) => vec![],
&Return(ref vals) => vals.to_vec(),
&Throw(ref vals) => vals.to_vec(),
&TailCall(ref call) => call.list_operands(),
......@@ -330,76 +364,6 @@ impl OperandIteratable for Terminal {
}
}
impl fmt::Debug for Terminal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Terminal::Return(ref vals) => write!(f, "RET {:?}", vals),
&Terminal::ThreadExit => write!(f, "THREADEXIT"),
&Terminal::Throw(ref vals) => write!(f, "THROW {:?}", vals),
&Terminal::TailCall(ref call) => write!(f, "TAILCALL {:?}", call),
&Terminal::Branch1(ref dest) => write!(f, "BRANCH {:?}", dest),
&Terminal::Branch2{ref cond, ref true_dest, ref false_dest} => {
write!(f, "BRANCH2 {:?} {:?} {:?}", cond, true_dest, false_dest)
},
&Terminal::Watchpoint{id, ref disable_dest, ref resume} => {
match id {
Some(id) => {
write!(f, "WATCHPOINT {:?} {:?} {:?}", id, disable_dest.as_ref().unwrap(), resume)
},
None => {
write!(f, "TRAP {:?}", resume)
}
}
},
&Terminal::WPBranch{wp, ref disable_dest, ref enable_dest} => {
write!(f, "WPBRANCH {:?} {:?} {:?}", wp, disable_dest, enable_dest)
},
&Terminal::Call{ref data, ref resume} => write!(f, "CALL {:?} {:?}", data, resume),
&Terminal::SwapStack{ref stack, is_exception, ref args, ref resume} => {
write!(f, "SWAPSTACK {:?} {:?} {:?} {:?}", stack, is_exception, args, resume)
},
&Terminal::Switch{ref cond, ref default, ref branches} => {
write!(f, "SWITCH {:?} {:?} {{{:?}}}", cond, default, branches)
},
&Terminal::ExnInstruction{ref inner, ref resume} => {
write!(f, "{:?} {:?}", inner, resume)
}
}
}
}
#[derive(Clone)]
pub enum NonTermInstruction {
Assign{
left: Vec<P<TreeNode>>,
right: Expression_
},
Fence(MemoryOrder),
}
impl fmt::Debug for NonTermInstruction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&NonTermInstruction::Assign{ref left, ref right} => {
write!(f, "{:?} = {:?}", left, right)
},
&NonTermInstruction::Fence(order) => {
write!(f, "FENCE {:?}", order)
}
}
}
}
impl OperandIteratable for NonTermInstruction {
fn list_operands(&self) -> Vec<P<TreeNode>> {
match self {
&NonTermInstruction::Assign{ref right, ..} => right.list_operands(),
&NonTermInstruction::Fence(_) => vec![]
}
}
}
#[derive(Clone)]
pub enum Expression_ {
BinOp(BinOp, P<TreeNode>, P<TreeNode>),
......
#[derive(Copy, Clone, Debug)]
pub enum OpCode {
// SSA
RegI64,
RegFP,
// Constant
IntImmI64,
FPImm,
// non-terminal
Assign,
Fence,
//terminal
Return,
ThreadExit,
Throw,
TailCall,
Branch1,
Branch2,
Watchpoint,
WPBranch,
Call,
SwapStack,
Switch,
ExnInstruction,
// expression
BinOp,
CmpOp,
ExprCall,
Load,
Store,
CmpXchg,
AtomicRMWOp,
New,
AllocA,
NewHybrid,
AllocAHybrid,
NewStack,
NewThread,
NewThreadExn,
NewFrameCursor,
GetIRef,
GetFieldIRef,
GetElementIRef,
ShiftIRef,
GetVarPartIRef
}
#[derive(Copy, Clone, Debug)]
pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n)
......
......@@ -39,6 +39,7 @@ impl CompilerPolicy {
}
}
#[allow(unused_variables)]
pub trait CompilerPass {
fn name(&self) -> &'static str;
......
......@@ -18,6 +18,7 @@ impl CompilerPass for DefUse {
self.name
}
#[allow(unused_variables)]
fn visit_inst(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, node: &mut TreeNode) {
match node.v {
TreeNode_::Instruction(ref inst) => {
......@@ -26,7 +27,7 @@ impl CompilerPass for DefUse {
TreeNode_::Value(ref val) => {
match val.v {
Value_::SSAVar(ref id) => {
let mut entry = func_context.values.get_mut(id).unwrap();
let entry = func_context.values.get_mut(id).unwrap();
entry.use_count.set(entry.use_count.get() + 1);
},
_ => {} // dont worry about constants
......@@ -40,6 +41,7 @@ impl CompilerPass for DefUse {
}
}
#[allow(unused_variables)]
fn finish_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
debug!("check use count for variables");
......
use ast::ir::*;
use vm::context::VMContext;
use compiler::CompilerPass;
pub struct TreeGen {
......
......@@ -52,10 +52,10 @@ pub fn factorial() -> VMContext {
blk_0_n_3.clone(),
const_def_int64_1_local.clone()
);
let blk_0_inst0 = TreeNode::new_inst(Instruction::NonTerm(NonTermInstruction::Assign{left: vec![blk_0_v48.clone()], right: blk_0_v48_expr}));
let blk_0_inst0 = TreeNode::new_inst(Instruction::Assign{left: vec![blk_0_v48.clone()], right: blk_0_v48_expr});
// BRANCH2 %v48 %blk_2(@int_64_1) %blk_1(%n_3)
let blk_0_term = TreeNode::new_inst(Instruction::Term(Terminal::Branch2{
let blk_0_term = TreeNode::new_inst(Instruction::Branch2{
cond: blk_0_v48.clone(),
true_dest: Destination {
target: "blk_2",
......@@ -65,7 +65,7 @@ pub fn factorial() -> VMContext {
target: "blk_1",
args: vec![DestArg::Normal(blk_0_n_3.clone())]
}
}));
});
let blk_0_content = BlockContent {
args: vec![blk_0_n_3.clone()],
......@@ -79,7 +79,7 @@ pub fn factorial() -> VMContext {
let blk_2_v53 = func.new_ssa(2, "blk_2_v53", type_def_int64.clone());
// RET %v53
let blk_2_term = TreeNode::new_inst(Instruction::Term(Terminal::Return(vec![blk_2_v53.clone()])));
let blk_2_term = TreeNode::new_inst(Instruction::Return(vec![blk_2_v53.clone()]));
let blk_2_content = BlockContent {
args: vec![blk_2_v53.clone()],
......@@ -99,11 +99,11 @@ pub fn factorial() -> VMContext {
blk_1_n_3.clone(),
const_def_int64_1_local.clone()
);
let blk_1_inst0 = TreeNode::new_inst(Instruction::NonTerm(NonTermInstruction::Assign{left: vec![blk_1_v50.clone()], right: blk_1_v50_expr}));
let blk_1_inst0 = TreeNode::new_inst(Instruction::Assign{left: vec![blk_1_v50.clone()], right: blk_1_v50_expr});
// %v51 = CALL <@fac_sig> @fac (%v50)
let blk_1_v51 = func.new_ssa(5, "blk_1_v51", type_def_int64.clone());
let blk_1_inst1 = TreeNode::new_inst(Instruction::NonTerm(NonTermInstruction::Assign{
let blk_1_inst1 = TreeNode::new_inst(Instruction::Assign{
left: vec![blk_1_v51.clone()],
right: Expression_::ExprCall {
data: CallData {
......@@ -113,7 +113,7 @@ pub fn factorial() -> VMContext {
},
is_abort: true
}
}));
});
// %v52 = MUL <@int_64> %n_3 %v51
let blk_1_v52 = func.new_ssa(7, "blk_1_v52", type_def_int64.clone());
......@@ -122,17 +122,17 @@ pub fn factorial() -> VMContext {
blk_1_n_3.clone(),
blk_1_v51.clone()
);
let blk_1_inst2 = TreeNode::new_inst(Instruction::NonTerm(NonTermInstruction::Assign{
let blk_1_inst2 = TreeNode::new_inst(Instruction::Assign{
left: vec![blk_1_v52.clone()],
right: blk_1_v52_expr
}));
});
let blk_1_term = TreeNode::new_inst(Instruction::Term(Terminal::Branch1 (
let blk_1_term = TreeNode::new_inst(Instruction::Branch1 (
Destination {
target: "blk_2",
args: vec![DestArg::Normal(blk_1_v52.clone())]
}
)));
));
let blk_1_content = BlockContent {
args: vec![blk_1_n_3.clone()],
......
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