cmd/compile: reuse dead register before reusing register holding constant

For commuting ops, check whether the second argument is dead before
checking if the first argument is rematerializeable. Reusing the register
holding a dead value is always best.

Fixes #33580

Change-Id: I7372cfc03d514e6774d2d9cc727a3e6bf6ce2657
Reviewed-on: https://go-review.googlesource.com/c/go/+/199559
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Keith Randall 2019-10-06 23:03:28 -07:00 committed by Keith Randall
parent fc2915fabd
commit 72dc9ab191
2 changed files with 36 additions and 13 deletions

View file

@ -1328,27 +1328,25 @@ func (s *regAllocState) regalloc(f *Func) {
// arg0 is dead. We can clobber its register.
goto ok
}
if opcodeTable[v.Op].commutative && !s.liveAfterCurrentInstruction(v.Args[1]) {
args[0], args[1] = args[1], args[0]
goto ok
}
if s.values[v.Args[0].ID].rematerializeable {
// We can rematerialize the input, don't worry about clobbering it.
goto ok
}
if opcodeTable[v.Op].commutative && s.values[v.Args[1].ID].rematerializeable {
args[0], args[1] = args[1], args[0]
goto ok
}
if countRegs(s.values[v.Args[0].ID].regs) >= 2 {
// we have at least 2 copies of arg0. We can afford to clobber one.
goto ok
}
if opcodeTable[v.Op].commutative {
if !s.liveAfterCurrentInstruction(v.Args[1]) {
args[0], args[1] = args[1], args[0]
goto ok
}
if s.values[v.Args[1].ID].rematerializeable {
args[0], args[1] = args[1], args[0]
goto ok
}
if countRegs(s.values[v.Args[1].ID].regs) >= 2 {
args[0], args[1] = args[1], args[0]
goto ok
}
if opcodeTable[v.Op].commutative && countRegs(s.values[v.Args[1].ID].regs) >= 2 {
args[0], args[1] = args[1], args[0]
goto ok
}
// We can't overwrite arg0 (or arg1, if commutative). So we