]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: prefer fixed registers for values
authorKeith Randall <khr@golang.org>
Mon, 17 Nov 2025 23:33:01 +0000 (15:33 -0800)
committerKeith Randall <khr@golang.org>
Tue, 18 Nov 2025 17:37:02 +0000 (09:37 -0800)
For this code:

func f() (int, int) {
return 0, 0
}

We currently generate on arm64:

   MOVD ZR, R0
   MOVD R0, R1

This CL changes that to

   MOVD ZR, R0
   MOVD ZR, R1

Probably not a big performance difference, but it makes the generated
code clearer.

A followup-ish CL from 633075 when the zero fixed register was exposed
to the register allocator.

Change-Id: I869a92817dcbbca46c900999fab538e76e10ed05
Reviewed-on: https://go-review.googlesource.com/c/go/+/721440
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/compile/internal/ssa/regalloc.go

index b5174acbc99ccc208b630ca278d604696c6e88f3..9ed8a0e86c002265f062e14b2280f48e47954253 100644 (file)
@@ -596,17 +596,18 @@ func (s *regAllocState) allocValToReg(v *Value, mask regMask, nospill bool, pos
        var c *Value
        if vi.regs != 0 {
                // Copy from a register that v is already in.
-               r2 := pickReg(vi.regs)
                var current *Value
-               if !s.allocatable.contains(r2) {
-                       current = v // v is in a fixed register
+               if vi.regs&^s.allocatable != 0 {
+                       // v is in a fixed register, prefer that
+                       current = v
                } else {
+                       r2 := pickReg(vi.regs)
                        if s.regs[r2].v != v {
                                panic("bad register state")
                        }
                        current = s.regs[r2].c
+                       s.usedSinceBlockStart |= regMask(1) << r2
                }
-               s.usedSinceBlockStart |= regMask(1) << r2
                c = s.curBlock.NewValue1(pos, OpCopy, v.Type, current)
        } else if v.rematerializeable() {
                // Rematerialize instead of loading from the spill location.