diff options
| author | Keith Randall <khr@golang.org> | 2023-01-05 13:02:44 -0800 |
|---|---|---|
| committer | Keith Randall <khr@google.com> | 2023-01-26 00:07:40 +0000 |
| commit | 4a0e84a1be52d9a57574de0421d9aa38522a0b71 (patch) | |
| tree | a18d6a828916cc9f5a194b5cec073d9b709a3c2b | |
| parent | 2c7856087a7b3864284f908c0a091fd5af419d03 (diff) | |
| download | go-4a0e84a1be52d9a57574de0421d9aa38522a0b71.tar.xz | |
cmd/compile: improve register overwrite decision for resultInArg0 ops
When we're compiling a resultInArg0 op, we need to clobber the
register containing the input value. So we first make a register copy
of the input value. We can then clobber either of the two registers
the value is in and still have the original input value in a register
for future uses.
Before this CL, we always clobbered the original, not the copy.
But that's not always the right decision - if the original is already
in a specific register that it needs to be in later (typically, a
return value register), clobber the copy instead.
This optimization can remove a mov instruction. It saves 1376 bytes
of instructions in cmd/go.
Redo of CL 460656, reverted at CL 463475, with a fix for s390x.
The new code just ensures that the copied value is in a register
which is a valid input register for the instruction.
Change-Id: Id570b8a60a6d2da9090de80a90b6bb0266e9e38a
Reviewed-on: https://go-review.googlesource.com/c/go/+/463221
Auto-Submit: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
| -rw-r--r-- | src/cmd/compile/internal/ssa/regalloc.go | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index 294c522a90..80f6434e76 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -1544,6 +1544,7 @@ func (s *regAllocState) regalloc(f *Func) { } } } + // Avoid future fixed uses if we can. if m&^desired.avoid != 0 { m &^= desired.avoid @@ -1551,6 +1552,21 @@ func (s *regAllocState) regalloc(f *Func) { // Save input 0 to a new register so we can clobber it. c := s.allocValToReg(v.Args[0], m, true, v.Pos) s.copies[c] = false + + // Normally we use the register of the old copy of input 0 as the target. + // However, if input 0 is already in its desired register then we use + // the register of the new copy instead. + if regspec.outputs[0].regs>>s.f.getHome(c.ID).(*Register).num&1 != 0 { + if rp, ok := s.f.getHome(args[0].ID).(*Register); ok { + r := register(rp.num) + for _, r2 := range dinfo[idx].in[0] { + if r == r2 { + args[0] = c + break + } + } + } + } } ok: |
