To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit b974c3b1 authored by qinsoon's avatar qinsoon
Browse files

refactoring tree (part 1)

parent b9b363ec
use ast::ptr::P; use ast::ptr::P;
use ast::op::{BinOp, CmpOp, AtomicRMWOp}; use ast::op::*;
use ast::types::*; use ast::types::*;
use std::collections::HashMap; use std::collections::HashMap;
...@@ -106,6 +106,7 @@ pub trait OperandIteratable { ...@@ -106,6 +106,7 @@ pub trait OperandIteratable {
#[derive(Clone)] #[derive(Clone)]
/// always use with P<TreeNode> /// always use with P<TreeNode>
pub struct TreeNode { pub struct TreeNode {
// pub op: OpCode,
pub v: TreeNode_ pub v: TreeNode_
} }
...@@ -196,30 +197,15 @@ impl fmt::Debug for Constant { ...@@ -196,30 +197,15 @@ impl fmt::Debug for Constant {
#[derive(Clone)] #[derive(Clone)]
pub enum Instruction { pub enum Instruction {
NonTerm(NonTermInstruction), // non-terminal instruction
Term(Terminal) Assign{
} left: Vec<P<TreeNode>>,
right: Expression_
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 { Fence(MemoryOrder),
fn list_operands(&self) -> Vec<P<TreeNode>> {
match self {
&Instruction::NonTerm(ref inst) => inst.list_operands(),
&Instruction::Term(ref inst) => inst.list_operands()
}
}
}
#[derive(Clone)] // terminal instruction
pub enum Terminal {
Return(Vec<P<TreeNode>>), Return(Vec<P<TreeNode>>),
ThreadExit, // TODO: common inst ThreadExit, // TODO: common inst
Throw(Vec<P<TreeNode>>), Throw(Vec<P<TreeNode>>),
...@@ -260,15 +246,63 @@ pub enum Terminal { ...@@ -260,15 +246,63 @@ pub enum Terminal {
branches: Vec<(P<TreeNode>, Destination)> branches: Vec<(P<TreeNode>, Destination)>
}, },
ExnInstruction{ ExnInstruction{
inner: NonTermInstruction, inner: P<Instruction>,
resume: ResumptionData 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>> { fn list_operands(&self) -> Vec<P<TreeNode>> {
use ast::ir::Terminal::*; use ast::ir::Instruction::*;
match self { match self {
&Assign{ref right, ..} => right.list_operands(),
&Fence(_) => vec![],
&Return(ref vals) => vals.to_vec(), &Return(ref vals) => vals.to_vec(),
&Throw(ref vals) => vals.to_vec(), &Throw(ref vals) => vals.to_vec(),
&TailCall(ref call) => call.list_operands(), &TailCall(ref call) => call.list_operands(),
...@@ -330,76 +364,6 @@ impl OperandIteratable for Terminal { ...@@ -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)] #[derive(Clone)]
pub enum Expression_ { pub enum Expression_ {
BinOp(BinOp, P<TreeNode>, P<TreeNode>), 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)] #[derive(Copy, Clone, Debug)]
pub enum BinOp { pub enum BinOp {
// Int(n) BinOp Int(n) -> Int(n) // Int(n) BinOp Int(n) -> Int(n)
......
...@@ -39,6 +39,7 @@ impl CompilerPolicy { ...@@ -39,6 +39,7 @@ impl CompilerPolicy {
} }
} }
#[allow(unused_variables)]
pub trait CompilerPass { pub trait CompilerPass {
fn name(&self) -> &'static str; fn name(&self) -> &'static str;
......
...@@ -18,6 +18,7 @@ impl CompilerPass for DefUse { ...@@ -18,6 +18,7 @@ impl CompilerPass for DefUse {
self.name self.name
} }
#[allow(unused_variables)]
fn visit_inst(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, node: &mut TreeNode) { fn visit_inst(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, node: &mut TreeNode) {
match node.v { match node.v {
TreeNode_::Instruction(ref inst) => { TreeNode_::Instruction(ref inst) => {
...@@ -26,7 +27,7 @@ impl CompilerPass for DefUse { ...@@ -26,7 +27,7 @@ impl CompilerPass for DefUse {
TreeNode_::Value(ref val) => { TreeNode_::Value(ref val) => {
match val.v { match val.v {
Value_::SSAVar(ref id) => { 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); entry.use_count.set(entry.use_count.get() + 1);
}, },
_ => {} // dont worry about constants _ => {} // dont worry about constants
...@@ -40,6 +41,7 @@ impl CompilerPass for DefUse { ...@@ -40,6 +41,7 @@ impl CompilerPass for DefUse {
} }
} }
#[allow(unused_variables)]
fn finish_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) { fn finish_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
debug!("check use count for variables"); debug!("check use count for variables");
......
use ast::ir::*;
use vm::context::VMContext;
use compiler::CompilerPass; use compiler::CompilerPass;
pub struct TreeGen { pub struct TreeGen {
......
...@@ -52,10 +52,10 @@ pub fn factorial() -> VMContext { ...@@ -52,10 +52,10 @@ pub fn factorial() -> VMContext {
blk_0_n_3.clone(), blk_0_n_3.clone(),
const_def_int64_1_local.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) // 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(), cond: blk_0_v48.clone(),
true_dest: Destination { true_dest: Destination {
target: "blk_2", target: "blk_2",
...@@ -65,7 +65,7 @@ pub fn factorial() -> VMContext { ...@@ -65,7 +65,7 @@ pub fn factorial() -> VMContext {
target: "blk_1", target: "blk_1",
args: vec![DestArg::Normal(blk_0_n_3.clone())] args: vec![DestArg::Normal(blk_0_n_3.clone())]
} }
})); });
let blk_0_content = BlockContent { let blk_0_content = BlockContent {
args: vec![blk_0_n_3.clone()], args: vec![blk_0_n_3.clone()],
...@@ -79,7 +79,7 @@ pub fn factorial() -> VMContext { ...@@ -79,7 +79,7 @@ pub fn factorial() -> VMContext {
let blk_2_v53 = func.new_ssa(2, "blk_2_v53", type_def_int64.clone()); let blk_2_v53 = func.new_ssa(2, "blk_2_v53", type_def_int64.clone());
// RET %v53 // 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 { let blk_2_content = BlockContent {
args: vec![blk_2_v53.clone()], args: vec![blk_2_v53.clone()],
...@@ -99,11 +99,11 @@ pub fn factorial() -> VMContext { ...@@ -99,11 +99,11 @@ pub fn factorial() -> VMContext {
blk_1_n_3.clone(), blk_1_n_3.clone(),
const_def_int64_1_local.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) // %v51 = CALL <@fac_sig> @fac (%v50)
let blk_1_v51 = func.new_ssa(5, "blk_1_v51", type_def_int64.clone()); 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()], left: vec![blk_1_v51.clone()],
right: Expression_::ExprCall { right: Expression_::ExprCall {
data: CallData { data: CallData {
...@@ -113,7 +113,7 @@ pub fn factorial() -> VMContext { ...@@ -113,7 +113,7 @@ pub fn factorial() -> VMContext {
}, },
is_abort: true is_abort: true
} }
})); });
// %v52 = MUL <@int_64> %n_3 %v51 // %v52 = MUL <@int_64> %n_3 %v51
let blk_1_v52 = func.new_ssa(7, "blk_1_v52", type_def_int64.clone()); let blk_1_v52 = func.new_ssa(7, "blk_1_v52", type_def_int64.clone());
...@@ -122,17 +122,17 @@ pub fn factorial() -> VMContext { ...@@ -122,17 +122,17 @@ pub fn factorial() -> VMContext {
blk_1_n_3.clone(), blk_1_n_3.clone(),
blk_1_v51.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()], left: vec![blk_1_v52.clone()],
right: blk_1_v52_expr 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 { Destination {
target: "blk_2", target: "blk_2",
args: vec![DestArg::Normal(blk_1_v52.clone())] args: vec![DestArg::Normal(blk_1_v52.clone())]
} }
))); ));
let blk_1_content = BlockContent { let blk_1_content = BlockContent {
args: vec![blk_1_n_3.clone()], 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