]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: place reg spills after OpArg{Int,Float}Reg ops
authorThan McIntosh <thanm@google.com>
Tue, 25 May 2021 14:13:07 +0000 (10:13 -0400)
committerThan McIntosh <thanm@google.com>
Thu, 27 May 2021 18:47:37 +0000 (18:47 +0000)
Tweak the register allocator to maintain the invariant that
OpArg{Int,Float}Reg values are placed together at the start of the
entry block, before any other non-pseudo-op values. Without this
change, when the register allocator adds spills we can wind up with an
interleaving of OpArg*Reg and stores, which complicates debug location
analysis.

Updates #40724.

Change-Id: Icf30dd814a9e25263ecbea2e48feb840a6e7f2bd
Reviewed-on: https://go-review.googlesource.com/c/go/+/322630
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
src/cmd/compile/internal/ssa/regalloc.go

index c81d5574fe5fee1a9a96d6a57c6f8c5c5b67ab7f..3b90b8769c2f1d8ffe484b0ab40d832aea650175 100644 (file)
@@ -1882,6 +1882,10 @@ func (s *regAllocState) placeSpills() {
                phiRegs[b.ID] = m
        }
 
+       mustBeFirst := func(op Op) bool {
+               return op.isLoweredGetClosurePtr() || op == OpPhi || op == OpArgIntReg || op == OpArgFloatReg
+       }
+
        // Start maps block IDs to the list of spills
        // that go at the start of the block (but after any phis).
        start := map[ID][]*Value{}
@@ -1971,7 +1975,7 @@ func (s *regAllocState) placeSpills() {
                // Put the spill in the best block we found.
                spill.Block = best
                spill.AddArg(bestArg)
-               if best == v.Block && v.Op != OpPhi {
+               if best == v.Block && !mustBeFirst(v.Op) {
                        // Place immediately after v.
                        after[v.ID] = append(after[v.ID], spill)
                } else {
@@ -1983,15 +1987,15 @@ func (s *regAllocState) placeSpills() {
        // Insert spill instructions into the block schedules.
        var oldSched []*Value
        for _, b := range s.visitOrder {
-               nphi := 0
+               nfirst := 0
                for _, v := range b.Values {
-                       if v.Op != OpPhi {
+                       if !mustBeFirst(v.Op) {
                                break
                        }
-                       nphi++
+                       nfirst++
                }
-               oldSched = append(oldSched[:0], b.Values[nphi:]...)
-               b.Values = b.Values[:nphi]
+               oldSched = append(oldSched[:0], b.Values[nfirst:]...)
+               b.Values = b.Values[:nfirst]
                b.Values = append(b.Values, start[b.ID]...)
                for _, v := range oldSched {
                        b.Values = append(b.Values, v)