Coverage Report

Created: 2021-03-22 08:29

/src/regalloc.rs/lib/src/sparse_set.rs
Line
Count
Source (jump to first uncovered line)
1
#![allow(non_snake_case)]
2
#![allow(non_camel_case_types)]
3
4
//! An implementation of sets which aims to be fast for both large sets and
5
//! very small sets, even if the elements are sparse relative to the universe.
6
7
use rustc_hash::FxHashSet;
8
use std::fmt;
9
use std::hash::Hash;
10
11
//=============================================================================
12
// SparseSet
13
14
// Handy wrappers around `SparseSetU`, if you don't want to have to guess at an "optimal"
15
// in-line size.
16
pub type SparseSet<T> = SparseSetU<[T; 12]>;
17
//pub type SparseSetIter<'a, T> = SparseSetUIter<'a, [T; 12]>; // No use case yet
18
19
// Implementation: for small, unordered but no dups
20
21
use core::mem::MaybeUninit;
22
use core::ptr::{read, write};
23
24
// Types that can be used as the backing store for a SparseSet.
25
pub trait Array {
26
    // The type of the array's elements.
27
    type Item;
28
    // Returns the number of items the array can hold.
29
    fn size() -> usize;
30
}
31
macro_rules! impl_array(
32
  ($($size:expr),+) => {
33
    $(
34
      impl<T> Array for [T; $size] {
35
        type Item = T;
36
610k
        fn size() -> usize { $size }
<[regalloc::data_structures::BlockIx; 4] as regalloc::sparse_set::Array>::size
Line
Count
Source
36
101k
        fn size() -> usize { $size }
<[regalloc::data_structures::VirtualRangeIx; 4] as regalloc::sparse_set::Array>::size
Line
Count
Source
36
43.9k
        fn size() -> usize { $size }
<[regalloc::data_structures::Reg; 12] as regalloc::sparse_set::Array>::size
Line
Count
Source
36
391k
        fn size() -> usize { $size }
<[regalloc::data_structures::RangeId; 12] as regalloc::sparse_set::Array>::size
Line
Count
Source
36
28.4k
        fn size() -> usize { $size }
<[regalloc::data_structures::RangeId; 4] as regalloc::sparse_set::Array>::size
Line
Count
Source
36
44.5k
        fn size() -> usize { $size }
37
      }
38
    )+
39
  }
40
);
41
impl_array!(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 28, 32);
42
43
// The U here stands for "unordered".  It refers to the fact that the elements
44
// in `Small::arr` are in no particular order, although they are
45
// duplicate-free.
46
pub enum SparseSetU<A: Array> {
47
    Large { set: FxHashSet<A::Item> },
48
    Small { card: usize, arr: MaybeUninit<A> },
49
}
50
51
// ================ Admin (private) methods ================
52
53
impl<A> SparseSetU<A>
54
where
55
    A: Array,
56
    A::Item: Eq + Hash + Copy,
57
{
58
    #[cfg(test)]
59
    fn is_small(&self) -> bool {
60
        match self {
61
            SparseSetU::Large { .. } => false,
62
            SparseSetU::Small { .. } => true,
63
        }
64
    }
65
66
    #[cfg(test)]
67
    fn is_large(&self) -> bool {
68
        !self.is_small()
69
    }
70
71
    #[inline(never)]
72
1.53k
    fn upgrade(&mut self) {
73
1.53k
        match self {
74
0
            SparseSetU::Large { .. } => panic!("SparseSetU: upgrade"),
75
1.53k
            SparseSetU::Small { card, arr } => {
76
1.53k
                assert!(*card == A::size());
77
1.53k
                let mut set = FxHashSet::<A::Item>::default();
78
1.53k
                set.reserve(A::size());
79
1.53k
                // Could this be done faster?
80
1.53k
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
81
13.2k
                for i in 0..*card {
82
13.2k
                    set.insert(unsafe { read(arr_p.add(i)) });
83
13.2k
                }
84
1.53k
                *self = SparseSetU::Large { set }
85
1.53k
            }
86
1.53k
        }
87
1.53k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::linear_scan::analysis::RangeId; 12]>>::upgrade
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::upgrade
Line
Count
Source
72
450
    fn upgrade(&mut self) {
73
450
        match self {
74
0
            SparseSetU::Large { .. } => panic!("SparseSetU: upgrade"),
75
450
            SparseSetU::Small { card, arr } => {
76
450
                assert!(*card == A::size());
77
450
                let mut set = FxHashSet::<A::Item>::default();
78
450
                set.reserve(A::size());
79
450
                // Could this be done faster?
80
450
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
81
5.40k
                for i in 0..*card {
82
5.40k
                    set.insert(unsafe { read(arr_p.add(i)) });
83
5.40k
                }
84
450
                *self = SparseSetU::Large { set }
85
450
            }
86
450
        }
87
450
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 12]>>::upgrade
Line
Count
Source
72
441
    fn upgrade(&mut self) {
73
441
        match self {
74
0
            SparseSetU::Large { .. } => panic!("SparseSetU: upgrade"),
75
441
            SparseSetU::Small { card, arr } => {
76
441
                assert!(*card == A::size());
77
441
                let mut set = FxHashSet::<A::Item>::default();
78
441
                set.reserve(A::size());
79
441
                // Could this be done faster?
80
441
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
81
5.29k
                for i in 0..*card {
82
5.29k
                    set.insert(unsafe { read(arr_p.add(i)) });
83
5.29k
                }
84
441
                *self = SparseSetU::Large { set }
85
441
            }
86
441
        }
87
441
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::VirtualRangeIx; 4]>>::upgrade
Line
Count
Source
72
103
    fn upgrade(&mut self) {
73
103
        match self {
74
0
            SparseSetU::Large { .. } => panic!("SparseSetU: upgrade"),
75
103
            SparseSetU::Small { card, arr } => {
76
103
                assert!(*card == A::size());
77
103
                let mut set = FxHashSet::<A::Item>::default();
78
103
                set.reserve(A::size());
79
103
                // Could this be done faster?
80
103
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
81
412
                for i in 0..*card {
82
412
                    set.insert(unsafe { read(arr_p.add(i)) });
83
412
                }
84
103
                *self = SparseSetU::Large { set }
85
103
            }
86
103
        }
87
103
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 4]>>::upgrade
Line
Count
Source
72
221
    fn upgrade(&mut self) {
73
221
        match self {
74
0
            SparseSetU::Large { .. } => panic!("SparseSetU: upgrade"),
75
221
            SparseSetU::Small { card, arr } => {
76
221
                assert!(*card == A::size());
77
221
                let mut set = FxHashSet::<A::Item>::default();
78
221
                set.reserve(A::size());
79
221
                // Could this be done faster?
80
221
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
81
884
                for i in 0..*card {
82
884
                    set.insert(unsafe { read(arr_p.add(i)) });
83
884
                }
84
221
                *self = SparseSetU::Large { set }
85
221
            }
86
221
        }
87
221
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::linear_scan::analysis::RangeId; 4]>>::upgrade
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::BlockIx; 4]>>::upgrade
Line
Count
Source
72
317
    fn upgrade(&mut self) {
73
317
        match self {
74
0
            SparseSetU::Large { .. } => panic!("SparseSetU: upgrade"),
75
317
            SparseSetU::Small { card, arr } => {
76
317
                assert!(*card == A::size());
77
317
                let mut set = FxHashSet::<A::Item>::default();
78
317
                set.reserve(A::size());
79
317
                // Could this be done faster?
80
317
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
81
1.26k
                for i in 0..*card {
82
1.26k
                    set.insert(unsafe { read(arr_p.add(i)) });
83
1.26k
                }
84
317
                *self = SparseSetU::Large { set }
85
317
            }
86
317
        }
87
317
    }
88
89
    // A large set is only downgradeable if its card does not exceed this value.
90
    #[inline(always)]
91
2.60k
    fn small_halfmax_card(&self) -> usize {
92
2.60k
        let limit = A::size();
93
2.60k
        //if limit >= 4 {
94
2.60k
        //  limit / 2
95
2.60k
        //} else {
96
2.60k
        //  limit - 1
97
2.60k
        //}
98
2.60k
        if false {
99
            // Set the transition point as roughly half of the inline size
100
            match limit {
101
                0 | 1 => panic!("SparseSetU: small_halfmax_card"),
102
                2 => 1,
103
                3 => 2,
104
                4 => 2,
105
                5 => 3,
106
                6 => 3,
107
                _ => limit / 2,
108
            }
109
        } else {
110
            // Set the transition point as roughly two thirds of the inline size
111
2.60k
            match limit {
112
0
                0 | 1 => panic!("SparseSetU: small_halfmax_card"),
113
0
                2 => 1,
114
0
                3 => 2,
115
0
                4 => 3,
116
0
                5 => 4,
117
0
                6 => 4,
118
                // FIXME JRS 2020Apr10 avoid possible integer overflow here:
119
2.60k
                _ => (2 * limit) / 3,
120
            }
121
        }
122
2.60k
    }
123
124
    // If we have a large-format set, but the cardinality has fallen below half
125
    // the size of a small format set, convert it to the small format.  This
126
    // isn't done at the point when the cardinality falls to the max capacity of
127
    // a small set in order to give some hysteresis -- we don't want to be
128
    // constantly converting back and forth for a set whose size repeatedly
129
    // crosses the border.
130
    #[inline(never)]
131
2.60k
    fn maybe_downgrade(&mut self) {
132
2.60k
        let small_halfmax_card = self.small_halfmax_card();
133
2.60k
        match self {
134
2.60k
            SparseSetU::Large { set } => {
135
2.60k
                if set.len() <= small_halfmax_card {
136
525
                    let mut arr = MaybeUninit::<A>::uninit();
137
525
                    let arr_p = arr.as_mut_ptr() as *mut A::Item;
138
525
                    let mut i = 0;
139
3.67k
                    for e in set.iter() {
140
3.67k
                        unsafe { write(arr_p.add(i), *e) };
141
3.67k
                        i += 1;
142
3.67k
                    }
143
525
                    assert!(i <= small_halfmax_card);
144
525
                    *self = SparseSetU::Small { card: i, arr };
145
2.07k
                }
146
            }
147
            SparseSetU::Small { .. } => {
148
0
                panic!("SparseSetU::maybe_downgrade: is already small");
149
            }
150
        }
151
2.60k
    }
152
153
    #[inline(always)]
154
106k
    fn insert_no_dup_check(&mut self, item: A::Item) {
155
106k
        match self {
156
96
            SparseSetU::Large { set } => {
157
96
                set.insert(item);
158
96
            }
159
106k
            SparseSetU::Small { card, arr } => {
160
106k
                assert!(*card <= A::size());
161
106k
                if *card < A::size() {
162
105k
                    // Stay small
163
105k
                    let arr_p = arr.as_mut_ptr() as *mut A::Item;
164
105k
                    unsafe {
165
105k
                        write(arr_p.add(*card), item);
166
105k
                    }
167
105k
                    *card += 1;
168
105k
                } else {
169
                    // Transition up
170
361
                    self.upgrade();
171
361
                    match self {
172
361
                        SparseSetU::Large { set } => {
173
361
                            let _ = set.insert(item);
174
361
                        }
175
                        SparseSetU::Small { .. } => {
176
                            // Err, what?  Still Small after upgrade?
177
0
                            panic!("SparseSetU::insert_no_dup_check")
178
                        }
179
                    }
180
                }
181
            }
182
        }
183
106k
    }
184
}
185
186
#[inline(always)]
187
303k
fn small_contains<A>(card: usize, arr: &MaybeUninit<A>, item: A::Item) -> bool
188
303k
where
189
303k
    A: Array,
190
303k
    A::Item: Eq,
191
303k
{
192
303k
    let arr_p = arr.as_ptr() as *const A::Item;
193
342k
    for i in 0..card {
194
342k
        if unsafe { read(arr_p.add(i)) } == item {
195
79.4k
            return true;
196
262k
        }
197
    }
198
223k
    false
199
303k
}
Unexecuted instantiation: regalloc::sparse_set::small_contains::<[regalloc::data_structures::Reg; 12]>
regalloc::sparse_set::small_contains::<[regalloc::data_structures::VirtualRangeIx; 4]>
Line
Count
Source
187
27.6k
fn small_contains<A>(card: usize, arr: &MaybeUninit<A>, item: A::Item) -> bool
188
27.6k
where
189
27.6k
    A: Array,
190
27.6k
    A::Item: Eq,
191
27.6k
{
192
27.6k
    let arr_p = arr.as_ptr() as *const A::Item;
193
27.6k
    for i in 0..card {
194
7.16k
        if unsafe { read(arr_p.add(i)) } == item {
195
5.67k
            return true;
196
1.49k
        }
197
    }
198
21.9k
    false
199
27.6k
}
regalloc::sparse_set::small_contains::<[regalloc::data_structures::Reg; 12]>
Line
Count
Source
187
56.3k
fn small_contains<A>(card: usize, arr: &MaybeUninit<A>, item: A::Item) -> bool
188
56.3k
where
189
56.3k
    A: Array,
190
56.3k
    A::Item: Eq,
191
56.3k
{
192
56.3k
    let arr_p = arr.as_ptr() as *const A::Item;
193
73.8k
    for i in 0..card {
194
73.8k
        if unsafe { read(arr_p.add(i)) } == item {
195
23.1k
            return true;
196
50.7k
        }
197
    }
198
33.1k
    false
199
56.3k
}
regalloc::sparse_set::small_contains::<[regalloc::data_structures::VirtualRangeIx; 4]>
Line
Count
Source
187
21.8k
fn small_contains<A>(card: usize, arr: &MaybeUninit<A>, item: A::Item) -> bool
188
21.8k
where
189
21.8k
    A: Array,
190
21.8k
    A::Item: Eq,
191
21.8k
{
192
21.8k
    let arr_p = arr.as_ptr() as *const A::Item;
193
21.8k
    for i in 0..card {
194
1.35k
        if unsafe { read(arr_p.add(i)) } == item {
195
0
            return true;
196
1.35k
        }
197
    }
198
21.8k
    false
199
21.8k
}
regalloc::sparse_set::small_contains::<[regalloc::data_structures::RangeId; 12]>
Line
Count
Source
187
19.4k
fn small_contains<A>(card: usize, arr: &MaybeUninit<A>, item: A::Item) -> bool
188
19.4k
where
189
19.4k
    A: Array,
190
19.4k
    A::Item: Eq,
191
19.4k
{
192
19.4k
    let arr_p = arr.as_ptr() as *const A::Item;
193
79.3k
    for i in 0..card {
194
79.3k
        if unsafe { read(arr_p.add(i)) } == item {
195
8.37k
            return true;
196
70.9k
        }
197
    }
198
11.1k
    false
199
19.4k
}
regalloc::sparse_set::small_contains::<[regalloc::data_structures::RangeId; 4]>
Line
Count
Source
187
22.1k
fn small_contains<A>(card: usize, arr: &MaybeUninit<A>, item: A::Item) -> bool
188
22.1k
where
189
22.1k
    A: Array,
190
22.1k
    A::Item: Eq,
191
22.1k
{
192
22.1k
    let arr_p = arr.as_ptr() as *const A::Item;
193
22.1k
    for i in 0..card {
194
5.66k
        if unsafe { read(arr_p.add(i)) } == item {
195
218
            return true;
196
5.44k
        }
197
    }
198
21.9k
    false
199
22.1k
}
regalloc::sparse_set::small_contains::<[regalloc::data_structures::BlockIx; 4]>
Line
Count
Source
187
51.0k
fn small_contains<A>(card: usize, arr: &MaybeUninit<A>, item: A::Item) -> bool
188
51.0k
where
189
51.0k
    A: Array,
190
51.0k
    A::Item: Eq,
191
51.0k
{
192
51.0k
    let arr_p = arr.as_ptr() as *const A::Item;
193
51.0k
    for i in 0..card {
194
15.4k
        if unsafe { read(arr_p.add(i)) } == item {
195
1.66k
            return true;
196
13.8k
        }
197
    }
198
49.4k
    false
199
51.0k
}
Unexecuted instantiation: regalloc::sparse_set::small_contains::<[regalloc::linear_scan::analysis::RangeId; 4]>
regalloc::sparse_set::small_contains::<[regalloc::data_structures::Reg; 12]>
Line
Count
Source
187
104k
fn small_contains<A>(card: usize, arr: &MaybeUninit<A>, item: A::Item) -> bool
188
104k
where
189
104k
    A: Array,
190
104k
    A::Item: Eq,
191
104k
{
192
104k
    let arr_p = arr.as_ptr() as *const A::Item;
193
159k
    for i in 0..card {
194
159k
        if unsafe { read(arr_p.add(i)) } == item {
195
40.3k
            return true;
196
118k
        }
197
    }
198
64.4k
    false
199
104k
}
Unexecuted instantiation: regalloc::sparse_set::small_contains::<[regalloc::linear_scan::analysis::RangeId; 12]>
200
201
// ================ Public methods ================
202
203
impl<A> SparseSetU<A>
204
where
205
    A: Array,
206
    A::Item: Eq + Hash + Copy,
207
{
208
    #[inline(always)]
209
290k
    pub fn empty() -> Self {
210
290k
        SparseSetU::Small {
211
290k
            card: 0,
212
290k
            arr: MaybeUninit::uninit(),
213
290k
        }
214
290k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::VirtualRangeIx; 4]>>::empty
Line
Count
Source
209
176k
    pub fn empty() -> Self {
210
176k
        SparseSetU::Small {
211
176k
            card: 0,
212
176k
            arr: MaybeUninit::uninit(),
213
176k
        }
214
176k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::empty
Line
Count
Source
209
65.2k
    pub fn empty() -> Self {
210
65.2k
        SparseSetU::Small {
211
65.2k
            card: 0,
212
65.2k
            arr: MaybeUninit::uninit(),
213
65.2k
        }
214
65.2k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::BlockIx; 4]>>::empty
Line
Count
Source
209
26.1k
    pub fn empty() -> Self {
210
26.1k
        SparseSetU::Small {
211
26.1k
            card: 0,
212
26.1k
            arr: MaybeUninit::uninit(),
213
26.1k
        }
214
26.1k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 12]>>::empty
Line
Count
Source
209
3.45k
    pub fn empty() -> Self {
210
3.45k
        SparseSetU::Small {
211
3.45k
            card: 0,
212
3.45k
            arr: MaybeUninit::uninit(),
213
3.45k
        }
214
3.45k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 4]>>::empty
Line
Count
Source
209
18.5k
    pub fn empty() -> Self {
210
18.5k
        SparseSetU::Small {
211
18.5k
            card: 0,
212
18.5k
            arr: MaybeUninit::uninit(),
213
18.5k
        }
214
18.5k
    }
215
216
    #[inline(always)]
217
269k
    pub fn is_empty(&self) -> bool {
218
269k
        match self {
219
268k
            SparseSetU::Small { card, .. } => *card == 0,
220
280
            SparseSetU::Large { set } => {
221
                // This holds because `maybe_downgrade` will always convert a
222
                // zero-sized large variant into a small variant.
223
280
                assert!(set.len() > 0);
224
280
                false
225
            }
226
        }
227
269k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::VirtualRangeIx; 4]>>::is_empty
Line
Count
Source
217
218k
    pub fn is_empty(&self) -> bool {
218
218k
        match self {
219
218k
            SparseSetU::Small { card, .. } => *card == 0,
220
85
            SparseSetU::Large { set } => {
221
                // This holds because `maybe_downgrade` will always convert a
222
                // zero-sized large variant into a small variant.
223
85
                assert!(set.len() > 0);
224
85
                false
225
            }
226
        }
227
218k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::data_structures::VirtualRangeIx; 4]>>::is_empty
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::BlockIx; 4]>>::is_empty
Line
Count
Source
217
50.8k
    pub fn is_empty(&self) -> bool {
218
50.8k
        match self {
219
50.6k
            SparseSetU::Small { card, .. } => *card == 0,
220
195
            SparseSetU::Large { set } => {
221
                // This holds because `maybe_downgrade` will always convert a
222
                // zero-sized large variant into a small variant.
223
195
                assert!(set.len() > 0);
224
195
                false
225
            }
226
        }
227
50.8k
    }
228
229
    #[inline(never)]
230
88.3k
    pub fn card(&self) -> usize {
231
88.3k
        match self {
232
2.27k
            SparseSetU::Large { set } => set.len(),
233
86.0k
            SparseSetU::Small { card, .. } => *card,
234
        }
235
88.3k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::BlockIx; 4]>>::card
Line
Count
Source
230
29.6k
    pub fn card(&self) -> usize {
231
29.6k
        match self {
232
14
            SparseSetU::Large { set } => set.len(),
233
29.6k
            SparseSetU::Small { card, .. } => *card,
234
        }
235
29.6k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::card
Line
Count
Source
230
58.6k
    pub fn card(&self) -> usize {
231
58.6k
        match self {
232
2.26k
            SparseSetU::Large { set } => set.len(),
233
56.3k
            SparseSetU::Small { card, .. } => *card,
234
        }
235
58.6k
    }
236
237
    #[inline(never)]
238
236k
    pub fn insert(&mut self, item: A::Item) {
239
236k
        match self {
240
20.4k
            SparseSetU::Large { set } => {
241
20.4k
                set.insert(item);
242
20.4k
            }
243
216k
            SparseSetU::Small { card, arr } => {
244
216k
                assert!(*card <= A::size());
245
                // Do we already have it?
246
216k
                if small_contains(*card, arr, item) {
247
47.6k
                    return;
248
168k
                }
249
168k
                // No.
250
168k
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
251
167k
                if *card < A::size() {
252
167k
                    // Stay small
253
167k
                    unsafe {
254
167k
                        write(arr_p.add(*card), item);
255
167k
                    }
256
167k
                    *card += 1;
257
1.17k
                } else {
258
1.17k
                    // Transition up
259
1.17k
                    self.upgrade();
260
1.17k
                    self.insert(item);
261
1.17k
                }
262
            }
263
        }
264
236k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::insert
Line
Count
Source
238
105k
    pub fn insert(&mut self, item: A::Item) {
239
105k
        match self {
240
238
            SparseSetU::Large { set } => {
241
238
                set.insert(item);
242
238
            }
243
104k
            SparseSetU::Small { card, arr } => {
244
104k
                assert!(*card <= A::size());
245
                // Do we already have it?
246
104k
                if small_contains(*card, arr, item) {
247
40.3k
                    return;
248
64.4k
                }
249
64.4k
                // No.
250
64.4k
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
251
64.3k
                if *card < A::size() {
252
64.3k
                    // Stay small
253
64.3k
                    unsafe {
254
64.3k
                        write(arr_p.add(*card), item);
255
64.3k
                    }
256
64.3k
                    *card += 1;
257
89
                } else {
258
89
                    // Transition up
259
89
                    self.upgrade();
260
89
                    self.insert(item);
261
89
                }
262
            }
263
        }
264
105k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::linear_scan::analysis::RangeId; 12]>>::insert
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::BlockIx; 4]>>::insert
Line
Count
Source
238
51.7k
    pub fn insert(&mut self, item: A::Item) {
239
51.7k
        match self {
240
631
            SparseSetU::Large { set } => {
241
631
                set.insert(item);
242
631
            }
243
51.0k
            SparseSetU::Small { card, arr } => {
244
51.0k
                assert!(*card <= A::size());
245
                // Do we already have it?
246
51.0k
                if small_contains(*card, arr, item) {
247
1.66k
                    return;
248
49.4k
                }
249
49.4k
                // No.
250
49.4k
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
251
49.0k
                if *card < A::size() {
252
49.0k
                    // Stay small
253
49.0k
                    unsafe {
254
49.0k
                        write(arr_p.add(*card), item);
255
49.0k
                    }
256
49.0k
                    *card += 1;
257
317
                } else {
258
317
                    // Transition up
259
317
                    self.upgrade();
260
317
                    self.insert(item);
261
317
                }
262
            }
263
        }
264
51.7k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 4]>>::insert
Line
Count
Source
238
23.9k
    pub fn insert(&mut self, item: A::Item) {
239
23.9k
        match self {
240
1.77k
            SparseSetU::Large { set } => {
241
1.77k
                set.insert(item);
242
1.77k
            }
243
22.1k
            SparseSetU::Small { card, arr } => {
244
22.1k
                assert!(*card <= A::size());
245
                // Do we already have it?
246
22.1k
                if small_contains(*card, arr, item) {
247
218
                    return;
248
21.9k
                }
249
21.9k
                // No.
250
21.9k
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
251
21.7k
                if *card < A::size() {
252
21.7k
                    // Stay small
253
21.7k
                    unsafe {
254
21.7k
                        write(arr_p.add(*card), item);
255
21.7k
                    }
256
21.7k
                    *card += 1;
257
221
                } else {
258
221
                    // Transition up
259
221
                    self.upgrade();
260
221
                    self.insert(item);
261
221
                }
262
            }
263
        }
264
23.9k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::linear_scan::analysis::RangeId; 4]>>::insert
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::VirtualRangeIx; 4]>>::insert
Line
Count
Source
238
22.7k
    pub fn insert(&mut self, item: A::Item) {
239
22.7k
        match self {
240
919
            SparseSetU::Large { set } => {
241
919
                set.insert(item);
242
919
            }
243
21.8k
            SparseSetU::Small { card, arr } => {
244
21.8k
                assert!(*card <= A::size());
245
                // Do we already have it?
246
21.8k
                if small_contains(*card, arr, item) {
247
0
                    return;
248
21.8k
                }
249
21.8k
                // No.
250
21.8k
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
251
21.7k
                if *card < A::size() {
252
21.7k
                    // Stay small
253
21.7k
                    unsafe {
254
21.7k
                        write(arr_p.add(*card), item);
255
21.7k
                    }
256
21.7k
                    *card += 1;
257
103
                } else {
258
103
                    // Transition up
259
103
                    self.upgrade();
260
103
                    self.insert(item);
261
103
                }
262
            }
263
        }
264
22.7k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 12]>>::insert
Line
Count
Source
238
33.3k
    pub fn insert(&mut self, item: A::Item) {
239
33.3k
        match self {
240
16.8k
            SparseSetU::Large { set } => {
241
16.8k
                set.insert(item);
242
16.8k
            }
243
16.4k
            SparseSetU::Small { card, arr } => {
244
16.4k
                assert!(*card <= A::size());
245
                // Do we already have it?
246
16.4k
                if small_contains(*card, arr, item) {
247
5.38k
                    return;
248
11.1k
                }
249
11.1k
                // No.
250
11.1k
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
251
10.6k
                if *card < A::size() {
252
10.6k
                    // Stay small
253
10.6k
                    unsafe {
254
10.6k
                        write(arr_p.add(*card), item);
255
10.6k
                    }
256
10.6k
                    *card += 1;
257
441
                } else {
258
441
                    // Transition up
259
441
                    self.upgrade();
260
441
                    self.insert(item);
261
441
                }
262
            }
263
        }
264
33.3k
    }
265
266
    #[inline(always)]
267
97.9k
    pub fn contains(&self, item: A::Item) -> bool {
268
97.9k
        match self {
269
11.0k
            SparseSetU::Large { set } => set.contains(&item),
270
86.8k
            SparseSetU::Small { card, arr } => small_contains(*card, arr, item),
271
        }
272
97.9k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::contains
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::VirtualRangeIx; 4]>>::contains
Line
Count
Source
267
28.5k
    pub fn contains(&self, item: A::Item) -> bool {
268
28.5k
        match self {
269
992
            SparseSetU::Large { set } => set.contains(&item),
270
27.6k
            SparseSetU::Small { card, arr } => small_contains(*card, arr, item),
271
        }
272
28.5k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::contains
Line
Count
Source
267
56.3k
    pub fn contains(&self, item: A::Item) -> bool {
268
56.3k
        match self {
269
0
            SparseSetU::Large { set } => set.contains(&item),
270
56.3k
            SparseSetU::Small { card, arr } => small_contains(*card, arr, item),
271
        }
272
56.3k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::data_structures::VirtualRangeIx; 4]>>::contains
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::contains
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 12]>>::contains
Line
Count
Source
267
13.0k
    pub fn contains(&self, item: A::Item) -> bool {
268
13.0k
        match self {
269
10.0k
            SparseSetU::Large { set } => set.contains(&item),
270
2.98k
            SparseSetU::Small { card, arr } => small_contains(*card, arr, item),
271
        }
272
13.0k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::linear_scan::analysis::RangeId; 12]>>::contains
273
274
    #[inline(never)]
275
79.7k
    pub fn union(&mut self, other: &Self) {
276
79.7k
        match self {
277
2.47k
            SparseSetU::Large { set: set1 } => match other {
278
365
                SparseSetU::Large { set: set2 } => {
279
4.76k
                    for item in set2.iter() {
280
4.76k
                        set1.insert(*item);
281
4.76k
                    }
282
                }
283
                SparseSetU::Small {
284
2.11k
                    card: card2,
285
2.11k
                    arr: arr2,
286
2.11k
                } => {
287
2.11k
                    let arr2_p = arr2.as_ptr() as *const A::Item;
288
5.88k
                    for i in 0..*card2 {
289
5.88k
                        let item = unsafe { read(arr2_p.add(i)) };
290
5.88k
                        set1.insert(item);
291
5.88k
                    }
292
                }
293
            },
294
            SparseSetU::Small {
295
77.2k
                card: card1,
296
77.2k
                arr: arr1,
297
77.2k
            } => {
298
77.2k
                let arr1_p = arr1.as_mut_ptr() as *mut A::Item;
299
77.2k
                match other {
300
1.73k
                    SparseSetU::Large { set: set2 } => {
301
1.73k
                        let mut set2c = set2.clone();
302
1.73k
                        for i in 0..*card1 {
303
1.27k
                            let item = unsafe { read(arr1_p.add(i)) };
304
1.27k
                            set2c.insert(item);
305
1.27k
                        }
306
1.73k
                        *self = SparseSetU::Large { set: set2c };
307
                    }
308
                    SparseSetU::Small {
309
75.5k
                        card: card2,
310
75.5k
                        arr: arr2,
311
75.5k
                    } => {
312
75.5k
                        let mut extras: MaybeUninit<A> = MaybeUninit::uninit();
313
75.5k
                        let mut n_extras = 0;
314
75.5k
                        let extras_p = extras.as_mut_ptr() as *mut A::Item;
315
75.5k
                        let arr2_p = arr2.as_ptr() as *const A::Item;
316
                        // Iterate through the second set.  Add every item not in the
317
                        // first set to `extras`.
318
134k
                        for i in 0..*card2 {
319
134k
                            let item2 = unsafe { read(arr2_p.add(i)) };
320
134k
                            let mut in1 = false;
321
180k
                            for j in 0..*card1 {
322
180k
                                let item1 = unsafe { read(arr1_p.add(j)) };
323
180k
                                if item1 == item2 {
324
28.6k
                                    in1 = true;
325
28.6k
                                    break;
326
152k
                                }
327
                            }
328
134k
                            if !in1 {
329
                                debug_assert!(n_extras < A::size());
330
106k
                                unsafe {
331
106k
                                    write(extras_p.add(n_extras), item2);
332
106k
                                }
333
106k
                                n_extras += 1;
334
28.6k
                            }
335
                        }
336
                        // The result is the concatenation of arr1 and extras.
337
106k
                        for i in 0..n_extras {
338
106k
                            let item = unsafe { read(extras_p.add(i)) };
339
106k
                            self.insert_no_dup_check(item);
340
106k
                        }
341
                    }
342
                }
343
            }
344
        }
345
79.7k
    }
346
347
    #[inline(never)]
348
48.6k
    pub fn remove(&mut self, other: &Self) {
349
48.6k
        match self {
350
2.60k
            SparseSetU::Large { set: set1 } => {
351
2.60k
                match other {
352
0
                    SparseSetU::Large { set: set2 } => {
353
0
                        for item in set2.iter() {
354
0
                            set1.remove(item);
355
0
                        }
356
                    }
357
                    SparseSetU::Small {
358
2.60k
                        card: card2,
359
2.60k
                        arr: arr2,
360
2.60k
                    } => {
361
2.60k
                        let arr2_p = arr2.as_ptr() as *const A::Item;
362
7.50k
                        for i in 0..*card2 {
363
7.50k
                            let item = unsafe { read(arr2_p.add(i)) };
364
7.50k
                            set1.remove(&item);
365
7.50k
                        }
366
                    }
367
                }
368
2.60k
                self.maybe_downgrade();
369
            }
370
            SparseSetU::Small {
371
46.0k
                card: card1,
372
46.0k
                arr: arr1,
373
46.0k
            } => {
374
46.0k
                let arr1_p = arr1.as_mut_ptr() as *mut A::Item;
375
46.0k
                match other {
376
0
                    SparseSetU::Large { set: set2 } => {
377
0
                        let mut w = 0;
378
0
                        for r in 0..*card1 {
379
0
                            let item = unsafe { read(arr1_p.add(r)) };
380
0
                            let is_in2 = set2.contains(&item);
381
0
                            if !is_in2 {
382
                                // Keep it.
383
0
                                if r != w {
384
0
                                    unsafe {
385
0
                                        write(arr1_p.add(w), item);
386
0
                                    }
387
0
                                }
388
0
                                w += 1;
389
0
                            }
390
                        }
391
0
                        *card1 = w;
392
                    }
393
                    SparseSetU::Small {
394
46.0k
                        card: card2,
395
46.0k
                        arr: arr2,
396
                    } => {
397
46.0k
                        let arr2_p = arr2.as_ptr() as *const A::Item;
398
46.0k
                        let mut w = 0;
399
109k
                        for r in 0..*card1 {
400
109k
                            let item = unsafe { read(arr1_p.add(r)) };
401
109k
                            let mut is_in2 = false;
402
239k
                            for i in 0..*card2 {
403
239k
                                if unsafe { read(arr2_p.add(i)) } == item {
404
39.4k
                                    is_in2 = true;
405
39.4k
                                    break;
406
200k
                                }
407
                            }
408
109k
                            if !is_in2 {
409
                                // Keep it.
410
69.6k
                                if r != w {
411
21.9k
                                    unsafe {
412
21.9k
                                        write(arr1_p.add(w), item);
413
21.9k
                                    }
414
47.7k
                                }
415
69.6k
                                w += 1;
416
39.4k
                            }
417
                        }
418
46.0k
                        *card1 = w;
419
                    }
420
                }
421
            }
422
        }
423
48.6k
    }
424
425
    // return true if `self` is a subset of `other`
426
    #[inline(never)]
427
3.64k
    pub fn is_subset_of(&self, other: &Self) -> bool {
428
3.64k
        if self.card() > other.card() {
429
183
            return false;
430
3.45k
        }
431
3.45k
        // Visit all items in `self`, and see if they are in `other`.  If so
432
3.45k
        // return true.
433
3.45k
        match self {
434
0
            SparseSetU::Large { set: set1 } => match other {
435
0
                SparseSetU::Large { set: set2 } => set1.is_subset(set2),
436
                SparseSetU::Small {
437
0
                    card: card2,
438
0
                    arr: arr2,
439
                } => {
440
0
                    for item in set1.iter() {
441
0
                        if !small_contains(*card2, arr2, *item) {
442
0
                            return false;
443
0
                        }
444
                    }
445
0
                    true
446
                }
447
            },
448
            SparseSetU::Small {
449
3.45k
                card: card1,
450
3.45k
                arr: arr1,
451
3.45k
            } => {
452
3.45k
                let arr1_p = arr1.as_ptr() as *const A::Item;
453
3.45k
                match other {
454
0
                    SparseSetU::Large { set: set2 } => {
455
0
                        for i in 0..*card1 {
456
0
                            let item = unsafe { read(arr1_p.add(i)) };
457
0
                            if !set2.contains(&item) {
458
0
                                return false;
459
0
                            }
460
                        }
461
0
                        true
462
                    }
463
                    SparseSetU::Small {
464
3.45k
                        card: card2,
465
3.45k
                        arr: arr2,
466
                    } => {
467
3.45k
                        for i in 0..*card1 {
468
0
                            let item = unsafe { read(arr1_p.add(i)) };
469
0
                            if !small_contains(*card2, arr2, item) {
470
0
                                return false;
471
0
                            }
472
                        }
473
3.45k
                        true
474
                    }
475
                }
476
            }
477
        }
478
3.64k
    }
479
480
    #[inline(never)]
481
7.10k
    pub fn from_vec(vec: Vec<A::Item>) -> Self {
482
7.10k
        let vec_len = vec.len();
483
7.10k
        if vec_len <= A::size() {
484
7.10k
            let mut card = 0;
485
7.10k
            let mut arr: MaybeUninit<A> = MaybeUninit::uninit();
486
7.10k
            for i in 0..vec_len {
487
0
                let item = vec[i];
488
0
                if small_contains(card, &arr, item) {
489
                    continue;
490
0
                }
491
0
                let arr_p = arr.as_mut_ptr() as *mut A::Item;
492
0
                unsafe { write(arr_p.add(card), item) }
493
0
                card += 1;
494
            }
495
7.10k
            SparseSetU::Small { card, arr }
496
        } else {
497
0
            let mut set = FxHashSet::<A::Item>::default();
498
0
            for i in 0..vec_len {
499
0
                set.insert(vec[i]);
500
0
            }
501
0
            SparseSetU::Large { set }
502
        }
503
7.10k
    }
504
505
    #[inline(never)]
506
25.6k
    pub fn equals(&self, other: &Self) -> bool {
507
25.6k
        if self.card() != other.card() {
508
14.4k
            return false;
509
11.2k
        }
510
11.2k
        match (self, other) {
511
439
            (SparseSetU::Large { set: set1 }, SparseSetU::Large { set: set2 }) => set1 == set2,
512
            (
513
                SparseSetU::Small {
514
10.7k
                    card: card1,
515
10.7k
                    arr: arr1,
516
                },
517
                SparseSetU::Small {
518
10.7k
                    card: card2,
519
10.7k
                    arr: arr2,
520
                },
521
            ) => {
522
10.7k
                assert!(*card1 == *card2);
523
                // Check to see that all items in arr1 are present in arr2.  Since the
524
                // arrays have the same length and are duplicate free, although
525
                // unordered, this is a sufficient equality test.
526
10.7k
                let arr1_p = arr1.as_ptr() as *const A::Item;
527
10.7k
                let arr2_p = arr2.as_ptr() as *const A::Item;
528
10.7k
                for i1 in 0..*card1 {
529
8.91k
                    let item1 = unsafe { read(arr1_p.add(i1)) };
530
8.91k
                    let mut found1 = false;
531
34.5k
                    for i2 in 0..*card2 {
532
34.5k
                        let item2 = unsafe { read(arr2_p.add(i2)) };
533
34.5k
                        if item1 == item2 {
534
8.91k
                            found1 = true;
535
8.91k
                            break;
536
25.6k
                        }
537
                    }
538
8.91k
                    if !found1 {
539
0
                        return false;
540
8.91k
                    }
541
                }
542
10.7k
                true
543
            }
544
0
            (SparseSetU::Small { card, arr }, SparseSetU::Large { set })
545
32
            | (SparseSetU::Large { set }, SparseSetU::Small { card, arr }) => {
546
                // Same rationale as above as to why this is a sufficient test.
547
32
                let arr_p = arr.as_ptr() as *const A::Item;
548
367
                for i in 0..*card {
549
367
                    let item = unsafe { read(arr_p.add(i)) };
550
367
                    if !set.contains(&item) {
551
0
                        return false;
552
367
                    }
553
                }
554
32
                true
555
            }
556
        }
557
25.6k
    }
558
}
559
560
impl<A> SparseSetU<A>
561
where
562
    A: Array,
563
    A::Item: Eq + Ord + Hash + Copy + fmt::Debug,
564
{
565
    #[inline(never)]
566
183
    pub fn to_vec(&self) -> Vec<A::Item> {
567
183
        let mut res = Vec::<A::Item>::new();
568
183
        match self {
569
71
            SparseSetU::Large { set } => {
570
784
                for item in set.iter() {
571
784
                    res.push(*item);
572
784
                }
573
            }
574
112
            SparseSetU::Small { card, arr } => {
575
112
                let arr_p = arr.as_ptr() as *const A::Item;
576
469
                for i in 0..*card {
577
469
                    res.push(unsafe { read(arr_p.add(i)) });
578
469
                }
579
            }
580
        }
581
        // Don't delete this.  It is important.
582
183
        res.sort_unstable();
583
183
        res
584
183
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::to_vec
Line
Count
Source
566
183
    pub fn to_vec(&self) -> Vec<A::Item> {
567
183
        let mut res = Vec::<A::Item>::new();
568
183
        match self {
569
71
            SparseSetU::Large { set } => {
570
784
                for item in set.iter() {
571
784
                    res.push(*item);
572
784
                }
573
            }
574
112
            SparseSetU::Small { card, arr } => {
575
112
                let arr_p = arr.as_ptr() as *const A::Item;
576
469
                for i in 0..*card {
577
469
                    res.push(unsafe { read(arr_p.add(i)) });
578
469
                }
579
            }
580
        }
581
        // Don't delete this.  It is important.
582
183
        res.sort_unstable();
583
183
        res
584
183
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::data_structures::BlockIx; 4]>>::to_vec
585
}
586
587
impl<A> fmt::Debug for SparseSetU<A>
588
where
589
    A: Array + Eq + Ord + Hash + Copy + fmt::Debug,
590
    A::Item: Eq + Ord + Hash + Copy + fmt::Debug,
591
{
592
    #[inline(never)]
593
0
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
594
0
        // Print the elements in some way which depends only on what is
595
0
        // present in the set, and not on any other factor.  In particular,
596
0
        // <Debug for FxHashSet> has been observed to to print the elements
597
0
        // of a two element set in both orders on different occasions.
598
0
        let sorted_vec = self.to_vec();
599
0
        let mut s = "{".to_string();
600
0
        for i in 0..sorted_vec.len() {
601
0
            if i > 0 {
602
0
                s = s + &", ".to_string();
603
0
            }
604
0
            s = s + &format!("{:?}", &sorted_vec[i]);
605
        }
606
0
        s = s + &"}".to_string();
607
0
        write!(fmt, "{}", s)
608
0
    }
609
}
610
611
impl<A> Clone for SparseSetU<A>
612
where
613
    A: Array + Eq + Hash + Copy + Clone,
614
    A::Item: Eq + Hash + Copy + Clone,
615
{
616
    #[inline(never)]
617
105k
    fn clone(&self) -> Self {
618
105k
        match self {
619
3.04k
            SparseSetU::Large { set } => SparseSetU::Large { set: set.clone() },
620
102k
            SparseSetU::Small { card, arr } => {
621
102k
                let arr2 = arr.clone();
622
102k
                SparseSetU::Small {
623
102k
                    card: *card,
624
102k
                    arr: arr2,
625
102k
                }
626
            }
627
        }
628
105k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]> as core::clone::Clone>::clone
Line
Count
Source
617
84.6k
    fn clone(&self) -> Self {
618
84.6k
        match self {
619
2.60k
            SparseSetU::Large { set } => SparseSetU::Large { set: set.clone() },
620
82.0k
            SparseSetU::Small { card, arr } => {
621
82.0k
                let arr2 = arr.clone();
622
82.0k
                SparseSetU::Small {
623
82.0k
                    card: *card,
624
82.0k
                    arr: arr2,
625
82.0k
                }
626
            }
627
        }
628
84.6k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::linear_scan::analysis::RangeId; 12]> as core::clone::Clone>::clone
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 12]> as core::clone::Clone>::clone
Line
Count
Source
617
3.45k
    fn clone(&self) -> Self {
618
3.45k
        match self {
619
441
            SparseSetU::Large { set } => SparseSetU::Large { set: set.clone() },
620
3.01k
            SparseSetU::Small { card, arr } => {
621
3.01k
                let arr2 = arr.clone();
622
3.01k
                SparseSetU::Small {
623
3.01k
                    card: *card,
624
3.01k
                    arr: arr2,
625
3.01k
                }
626
            }
627
        }
628
3.45k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::BlockIx; 4]> as core::clone::Clone>::clone
Line
Count
Source
617
17.6k
    fn clone(&self) -> Self {
618
17.6k
        match self {
619
0
            SparseSetU::Large { set } => SparseSetU::Large { set: set.clone() },
620
17.6k
            SparseSetU::Small { card, arr } => {
621
17.6k
                let arr2 = arr.clone();
622
17.6k
                SparseSetU::Small {
623
17.6k
                    card: *card,
624
17.6k
                    arr: arr2,
625
17.6k
                }
626
            }
627
        }
628
17.6k
    }
629
}
630
631
pub enum SparseSetUIter<'a, A: Array> {
632
    Large {
633
        set_iter: std::collections::hash_set::Iter<'a, A::Item>,
634
    },
635
    Small {
636
        card: usize,
637
        arr: &'a MaybeUninit<A>,
638
        next: usize,
639
    },
640
}
641
impl<A: Array> SparseSetU<A> {
642
344k
    pub fn iter(&self) -> SparseSetUIter<A> {
643
344k
        match self {
644
1.96k
            SparseSetU::Large { set } => SparseSetUIter::Large {
645
1.96k
                set_iter: set.iter(),
646
1.96k
            },
647
342k
            SparseSetU::Small { card, arr } => SparseSetUIter::Small {
648
342k
                card: *card,
649
342k
                arr,
650
342k
                next: 0,
651
342k
            },
652
        }
653
344k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::BlockIx; 4]>>::iter
Line
Count
Source
642
225k
    pub fn iter(&self) -> SparseSetUIter<A> {
643
225k
        match self {
644
321
            SparseSetU::Large { set } => SparseSetUIter::Large {
645
321
                set_iter: set.iter(),
646
321
            },
647
224k
            SparseSetU::Small { card, arr } => SparseSetUIter::Small {
648
224k
                card: *card,
649
224k
                arr,
650
224k
                next: 0,
651
224k
            },
652
        }
653
225k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 4]>>::iter
Line
Count
Source
642
12.0k
    pub fn iter(&self) -> SparseSetUIter<A> {
643
12.0k
        match self {
644
6
            SparseSetU::Large { set } => SparseSetUIter::Large {
645
6
                set_iter: set.iter(),
646
6
            },
647
12.0k
            SparseSetU::Small { card, arr } => SparseSetUIter::Small {
648
12.0k
                card: *card,
649
12.0k
                arr,
650
12.0k
                next: 0,
651
12.0k
            },
652
        }
653
12.0k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::linear_scan::analysis::RangeId; 4]>>::iter
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::Reg; 12]>>::iter
Line
Count
Source
642
33.4k
    pub fn iter(&self) -> SparseSetUIter<A> {
643
33.4k
        match self {
644
723
            SparseSetU::Large { set } => SparseSetUIter::Large {
645
723
                set_iter: set.iter(),
646
723
            },
647
32.7k
            SparseSetU::Small { card, arr } => SparseSetUIter::Small {
648
32.7k
                card: *card,
649
32.7k
                arr,
650
32.7k
                next: 0,
651
32.7k
            },
652
        }
653
33.4k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetU<[regalloc::linear_scan::analysis::RangeId; 12]>>::iter
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::VirtualRangeIx; 4]>>::iter
Line
Count
Source
642
67.0k
    pub fn iter(&self) -> SparseSetUIter<A> {
643
67.0k
        match self {
644
28
            SparseSetU::Large { set } => SparseSetUIter::Large {
645
28
                set_iter: set.iter(),
646
28
            },
647
67.0k
            SparseSetU::Small { card, arr } => SparseSetUIter::Small {
648
67.0k
                card: *card,
649
67.0k
                arr,
650
67.0k
                next: 0,
651
67.0k
            },
652
        }
653
67.0k
    }
<regalloc::sparse_set::SparseSetU<[regalloc::data_structures::RangeId; 12]>>::iter
Line
Count
Source
642
6.91k
    pub fn iter(&self) -> SparseSetUIter<A> {
643
6.91k
        match self {
644
882
            SparseSetU::Large { set } => SparseSetUIter::Large {
645
882
                set_iter: set.iter(),
646
882
            },
647
6.03k
            SparseSetU::Small { card, arr } => SparseSetUIter::Small {
648
6.03k
                card: *card,
649
6.03k
                arr,
650
6.03k
                next: 0,
651
6.03k
            },
652
        }
653
6.91k
    }
654
}
655
impl<'a, A: Array> Iterator for SparseSetUIter<'a, A> {
656
    type Item = &'a A::Item;
657
719k
    fn next(&mut self) -> Option<Self::Item> {
658
719k
        match self {
659
35.2k
            SparseSetUIter::Large { set_iter } => set_iter.next(),
660
684k
            SparseSetUIter::Small { card, arr, next } => {
661
684k
                if next < card {
662
371k
                    let arr_p = arr.as_ptr() as *const A::Item;
663
371k
                    let item_p = unsafe { arr_p.add(*next) };
664
371k
                    *next += 1;
665
371k
                    Some(unsafe { &*item_p })
666
                } else {
667
313k
                    None
668
                }
669
            }
670
        }
671
719k
    }
<regalloc::sparse_set::SparseSetUIter<[regalloc::data_structures::RangeId; 12]> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
657
39.8k
    fn next(&mut self) -> Option<Self::Item> {
658
39.8k
        match self {
659
23.0k
            SparseSetUIter::Large { set_iter } => set_iter.next(),
660
16.8k
            SparseSetUIter::Small { card, arr, next } => {
661
16.8k
                if next < card {
662
10.7k
                    let arr_p = arr.as_ptr() as *const A::Item;
663
10.7k
                    let item_p = unsafe { arr_p.add(*next) };
664
10.7k
                    *next += 1;
665
10.7k
                    Some(unsafe { &*item_p })
666
                } else {
667
6.03k
                    None
668
                }
669
            }
670
        }
671
39.8k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetUIter<[regalloc::linear_scan::analysis::RangeId; 4]> as core::iter::traits::iterator::Iterator>::next
<regalloc::sparse_set::SparseSetUIter<[regalloc::data_structures::Reg; 12]> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
657
119k
    fn next(&mut self) -> Option<Self::Item> {
658
119k
        match self {
659
10.3k
            SparseSetUIter::Large { set_iter } => set_iter.next(),
660
108k
            SparseSetUIter::Small { card, arr, next } => {
661
108k
                if next < card {
662
76.0k
                    let arr_p = arr.as_ptr() as *const A::Item;
663
76.0k
                    let item_p = unsafe { arr_p.add(*next) };
664
76.0k
                    *next += 1;
665
76.0k
                    Some(unsafe { &*item_p })
666
                } else {
667
32.7k
                    None
668
                }
669
            }
670
        }
671
119k
    }
<regalloc::sparse_set::SparseSetUIter<[regalloc::data_structures::RangeId; 4]> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
657
25.1k
    fn next(&mut self) -> Option<Self::Item> {
658
25.1k
        match self {
659
46
            SparseSetUIter::Large { set_iter } => set_iter.next(),
660
25.0k
            SparseSetUIter::Small { card, arr, next } => {
661
25.0k
                if next < card {
662
12.9k
                    let arr_p = arr.as_ptr() as *const A::Item;
663
12.9k
                    let item_p = unsafe { arr_p.add(*next) };
664
12.9k
                    *next += 1;
665
12.9k
                    Some(unsafe { &*item_p })
666
                } else {
667
12.0k
                    None
668
                }
669
            }
670
        }
671
25.1k
    }
<regalloc::sparse_set::SparseSetUIter<[regalloc::data_structures::VirtualRangeIx; 4]> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
657
71.6k
    fn next(&mut self) -> Option<Self::Item> {
658
71.6k
        match self {
659
462
            SparseSetUIter::Large { set_iter } => set_iter.next(),
660
71.2k
            SparseSetUIter::Small { card, arr, next } => {
661
71.2k
                if next < card {
662
4.20k
                    let arr_p = arr.as_ptr() as *const A::Item;
663
4.20k
                    let item_p = unsafe { arr_p.add(*next) };
664
4.20k
                    *next += 1;
665
4.20k
                    Some(unsafe { &*item_p })
666
                } else {
667
67.0k
                    None
668
                }
669
            }
670
        }
671
71.6k
    }
<regalloc::sparse_set::SparseSetUIter<[regalloc::data_structures::BlockIx; 4]> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
657
463k
    fn next(&mut self) -> Option<Self::Item> {
658
463k
        match self {
659
1.33k
            SparseSetUIter::Large { set_iter } => set_iter.next(),
660
462k
            SparseSetUIter::Small { card, arr, next } => {
661
462k
                if next < card {
662
267k
                    let arr_p = arr.as_ptr() as *const A::Item;
663
267k
                    let item_p = unsafe { arr_p.add(*next) };
664
267k
                    *next += 1;
665
267k
                    Some(unsafe { &*item_p })
666
                } else {
667
195k
                    None
668
                }
669
            }
670
        }
671
463k
    }
Unexecuted instantiation: <regalloc::sparse_set::SparseSetUIter<[regalloc::linear_scan::analysis::RangeId; 12]> as core::iter::traits::iterator::Iterator>::next
672
}
673
674
// ================ Testing machinery for SparseSetU ================
675
676
#[cfg(test)]
677
mod sparse_set_test_utils {
678
    // As currently set up, each number (from rand, not rand_base) has a 1-in-4
679
    // chance of being a dup of the last 8 numbers produced.
680
    pub struct RNGwithDups {
681
        seed: u32,
682
        circ: [u32; 8],
683
        circC: usize, // the cursor for `circ`
684
    }
685
    impl RNGwithDups {
686
        pub fn new() -> Self {
687
            Self {
688
                seed: 0,
689
                circ: [0; 8],
690
                circC: 0,
691
            }
692
        }
693
        fn rand_base(&mut self) -> u32 {
694
            self.seed = self.seed.wrapping_mul(1103515245).wrapping_add(12345);
695
            self.seed
696
        }
697
        pub fn rand(&mut self) -> u32 {
698
            let r = self.rand_base();
699
            let rlo = r & 0xFFFF;
700
            let rhi = (r >> 16) & 0xFF;
701
            if rhi < 64 {
702
                self.circ[(rhi % 8) as usize]
703
            } else {
704
                self.circ[self.circC as usize] = rlo;
705
                self.circC += 1;
706
                if self.circC == 8 {
707
                    self.circC = 0
708
                };
709
                rlo
710
            }
711
        }
712
        pub fn rand_vec(&mut self, len: usize) -> Vec<u32> {
713
            let mut res = vec![];
714
            for _ in 0..len {
715
                res.push(self.rand());
716
            }
717
            res
718
        }
719
    }
720
}
721
722
#[test]
723
fn test_sparse_set() {
724
    use crate::data_structures::Set;
725
    let mut set = SparseSetU::<[u32; 3]>::empty();
726
    assert!(set.is_small());
727
    set.insert(3);
728
    assert!(set.is_small());
729
    set.insert(1);
730
    assert!(set.is_small());
731
    set.insert(4);
732
    assert!(set.is_small());
733
    set.insert(7);
734
    assert!(set.is_large());
735
736
    let iters = 20;
737
    let mut rng = sparse_set_test_utils::RNGwithDups::new();
738
739
    // empty
740
    {
741
        let spa = SparseSetU::<[u32; 10]>::empty();
742
        assert!(spa.card() == 0);
743
    }
744
745
    // card, is_empty
746
    for _ in 0..iters * 3 {
747
        for n1 in 0..100 {
748
            let size1 = n1 % 25;
749
            let vec1a = rng.rand_vec(size1);
750
            let vec1b = vec1a.clone(); // This is very stupid.
751
            let spa1 = SparseSetU::<[u32; 10]>::from_vec(vec1a);
752
            let std1 = Set::<u32>::from_vec(vec1b);
753
            assert!(spa1.card() == std1.card());
754
            assert!(spa1.is_empty() == (size1 == 0));
755
        }
756
    }
757
758
    // insert
759
    for _ in 0..iters * 3 {
760
        for n1 in 0..100 {
761
            let size1 = n1 % 25;
762
            let vec1a = rng.rand_vec(size1);
763
            let vec1b = vec1a.clone();
764
            let tmp = if size1 == 0 { 0 } else { vec1a[0] };
765
            let mut spa1 = SparseSetU::<[u32; 10]>::from_vec(vec1a);
766
            let mut std1 = Set::<u32>::from_vec(vec1b);
767
            // Insert an item which is almost certainly not in the set.
768
            let n = rng.rand();
769
            spa1.insert(n);
770
            std1.insert(n);
771
            assert!(spa1.card() == std1.card());
772
            assert!(spa1.to_vec() == std1.to_vec());
773
            // Insert an item which is already in the set.
774
            if n1 > 0 {
775
                spa1.insert(tmp);
776
                std1.insert(tmp);
777
                assert!(spa1.card() == std1.card());
778
                assert!(spa1.to_vec() == std1.to_vec());
779
            }
780
        }
781
    }
782
783
    // contains
784
    for _ in 0..iters * 2 {
785
        for n1 in 0..100 {
786
            let size1 = n1 % 25;
787
            let vec1a = rng.rand_vec(size1);
788
            let vec1b = vec1a.clone();
789
            let tmp = if size1 == 0 { 0 } else { vec1a[0] };
790
            let spa1 = SparseSetU::<[u32; 10]>::from_vec(vec1a);
791
            let std1 = Set::<u32>::from_vec(vec1b);
792
            // Check for an item which is almost certainly not in the set.
793
            let n = rng.rand();
794
            assert!(spa1.contains(n) == std1.contains(n));
795
            // Check for an item which is already in the set.
796
            if n1 > 0 {
797
                assert!(spa1.contains(tmp) == std1.contains(tmp));
798
            }
799
        }
800
    }
801
802
    // union
803
    for _ in 0..iters * 2 {
804
        for size1 in 0..25 {
805
            for size2 in 0..25 {
806
                let vec1a = rng.rand_vec(size1);
807
                let vec2a = rng.rand_vec(size2);
808
                let vec1b = vec1a.clone();
809
                let vec2b = vec2a.clone();
810
                let mut spa1 = SparseSetU::<[u32; 10]>::from_vec(vec1a);
811
                let spa2 = SparseSetU::<[u32; 10]>::from_vec(vec2a);
812
                let mut std1 = Set::<u32>::from_vec(vec1b);
813
                let std2 = Set::<u32>::from_vec(vec2b);
814
                spa1.union(&spa2);
815
                std1.union(&std2);
816
                assert!(spa1.to_vec() == std1.to_vec());
817
            }
818
        }
819
    }
820
821
    // remove
822
    for _ in 0..iters * 2 {
823
        for size1 in 0..25 {
824
            for size2 in 0..25 {
825
                let vec1a = rng.rand_vec(size1);
826
                let vec2a = rng.rand_vec(size2);
827
                let vec1b = vec1a.clone();
828
                let vec2b = vec2a.clone();
829
                let mut spa1 = SparseSetU::<[u32; 10]>::from_vec(vec1a);
830
                let spa2 = SparseSetU::<[u32; 10]>::from_vec(vec2a);
831
                let mut std1 = Set::<u32>::from_vec(vec1b);
832
                let std2 = Set::<u32>::from_vec(vec2b);
833
                spa1.remove(&spa2);
834
                std1.remove(&std2);
835
                assert!(spa1.to_vec() == std1.to_vec());
836
            }
837
        }
838
    }
839
840
    // is_subset_of
841
    for _ in 0..iters * 2 {
842
        for size1 in 0..25 {
843
            for size2 in 0..25 {
844
                let vec1a = rng.rand_vec(size1);
845
                let vec2a = rng.rand_vec(size2);
846
                let vec1b = vec1a.clone();
847
                let vec2b = vec2a.clone();
848
                let spa1 = SparseSetU::<[u32; 10]>::from_vec(vec1a);
849
                let spa2 = SparseSetU::<[u32; 10]>::from_vec(vec2a);
850
                let std1 = Set::<u32>::from_vec(vec1b);
851
                let std2 = Set::<u32>::from_vec(vec2b);
852
                assert!(spa1.is_subset_of(&spa2) == std1.is_subset_of(&std2));
853
            }
854
        }
855
    }
856
857
    // to_vec and from_vec are implicitly tested by the above; there's no way
858
    // they could be wrong and still have the above tests succeed.
859
    // (Famous last words!)
860
861
    // equals
862
    for _ in 0..iters * 2 {
863
        for size1 in 0..25 {
864
            for size2 in 0..25 {
865
                let vec1a = rng.rand_vec(size1);
866
                let vec2a = rng.rand_vec(size2);
867
                let vec1b = vec1a.clone();
868
                let vec2b = vec2a.clone();
869
                let spa1 = SparseSetU::<[u32; 10]>::from_vec(vec1a);
870
                let spa2 = SparseSetU::<[u32; 10]>::from_vec(vec2a);
871
                let std1 = Set::<u32>::from_vec(vec1b);
872
                let std2 = Set::<u32>::from_vec(vec2b);
873
                assert!(std1.equals(&std1)); // obviously
874
                assert!(std2.equals(&std2)); // obviously
875
                assert!(spa1.equals(&spa1)); // obviously
876
                assert!(spa2.equals(&spa2)); // obviously
877
                                             // More seriously
878
                assert!(spa1.equals(&spa2) == std1.equals(&std2));
879
            }
880
        }
881
    }
882
883
    // clone
884
    for _ in 0..iters * 3 {
885
        for n1 in 0..100 {
886
            let size1 = n1 % 25;
887
            let vec1a = rng.rand_vec(size1);
888
            let spa1 = SparseSetU::<[u32; 10]>::from_vec(vec1a);
889
            let spa2 = spa1.clone();
890
            assert!(spa1.equals(&spa2));
891
        }
892
    }
893
}