Coverage Report

Created: 2025-01-09 07:53

/src/regalloc2/src/fastalloc/vregset.rs
Line
Count
Source (jump to first uncovered line)
1
use core::fmt;
2
3
use crate::ion::data_structures::VRegIndex;
4
use crate::VReg;
5
use alloc::vec;
6
use alloc::vec::Vec;
7
8
#[derive(Clone)]
9
struct VRegNode {
10
    next: VRegIndex,
11
    prev: VRegIndex,
12
    vreg: VReg,
13
}
14
15
// Using a doubly linked list here for fast insertion,
16
// removal and iteration.
17
pub struct VRegSet {
18
    items: Vec<VRegNode>,
19
    head: VRegIndex,
20
}
21
22
impl VRegSet {
23
0
    pub fn with_capacity(num_vregs: usize) -> Self {
24
0
        Self {
25
0
            items: vec![
26
0
                VRegNode {
27
0
                    prev: VRegIndex::new(num_vregs),
28
0
                    next: VRegIndex::new(num_vregs),
29
0
                    vreg: VReg::invalid()
30
0
                };
31
0
                num_vregs + 1
32
0
            ],
33
0
            head: VRegIndex::new(num_vregs),
34
0
        }
35
0
    }
36
37
0
    pub fn insert(&mut self, vreg: VReg) {
38
0
        debug_assert_eq!(self.items[vreg.vreg()].vreg, VReg::invalid());
39
0
        let old_head_next = self.items[self.head.index()].next;
40
0
        self.items[vreg.vreg()] = VRegNode {
41
0
            next: old_head_next,
42
0
            prev: self.head,
43
0
            vreg,
44
0
        };
45
0
        self.items[self.head.index()].next = VRegIndex::new(vreg.vreg());
46
0
        self.items[old_head_next.index()].prev = VRegIndex::new(vreg.vreg());
47
0
    }
48
49
0
    pub fn remove(&mut self, vreg_num: usize) {
50
0
        let prev = self.items[vreg_num].prev;
51
0
        let next = self.items[vreg_num].next;
52
0
        self.items[prev.index()].next = next;
53
0
        self.items[next.index()].prev = prev;
54
0
        self.items[vreg_num].vreg = VReg::invalid();
55
0
    }
56
57
0
    pub fn is_empty(&self) -> bool {
58
0
        self.items[self.head.index()].next == self.head
59
0
    }
60
61
0
    pub fn iter(&self) -> VRegSetIter {
62
0
        VRegSetIter {
63
0
            curr_item: self.items[self.head.index()].next,
64
0
            head: self.head,
65
0
            items: &self.items,
66
0
        }
67
0
    }
68
}
69
70
pub struct VRegSetIter<'a> {
71
    curr_item: VRegIndex,
72
    head: VRegIndex,
73
    items: &'a [VRegNode],
74
}
75
76
impl<'a> Iterator for VRegSetIter<'a> {
77
    type Item = VReg;
78
79
0
    fn next(&mut self) -> Option<Self::Item> {
80
0
        if self.curr_item != self.head {
81
0
            let item = self.items[self.curr_item.index()].clone();
82
0
            self.curr_item = item.next;
83
0
            Some(item.vreg)
84
        } else {
85
0
            None
86
        }
87
0
    }
88
}
89
90
impl fmt::Debug for VRegSet {
91
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92
0
        write!(f, "{{ ")?;
93
0
        for vreg in self.iter() {
94
0
            write!(f, "{vreg} ")?;
95
        }
96
0
        write!(f, "}}")
97
0
    }
98
}
99
100
#[cfg(test)]
101
mod tests {
102
    use super::*;
103
    use crate::RegClass;
104
    use RegClass::*;
105
    const VREG: fn(usize, RegClass) -> VReg = VReg::new;
106
107
    #[test]
108
    fn operations() {
109
        let mut set = VRegSet::with_capacity(3090);
110
        assert!(set.is_empty());
111
        set.insert(VREG(10, Int));
112
        set.insert(VREG(2000, Int));
113
        set.insert(VREG(11, Vector));
114
        set.insert(VREG(199, Float));
115
        set.insert(VREG(23, Int));
116
        let mut iter = set.iter();
117
        assert_eq!(iter.next(), Some(VREG(23, Int)));
118
        assert_eq!(iter.next(), Some(VREG(199, Float)));
119
        assert_eq!(iter.next(), Some(VREG(11, Vector)));
120
        assert_eq!(iter.next(), Some(VREG(2000, Int)));
121
        assert_eq!(iter.next(), Some(VREG(10, Int)));
122
123
        set.remove(23);
124
        set.remove(11);
125
        set.insert(VREG(73, Vector));
126
        let mut iter = set.iter();
127
        assert_eq!(iter.next(), Some(VREG(73, Vector)));
128
        assert_eq!(iter.next(), Some(VREG(199, Float)));
129
        assert_eq!(iter.next(), Some(VREG(2000, Int)));
130
        assert_eq!(iter.next(), Some(VREG(10, Int)));
131
        assert!(!set.is_empty());
132
    }
133
134
    #[test]
135
    fn empty() {
136
        let mut set = VRegSet::with_capacity(2000);
137
        assert!(set.is_empty());
138
        set.insert(VREG(100, Int));
139
        assert!(!set.is_empty());
140
        set.remove(100);
141
        assert!(set.is_empty());
142
    }
143
}