mirror of https://github.com/golang/go.git
cmd/compile: don't shuffle rematerializeable values around
Better to just rematerialize them when needed instead of
cross-register spilling or other techniques for keeping them in
registers.
This helps for amd64 code that does 1 << x. It is better to do
loop:
MOVQ $1, AX // materialize arg to SLLQ
SLLQ CX, AX
...
goto loop
than to do
MOVQ $1, AX // materialize outsize of loop
loop:
MOVQ AX, DX // save value that's about to be clobbered
SLLQ CX, AX
MOVQ DX, AX // move it back to the correct register
goto loop
Update #16092
Change-Id: If7ac290208f513061ebb0736e8a79dcb0ba338c0
Reviewed-on: https://go-review.googlesource.com/30471
TryBot-Result: Gobot Gobot <gobot@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
e5421e21ef
commit
1bddd2ee6a
|
|
@ -389,7 +389,7 @@ func (s *regAllocState) allocReg(mask regMask, v *Value) register {
|
|||
// We generate a Copy and record it. It will be deleted if never used.
|
||||
v2 := s.regs[r].v
|
||||
m := s.compatRegs(v2.Type) &^ s.used &^ s.tmpused &^ (regMask(1) << r)
|
||||
if countRegs(s.values[v2.ID].regs) == 1 && m != 0 {
|
||||
if m != 0 && !s.values[v2.ID].rematerializeable && countRegs(s.values[v2.ID].regs) == 1 {
|
||||
r2 := pickReg(m)
|
||||
c := s.curBlock.NewValue1(v2.Line, OpCopy, v2.Type, s.regs[r].c)
|
||||
s.copies[c] = false
|
||||
|
|
@ -1146,6 +1146,10 @@ func (s *regAllocState) regalloc(f *Func) {
|
|||
// arg0 is dead. We can clobber its register.
|
||||
goto ok
|
||||
}
|
||||
if s.values[v.Args[0].ID].rematerializeable {
|
||||
// We can rematerialize the input, don't worry about clobbering it.
|
||||
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
|
||||
|
|
@ -1155,6 +1159,10 @@ func (s *regAllocState) regalloc(f *Func) {
|
|||
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
|
||||
|
|
@ -1389,6 +1397,9 @@ func (s *regAllocState) regalloc(f *Func) {
|
|||
if vi.regs != 0 {
|
||||
continue
|
||||
}
|
||||
if vi.rematerializeable {
|
||||
continue
|
||||
}
|
||||
v := s.orig[vid]
|
||||
if s.f.Config.use387 && v.Type.IsFloat() {
|
||||
continue // 387 can't handle floats in registers between blocks
|
||||
|
|
|
|||
Loading…
Reference in New Issue