3838// x3 can then be used wherever x is referenced again.
3939// If the spill (x2) is never used, it will be removed at the end of regalloc.
4040//
41- // Flags values are special. Instead of attempting to spill and restore the flags
42- // register, we recalculate it if needed.
43- // There are more efficient schemes (see the discussion in CL 13844),
44- // but flag restoration is empirically rare, and this approach is simple
45- // and architecture-independent.
46- //
4741// Phi values are special, as always. We define two kinds of phis, those
4842// where the merge happens in a register (a "register" phi) and those where
4943// the merge happens in a stack location (a "stack" phi).
@@ -173,7 +167,6 @@ var registers = [...]Register{
173167 Register {30 , "X14" },
174168 Register {31 , "X15" },
175169 Register {32 , "SB" }, // pseudo-register for global base pointer (aka %rip)
176- Register {33 , "FLAGS" },
177170
178171 // TODO: make arch-dependent
179172}
@@ -226,7 +219,7 @@ type regAllocState struct {
226219 f * Func
227220
228221 // For each value, whether it needs a register or not.
229- // Cached value of !v.Type.IsMemory() && !v.Type.IsVoid().
222+ // Cached value of !v.Type.IsMemory() && !v.Type.IsVoid() && !v.Type.IsFlags() .
230223 needReg []bool
231224
232225 // for each block, its primary predecessor.
@@ -435,40 +428,9 @@ func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool) *Val
435428 c = s .curBlock .NewValue1 (v .Line , OpCopy , v .Type , s .regs [r2 ].c )
436429 } else if v .rematerializeable () {
437430 // Rematerialize instead of loading from the spill location.
438- c = s .curBlock .NewValue0 (v .Line , v .Op , v .Type )
439- c .Aux = v .Aux
440- c .AuxInt = v .AuxInt
441- c .AddArgs (v .Args ... )
431+ c = v .copyInto (s .curBlock )
442432 } else {
443433 switch {
444- // It is difficult to spill and reload flags on many architectures.
445- // Instead, we regenerate the flags register by issuing the same instruction again.
446- // This requires (possibly) spilling and reloading that instruction's args.
447- case v .Type .IsFlags ():
448- if logSpills {
449- fmt .Println ("regalloc: regenerating flags" )
450- }
451- ns := s .nospill
452- // Place v's arguments in registers, spilling and loading as needed
453- args := make ([]* Value , 0 , len (v .Args ))
454- regspec := opcodeTable [v .Op ].reg
455- for _ , i := range regspec .inputs {
456- // Extract the original arguments to v
457- a := s .orig [v .Args [i .idx ].ID ]
458- if a .Type .IsFlags () {
459- s .f .Fatalf ("cannot load flags value with flags arg: %v has unwrapped arg %v" , v .LongString (), a .LongString ())
460- }
461- cc := s .allocValToReg (a , i .regs , true )
462- args = append (args , cc )
463- }
464- s .nospill = ns
465- // Recalculate v
466- c = s .curBlock .NewValue0 (v .Line , v .Op , v .Type )
467- c .Aux = v .Aux
468- c .AuxInt = v .AuxInt
469- c .resetArgs ()
470- c .AddArgs (args ... )
471-
472434 // Load v from its spill location.
473435 case vi .spill2 != nil :
474436 if logSpills {
@@ -506,7 +468,7 @@ func (s *regAllocState) init(f *Func) {
506468 s .orig = make ([]* Value , f .NumValues ())
507469 for _ , b := range f .Blocks {
508470 for _ , v := range b .Values {
509- if v .Type .IsMemory () || v .Type .IsVoid () {
471+ if v .Type .IsMemory () || v .Type .IsVoid () || v . Type . IsFlags () {
510472 continue
511473 }
512474 s .needReg [v .ID ] = true
@@ -818,6 +780,10 @@ func (s *regAllocState) regalloc(f *Func) {
818780 // by the register specification (most constrained first).
819781 args = append (args [:0 ], v .Args ... )
820782 for _ , i := range regspec .inputs {
783+ if i .regs == flagRegMask {
784+ // TODO: remove flag input from regspec.inputs.
785+ continue
786+ }
821787 args [i .idx ] = s .allocValToReg (v .Args [i .idx ], i .regs , true )
822788 }
823789
@@ -834,8 +800,11 @@ func (s *regAllocState) regalloc(f *Func) {
834800 // Pick register for output.
835801 var r register
836802 var mask regMask
837- if len ( regspec . outputs ) > 0 {
803+ if s . needReg [ v . ID ] {
838804 mask = regspec .outputs [0 ] &^ s .reserved ()
805+ if mask >> 33 & 1 != 0 {
806+ s .f .Fatalf ("bad mask %s\n " , v .LongString ())
807+ }
839808 }
840809 if mask != 0 {
841810 r = s .allocReg (mask )
@@ -858,7 +827,7 @@ func (s *regAllocState) regalloc(f *Func) {
858827 // f()
859828 // }
860829 // It would be good to have both spill and restore inside the IF.
861- if ! v . Type . IsFlags () {
830+ if s . needReg [ v . ID ] {
862831 spill := b .NewValue1 (v .Line , OpStoreReg , v .Type , v )
863832 s .setOrig (spill , v )
864833 s .values [v .ID ].spill = spill
0 commit comments