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

alive_entry.rs 7.71 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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    pub fn add_temp_in_mem(&mut self, temp: MuID, mem: P<Value>) {
        debug!("alive alive temp in mem: {} in {}", temp, mem);

        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
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
    pub fn remove_reg(&mut self, reg: MuID) {
        debug!("removing alive reg: {}", reg);
        let mut indices = vec![];

        for (index, entry) in self.inner.iter() {
            if entry.match_reg(reg) {
                indices.push(*index);
            }
        }

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

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

        let index = {
            let mut ret = 0;

            for (index, entry) in self.inner.iter() {
                if entry.match_temp(reg) {
                    ret = *index;
                }
            }

            ret
        };

        self.inner.remove(&index);
    }
}

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

impl RegisterEntry {
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
    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
255
256
257
258
259
260
261
262
263
264
265
266
    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);
        }
    }

267
268
269
270
271
272
273
274
275
276
277
278
    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
279
280
281
282
    pub fn match_stack_loc(&self, mem: P<Value>) -> bool {
        vec_utils::find_value(&self.stack, mem).is_some()
    }

283
284
285
286
287
    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
288
289
290
291
292
293

    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)
        }
    }
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
}

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)
    }
}