@@ -293,6 +293,16 @@ impl PRegSet {
293293 pub fn is_empty ( & self , regclass : RegClass ) -> bool {
294294 self . bits [ regclass as usize ] == 0
295295 }
296+
297+ /// Returns the number of register in this set.
298+ pub fn len ( & self ) -> u32 {
299+ self . bits . iter ( ) . map ( |s| s. count_ones ( ) ) . sum ( )
300+ }
301+
302+ /// Returns the maximum register in this set, with the highest hw_enc value.
303+ pub fn max_preg ( & self ) -> Option < PReg > {
304+ self . into_iter ( ) . last ( )
305+ }
296306}
297307
298308impl core:: ops:: BitAnd < PRegSet > for PRegSet {
@@ -315,6 +325,14 @@ impl core::ops::BitOr<PRegSet> for PRegSet {
315325 }
316326}
317327
328+ impl IntoIterator for & PRegSet {
329+ type Item = PReg ;
330+ type IntoIter = PRegSetIter ;
331+ fn into_iter ( self ) -> PRegSetIter {
332+ ( * self ) . into_iter ( )
333+ }
334+ }
335+
318336impl IntoIterator for PRegSet {
319337 type Item = PReg ;
320338 type IntoIter = PRegSetIter ;
@@ -352,15 +370,11 @@ impl From<&MachineEnv> for PRegSet {
352370 let mut res = Self :: default ( ) ;
353371
354372 for class in env. preferred_regs_by_class . iter ( ) {
355- for preg in class {
356- res. add ( * preg)
357- }
373+ res. union_from ( * class)
358374 }
359375
360376 for class in env. non_preferred_regs_by_class . iter ( ) {
361- for preg in class {
362- res. add ( * preg)
363- }
377+ res. union_from ( * class)
364378 }
365379
366380 res
@@ -1483,7 +1497,7 @@ pub struct MachineEnv {
14831497 ///
14841498 /// If an explicit scratch register is provided in `scratch_by_class` then
14851499 /// it must not appear in this list.
1486- pub preferred_regs_by_class : [ Vec < PReg > ; 3 ] ,
1500+ pub preferred_regs_by_class : [ PRegSet ; 3 ] ,
14871501
14881502 /// Non-preferred physical registers for each class. These are the
14891503 /// registers that will be allocated if a preferred register is
@@ -1492,7 +1506,7 @@ pub struct MachineEnv {
14921506 ///
14931507 /// If an explicit scratch register is provided in `scratch_by_class` then
14941508 /// it must not appear in this list.
1495- pub non_preferred_regs_by_class : [ Vec < PReg > ; 3 ] ,
1509+ pub non_preferred_regs_by_class : [ PRegSet ; 3 ] ,
14961510
14971511 /// Optional dedicated scratch register per class. This is needed to perform
14981512 /// moves between registers when cyclic move patterns occur. The
@@ -1774,3 +1788,37 @@ unsafe impl allocator_api2::alloc::Allocator for Bump {
17741788 self . 0 . deref ( ) . shrink ( ptr, old_layout, new_layout)
17751789 }
17761790}
1791+
1792+ #[ cfg( test) ]
1793+ mod tests {
1794+ use super :: { PReg , PRegSet , RegClass :: Int } ;
1795+
1796+ #[ test]
1797+ fn preg_set_len ( ) {
1798+ let mut set = PRegSet :: empty ( ) ;
1799+ assert_eq ! ( set. len( ) , 0 ) ;
1800+
1801+ set. add ( PReg :: new ( 3 , Int ) ) ;
1802+ assert_eq ! ( set. len( ) , 1 ) ;
1803+ set. add ( PReg :: new ( 3 , Int ) ) ;
1804+ assert_eq ! ( set. len( ) , 1 ) ;
1805+
1806+ set. add ( PReg :: new ( 4 , Int ) ) ;
1807+ assert_eq ! ( set. len( ) , 2 ) ;
1808+ }
1809+
1810+ #[ test]
1811+ fn preg_set_max_preg ( ) {
1812+ let mut set = PRegSet :: empty ( ) ;
1813+ assert_eq ! ( set. max_preg( ) , None ) ;
1814+
1815+ set. add ( PReg :: new ( 3 , Int ) ) ;
1816+ assert_eq ! ( set. max_preg( ) , Some ( PReg :: new( 3 , Int ) ) ) ;
1817+
1818+ set. add ( PReg :: new ( 4 , Int ) ) ;
1819+ assert_eq ! ( set. max_preg( ) , Some ( PReg :: new( 4 , Int ) ) ) ;
1820+
1821+ set. add ( PReg :: new ( 2 , Int ) ) ;
1822+ assert_eq ! ( set. max_preg( ) , Some ( PReg :: new( 4 , Int ) ) ) ;
1823+ }
1824+ }
0 commit comments