From 8a961aee286cc7c891d5e0a49ed362fe500f81f4 Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Thu, 28 Jan 2016 17:43:45 -0800 Subject: [PATCH] [dev.ssa] cmd/compile: fix -N build The OpSB hack didn't quite work. We need to really CSE these ops to make regalloc happy. Change-Id: I9f4d7bfb0929407c84ee60c9e25ff0c0fbea84af Reviewed-on: https://go-review.googlesource.com/19083 Run-TryBot: Keith Randall TryBot-Result: Gobot Gobot Reviewed-by: David Chase --- src/cmd/compile/internal/ssa/compile.go | 2 +- src/cmd/compile/internal/ssa/cse.go | 28 ++++++++++++++++++++++++ src/cmd/compile/internal/ssa/regalloc.go | 6 ----- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go index 048f189ffe..121c1e1a37 100644 --- a/src/cmd/compile/internal/ssa/compile.go +++ b/src/cmd/compile/internal/ssa/compile.go @@ -92,7 +92,7 @@ var passes = [...]pass{ {"decompose", decompose, true}, {"opt", opt, true}, // TODO: split required rules and optimizing rules {"opt deadcode", deadcode, false}, // remove any blocks orphaned during opt - {"generic cse", cse, false}, + {"generic cse", cse, true}, {"nilcheckelim", nilcheckelim, false}, {"generic deadcode", deadcode, false}, {"fuse", fuse, false}, diff --git a/src/cmd/compile/internal/ssa/cse.go b/src/cmd/compile/internal/ssa/cse.go index 7603e17ecf..14cec12e92 100644 --- a/src/cmd/compile/internal/ssa/cse.go +++ b/src/cmd/compile/internal/ssa/cse.go @@ -10,6 +10,34 @@ import "sort" // Values are just relinked, nothing is deleted. A subsequent deadcode // pass is required to actually remove duplicate expressions. func cse(f *Func) { + if !f.Config.optimize { + // Don't do CSE in this case. But we need to do + // just a little bit, to combine multiple OpSB ops. + // Regalloc gets very confused otherwise. + var sb *Value + outer: + for _, b := range f.Blocks { + for _, v := range b.Values { + if v.Op == OpSB { + sb = v + break outer + } + } + } + if sb == nil { + return + } + for _, b := range f.Blocks { + for _, v := range b.Values { + for i, a := range v.Args { + if a.Op == OpSB { + v.Args[i] = sb + } + } + } + } + return + } // Two values are equivalent if they satisfy the following definition: // equivalent(v, w): // v.op == w.op diff --git a/src/cmd/compile/internal/ssa/regalloc.go b/src/cmd/compile/internal/ssa/regalloc.go index 2a92624319..1ab08b733c 100644 --- a/src/cmd/compile/internal/ssa/regalloc.go +++ b/src/cmd/compile/internal/ssa/regalloc.go @@ -316,12 +316,6 @@ func (s *regAllocState) assignReg(r register, v *Value, c *Value) { fmt.Printf("assignReg %s %s/%s\n", registers[r].Name(), v, c) } if s.regs[r].v != nil { - if v.Op == OpSB && !v.Block.Func.Config.optimize { - // Rewrite rules may introduce multiple OpSB, and with - // -N they don't get CSEd. Ignore the extra assignments. - s.f.setHome(c, ®isters[r]) - return - } s.f.Fatalf("tried to assign register %d to %s/%s but it is already used by %s", r, v, c, s.regs[r].v) } -- 2.48.1