{name: "checkLower", fn: checkLower, required: true},
{name: "late phielim", fn: phielim},
{name: "late copyelim", fn: copyelim},
- {name: "tighten", fn: tighten}, // move values closer to their uses
+ {name: "tighten", fn: tighten, required: true}, // move values closer to their uses
{name: "late deadcode", fn: deadcode},
{name: "critical", fn: critical, required: true}, // remove critical edges
{name: "phi tighten", fn: phiTighten}, // place rematerializable phi args near uses to reduce value lifetimes
package ssa
+import "cmd/compile/internal/base"
+
// tighten moves Values closer to the Blocks in which they are used.
// This can reduce the amount of register spilling required,
// if it doesn't also create more live values.
// A Value can be moved to any block that
// dominates all blocks in which it is used.
func tighten(f *Func) {
+ if base.Flag.N != 0 && len(f.Blocks) < 10000 {
+ // Skip the optimization in -N mode, except for huge functions.
+ // Too many values live across blocks can cause pathological
+ // behavior in the register allocator (see issue 52180).
+ return
+ }
+
canMove := f.Cache.allocBoolSlice(f.NumValues())
defer f.Cache.freeBoolSlice(canMove)
for _, b := range f.Blocks {