Commit baa25cdf authored by qinsoon's avatar qinsoon

allowing list operands of instructions. Defuse doesnt work. P<T>.clone() is...

allowing list operands of instructions. Defuse doesnt work. P<T>.clone() is creating new copies of old objects, thus updating cloned objs wont affect the original ones.
parent 495c8587
......@@ -37,6 +37,10 @@ pub struct BlockContent {
pub keepalives: Option<Vec<P<TreeNode>>>
}
pub trait OperandIteratable {
fn list_operands(&self) -> Vec<P<TreeNode>>;
}
#[derive(Clone)]
/// always use with P<TreeNode>
pub struct TreeNode {
......@@ -86,7 +90,7 @@ impl fmt::Debug for TreeNode {
TreeNode_::Value(ref pv) => {
match pv.v {
Value_::SSAVar => {
write!(f, "{:?} %{}#{}", pv.ty, self.tag, self.id)
write!(f, "{:?} %{}#{} (use: {})", pv.ty, self.tag, self.id, self.use_count.get())
},
Value_::Constant(ref c) => {
write!(f, "{:?} {:?}", pv.ty, c)
......@@ -159,6 +163,15 @@ impl fmt::Debug for Instruction {
}
}
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()
}
}
}
#[derive(Clone)]
pub enum Terminal {
Return(Vec<P<TreeNode>>),
......@@ -206,6 +219,71 @@ pub enum Terminal {
}
}
impl OperandIteratable for Terminal {
fn list_operands(&self) -> Vec<P<TreeNode>> {
use ast::ir::Terminal::*;
match self {
&Return(ref vals) => vals.to_vec(),
&Throw(ref vals) => vals.to_vec(),
&TailCall(ref call) => call.list_operands(),
&Branch1(ref dest) => dest.list_operands(),
&Branch2{ref cond, ref true_dest, ref false_dest} => {
let mut ret = vec![];
ret.push(cond.clone());
ret.append(&mut true_dest.list_operands());
ret.append(&mut false_dest.list_operands());
ret
},
&Watchpoint{ref disable_dest, ref resume, ..} => {
let mut ret = vec![];
if disable_dest.is_some() {
ret.append(&mut disable_dest.as_ref().unwrap().list_operands())
}
ret.append(&mut resume.list_operands());
ret
},
&WPBranch{ref disable_dest, ref enable_dest, ..} => {
let mut ret = vec![];
ret.append(&mut disable_dest.list_operands());
ret.append(&mut enable_dest.list_operands());
ret
},
&Call{ref data, ref resume} => {
let mut ret = vec![];
ret.append(&mut data.list_operands());
ret.append(&mut resume.list_operands());
ret
},
&SwapStack{ref stack, ref args, ref resume, ..} => {
let mut ret = vec![];
ret.push(stack.clone());
ret.append(&mut args.to_vec());
ret.append(&mut resume.list_operands());
ret
},
&Switch{ref cond, ref default, ref branches} => {
let mut ret = vec![];
ret.push(cond.clone());
ret.append(&mut default.list_operands());
for entry in branches.iter() {
ret.push(entry.0.clone());
ret.append(&mut entry.1.list_operands());
}
ret
},
&ExnInstruction{ref inner, ref resume} => {
let mut ret = vec![];
ret.append(&mut inner.list_operands());
ret.append(&mut resume.list_operands());
ret
},
&ThreadExit => vec![]
}
}
}
impl fmt::Debug for Terminal {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
......@@ -267,6 +345,15 @@ impl fmt::Debug for NonTermInstruction {
}
}
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>),
......@@ -387,6 +474,38 @@ macro_rules! select {
}
}
impl OperandIteratable for Expression_ {
fn list_operands(&self) -> Vec<P<TreeNode>> {
match self {
&Expression_::BinOp(_, ref op1, ref op2) => vec![op1.clone(), op2.clone()],
&Expression_::CmpOp(_, ref op1, ref op2) => vec![op1.clone(), op2.clone()],
&Expression_::ExprCall{ref data, ..} => data.list_operands(),
&Expression_::Load{ref mem_loc, ..} => vec![mem_loc.clone()],
&Expression_::Store{ref value, ref mem_loc, ..} => vec![value.clone(), mem_loc.clone()],
&Expression_::CmpXchg{ref mem_loc, ref expected_value, ref desired_value, ..} => vec![mem_loc.clone(), expected_value.clone(), desired_value.clone()],
&Expression_::AtomicRMW{ref mem_loc, ref value, ..} => vec![mem_loc.clone(), value.clone()],
&Expression_::NewHybrid(_, ref len) => vec![len.clone()],
&Expression_::AllocAHybrid(_, ref len) => vec![len.clone()],
&Expression_::NewStack(ref func) => vec![func.clone()],
&Expression_::NewThread(ref stack, ref args) => {
let mut ret = vec![];
ret.push(stack.clone());
ret.append(&mut args.to_vec());
ret
},
&Expression_::NewThreadExn(ref stack, ref exception) => vec![stack.clone(), exception.clone()],
&Expression_::NewFrameCursor(ref stack) => vec![stack.clone()],
&Expression_::GetIRef(ref reference) => vec![reference.clone()],
&Expression_::GetFieldIRef{ref base, ref index, ..} => vec![base.clone(), index.clone()],
&Expression_::GetElementIRef{ref base, ref index, ..} => vec![base.clone(), index.clone()],
&Expression_::ShiftIRef{ref base, ref offset, ..} => vec![base.clone(), offset.clone()],
&Expression_::GetVarPartIRef{ref base, ..} => vec![base.clone()],
&Expression_::New(_) | &Expression_::AllocA(_) => vec![]
}
}
}
impl fmt::Debug for Expression_ {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
......@@ -479,6 +598,17 @@ impl fmt::Debug for CallData {
}
}
impl OperandIteratable for CallData {
fn list_operands(&self) -> Vec<P<TreeNode>> {
let mut ret = vec![];
ret.push(self.func.clone());
ret.append(&mut self.args.to_vec());
ret
}
}
#[derive(Clone)]
pub struct ResumptionData {
pub normal_dest: Destination,
......@@ -491,12 +621,37 @@ impl fmt::Debug for ResumptionData {
}
}
impl OperandIteratable for ResumptionData {
fn list_operands(&self) -> Vec<P<TreeNode>> {
let mut ret = vec![];
ret.append(&mut self.normal_dest.list_operands());
ret.append(&mut self.exn_dest.list_operands());
ret
}
}
#[derive(Clone)]
pub struct Destination {
pub target: MuTag,
pub args: Vec<DestArg>
}
impl OperandIteratable for Destination {
fn list_operands(&self) -> Vec<P<TreeNode>> {
let mut ret = vec![];
for arg in self.args.iter() {
match arg {
&DestArg::Normal(ref op) => ret.push(op.clone()),
_ => {}
}
}
ret
}
}
impl fmt::Debug for Destination {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{:?}", self.target, self.args)
......
......@@ -39,6 +39,7 @@
use std::fmt::{self, Display, Debug};
use std::hash::{Hash, Hasher};
use std::ops::Deref;
use std::ops::DerefMut;
/// An owned smart pointer.
pub struct P<T> {
......@@ -71,6 +72,12 @@ impl<T> Deref for P<T> {
}
}
impl<T> DerefMut for P<T> {
fn deref_mut<'a>(&'a mut self) -> &'a mut T {
&mut *self.ptr
}
}
impl<T: 'static + Clone> Clone for P<T> {
fn clone(&self) -> P<T> {
P((**self).clone())
......
......@@ -29,6 +29,7 @@ pub struct CompilerPolicy {
impl CompilerPolicy {
pub fn default() -> CompilerPolicy {
let mut passes : Vec<Box<CompilerPass>> = vec![];
passes.push(Box::new(passes::def_use::DefUsePass::new("DefUse")));
passes.push(Box::new(passes::tree_gen::TreeGenerationPass::new("Tree Generation")));
CompilerPolicy{passes: passes}
......@@ -49,8 +50,10 @@ pub trait CompilerPass {
debug!("block: {}", label);
for node in block.content.as_mut().unwrap().body.iter_mut() {
debug!("{:?}", node);
for inst in block.content.as_mut().unwrap().body.iter_mut() {
debug!("{:?}", inst);
self.visit_inst(vm_context, inst);
}
debug!("---finish---");
......@@ -59,5 +62,5 @@ pub trait CompilerPass {
fn visit_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {}
fn visit_block(&mut self, vm_context: &VMContext, block: &mut Block) {}
fn visit_node(&mut self, vm_context: &VMContext, node: &mut TreeNode) {}
fn visit_inst(&mut self, vm_context: &VMContext, node: &mut TreeNode) {}
}
......@@ -8,7 +8,7 @@ pub struct DefUsePass {
}
impl DefUsePass {
pub fn name(name: &'static str) -> DefUsePass {
pub fn new(name: &'static str) -> DefUsePass {
DefUsePass{name: name}
}
}
......@@ -18,7 +18,14 @@ impl CompilerPass for DefUsePass {
self.name
}
fn visit_node(&mut self, vm_context: &VMContext, node: &mut TreeNode) {
fn visit_inst(&mut self, vm_context: &VMContext, node: &mut TreeNode) {
match node.v {
TreeNode_::Instruction(ref inst) => {
for p_node in inst.list_operands() {
p_node.use_count.set(p_node.use_count.get() + 1)
}
},
TreeNode_::Value(_) => panic!("expected instruction node")
}
}
}
\ No newline at end of file
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