def_use.rs 2.06 KB
Newer Older
qinsoon's avatar
qinsoon committed
1
use ast::ir::*;
2
use ast::ptr::*;
qinsoon's avatar
qinsoon committed
3 4 5 6
use vm::context::VMContext;

use compiler::CompilerPass;

qinsoon's avatar
qinsoon committed
7
pub struct DefUse {
qinsoon's avatar
qinsoon committed
8 9 10
    name: &'static str,
}

qinsoon's avatar
qinsoon committed
11 12 13
impl DefUse {
    pub fn new() -> DefUse {
        DefUse{name: "Def-Use Pass"}
qinsoon's avatar
qinsoon committed
14 15 16
    }
}

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
fn use_op(op: &P<TreeNode>, func_context: &mut FunctionContext) {
    match op.v {
        TreeNode_::Value(ref val) => {
            match val.v {
                Value_::SSAVar(ref id) => {
                    let entry = func_context.values.get_mut(id).unwrap();
                    entry.use_count.set(entry.use_count.get() + 1);
                },
                _ => {} // dont worry about constants
            }
        },
        _ => {} // dont worry about instruction
    }
}

qinsoon's avatar
qinsoon committed
32
impl CompilerPass for DefUse {
qinsoon's avatar
qinsoon committed
33 34 35 36
    fn name(&self) -> &'static str {
        self.name
    }
    
37 38 39 40 41 42 43 44 45 46 47
    #[allow(unused_variables)]
    fn visit_block(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, block: &mut Block) {
        // if an SSA appears in keepalives, its use count increases
        let ref mut keepalives = block.content.as_mut().unwrap().keepalives;
        if keepalives.is_some() {
            for op in keepalives.as_mut().unwrap().iter_mut() {
                use_op(op, func_context);
            }
        }
    }
    
qinsoon's avatar
qinsoon committed
48
    #[allow(unused_variables)]
qinsoon's avatar
qinsoon committed
49
    fn visit_inst(&mut self, vm_context: &VMContext, func_context: &mut FunctionContext, node: &mut TreeNode) {
50
        // if an SSA appears in operands of instrs, its use count increases
qinsoon's avatar
qinsoon committed
51 52
        match node.v {
            TreeNode_::Instruction(ref inst) => {
53 54
                for op in inst.ops.borrow().iter() {
                    use_op(op, func_context);
qinsoon's avatar
qinsoon committed
55 56 57 58 59 60
                }
            },
            _ => panic!("expected instruction node in visit_inst()")
        }
    }
    
qinsoon's avatar
qinsoon committed
61
    #[allow(unused_variables)]
qinsoon's avatar
qinsoon committed
62 63 64 65
    fn finish_function(&mut self, vm_context: &VMContext, func: &mut MuFunction) {
        debug!("check use count for variables");
        
        for entry in func.context.values.values() {
66
            debug!("{}#{}: {}", entry.tag, entry.id, entry.use_count.get())
qinsoon's avatar
qinsoon committed
67
        }
qinsoon's avatar
qinsoon committed
68 69
    }
}