fidget_core/compiler/
reg_tape.rs1use crate::compiler::{RegOp, RegisterAllocator, SsaTape};
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Clone, Default, Serialize, Deserialize)]
9pub struct RegTape {
10 tape: Vec<RegOp>,
11
12 pub(super) slot_count: u32,
17}
18
19impl RegTape {
20 pub fn new<const N: usize>(ssa: &SsaTape) -> Self {
27 let mut alloc = RegisterAllocator::<N>::new(ssa.len());
28 for &op in ssa.iter() {
29 alloc.op(op)
30 }
31 alloc.finalize()
32 }
33
34 pub fn repack(&mut self) {
36 let map = self.repack_map();
37 for op in &mut self.tape {
38 op.visit_regs_mut(|reg| *reg = map[reg]);
39 }
40 }
41
42 pub fn repack_map(&self) -> HashMap<u8, u8> {
47 let mut reg_counts: HashMap<u8, usize> = HashMap::new();
48 for op in &self.tape {
49 op.visit_regs(|reg| *reg_counts.entry(reg).or_default() += 1);
50 }
51 let mut sorted = reg_counts
52 .into_iter()
53 .map(|(reg, count)| (std::cmp::Reverse(count), reg))
54 .collect::<Vec<_>>();
55 sorted.sort_unstable();
56 sorted
57 .into_iter()
58 .enumerate()
59 .map(|(i, (_count, reg))| (reg, u8::try_from(i).unwrap()))
60 .collect()
61 }
62
63 pub(crate) fn empty() -> Self {
65 Self {
66 tape: vec![],
67 slot_count: 0,
68 }
69 }
70
71 pub fn reset(&mut self) {
73 self.tape.clear();
74 self.slot_count = 0;
75 }
76
77 #[inline]
80 pub fn slot_count(&self) -> usize {
81 self.slot_count as usize
82 }
83 #[inline]
85 pub fn len(&self) -> usize {
86 self.tape.len()
87 }
88 #[inline]
90 pub fn is_empty(&self) -> bool {
91 self.tape.is_empty()
92 }
93 #[inline]
98 pub fn iter(&self) -> impl DoubleEndedIterator<Item = &RegOp> {
99 self.into_iter()
100 }
101 #[inline]
102 pub(crate) fn push(&mut self, op: RegOp) {
103 self.tape.push(op)
104 }
105}
106
107impl<'a> IntoIterator for &'a RegTape {
108 type Item = &'a RegOp;
109 type IntoIter = std::slice::Iter<'a, RegOp>;
110 fn into_iter(self) -> Self::IntoIter {
111 self.tape.iter()
112 }
113}