wave_compiler/regalloc/
mod.rs1pub mod coalesce;
12pub mod coloring;
13pub mod interference;
14pub mod live_range;
15pub mod spill;
16
17use std::collections::HashMap;
18
19use crate::emit::wave_emit::RegMap;
20use crate::lir::instruction::LirInst;
21use crate::lir::operand::VReg;
22
23#[must_use]
28pub fn allocate_registers(instructions: &[LirInst], num_params: u32, max_regs: u32) -> RegMap {
29 let ig = interference::InterferenceGraph::build_with_params(instructions, num_params);
30 let coalesce_result = coalesce::coalesce(&ig, max_regs);
31 let coloring_result = coloring::color(&ig, max_regs, num_params);
32
33 let mut reg_map: RegMap = HashMap::new();
34
35 for (vreg, phys) in &coloring_result.assignment {
36 let final_vreg = find_representative(&coalesce_result.mapping, *vreg);
37 reg_map.insert(final_vreg, *phys);
38 reg_map.insert(*vreg, *phys);
39 }
40
41 for (coalesced, representative) in &coalesce_result.mapping {
42 if let Some(&phys) = reg_map.get(representative) {
43 reg_map.insert(*coalesced, phys);
44 }
45 }
46
47 reg_map
48}
49
50fn find_representative(mapping: &HashMap<VReg, VReg>, vreg: VReg) -> VReg {
51 let mut current = vreg;
52 while let Some(&next) = mapping.get(¤t) {
53 if next == current {
54 break;
55 }
56 current = next;
57 }
58 current
59}
60
61#[must_use]
63pub fn max_register_used(reg_map: &RegMap) -> u32 {
64 reg_map
65 .values()
66 .map(|p| u32::from(p.0) + 1)
67 .max()
68 .unwrap_or(0)
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::lir::operand::PhysReg;
75
76 #[test]
77 fn test_allocate_registers_simple() {
78 let insts = vec![
79 LirInst::MovImm {
80 dest: VReg(0),
81 value: 1,
82 },
83 LirInst::MovImm {
84 dest: VReg(1),
85 value: 2,
86 },
87 LirInst::Iadd {
88 dest: VReg(2),
89 src1: VReg(0),
90 src2: VReg(1),
91 },
92 LirInst::Halt,
93 ];
94
95 let reg_map = allocate_registers(&insts, 0, 32);
96 assert!(reg_map.contains_key(&VReg(0)));
97 assert!(reg_map.contains_key(&VReg(1)));
98 assert!(reg_map.contains_key(&VReg(2)));
99 }
100
101 #[test]
102 fn test_allocate_with_params() {
103 let insts = vec![
104 LirInst::Iadd {
105 dest: VReg(2),
106 src1: VReg(0),
107 src2: VReg(1),
108 },
109 LirInst::Halt,
110 ];
111
112 let reg_map = allocate_registers(&insts, 2, 32);
113 assert_eq!(reg_map[&VReg(0)], PhysReg(0));
114 assert_eq!(reg_map[&VReg(1)], PhysReg(1));
115 }
116
117 #[test]
118 fn test_max_register_used() {
119 let mut map = RegMap::new();
120 map.insert(VReg(0), PhysReg(5));
121 map.insert(VReg(1), PhysReg(10));
122 assert_eq!(max_register_used(&map), 11);
123 }
124}