@@ -183,6 +183,9 @@ impl core::fmt::Display for PReg {
183183 }
184184}
185185
186+ /// A type for internal bit arrays.
187+ type Bits = u64 ;
188+
186189/// A physical register set. Used to represent clobbers
187190/// efficiently.
188191///
@@ -191,82 +194,92 @@ impl core::fmt::Display for PReg {
191194#[ derive( Clone , Copy , Debug , PartialEq , Eq , PartialOrd , Ord , Hash , Default ) ]
192195#[ cfg_attr( feature = "enable-serde" , derive( Serialize , Deserialize ) ) ]
193196pub struct PRegSet {
194- bits : [ u128 ; 2 ] ,
197+ bits : [ Bits ; Self :: LEN ] ,
195198}
196199
197200impl PRegSet {
201+ /// The number of bits per element in the internal bit array.
202+ const BITS : usize = core:: mem:: size_of :: < Bits > ( ) * 8 ;
203+
204+ /// Length of the internal bit array.
205+ const LEN : usize = ( PReg :: NUM_INDEX + Self :: BITS - 1 ) / Self :: BITS ;
206+
198207 /// Create an empty set.
199208 pub const fn empty ( ) -> Self {
200- Self { bits : [ 0 ; 2 ] }
209+ Self {
210+ bits : [ 0 ; Self :: LEN ] ,
211+ }
212+ }
213+
214+ /// Splits the given register index into parts to access the internal bit array.
215+ const fn split_index ( reg : PReg ) -> ( usize , usize ) {
216+ let index = reg. index ( ) ;
217+ ( index >> Self :: BITS . ilog2 ( ) , index & ( Self :: BITS - 1 ) )
201218 }
202219
203220 /// Returns whether the given register is part of the set.
204221 pub fn contains ( & self , reg : PReg ) -> bool {
205- debug_assert ! ( reg. index( ) < 256 ) ;
206- let bit = reg. index ( ) & 127 ;
207- let index = reg. index ( ) >> 7 ;
208- self . bits [ index] & ( 1u128 << bit) != 0
222+ let ( index, bit) = Self :: split_index ( reg) ;
223+ self . bits [ index] & ( 1 << bit) != 0
209224 }
210225
211226 /// Add a physical register (PReg) to the set, returning the new value.
212227 pub const fn with ( self , reg : PReg ) -> Self {
213- debug_assert ! ( reg. index( ) < 256 ) ;
214- let bit = reg. index ( ) & 127 ;
215- let index = reg. index ( ) >> 7 ;
228+ let ( index, bit) = Self :: split_index ( reg) ;
216229 let mut out = self ;
217- out. bits [ index] |= 1u128 << bit;
230+ out. bits [ index] |= 1 << bit;
218231 out
219232 }
220233
221234 /// Add a physical register (PReg) to the set.
222235 pub fn add ( & mut self , reg : PReg ) {
223- debug_assert ! ( reg. index( ) < 256 ) ;
224- let bit = reg. index ( ) & 127 ;
225- let index = reg. index ( ) >> 7 ;
226- self . bits [ index] |= 1u128 << bit;
236+ let ( index, bit) = Self :: split_index ( reg) ;
237+ self . bits [ index] |= 1 << bit;
227238 }
228239
229240 /// Remove a physical register (PReg) from the set.
230241 pub fn remove ( & mut self , reg : PReg ) {
231- debug_assert ! ( reg. index( ) < 256 ) ;
232- let bit = reg. index ( ) & 127 ;
233- let index = reg. index ( ) >> 7 ;
234- self . bits [ index] &= !( 1u128 << bit) ;
242+ let ( index, bit) = Self :: split_index ( reg) ;
243+ self . bits [ index] &= !( 1 << bit) ;
235244 }
236245
237246 /// Add all of the registers in one set to this one, mutating in
238247 /// place.
239248 pub fn union_from ( & mut self , other : PRegSet ) {
240- self . bits [ 0 ] |= other. bits [ 0 ] ;
241- self . bits [ 1 ] |= other. bits [ 1 ] ;
249+ for i in 0 ..self . bits . len ( ) {
250+ self . bits [ i] |= other. bits [ i] ;
251+ }
242252 }
243253}
244254
245255impl IntoIterator for PRegSet {
246256 type Item = PReg ;
247257 type IntoIter = PRegSetIter ;
248258 fn into_iter ( self ) -> PRegSetIter {
249- PRegSetIter { bits : self . bits }
259+ PRegSetIter {
260+ bits : self . bits ,
261+ cur : 0 ,
262+ }
250263 }
251264}
252265
253266pub struct PRegSetIter {
254- bits : [ u128 ; 2 ] ,
267+ bits : [ Bits ; PRegSet :: LEN ] ,
268+ cur : usize ,
255269}
256270
257271impl Iterator for PRegSetIter {
258272 type Item = PReg ;
259273 fn next ( & mut self ) -> Option < PReg > {
260- if self . bits [ 0 ] != 0 {
261- let index = self . bits [ 0 ] . trailing_zeros ( ) ;
262- self . bits [ 0 ] &= !( 1u128 << index) ;
263- Some ( PReg :: from_index ( index as usize ) )
264- } else if self . bits [ 1 ] != 0 {
265- let index = self . bits [ 1 ] . trailing_zeros ( ) ;
266- self . bits [ 1 ] &= !( 1u128 << index) ;
267- Some ( PReg :: from_index ( index as usize + 128 ) )
268- } else {
269- None
274+ loop {
275+ let bits = self . bits . get_mut ( self . cur ) ?;
276+ if * bits != 0 {
277+ let bit = bits. trailing_zeros ( ) ;
278+ * bits &= !( 1 << bit) ;
279+ let index = bit as usize + self . cur * PRegSet :: BITS ;
280+ return Some ( PReg :: from_index ( index) ) ;
281+ }
282+ self . cur += 1 ;
270283 }
271284 }
272285}
0 commit comments