From 1bddd2ee6aed261830131f824fe32e07de326066 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Wed, 5 Oct 2016 14:35:47 -0700 Subject: [PATCH] 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 Run-TryBot: Keith Randall Reviewed-by: Cherry Zhang --- src/cmd/compile/internal/ssa/regalloc.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index 3b9f49d9df..4cf957a41a 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -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 -- 2.48.1