{"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},
// 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
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)
}