machine_code.rs 5.08 KB
Newer Older
1
use ast::ir::*;
qinsoon's avatar
qinsoon committed
2
use compiler::frame::*;
qinsoon's avatar
qinsoon committed
3
4
use runtime::ValueLocation;

5
use std::ops;
6
use std::collections::HashMap;
7

qinsoon's avatar
qinsoon committed
8
9
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};

10
pub struct CompiledFunction {
qinsoon's avatar
qinsoon committed
11
    pub func_id: MuID,
qinsoon's avatar
qinsoon committed
12
    pub func_ver_id: MuID,
qinsoon's avatar
qinsoon committed
13
14
15

    // assumes one temporary maps to one register
    pub temps: HashMap<MuID, MuID>,
qinsoon's avatar
qinsoon committed
16
    
qinsoon's avatar
qinsoon committed
17
    // not emitting this
18
    pub mc: Option<Box<MachineCode + Send + Sync>>,
qinsoon's avatar
qinsoon committed
19
20
21
22
23
24
25
26
27
28
29
    
    pub frame: Frame,
    pub start: ValueLocation,
    pub end: ValueLocation
}

const CF_SERIALIZE_FIELDS : usize = 6;

impl Encodable for CompiledFunction {
    fn encode<S: Encoder> (&self, s: &mut S) -> Result<(), S::Error> {
        s.emit_struct("CompiledFunction", CF_SERIALIZE_FIELDS, |s| {
qinsoon's avatar
qinsoon committed
30
            trace!("......serializing func_id");    
qinsoon's avatar
qinsoon committed
31
            try!(s.emit_struct_field("func_id",     0, |s| self.func_id.encode(s)));
qinsoon's avatar
qinsoon committed
32
            trace!("......serializing func_ver_id");
qinsoon's avatar
qinsoon committed
33
            try!(s.emit_struct_field("func_ver_id", 1, |s| self.func_ver_id.encode(s)));
qinsoon's avatar
qinsoon committed
34
            trace!("......serializing temps");
qinsoon's avatar
qinsoon committed
35
            try!(s.emit_struct_field("temps",       2, |s| self.temps.encode(s)));
qinsoon's avatar
qinsoon committed
36
37
            trace!("......serializing frame");
            trace!("{}", self.frame);
qinsoon's avatar
qinsoon committed
38
            try!(s.emit_struct_field("frame",       3, |s| self.frame.encode(s)));
qinsoon's avatar
qinsoon committed
39
            trace!("......serializing start");
qinsoon's avatar
qinsoon committed
40
            try!(s.emit_struct_field("start",       4, |s| self.start.encode(s)));
qinsoon's avatar
qinsoon committed
41
            trace!("......serializing end");
qinsoon's avatar
qinsoon committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
            try!(s.emit_struct_field("end",         5, |s| self.end.encode(s)));
            
            Ok(())
        })
    }
}

impl Decodable for CompiledFunction {
    fn decode<D: Decoder>(d: &mut D) -> Result<CompiledFunction, D::Error> {
        d.read_struct("CompiledFunction", CF_SERIALIZE_FIELDS, |d| {
            let func_id = 
                try!(d.read_struct_field("func_id",     0, |d| Decodable::decode(d)));
            let func_ver_id = 
                try!(d.read_struct_field("func_ver_id", 1, |d| Decodable::decode(d)));
            let temps = 
                try!(d.read_struct_field("temps",       2, |d| Decodable::decode(d)));
            let frame = 
                try!(d.read_struct_field("frame",       3, |d| Decodable::decode(d)));
            let start = 
                try!(d.read_struct_field("start",       4, |d| Decodable::decode(d)));
            let end =
                try!(d.read_struct_field("end",         5, |d| Decodable::decode(d)));
            
            Ok(CompiledFunction{
                func_id: func_id,
                func_ver_id: func_ver_id,
                temps: temps,
                mc: None,
                frame: frame,
                start: start,
                end: end
            })
        })
    }
}

impl CompiledFunction {
79
    pub fn mc(&self) -> &Box<MachineCode + Send + Sync> {
qinsoon's avatar
qinsoon committed
80
81
82
83
84
85
86
87
        match self.mc {
            Some(ref mc) => mc,
            None => panic!("trying to get mc from a compiled function. 
                But machine code is None (probably this compiled function is restored from
                boot image and mc is thrown away)")
        }
    }
    
88
    pub fn mc_mut(&mut self) -> &mut Box<MachineCode + Send + Sync> {
qinsoon's avatar
qinsoon committed
89
90
91
92
93
        match self.mc {
            Some(ref mut mc) => mc,
            None => panic!("no mc found from a compiled function")
        }
    }
94
95
}

96
97
use std::any::Any;

98
pub trait MachineCode {
99
100
101
    fn trace_mc(&self);
    fn trace_inst(&self, index: usize);
    
102
    fn emit(&self) -> Vec<u8>;
103
104
    
    fn number_of_insts(&self) -> usize;
qinsoon's avatar
qinsoon committed
105
    
106
    fn is_move(&self, index: usize) -> bool;
qinsoon's avatar
qinsoon committed
107
108
    fn is_using_mem_op(&self, index: usize) -> bool;
    
qinsoon's avatar
qinsoon committed
109
110
    fn get_succs(&self, index: usize) -> &Vec<usize>;
    fn get_preds(&self, index: usize) -> &Vec<usize>;
111
    
qinsoon's avatar
qinsoon committed
112
113
    fn get_inst_reg_uses(&self, index: usize) -> Vec<MuID>;
    fn get_inst_reg_defines(&self, index: usize) -> Vec<MuID>;
114
    
115
116
    fn get_ir_block_livein(&self, block: &str) -> Option<&Vec<MuID>>;
    fn get_ir_block_liveout(&self, block: &str) -> Option<&Vec<MuID>>;
117
118
    fn set_ir_block_livein(&mut self, block: &str, set: Vec<MuID>);
    fn set_ir_block_liveout(&mut self, block: &str, set: Vec<MuID>);
119
    
qinsoon's avatar
qinsoon committed
120
121
    fn get_all_blocks(&self) -> Vec<MuName>;
    // returns [start_inst, end_inst), inclusive at both end
122
    fn get_block_range(&self, block: &str) -> Option<ops::Range<usize>>;
qinsoon's avatar
qinsoon committed
123
124

    // functions for rewrite
125
    /// replace a temp with a machine register (to_reg must be a machine register)
126
    fn replace_reg(&mut self, from: MuID, to: MuID);
qinsoon's avatar
qinsoon committed
127
    /// replace a temp that is defined in the inst with another temp
128
    fn replace_define_tmp_for_inst(&mut self, from: MuID, to: MuID, inst: usize);
qinsoon's avatar
qinsoon committed
129
    /// replace a temp that is used in the inst with another temp
130
    fn replace_use_tmp_for_inst(&mut self, from: MuID, to: MuID, inst: usize);
qinsoon's avatar
qinsoon committed
131
    /// set an instruction as nop
132
    fn set_inst_nop(&mut self, index: usize);
qinsoon's avatar
qinsoon committed
133
134
135
    /// remove unnecessary push/pop if the callee saved register is not used
    /// returns what registers push/pop have been deleted
    fn remove_unnecessary_callee_saved(&mut self, used_callee_saved: Vec<MuID>) -> Vec<MuID>;
136
137

    fn as_any(&self) -> &Any;
138
}
139
140
141
142

pub trait MachineInst {

}