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

use compiler::CompilerPass;
qinsoon's avatar
qinsoon committed
6
use std::any::Any;
qinsoon's avatar
qinsoon committed
7

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

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

18 19 20
fn use_op(op: &P<TreeNode>, func_context: &mut FunctionContext) {
    match op.v {
        TreeNode_::Value(ref val) => {
21
            use_value(val, func_context);
22 23 24 25 26
        },
        _ => {} // dont worry about instruction
    }
}

27 28 29 30
fn use_value(val: &P<Value>, func_context: &mut FunctionContext) {
        match val.v {
            Value_::SSAVar(ref id) => {
                let entry = func_context.values.get_mut(id).unwrap();
qinsoon's avatar
qinsoon committed
31
                entry.increase_use_count();
32 33 34 35 36
            },
            _ => {} // dont worry about constants
        }    
}

qinsoon's avatar
qinsoon committed
37
impl CompilerPass for DefUse {
qinsoon's avatar
qinsoon committed
38 39 40
    fn name(&self) -> &'static str {
        self.name
    }
qinsoon's avatar
qinsoon committed
41 42 43 44

    fn as_any(&self) -> &Any {
        self
    }
qinsoon's avatar
qinsoon committed
45
    
46
    #[allow(unused_variables)]
qinsoon's avatar
qinsoon committed
47
    fn start_block(&mut self, vm: &VM, func_context: &mut FunctionContext, block: &mut Block) {
48 49 50 51
        // 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() {
52
                use_value(op, func_context);
53 54 55 56
            }
        }
    }
    
qinsoon's avatar
qinsoon committed
57
    #[allow(unused_variables)]
58
    fn visit_inst(&mut self, vm: &VM, func_context: &mut FunctionContext, node: &TreeNode) {
59
        // if an SSA appears in operands of instrs, its use count increases
qinsoon's avatar
qinsoon committed
60 61
        match node.v {
            TreeNode_::Instruction(ref inst) => {
qinsoon's avatar
qinsoon committed
62
                for op in inst.ops.read().unwrap().iter() {
63
                    use_op(op, func_context);
qinsoon's avatar
qinsoon committed
64 65 66 67 68
                }
            },
            _ => panic!("expected instruction node in visit_inst()")
        }
    }
69 70 71 72 73 74 75

    #[allow(unused_variables)]
    fn start_function(&mut self, vm: &VM, func: &mut MuFunctionVersion) {
        for entry in func.context.values.values() {
            entry.reset_use_count();
        }
    }
qinsoon's avatar
qinsoon committed
76
    
qinsoon's avatar
qinsoon committed
77
    #[allow(unused_variables)]
qinsoon's avatar
qinsoon committed
78
    fn finish_function(&mut self, vm: &VM, func: &mut MuFunctionVersion) {
qinsoon's avatar
qinsoon committed
79 80 81
        debug!("check use count for variables");
        
        for entry in func.context.values.values() {
qinsoon's avatar
qinsoon committed
82
            debug!("{}: {}", entry, entry.use_count())
qinsoon's avatar
qinsoon committed
83
        }
qinsoon's avatar
qinsoon committed
84
    }
85
}