const debugPhi = false
+// FwdRefAux wraps an arbitrary ir.Node as an ssa.Aux for use with OpFwdref.
+type FwdRefAux struct {
+ _ [0]func() // ensure ir.Node isn't compared for equality
+ N ir.Node
+}
+
+func (FwdRefAux) CanBeAnSSAAux() {}
+
// insertPhis finds all the places in the function where a phi is
// necessary and inserts them.
// Uses FwdRef ops to find all uses of variables, and s.defvars to find
if v.Op != ssa.OpFwdRef {
continue
}
- var_ := v.Aux.(ir.Node)
+ var_ := v.Aux.(FwdRefAux).N
// Optimization: look back 1 block for the definition.
if len(b.Preds) == 1 {
if v.Op != ssa.OpFwdRef {
continue
}
- n := s.varnum[v.Aux.(ir.Node)]
+ n := s.varnum[v.Aux.(FwdRefAux).N]
v.Op = ssa.OpCopy
v.Aux = nil
v.AddArg(values[n])
continue
}
s.fwdrefs = append(s.fwdrefs, v)
- var_ := v.Aux.(ir.Node)
+ var_ := v.Aux.(FwdRefAux).N
if _, ok := s.defvars[b.ID][var_]; !ok {
s.defvars[b.ID][var_] = v // treat FwdDefs as definitions.
}
v := s.fwdrefs[len(s.fwdrefs)-1]
s.fwdrefs = s.fwdrefs[:len(s.fwdrefs)-1]
b := v.Block
- var_ := v.Aux.(ir.Node)
+ var_ := v.Aux.(FwdRefAux).N
if b == s.f.Entry {
// No variable should be live at entry.
s.s.Fatalf("Value live at entry. It shouldn't be. func %s, node %v, value %v", s.f.Name, var_, v)
}
}
// Generate a FwdRef for the variable and return that.
- v := b.NewValue0A(line, ssa.OpFwdRef, t, var_)
+ v := b.NewValue0A(line, ssa.OpFwdRef, t, FwdRefAux{N: var_})
s.defvars[b.ID][var_] = v
s.s.addNamedValue(var_, v)
s.fwdrefs = append(s.fwdrefs, v)