@@ -327,45 +327,37 @@ impl<'a, F: Function> Env<'a, F> {
327327 self . edits . scratch_regs = self . edits . dedicated_scratch_regs . clone ( ) ;
328328 }
329329
330- fn alloc_scratch_reg ( & mut self , inst : Inst , class : RegClass ) -> Result < ( ) , RegAllocError > {
330+ fn alloc_scratch_reg (
331+ & mut self ,
332+ inst : Inst ,
333+ class : RegClass ,
334+ pos : InstPosition ,
335+ ) -> Result < ( ) , RegAllocError > {
331336 use OperandPos :: { Early , Late } ;
332337 let reg = self . get_scratch_reg (
333338 inst,
334339 class,
335340 self . available_pregs [ Late ] & self . available_pregs [ Early ] ,
341+ pos,
336342 ) ?;
337343 self . edits . scratch_regs [ class] = Some ( reg) ;
338344 self . available_pregs [ OperandPos :: Early ] . remove ( reg) ;
339345 self . available_pregs [ OperandPos :: Late ] . remove ( reg) ;
340346 Ok ( ( ) )
341347 }
342348
343- fn get_scratch_reg_for_reload (
344- & mut self ,
345- inst : Inst ,
346- class : RegClass ,
347- avail_regs : PRegSet ,
348- ) -> Result < PReg , RegAllocError > {
349- let Some ( preg) = self . lrus [ class] . last ( avail_regs) else {
350- return Err ( RegAllocError :: TooManyLiveRegs ) ;
351- } ;
352- if self . vreg_in_preg [ preg. index ( ) ] != VReg :: invalid ( ) {
353- self . evict_vreg_in_preg_before_inst ( inst, preg) ;
354- }
355- Ok ( preg)
356- }
357-
358349 fn get_scratch_reg (
359350 & mut self ,
360351 inst : Inst ,
361352 class : RegClass ,
362353 avail_regs : PRegSet ,
354+ pos : InstPosition ,
363355 ) -> Result < PReg , RegAllocError > {
364356 let Some ( preg) = self . lrus [ class] . last ( avail_regs) else {
365357 return Err ( RegAllocError :: TooManyLiveRegs ) ;
366358 } ;
367359 if self . vreg_in_preg [ preg. index ( ) ] != VReg :: invalid ( ) {
368- self . evict_vreg_in_preg ( inst, preg) ;
360+ self . evict_vreg_in_preg ( inst, preg, pos ) ;
369361 }
370362 Ok ( preg)
371363 }
@@ -461,7 +453,7 @@ impl<'a, F: Function> Env<'a, F> {
461453 }
462454 }
463455
464- fn base_evict_vreg_in_preg ( & mut self , inst : Inst , preg : PReg , pos : InstPosition ) {
456+ fn evict_vreg_in_preg ( & mut self , inst : Inst , preg : PReg , pos : InstPosition ) {
465457 trace ! ( "Removing the vreg in preg {} for eviction" , preg) ;
466458 let evicted_vreg = self . vreg_in_preg [ preg. index ( ) ] ;
467459 trace ! ( "The removed vreg: {}" , evicted_vreg) ;
@@ -481,14 +473,6 @@ impl<'a, F: Function> Env<'a, F> {
481473 ) ;
482474 }
483475
484- fn evict_vreg_in_preg_before_inst ( & mut self , inst : Inst , preg : PReg ) {
485- self . base_evict_vreg_in_preg ( inst, preg, InstPosition :: Before )
486- }
487-
488- fn evict_vreg_in_preg ( & mut self , inst : Inst , preg : PReg ) {
489- self . base_evict_vreg_in_preg ( inst, preg, InstPosition :: After )
490- }
491-
492476 fn freealloc ( & mut self , vreg : VReg ) {
493477 trace ! ( "Freeing vreg {}" , vreg) ;
494478 let alloc = self . vreg_allocs [ vreg. vreg ( ) ] ;
@@ -542,7 +526,7 @@ impl<'a, F: Function> Env<'a, F> {
542526 return Err ( RegAllocError :: TooManyLiveRegs ) ;
543527 } ;
544528 if self . vreg_in_preg [ preg. index ( ) ] != VReg :: invalid ( ) {
545- self . evict_vreg_in_preg ( inst, preg) ;
529+ self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ;
546530 }
547531 trace ! ( "The allocated register for vreg {}: {}" , op. vreg( ) , preg) ;
548532 self . lrus [ op. class ( ) ] . poke ( preg) ;
@@ -643,7 +627,7 @@ impl<'a, F: Function> Env<'a, F> {
643627 && self . edits . is_stack ( curr_alloc)
644628 && self . edits . scratch_regs [ op. class ( ) ] . is_none ( )
645629 {
646- self . alloc_scratch_reg ( inst, op. class ( ) ) ?;
630+ self . alloc_scratch_reg ( inst, op. class ( ) , InstPosition :: After ) ?;
647631 }
648632 if op. kind ( ) == OperandKind :: Def {
649633 trace ! ( "Adding edit from {new_alloc:?} to {curr_alloc:?} after inst {inst:?} for {op}" ) ;
@@ -761,10 +745,11 @@ impl<'a, F: Function> Env<'a, F> {
761745 if self . edits . is_stack ( curr_alloc)
762746 && self . edits . scratch_regs [ vreg. class ( ) ] . is_none ( )
763747 {
764- let reg = self . get_scratch_reg_for_reload (
748+ let reg = self . get_scratch_reg (
765749 inst,
766750 vreg. class ( ) ,
767751 self . available_pregs [ Early ] & self . available_pregs [ Late ] ,
752+ InstPosition :: Before ,
768753 ) ?;
769754 self . edits . scratch_regs [ vreg. class ( ) ] = Some ( reg) ;
770755 self . available_pregs [ OperandPos :: Early ] . remove ( reg) ;
@@ -889,9 +874,9 @@ impl<'a, F: Function> Env<'a, F> {
889874 if self . fixed_stack_slots . contains ( preg)
890875 && self . edits . scratch_regs [ preg. class ( ) ] . is_none ( )
891876 {
892- self . alloc_scratch_reg ( inst, preg. class ( ) ) ?;
877+ self . alloc_scratch_reg ( inst, preg. class ( ) , InstPosition :: After ) ?;
893878 }
894- self . evict_vreg_in_preg ( inst, preg) ;
879+ self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ;
895880 self . vreg_in_preg [ preg. index ( ) ] = VReg :: invalid ( ) ;
896881 }
897882 }
@@ -905,9 +890,9 @@ impl<'a, F: Function> Env<'a, F> {
905890 if self . fixed_stack_slots . contains ( preg)
906891 && self . edits . scratch_regs [ preg. class ( ) ] . is_none ( )
907892 {
908- self . alloc_scratch_reg ( inst, preg. class ( ) ) ?;
893+ self . alloc_scratch_reg ( inst, preg. class ( ) , InstPosition :: After ) ?;
909894 }
910- self . evict_vreg_in_preg ( inst, preg) ;
895+ self . evict_vreg_in_preg ( inst, preg, InstPosition :: After ) ;
911896 self . vreg_in_preg [ preg. index ( ) ] = VReg :: invalid ( ) ;
912897 }
913898 }
@@ -935,7 +920,7 @@ impl<'a, F: Function> Env<'a, F> {
935920 } ;
936921 if !src_and_dest_are_same {
937922 if is_stack_to_stack && self . edits . scratch_regs [ op. class ( ) ] . is_none ( ) {
938- self . alloc_scratch_reg ( inst, op. class ( ) ) ?;
923+ self . alloc_scratch_reg ( inst, op. class ( ) , InstPosition :: After ) ?;
939924 } ;
940925 self . edits . add_move (
941926 inst,
@@ -974,6 +959,13 @@ impl<'a, F: Function> Env<'a, F> {
974959 let curr_alloc = self . vreg_allocs [ op. vreg ( ) . vreg ( ) ] ;
975960 let new_alloc = self . allocs [ ( inst. index ( ) , op_idx) ] ;
976961 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+ }
977969 self . edits . add_move (
978970 inst,
979971 curr_alloc,
@@ -1060,10 +1052,11 @@ impl<'a, F: Function> Env<'a, F> {
10601052 vreg
10611053 ) ;
10621054 if self . edits . is_stack ( prev_alloc) && self . edits . scratch_regs [ vreg. class ( ) ] . is_none ( ) {
1063- let reg = self . get_scratch_reg_for_reload (
1055+ let reg = self . get_scratch_reg (
10641056 first_inst,
10651057 vreg. class ( ) ,
10661058 avail_regs_for_scratch,
1059+ InstPosition :: Before ,
10671060 ) ?;
10681061 self . edits . scratch_regs [ vreg. class ( ) ] = Some ( reg) ;
10691062 }
0 commit comments