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

alive_entry.rs 8.03 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#![allow(dead_code)]

use utils::LinkedHashMap;
use utils::vec_utils;
use ast::ir::*;
use ast::ptr::*;
use std::fmt;

type EntryID = usize;

pub struct AliveEntries {
    index: EntryID,

    inner: LinkedHashMap<EntryID, RegisterEntry>
}

impl fmt::Display for AliveEntries {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        writeln!(f, "{} entries", self.inner.len()).unwrap();
        writeln!(f, "| {:20} | {:20} | {:20} |", "ssa", "registers", "stack slots").unwrap();
        for entry in self.inner.values() {
            writeln!(f, "{}", entry).unwrap()
        }

        Ok(())
    }
}

impl AliveEntries {
    pub fn new() -> AliveEntries {
        AliveEntries {
            index: 0,
            inner: LinkedHashMap::new()
        }
    }

    fn new_index(&mut self) -> EntryID {
        let ret = self.index;
        self.index += 1;

        ret
    }

qinsoon's avatar
qinsoon committed
44
    pub fn has_entries_for_temp(&self, temp: MuID) -> bool {
45
46
        for entry in self.inner.values() {
            if entry.match_temp(temp) {
qinsoon's avatar
qinsoon committed
47
                return true;
48
49
50
            }
        }

qinsoon's avatar
qinsoon committed
51
        false
52
    }
qinsoon's avatar
qinsoon committed
53
54
55
56
57
58
59
60
61
62
63
    pub fn find_entries_for_temp(&self, temp: MuID) -> Vec<&RegisterEntry> {
        let mut ret = vec![];
        for entry in self.inner.values() {
            if entry.match_temp(temp) {
                ret.push(entry);
            }
        }
        ret
    }
    pub fn find_entries_for_temp_mut(&mut self, temp: MuID) -> Vec<&mut RegisterEntry> {
        let mut ret = vec![];
64
65
        for entry in self.inner.values_mut() {
            if entry.match_temp(temp) {
qinsoon's avatar
qinsoon committed
66
                ret.push(entry);
67
68
            }
        }
qinsoon's avatar
qinsoon committed
69
        ret
70
71
    }

qinsoon's avatar
qinsoon committed
72
    pub fn has_entries_for_reg(&self, reg: MuID) -> bool {
73
74
        for entry in self.inner.values() {
            if entry.match_reg(reg) {
qinsoon's avatar
qinsoon committed
75
                return true;
76
77
            }
        }
qinsoon's avatar
qinsoon committed
78
        false
79
    }
qinsoon's avatar
qinsoon committed
80
81
82
83
84
85
86
87
88
89
90
    pub fn find_entries_for_reg(&self, reg: MuID) -> Vec<&RegisterEntry> {
        let mut ret = vec![];
        for entry in self.inner.values() {
            if entry.match_reg(reg) {
                ret.push(entry);
            }
        }
        ret
    }
    pub fn find_entries_for_reg_mut(&mut self, reg: MuID) -> Vec<&mut RegisterEntry> {
        let mut ret = vec![];
91
92
        for entry in self.inner.values_mut() {
            if entry.match_reg(reg) {
qinsoon's avatar
qinsoon committed
93
                ret.push(entry)
94
95
            }
        }
qinsoon's avatar
qinsoon committed
96
97
        ret
    }
98

qinsoon's avatar
qinsoon committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
    pub fn has_entries_for_mem(&self, mem: P<Value>) -> bool {
        for entry in self.inner.values() {
            if entry.match_stack_loc(mem.clone()) {
                return true;
            }
        }
        false
    }
    pub fn find_entries_for_mem(&self, mem: P<Value>) -> Vec<&RegisterEntry> {
        let mut ret = vec![];
        for entry in self.inner.values() {
            if entry.match_stack_loc(mem.clone()) {
                ret.push(entry)
            }
        }
        ret
    }
    pub fn find_entries_for_mem_mut(&mut self, mem: P<Value>) -> Vec<&mut RegisterEntry> {
        let mut ret = vec![];
        for entry in self.inner.values_mut() {
            if entry.match_stack_loc(mem.clone()) {
                ret.push(entry)
            }
        }
        ret
124
125
    }

qinsoon's avatar
qinsoon committed
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
    pub fn new_alive_reg(&mut self, reg: MuID) {
        debug!("adding alive reg: {}", reg);

        let id = self.new_index();
        let entry = RegisterEntry {
            temp : None,
            real : vec![reg],
            stack: vec![]
        };

        self.inner.insert(id, entry);
    }

    pub fn new_alive_mem(&mut self, mem: P<Value>) {
        debug!("adding alive mem: {}", mem);

        let id = self.new_index();
        let entry = RegisterEntry {
            temp : None,
            real : vec![],
            stack: vec![mem]
        };

        self.inner.insert(id, entry);
    }

    pub fn add_temp_in_reg(&mut self, temp: MuID, reg: MuID) {
        debug!("adding alive temp in reg: {} in {}", temp, reg);

qinsoon's avatar
qinsoon committed
156
        let entry_exists = self.has_entries_for_temp(temp);
157
158

        if entry_exists {
qinsoon's avatar
qinsoon committed
159
160
161
162
            let mut entries = self.find_entries_for_temp_mut(temp);
            for entry in entries {
                entry.add_real_reg(reg);
            }
163
164
165
166
167
168
169
170
171
172
173
174
        } else {
            let id = self.new_index();
            let entry = RegisterEntry {
                temp: Some(temp),
                real: vec![reg],
                stack: vec![]
            };

            self.inner.insert(id, entry);
        }
    }

qinsoon's avatar
qinsoon committed
175
    pub fn add_temp_in_mem(&mut self, temp: MuID, mem: P<Value>) {
qinsoon's avatar
qinsoon committed
176
        debug!("adding alive temp in mem: {} in {}", temp, mem);
qinsoon's avatar
qinsoon committed
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196

        let entry_exists = self.has_entries_for_temp(temp);

        if entry_exists {
            let mut entries = self.find_entries_for_temp_mut(temp);
            for entry in entries {
                entry.add_stack_loc(mem.clone());
            }
        } else {
            let id = self.new_index();
            let entry = RegisterEntry {
                temp: Some(temp),
                real: vec![],
                stack: vec![mem]
            };

            self.inner.insert(id, entry);
        }
    }

197
198
199
200
    pub fn remove_reg(&mut self, reg: MuID) {
        debug!("removing alive reg: {}", reg);
        let mut indices = vec![];

201
        for (index, entry) in self.inner.iter_mut() {
202
            if entry.match_reg(reg) {
203
204
205
206
207
                entry.remove_real(reg);

                if entry.is_empty() {
                    indices.push(*index);
                }
208
209
210
211
212
213
214
215
            }
        }

        for index in indices {
            self.inner.remove(&index);
        }
    }

216
217
    pub fn remove_temp(&mut self, temp: MuID) {
        debug!("removing alive temp: {}", temp);
218

219
        let mut ret = vec![];
220

221
222
223
        for (index, entry) in self.inner.iter() {
            if entry.match_temp(temp) {
                ret.push(*index);
224
            }
225
        }
226

227
228
229
230
231
232
233
        if ret.len() == 0 {
            return;
        } else if ret.len() == 1 {
            self.inner.remove(&ret[0]);
        } else {
            panic!("Temp{} has more than one entry in AliveEntries");
        }
234
235
236
237
238
239
240
241
242
243
    }
}

pub struct RegisterEntry {
    temp  : Option<MuID>,
    real  : Vec<MuID>,
    stack : Vec<P<Value>>
}

impl RegisterEntry {
244
245
246
247
    pub fn is_empty(&self) -> bool {
        !self.has_real() && !self.has_stack_slots()
    }

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
    pub fn has_temp(&self) -> bool {
        self.temp.is_some()
    }
    pub fn has_real(&self) -> bool {
        !self.real.is_empty()
    }
    pub fn has_stack_slots(&self) -> bool {
        !self.stack.is_empty()
    }

    pub fn set_temp(&mut self, temp: MuID) {
        self.temp = Some(temp);
    }
    pub fn get_temp(&self) -> Option<MuID> {
        self.temp.clone()
    }

qinsoon's avatar
qinsoon committed
265
266
267
268
269
270
271
272
273
274
275
276
    pub fn remove_real(&mut self, reg: MuID) {
        if let Some(index) = vec_utils::find_value(&self.real, reg) {
            self.real.remove(index);
        }
    }

    pub fn remove_stack_loc(&mut self, mem: P<Value>) {
        if let Some(index) = vec_utils::find_value(&self.stack, mem) {
            self.stack.remove(index);
        }
    }

277
278
279
280
281
282
283
284
285
286
287
288
    pub fn match_temp(&self, temp: MuID) -> bool {
        if self.temp.is_some() && self.temp.unwrap() == temp {
            true
        } else {
            false
        }
    }

    pub fn match_reg(&self, reg: MuID) -> bool {
        vec_utils::find_value(&self.real, reg).is_some()
    }

qinsoon's avatar
qinsoon committed
289
290
291
292
    pub fn match_stack_loc(&self, mem: P<Value>) -> bool {
        vec_utils::find_value(&self.stack, mem).is_some()
    }

293
294
295
296
297
    pub fn add_real_reg(&mut self, reg: MuID) {
        if vec_utils::find_value(&mut self.real, reg).is_none() {
            self.real.push(reg);
        }
    }
qinsoon's avatar
qinsoon committed
298
299
300
301
302
303

    pub fn add_stack_loc(&mut self, mem: P<Value>) {
        if vec_utils::find_value(&mut self.stack, mem.clone()).is_none() {
            self.stack.push(mem)
        }
    }
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
}

impl fmt::Display for RegisterEntry {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let temp = match self.temp {
            Some(id) => format!("{}", id),
            None     => "_".to_string()
        };

        let real = format!("{:?}", self.real);
        let stack = format!("{:?}", self.stack);

        write!(f, "| {:20} | {:20} | {:20} |", temp, real, stack)
    }
}