squid/frontend/symbolization_passes/
regcache.rs1use crate::frontend::ao::{
2 Function,
3 Op,
4 Register,
5 Var,
6};
7
8const REGISTER_COUNT: usize = 32 + 32 + 1;
9fn register_index(reg: &Register) -> usize {
10 match reg {
11 Register::Gp(reg) => *reg as usize,
12 Register::Fp(reg) => 32 + *reg as usize,
13 Register::Csr(_) => 64,
14 }
15}
16
17pub(crate) struct RegisterCachingPass {
18 registers: [Option<Var>; REGISTER_COUNT],
19}
20
21impl RegisterCachingPass {
22 #[allow(clippy::new_without_default)]
23 pub(crate) fn new() -> Self {
24 Self {
25 registers: [None; REGISTER_COUNT],
26 }
27 }
28
29 pub(crate) fn run(&mut self, func: &mut Function) -> Result<(), String> {
30 for bb in func.cfg_mut().iter_basic_blocks_mut() {
31 for reg in &mut self.registers {
32 *reg = None;
33 }
34
35 bb.set_cursor(0);
36
37 while let Some(op) = bb.cursor_op() {
38 match op {
39 Op::StoreRegister {
40 reg,
41 var,
42 } => {
43 self.registers[register_index(reg)] = Some(*var);
44 },
45 Op::LoadRegister {
46 var,
47 reg,
48 } => {
49 if let Some(orig_var) = &self.registers[register_index(reg)] {
50 bb.replace_op(Op::Copy {
51 dst: *var,
52 src: *orig_var,
53 });
54 }
55 },
56 _ => {},
57 }
58
59 if !bb.move_cursor_forward() {
60 break;
61 }
62 }
63 }
64
65 Ok(())
66 }
67}