diff options
| author | Simonas Kazlauskas <git@kazlauskas.me> | 2016-01-31 19:17:15 +0200 |
|---|---|---|
| committer | Simonas Kazlauskas <git@kazlauskas.me> | 2016-02-23 11:43:52 +0200 |
| commit | b92e2437f5e2653f6a486c84732466ed1812c353 (patch) | |
| tree | 939540804264df6ce175378399fac6bbcc8de8e6 /src/librustc_data_structures | |
| parent | be7196a793a185355efb7ec8801102ddec95483d (diff) | |
[MIR] Change SimplifyCfg pass to use bitvec
BitVector is much more space efficient.
Diffstat (limited to 'src/librustc_data_structures')
| -rw-r--r-- | src/librustc_data_structures/bitvec.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/librustc_data_structures/bitvec.rs b/src/librustc_data_structures/bitvec.rs index 70f50b4c042..7b5dacece8c 100644 --- a/src/librustc_data_structures/bitvec.rs +++ b/src/librustc_data_structures/bitvec.rs @@ -50,6 +50,45 @@ impl BitVector { let extra_words = self.data.len() - num_words; self.data.extend((0..extra_words).map(|_| 0)); } + + /// Iterates over indexes of set bits in a sorted order + pub fn iter<'a>(&'a self) -> BitVectorIter<'a> { + BitVectorIter { + iter: self.data.iter(), + current: 0, + idx: 0 + } + } +} + +pub struct BitVectorIter<'a> { + iter: ::std::slice::Iter<'a, u64>, + current: u64, + idx: usize +} + +impl<'a> Iterator for BitVectorIter<'a> { + type Item = usize; + fn next(&mut self) -> Option<usize> { + while self.current == 0 { + self.current = if let Some(&i) = self.iter.next() { + if i == 0 { + self.idx += 64; + continue; + } else { + self.idx = u64s(self.idx) * 64; + i + } + } else { + return None; + } + } + let offset = self.current.trailing_zeros() as usize; + self.current >>= offset; + self.current >>= 1; // shift otherwise overflows for 0b1000_0000_…_0000 + self.idx += offset + 1; + return Some(self.idx - 1); + } } /// A "bit matrix" is basically a square matrix of booleans @@ -154,6 +193,46 @@ fn word_mask(index: usize) -> (usize, u64) { } #[test] +fn bitvec_iter_works() { + let mut bitvec = BitVector::new(100); + bitvec.insert(1); + bitvec.insert(10); + bitvec.insert(19); + bitvec.insert(62); + bitvec.insert(63); + bitvec.insert(64); + bitvec.insert(65); + bitvec.insert(66); + bitvec.insert(99); + assert_eq!(bitvec.iter().collect::<Vec<_>>(), [1, 10, 19, 62, 63, 64, 65, 66, 99]); +} + +#[test] +fn bitvec_iter_works_2() { + let mut bitvec = BitVector::new(300); + bitvec.insert(1); + bitvec.insert(10); + bitvec.insert(19); + bitvec.insert(62); + bitvec.insert(66); + bitvec.insert(99); + bitvec.insert(299); + assert_eq!(bitvec.iter().collect::<Vec<_>>(), [1, 10, 19, 62, 66, 99, 299]); + +} + +#[test] +fn bitvec_iter_works_3() { + let mut bitvec = BitVector::new(319); + bitvec.insert(0); + bitvec.insert(127); + bitvec.insert(191); + bitvec.insert(255); + bitvec.insert(319); + assert_eq!(bitvec.iter().collect::<Vec<_>>(), [0, 127, 191, 255, 319]); +} + +#[test] fn union_two_vecs() { let mut vec1 = BitVector::new(65); let mut vec2 = BitVector::new(65); |
