mirror of
https://github.com/golang/go
synced 2024-11-23 18:00:06 -07: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. 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>
This commit is contained in:
parent
2c7856087a
commit
4a0e84a1be
@ -1544,6 +1544,7 @@ func (s *regAllocState) regalloc(f *Func) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid future fixed uses if we can.
|
// Avoid future fixed uses if we can.
|
||||||
if m&^desired.avoid != 0 {
|
if m&^desired.avoid != 0 {
|
||||||
m &^= desired.avoid
|
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.
|
// Save input 0 to a new register so we can clobber it.
|
||||||
c := s.allocValToReg(v.Args[0], m, true, v.Pos)
|
c := s.allocValToReg(v.Args[0], m, true, v.Pos)
|
||||||
s.copies[c] = false
|
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:
|
ok:
|
||||||
|
Loading…
Reference in New Issue
Block a user