mirror of
https://github.com/golang/go.git
synced 2025-05-06 08:03:03 +00:00
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:
parent
fc2915fabd
commit
72dc9ab191
@ -1328,28 +1328,26 @@ func (s *regAllocState) regalloc(f *Func) {
|
|||||||
// arg0 is dead. We can clobber its register.
|
// arg0 is dead. We can clobber its register.
|
||||||
goto ok
|
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 {
|
if s.values[v.Args[0].ID].rematerializeable {
|
||||||
// We can rematerialize the input, don't worry about clobbering it.
|
// We can rematerialize the input, don't worry about clobbering it.
|
||||||
goto ok
|
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 {
|
if countRegs(s.values[v.Args[0].ID].regs) >= 2 {
|
||||||
// we have at least 2 copies of arg0. We can afford to clobber one.
|
// we have at least 2 copies of arg0. We can afford to clobber one.
|
||||||
goto ok
|
goto ok
|
||||||
}
|
}
|
||||||
if opcodeTable[v.Op].commutative {
|
if opcodeTable[v.Op].commutative && countRegs(s.values[v.Args[1].ID].regs) >= 2 {
|
||||||
if !s.liveAfterCurrentInstruction(v.Args[1]) {
|
|
||||||
args[0], args[1] = args[1], args[0]
|
args[0], args[1] = args[1], args[0]
|
||||||
goto ok
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We can't overwrite arg0 (or arg1, if commutative). So we
|
// We can't overwrite arg0 (or arg1, if commutative). So we
|
||||||
// need to make a copy of an input so we have a register we can modify.
|
// need to make a copy of an input so we have a register we can modify.
|
||||||
|
25
test/codegen/issue33580.go
Normal file
25
test/codegen/issue33580.go
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// asmcheck
|
||||||
|
|
||||||
|
// Copyright 2019 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Make sure we reuse large constant loads, if we can.
|
||||||
|
// See issue 33580.
|
||||||
|
|
||||||
|
package codegen
|
||||||
|
|
||||||
|
const (
|
||||||
|
A = 7777777777777777
|
||||||
|
B = 8888888888888888
|
||||||
|
)
|
||||||
|
|
||||||
|
func f(x, y uint64) uint64 {
|
||||||
|
p := x & A
|
||||||
|
q := y & A
|
||||||
|
r := x & B
|
||||||
|
// amd64:-"MOVQ.*8888888888888888"
|
||||||
|
s := y & B
|
||||||
|
|
||||||
|
return p * q * r * s
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user