11//! Iterate over available registers.
22
3- use crate :: { MachineEnv , PReg , RegClass } ;
3+ use crate :: { MachineEnv , PReg , PRegSet , PRegSetIter , RegClass } ;
44
55/// Keep track of where we are in the register traversal.
6- struct Cursor < ' a > {
7- registers : & ' a [ PReg ] ,
8- index : usize ,
9- offset : usize ,
6+ struct Cursor {
7+ first : PRegSetIter ,
8+ second : PRegSetIter ,
109}
1110
12- impl < ' a > Cursor < ' a > {
11+ impl Cursor {
1312 #[ inline]
14- fn new ( registers : & ' a [ PReg ] , offset_hint : usize ) -> Self {
15- let offset = if registers. len ( ) > 0 {
16- offset_hint % registers. len ( )
17- } else {
18- 0
19- } ;
13+ fn new ( registers : & PRegSet , class : RegClass , offset_hint : usize ) -> Self {
14+ let mut mask = PRegSet :: empty ( ) ;
15+ mask. add_up_to ( PReg :: new ( offset_hint % PReg :: MAX , class) ) ;
16+ let first = * registers & mask. invert ( ) ;
17+ let second = * registers & mask;
2018 Self {
21- registers,
22- index : 0 ,
23- offset,
19+ first : first. into_iter ( ) ,
20+ second : second. into_iter ( ) ,
2421 }
2522 }
2623
27- /// Wrap around the end of the register list; [`Cursor::done`] guarantees we
28- /// do not see the same register twice.
29- #[ inline]
30- fn wrap ( index : usize , end : usize ) -> usize {
31- if index >= end {
32- index - end
33- } else {
34- index
35- }
36- }
37-
38- /// Advance to the next register and return it.
39- #[ inline]
40- fn advance ( & mut self ) -> PReg {
41- let loc = Self :: wrap ( self . index + self . offset , self . registers . len ( ) ) ;
42- let reg = self . registers [ loc] ;
43- self . index += 1 ;
44- reg
45- }
46-
47- /// Return `true` if we have seen all registers.
48- #[ inline]
49- fn done ( & self ) -> bool {
50- self . index >= self . registers . len ( )
24+ fn next ( & mut self ) -> Option < PReg > {
25+ self . first . next ( ) . or_else ( || self . second . next ( ) )
5126 }
5227}
5328
@@ -65,19 +40,19 @@ impl<'a> Cursor<'a> {
6540/// registers; then, non-preferred registers. (In normal usage, these consist
6641/// of caller-save and callee-save registers respectively, to minimize
6742/// clobber-saves; but they need not.)
68- pub struct RegTraversalIter < ' a > {
43+ pub struct RegTraversalIter {
6944 is_fixed : bool ,
7045 fixed : Option < PReg > ,
7146 use_hint : bool ,
7247 hint : Option < PReg > ,
73- preferred : Cursor < ' a > ,
74- non_preferred : Cursor < ' a > ,
48+ preferred : Cursor ,
49+ non_preferred : Cursor ,
7550 limit : Option < usize > ,
7651}
7752
78- impl < ' a > RegTraversalIter < ' a > {
53+ impl RegTraversalIter {
7954 pub fn new (
80- env : & ' a MachineEnv ,
55+ env : & MachineEnv ,
8156 class : RegClass ,
8257 fixed : Option < PReg > ,
8358 hint : Option < PReg > ,
@@ -87,9 +62,10 @@ impl<'a> RegTraversalIter<'a> {
8762 debug_assert ! ( fixed != Some ( PReg :: invalid( ) ) ) ;
8863 debug_assert ! ( hint != Some ( PReg :: invalid( ) ) ) ;
8964
90- let class = class as u8 as usize ;
91- let preferred = Cursor :: new ( & env. preferred_regs_by_class [ class] , offset) ;
92- let non_preferred = Cursor :: new ( & env. non_preferred_regs_by_class [ class] , offset) ;
65+ let class_index = class as u8 as usize ;
66+ let preferred = Cursor :: new ( & env. preferred_regs_by_class [ class_index] , class, offset) ;
67+ let non_preferred =
68+ Cursor :: new ( & env. non_preferred_regs_by_class [ class_index] , class, offset) ;
9369
9470 Self {
9571 is_fixed : fixed. is_some ( ) ,
@@ -103,7 +79,7 @@ impl<'a> RegTraversalIter<'a> {
10379 }
10480}
10581
106- impl < ' a > core:: iter:: Iterator for RegTraversalIter < ' a > {
82+ impl core:: iter:: Iterator for RegTraversalIter {
10783 type Item = PReg ;
10884
10985 fn next ( & mut self ) -> Option < PReg > {
@@ -118,16 +94,14 @@ impl<'a> core::iter::Iterator for RegTraversalIter<'a> {
11894 }
11995 }
12096
121- while !self . preferred . done ( ) {
122- let reg = self . preferred . advance ( ) ;
97+ while let Some ( reg) = self . preferred . next ( ) {
12398 if Some ( reg) == self . hint || reg. hw_enc ( ) >= self . limit . unwrap_or ( usize:: MAX ) {
12499 continue ; // Try again; we already tried the hint or we are outside of the register range limit.
125100 }
126101 return Some ( reg) ;
127102 }
128103
129- while !self . non_preferred . done ( ) {
130- let reg = self . non_preferred . advance ( ) ;
104+ while let Some ( reg) = self . non_preferred . next ( ) {
131105 if Some ( reg) == self . hint || reg. hw_enc ( ) >= self . limit . unwrap_or ( usize:: MAX ) {
132106 continue ; // Try again; we already tried the hint or we are outside of the register range limit.
133107 }
0 commit comments