if x.debug {
x.Printf("...marking %v unused\n", a.LongString())
}
- a.reset(OpInvalid)
+ a.invalidateRecursively()
}
}
if x.debug {
x.Printf("...marking %v unused\n", a.LongString())
}
- a.reset(OpInvalid)
+ a.invalidateRecursively()
}
}
if x.debug {
if dupe == nil {
x.commonSelectors[sk] = v
} else if x.sdom.IsAncestorEq(dupe.Block, v.Block) {
+ if x.debug {
+ x.Printf("Duplicate, make %s copy of %s\n", v, dupe)
+ }
v.copyOf(dupe)
} else {
// Because values are processed in dominator order, the old common[s] will never dominate after a miss is seen.
x.Printf("allOrdered[%d] = b%d, %s, uses=%d\n", i, b.ID, v.LongString(), v.Uses)
}
if v.Uses == 0 {
- v.reset(OpInvalid)
+ v.invalidateRecursively()
continue
}
if v.Op == OpCopy {
v.SetArg(i, aa)
for a.Uses == 0 {
b := a.Args[0]
- a.reset(OpInvalid)
+ a.invalidateRecursively()
a = b
}
}
v.Aux = nil
}
+// invalidateRecursively marks a value as invalid (unused)
+// and after decrementing reference counts on its Args,
+// also recursively invalidates any of those whose use
+// count goes to zero.
+//
+// BEWARE of doing this *before* you've applied intended
+// updates to SSA.
+func (v *Value) invalidateRecursively() {
+ if v.InCache {
+ v.Block.Func.unCache(v)
+ }
+ v.Op = OpInvalid
+
+ for _, a := range v.Args {
+ a.Uses--
+ if a.Uses == 0 {
+ a.invalidateRecursively()
+ }
+ }
+
+ v.argstorage[0] = nil
+ v.argstorage[1] = nil
+ v.argstorage[2] = nil
+ v.Args = v.argstorage[:0]
+
+ v.AuxInt = 0
+ v.Aux = nil
+}
+
// copyOf is called from rewrite rules.
// It modifies v to be (Copy a).
//go:noinline