Commit 1bddd2ee authored by Keith Randall's avatar Keith Randall

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: default avatarCherry Zhang <cherryyz@google.com>
parent e5421e21
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment