@@ -5,8 +5,10 @@ use crate::{
55 AllocationKind , Block , FxHashMap , Inst , InstPosition , Operand , OperandConstraint , OperandKind ,
66 OperandPos , PReg , PRegSet , RegClass , SpillSlot , VReg ,
77} ;
8- use alloc:: vec:: Vec ;
8+ use alloc:: format;
9+ use alloc:: { vec, vec:: Vec } ;
910use core:: convert:: TryInto ;
11+ use core:: fmt;
1012use core:: iter:: FromIterator ;
1113use core:: ops:: { Index , IndexMut } ;
1214
@@ -194,8 +196,6 @@ impl<T> IndexMut<OperandPos> for PartedByOperandPos<T> {
194196 }
195197}
196198
197- use core:: fmt;
198-
199199impl < T : fmt:: Display > fmt:: Display for PartedByOperandPos < T > {
200200 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
201201 write ! ( f, "{{ early: {}, late: {} }}" , self . items[ 0 ] , self . items[ 1 ] )
@@ -243,7 +243,6 @@ pub struct Env<'a, F: Function> {
243243
244244impl < ' a , F : Function > Env < ' a , F > {
245245 fn new ( func : & ' a F , env : & ' a MachineEnv ) -> Self {
246- use alloc:: vec;
247246 let mut regs = [
248247 env. preferred_regs_by_class [ RegClass :: Int as usize ] . clone ( ) ,
249248 env. preferred_regs_by_class [ RegClass :: Float as usize ] . clone ( ) ,
@@ -333,33 +332,37 @@ impl<'a, F: Function> Env<'a, F> {
333332 class : RegClass ,
334333 pos : InstPosition ,
335334 ) -> Result < ( ) , RegAllocError > {
336- use OperandPos :: { Early , Late } ;
337- let reg = self . get_scratch_reg (
338- inst,
339- class,
340- self . available_pregs [ Late ] & self . available_pregs [ Early ] ,
341- pos,
342- ) ?;
343- self . edits . scratch_regs [ class] = Some ( reg) ;
344- self . available_pregs [ OperandPos :: Early ] . remove ( reg) ;
345- self . available_pregs [ OperandPos :: Late ] . remove ( reg) ;
346- Ok ( ( ) )
335+ let avail_regs =
336+ self . available_pregs [ OperandPos :: Late ] & self . available_pregs [ OperandPos :: Early ] ;
337+ if let Some ( preg) = self . lrus [ class] . last ( avail_regs) {
338+ if self . vreg_in_preg [ preg. index ( ) ] != VReg :: invalid ( ) {
339+ self . evict_vreg_in_preg ( inst, preg, pos) ?;
340+ }
341+ self . edits . scratch_regs [ class] = Some ( preg) ;
342+ self . available_pregs [ OperandPos :: Early ] . remove ( preg) ;
343+ self . available_pregs [ OperandPos :: Late ] . remove ( preg) ;
344+ Ok ( ( ) )
345+ } else {
346+ Err ( RegAllocError :: TooManyLiveRegs )
347+ }
347348 }
348349
349- fn get_scratch_reg (
350+ fn add_move (
350351 & mut self ,
351352 inst : Inst ,
353+ from : Allocation ,
354+ to : Allocation ,
352355 class : RegClass ,
353- avail_regs : PRegSet ,
354356 pos : InstPosition ,
355- ) -> Result < PReg , RegAllocError > {
356- let Some ( preg ) = self . lrus [ class ] . last ( avail_regs ) else {
357- return Err ( RegAllocError :: TooManyLiveRegs ) ;
358- } ;
359- if self . vreg_in_preg [ preg . index ( ) ] != VReg :: invalid ( ) {
360- self . evict_vreg_in_preg ( inst, preg , pos) ;
357+ ) -> Result < ( ) , RegAllocError > {
358+ if self . edits . is_stack ( from )
359+ && self . edits . is_stack ( to )
360+ && self . edits . scratch_regs [ class ] . is_none ( )
361+ {
362+ self . alloc_scratch_reg ( inst, class , pos) ? ;
361363 }
362- Ok ( preg)
364+ self . edits . add_move ( inst, from, to, class, pos) ;
365+ Ok ( ( ) )
363366 }
364367
365368 fn reserve_reg_for_fixed_operand (
@@ -453,7 +456,12 @@ impl<'a, F: Function> Env<'a, F> {
453456 }
454457 }
455458
456- fn evict_vreg_in_preg ( & mut self , inst : Inst , preg : PReg , pos : InstPosition ) {
459+ fn evict_vreg_in_preg (
460+ & mut self ,
461+ inst : Inst ,
462+ preg : PReg ,
463+ pos : InstPosition ,
464+ ) -> Result < ( ) , RegAllocError > {
457465 trace ! ( "Removing the vreg in preg {} for eviction" , preg) ;
458466 let evicted_vreg = self . vreg_in_preg [ preg. index ( ) ] ;
459467 trace ! ( "The removed vreg: {}" , evicted_vreg) ;
@@ -464,13 +472,13 @@ impl<'a, F: Function> Env<'a, F> {
464472 let slot = self . vreg_spillslots [ evicted_vreg. vreg ( ) ] ;
465473 self . vreg_allocs [ evicted_vreg. vreg ( ) ] = Allocation :: stack ( slot) ;
466474 trace ! ( "Move reason: eviction" ) ;
467- self . edits . add_move (
475+ self . add_move (
468476 inst,
469477 self . vreg_allocs [ evicted_vreg. vreg ( ) ] ,
470478 Allocation :: reg ( preg) ,
471479 evicted_vreg. class ( ) ,
472480 pos,
473- ) ;
481+ )
474482 }
475483
476484 fn freealloc ( & mut self , vreg : VReg ) {
@@ -526,7 +534,7 @@ impl<'a, F: Function> Env<'a, F> {
526534 return Err ( RegAllocError :: TooManyLiveRegs ) ;
527535 } ;
528536 if self . vreg_in_preg [ preg. index ( ) ] != VReg :: invalid ( ) {
529- self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ;
537+ self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ? ;
530538 }
531539 trace ! ( "The allocated register for vreg {}: {}" , op. vreg( ) , preg) ;
532540 self . lrus [ op. class ( ) ] . poke ( preg) ;
@@ -623,23 +631,9 @@ impl<'a, F: Function> Env<'a, F> {
623631 // used (in `prev_alloc`, that is).
624632 else {
625633 trace ! ( "Move reason: Prev allocation doesn't meet constraints" ) ;
626- if self . edits . is_stack ( new_alloc)
627- && self . edits . is_stack ( curr_alloc)
628- && self . edits . scratch_regs [ op. class ( ) ] . is_none ( )
629- {
630- self . alloc_scratch_reg ( inst, op. class ( ) , InstPosition :: After ) ?;
631- }
632634 if op. kind ( ) == OperandKind :: Def {
633635 trace ! ( "Adding edit from {new_alloc:?} to {curr_alloc:?} after inst {inst:?} for {op}" ) ;
634- self . edits . add_move (
635- inst,
636- new_alloc,
637- curr_alloc,
638- op. class ( ) ,
639- InstPosition :: After ,
640- ) ;
641- // No need to set vreg_in_preg because it will be set during
642- // `freealloc` if needed.
636+ self . add_move ( inst, new_alloc, curr_alloc, op. class ( ) , InstPosition :: After ) ?;
643637 }
644638 // Edits for use operands are added later to avoid inserting
645639 // edits out of order.
@@ -713,7 +707,6 @@ impl<'a, F: Function> Env<'a, F> {
713707 /// this function places branch arguments in the spillslots
714708 /// expected by the destination blocks.
715709 fn process_branch ( & mut self , block : Block , inst : Inst ) -> Result < ( ) , RegAllocError > {
716- use OperandPos :: * ;
717710 trace ! ( "Processing branch instruction {inst:?} in block {block:?}" ) ;
718711
719712 let mut int_parallel_moves = ParallelMoves :: new ( ) ;
@@ -742,26 +735,13 @@ impl<'a, F: Function> Env<'a, F> {
742735 self . live_vregs . insert ( * vreg) ;
743736 self . vreg_to_live_inst_range [ vreg. vreg ( ) ] . 1 = ProgPoint :: before ( inst) ;
744737 } else if curr_alloc != vreg_spill {
745- if self . edits . is_stack ( curr_alloc)
746- && self . edits . scratch_regs [ vreg. class ( ) ] . is_none ( )
747- {
748- let reg = self . get_scratch_reg (
749- inst,
750- vreg. class ( ) ,
751- self . available_pregs [ Early ] & self . available_pregs [ Late ] ,
752- InstPosition :: Before ,
753- ) ?;
754- self . edits . scratch_regs [ vreg. class ( ) ] = Some ( reg) ;
755- self . available_pregs [ OperandPos :: Early ] . remove ( reg) ;
756- self . available_pregs [ OperandPos :: Late ] . remove ( reg) ;
757- }
758- self . edits . add_move (
738+ self . add_move (
759739 inst,
760740 vreg_spill,
761741 curr_alloc,
762742 vreg. class ( ) ,
763743 InstPosition :: Before ,
764- ) ;
744+ ) ? ;
765745 }
766746 self . vreg_allocs [ vreg. vreg ( ) ] = vreg_spill;
767747 let parallel_moves = match vreg. class ( ) {
@@ -781,7 +761,8 @@ impl<'a, F: Function> Env<'a, F> {
781761 let resolved_vec = vec_parallel_moves. resolve ( ) ;
782762 let mut scratch_regs = self . edits . scratch_regs . clone ( ) ;
783763 let mut num_spillslots = self . stack . num_spillslots ;
784- let mut avail_regs = self . available_pregs [ Early ] & self . available_pregs [ Late ] ;
764+ let mut avail_regs =
765+ self . available_pregs [ OperandPos :: Early ] & self . available_pregs [ OperandPos :: Late ] ;
785766
786767 trace ! ( "Resolving parallel moves" ) ;
787768 for ( resolved, class) in [
@@ -871,12 +852,7 @@ impl<'a, F: Function> Env<'a, F> {
871852 "Evicting {} from fixed register {preg}" ,
872853 self . vreg_in_preg[ preg. index( ) ]
873854 ) ;
874- if self . fixed_stack_slots . contains ( preg)
875- && self . edits . scratch_regs [ preg. class ( ) ] . is_none ( )
876- {
877- self . alloc_scratch_reg ( inst, preg. class ( ) , InstPosition :: After ) ?;
878- }
879- self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ;
855+ self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ?;
880856 self . vreg_in_preg [ preg. index ( ) ] = VReg :: invalid ( ) ;
881857 }
882858 }
@@ -887,12 +863,7 @@ impl<'a, F: Function> Env<'a, F> {
887863 "Evicting {} from clobber {preg}" ,
888864 self . vreg_in_preg[ preg. index( ) ]
889865 ) ;
890- if self . fixed_stack_slots . contains ( preg)
891- && self . edits . scratch_regs [ preg. class ( ) ] . is_none ( )
892- {
893- self . alloc_scratch_reg ( inst, preg. class ( ) , InstPosition :: After ) ?;
894- }
895- self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ;
866+ self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ?;
896867 self . vreg_in_preg [ preg. index ( ) ] = VReg :: invalid ( ) ;
897868 }
898869 }
@@ -911,24 +882,9 @@ impl<'a, F: Function> Env<'a, F> {
911882 if slot. is_valid ( ) {
912883 self . vreg_to_live_inst_range [ op. vreg ( ) . vreg ( ) ] . 2 = Allocation :: stack ( slot) ;
913884 let curr_alloc = self . vreg_allocs [ op. vreg ( ) . vreg ( ) ] ;
914- let vreg_slot = self . vreg_spillslots [ op. vreg ( ) . vreg ( ) ] ;
915- let ( is_stack_to_stack, src_and_dest_are_same) =
916- if let Some ( curr_alloc) = curr_alloc. as_stack ( ) {
917- ( true , curr_alloc == vreg_slot)
918- } else {
919- ( self . edits . is_stack ( curr_alloc) , false )
920- } ;
921- if !src_and_dest_are_same {
922- if is_stack_to_stack && self . edits . scratch_regs [ op. class ( ) ] . is_none ( ) {
923- self . alloc_scratch_reg ( inst, op. class ( ) , InstPosition :: After ) ?;
924- } ;
925- self . edits . add_move (
926- inst,
927- self . vreg_allocs [ op. vreg ( ) . vreg ( ) ] ,
928- Allocation :: stack ( self . vreg_spillslots [ op. vreg ( ) . vreg ( ) ] ) ,
929- op. class ( ) ,
930- InstPosition :: After ,
931- ) ;
885+ let new_alloc = Allocation :: stack ( self . vreg_spillslots [ op. vreg ( ) . vreg ( ) ] ) ;
886+ if curr_alloc != new_alloc {
887+ self . add_move ( inst, curr_alloc, new_alloc, op. class ( ) , InstPosition :: After ) ?;
932888 }
933889 }
934890 self . vreg_to_live_inst_range [ op. vreg ( ) . vreg ( ) ] . 0 = ProgPoint :: after ( inst) ;
@@ -955,24 +911,17 @@ impl<'a, F: Function> Env<'a, F> {
955911 if op. as_fixed_nonallocatable ( ) . is_some ( ) {
956912 continue ;
957913 }
958- if self . vreg_allocs [ op. vreg ( ) . vreg ( ) ] != self . allocs [ ( inst . index ( ) , op_idx ) ] {
959- let curr_alloc = self . vreg_allocs [ op . vreg ( ) . vreg ( ) ] ;
960- let new_alloc = self . allocs [ ( inst . index ( ) , op_idx ) ] ;
914+ let curr_alloc = self . vreg_allocs [ op. vreg ( ) . vreg ( ) ] ;
915+ let new_alloc = self . allocs [ ( inst . index ( ) , op_idx ) ] ;
916+ if curr_alloc != new_alloc {
961917 trace ! ( "Adding edit from {curr_alloc:?} to {new_alloc:?} before inst {inst:?} for {op}" ) ;
962- if curr_alloc != new_alloc
963- && self . edits . is_stack ( curr_alloc)
964- && self . edits . is_stack ( new_alloc)
965- && self . edits . scratch_regs [ op. class ( ) ] . is_none ( )
966- {
967- self . alloc_scratch_reg ( inst, op. class ( ) , InstPosition :: Before ) ?;
968- }
969- self . edits . add_move (
918+ self . add_move (
970919 inst,
971920 curr_alloc,
972921 new_alloc,
973922 op. class ( ) ,
974923 InstPosition :: Before ,
975- ) ;
924+ ) ? ;
976925 }
977926 }
978927 if self . func . is_branch ( inst) {
@@ -1051,22 +1000,13 @@ impl<'a, F: Function> Env<'a, F> {
10511000 "Move reason: reload {} at begin - move from its spillslot" ,
10521001 vreg
10531002 ) ;
1054- if self . edits . is_stack ( prev_alloc) && self . edits . scratch_regs [ vreg. class ( ) ] . is_none ( ) {
1055- let reg = self . get_scratch_reg (
1056- first_inst,
1057- vreg. class ( ) ,
1058- avail_regs_for_scratch,
1059- InstPosition :: Before ,
1060- ) ?;
1061- self . edits . scratch_regs [ vreg. class ( ) ] = Some ( reg) ;
1062- }
1063- self . edits . add_move (
1003+ self . add_move (
10641004 self . func . block_insns ( block) . first ( ) ,
10651005 slot,
10661006 prev_alloc,
10671007 vreg. class ( ) ,
10681008 InstPosition :: Before ,
1069- ) ;
1009+ ) ? ;
10701010 }
10711011 for vreg in self . live_vregs . iter ( ) {
10721012 trace ! ( "Processing {}" , vreg) ;
@@ -1142,7 +1082,6 @@ impl<'a, F: Function> Env<'a, F> {
11421082 }
11431083
11441084 fn log_post_reload_at_begin_state ( & self , block : Block ) {
1145- use alloc:: format;
11461085 trace ! ( "" ) ;
11471086 trace ! ( "State after instruction reload_at_begin of {:?}" , block) ;
11481087 let mut map = FxHashMap :: default ( ) ;
@@ -1165,7 +1104,6 @@ impl<'a, F: Function> Env<'a, F> {
11651104 }
11661105
11671106 fn log_post_inst_processing_state ( & self , inst : Inst ) {
1168- use alloc:: format;
11691107 trace ! ( "" ) ;
11701108 trace ! ( "State after instruction {:?}" , inst) ;
11711109 let mut map = FxHashMap :: default ( ) ;
@@ -1259,7 +1197,6 @@ fn log_function<F: Function>(func: &F) {
12591197
12601198fn log_output < ' a , F : Function > ( env : & Env < ' a , F > ) {
12611199 trace ! ( "Done!" ) ;
1262- use alloc:: format;
12631200 let mut v = Vec :: new ( ) ;
12641201 for i in 0 ..env. func . num_vregs ( ) {
12651202 if env. vreg_spillslots [ i] . is_valid ( ) {
0 commit comments