1
0
mirror of https://github.com/golang/go synced 2024-09-29 07:14:29 -06:00

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.

Change-Id: I162870c84b9a180da6715bb24c296a902974fed3
Reviewed-on: https://go-review.googlesource.com/c/go/+/460656
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Keith Randall <khr@golang.org>
This commit is contained in:
Keith Randall 2023-01-05 13:02:44 -08:00
parent f85c282a18
commit 3c7884a21b

View File

@ -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,19 @@ 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 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: