// Helpers for expand calls
// Some of these are copied from generic.rules
-(IMake _typ (StructMake1 val)) => (IMake _typ val)
+(IMake _typ (StructMake val)) => (IMake _typ val)
(StructSelect [0] (IData x)) => (IData x)
-(StructSelect (StructMake1 x)) => x
-(StructSelect [0] (StructMake2 x _)) => x
-(StructSelect [1] (StructMake2 _ x)) => x
-(StructSelect [0] (StructMake3 x _ _)) => x
-(StructSelect [1] (StructMake3 _ x _)) => x
-(StructSelect [2] (StructMake3 _ _ x)) => x
-(StructSelect [0] (StructMake4 x _ _ _)) => x
-(StructSelect [1] (StructMake4 _ x _ _)) => x
-(StructSelect [2] (StructMake4 _ _ x _)) => x
-(StructSelect [3] (StructMake4 _ _ _ x)) => x
+(StructSelect [i] x:(StructMake ___)) => x.Args[i]
// Special case coming from immediate interface rewriting
// Typical case: (StructSelect [0] (IData (IMake typ dat)) rewrites to (StructSelect [0] dat)
// These, too. Bits is bits.
(ArrayMake1 x) && x.Type.IsPtrShaped() => x
-(StructMake1 x) && x.Type.IsPtrShaped() => x
-
-(Store dst (StructMake1 <t> f0) mem) =>
- (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
-(Store dst (StructMake2 <t> f0 f1) mem) =>
- (Store {t.FieldType(1)}
- (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
- f1
- (Store {t.FieldType(0)}
- (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
- f0 mem))
-(Store dst (StructMake3 <t> f0 f1 f2) mem) =>
- (Store {t.FieldType(2)}
- (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
- f2
- (Store {t.FieldType(1)}
- (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
- f1
- (Store {t.FieldType(0)}
- (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
- f0 mem)))
-(Store dst (StructMake4 <t> f0 f1 f2 f3) mem) =>
- (Store {t.FieldType(3)}
- (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)
- f3
- (Store {t.FieldType(2)}
- (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
- f2
- (Store {t.FieldType(1)}
- (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
- f1
- (Store {t.FieldType(0)}
- (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
- f0 mem))))
+(StructMake x) && x.Type.IsPtrShaped() => x
+
+
+(Store _ (StructMake ___) _) => rewriteStructStore(v)
(ArraySelect (ArrayMake1 x)) => x
(ArraySelect [0] (IData x)) => (IData x)
(PtrIndex <t> ptr idx) && config.PtrSize == 8 => (AddPtr ptr (Mul64 <typ.Int> idx (Const64 <typ.Int> [t.Elem().Size()])))
// struct operations
-(StructSelect (StructMake1 x)) => x
-(StructSelect [0] (StructMake2 x _)) => x
-(StructSelect [1] (StructMake2 _ x)) => x
-(StructSelect [0] (StructMake3 x _ _)) => x
-(StructSelect [1] (StructMake3 _ x _)) => x
-(StructSelect [2] (StructMake3 _ _ x)) => x
-(StructSelect [0] (StructMake4 x _ _ _)) => x
-(StructSelect [1] (StructMake4 _ x _ _)) => x
-(StructSelect [2] (StructMake4 _ _ x _)) => x
-(StructSelect [3] (StructMake4 _ _ _ x)) => x
-
-(Load <t> _ _) && t.IsStruct() && t.NumFields() == 0 && CanSSA(t) =>
- (StructMake0)
-(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 1 && CanSSA(t) =>
- (StructMake1
- (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem))
-(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 2 && CanSSA(t) =>
- (StructMake2
- (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem)
- (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem))
-(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 3 && CanSSA(t) =>
- (StructMake3
- (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem)
- (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem)
- (Load <t.FieldType(2)> (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] ptr) mem))
-(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 4 && CanSSA(t) =>
- (StructMake4
- (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem)
- (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem)
- (Load <t.FieldType(2)> (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] ptr) mem)
- (Load <t.FieldType(3)> (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] ptr) mem))
+(StructSelect [i] x:(StructMake ___)) => x.Args[i]
+(Load <t> _ _) && t.IsStruct() && CanSSA(t) => rewriteStructLoad(v)
+(Store _ (StructMake ___) _) => rewriteStructStore(v)
(StructSelect [i] x:(Load <t> ptr mem)) && !CanSSA(t) =>
@x.Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(int(i))] ptr) mem)
-(Store _ (StructMake0) mem) => mem
-(Store dst (StructMake1 <t> f0) mem) =>
- (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
-(Store dst (StructMake2 <t> f0 f1) mem) =>
- (Store {t.FieldType(1)}
- (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
- f1
- (Store {t.FieldType(0)}
- (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
- f0 mem))
-(Store dst (StructMake3 <t> f0 f1 f2) mem) =>
- (Store {t.FieldType(2)}
- (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
- f2
- (Store {t.FieldType(1)}
- (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
- f1
- (Store {t.FieldType(0)}
- (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
- f0 mem)))
-(Store dst (StructMake4 <t> f0 f1 f2 f3) mem) =>
- (Store {t.FieldType(3)}
- (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)
- f3
- (Store {t.FieldType(2)}
- (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
- f2
- (Store {t.FieldType(1)}
- (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
- f1
- (Store {t.FieldType(0)}
- (OffPtr <t.FieldType(0).PtrTo()> [0] dst)
- f0 mem))))
-
// Putting struct{*byte} and similar into direct interfaces.
-(IMake _typ (StructMake1 val)) => (IMake _typ val)
+(IMake _typ (StructMake val)) => (IMake _typ val)
(StructSelect [0] (IData x)) => (IData x)
// un-SSAable values use mem->mem copies
{name: "IData", argLength: 1}, // arg0=interface, returns data field
// Structs
- {name: "StructMake0"}, // Returns struct with 0 fields.
- {name: "StructMake1", argLength: 1}, // arg0=field0. Returns struct.
- {name: "StructMake2", argLength: 2}, // arg0,arg1=field0,field1. Returns struct.
- {name: "StructMake3", argLength: 3}, // arg0..2=field0..2. Returns struct.
- {name: "StructMake4", argLength: 4}, // arg0..3=field0..3. Returns struct.
+ {name: "StructMake", argLength: -1}, // args...=field0..n-1. Returns struct with n fields.
{name: "StructSelect", argLength: 1, aux: "Int64"}, // arg0=struct, auxint=field index. Returns the auxint'th field.
// Arrays
// Rewrite all 0-sized Go values to remove accessors, dereferences, loads, etc.
if t := v.Type; (t.IsStruct() || t.IsArray()) && t.Size() == 0 {
if t.IsStruct() {
- v.reset(OpStructMake0)
+ v.reset(OpStructMake)
} else {
v.reset(OpArrayMake0)
}
}
}
- makeOp := StructMakeOp(n)
var keep []*Value
// create named values for each struct field
for _, v := range f.NamedValues[*name] {
- if v.Op != makeOp {
+ if v.Op != OpStructMake || len(v.Args) != n {
keep = append(keep, v)
continue
}
fields[i].AddArg(a.Block.NewValue1I(v.Pos, OpStructSelect, t.FieldType(i), int64(i), a))
}
}
- v.reset(StructMakeOp(n))
+ v.reset(OpStructMake)
v.AddArgs(fields[:n]...)
// Recursively decompose phis for each field.
// can have and still be SSAable.
const MaxStruct = 4
-// StructMakeOp returns the opcode to construct a struct with the
-// given number of fields.
-func StructMakeOp(nf int) Op {
- switch nf {
- case 0:
- return OpStructMake0
- case 1:
- return OpStructMake1
- case 2:
- return OpStructMake2
- case 3:
- return OpStructMake3
- case 4:
- return OpStructMake4
- }
- panic("too many fields in an SSAable struct")
-}
-
type namedVal struct {
locIndex, valIndex int // f.NamedValues[f.Names[locIndex]][valIndex] = key
}
// Immediate interfaces cause so many headaches.
if a.Op == OpIMake {
data := a.Args[1]
- for data.Op == OpStructMake1 || data.Op == OpArrayMake1 {
+ for data.Op == OpStructMake || data.Op == OpArrayMake1 {
data = data.Args[0]
}
return x.decomposeAsNecessary(pos, b, data, mem, rc.next(data.Type))
return makeOf(a, OpArrayMake0, nil)
}
if at.IsStruct() {
- return makeOf(a, OpStructMake0, nil)
+ return makeOf(a, OpStructMake, nil)
}
return a
}
if at.NumFields() > 4 {
panic(fmt.Errorf("Too many fields (%d, %d bytes), container=%s", at.NumFields(), at.Size(), container.LongString()))
}
- a = makeOf(a, StructMakeOp(at.NumFields()), args)
+ a = makeOf(a, OpStructMake, args)
x.commonSelectors[sk] = a
return a
// Note that Nilcheck often vanishes, but when it doesn't, you'd love to start the statement there
// so that a debugger-user sees the stop before the panic, and can examine the value.
case OpAddr, OpLocalAddr, OpOffPtr, OpStructSelect, OpPhi, OpITab, OpIData,
- OpIMake, OpStringMake, OpSliceMake, OpStructMake0, OpStructMake1, OpStructMake2, OpStructMake3, OpStructMake4,
+ OpIMake, OpStringMake, OpSliceMake, OpStructMake,
OpConstBool, OpConst8, OpConst16, OpConst32, OpConst64, OpConst32F, OpConst64F, OpSB, OpSP,
OpArgIntReg, OpArgFloatReg:
return true
OpIMake
OpITab
OpIData
- OpStructMake0
- OpStructMake1
- OpStructMake2
- OpStructMake3
- OpStructMake4
+ OpStructMake
OpStructSelect
OpArrayMake0
OpArrayMake1
generic: true,
},
{
- name: "StructMake0",
- argLen: 0,
- generic: true,
- },
- {
- name: "StructMake1",
- argLen: 1,
- generic: true,
- },
- {
- name: "StructMake2",
- argLen: 2,
- generic: true,
- },
- {
- name: "StructMake3",
- argLen: 3,
- generic: true,
- },
- {
- name: "StructMake4",
- argLen: 4,
+ name: "StructMake",
+ argLen: -1,
generic: true,
},
{
}
return false
}
+
+func rewriteStructLoad(v *Value) *Value {
+ b := v.Block
+ ptr := v.Args[0]
+ mem := v.Args[1]
+
+ t := v.Type
+ args := make([]*Value, t.NumFields())
+ for i := range args {
+ ft := t.FieldType(i)
+ addr := b.NewValue1I(v.Pos, OpOffPtr, ft.PtrTo(), t.FieldOff(i), ptr)
+ args[i] = b.NewValue2(v.Pos, OpLoad, ft, addr, mem)
+ }
+
+ v.reset(OpStructMake)
+ v.AddArgs(args...)
+ return v
+}
+
+func rewriteStructStore(v *Value) *Value {
+ b := v.Block
+ dst := v.Args[0]
+ x := v.Args[1]
+ if x.Op != OpStructMake {
+ base.Fatalf("invalid struct store: %v", x)
+ }
+ mem := v.Args[2]
+
+ t := x.Type
+ for i, arg := range x.Args {
+ ft := t.FieldType(i)
+
+ addr := b.NewValue1I(v.Pos, OpOffPtr, ft.PtrTo(), t.FieldOff(i), dst)
+ mem = b.NewValue3A(v.Pos, OpStore, types.TypeMem, typeToAux(ft), addr, arg, mem)
+ }
+
+ return mem
+}
return rewriteValuedec_OpStringLen(v)
case OpStringPtr:
return rewriteValuedec_OpStringPtr(v)
- case OpStructMake1:
- return rewriteValuedec_OpStructMake1(v)
+ case OpStructMake:
+ return rewriteValuedec_OpStructMake(v)
case OpStructSelect:
return rewriteValuedec_OpStructSelect(v)
}
func rewriteValuedec_OpIMake(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- // match: (IMake _typ (StructMake1 val))
+ // match: (IMake _typ (StructMake val))
// result: (IMake _typ val)
for {
_typ := v_0
- if v_1.Op != OpStructMake1 {
+ if v_1.Op != OpStructMake || len(v_1.Args) != 1 {
break
}
val := v_1.Args[0]
v.AddArg3(v0, data, v1)
return true
}
- // match: (Store dst (StructMake1 <t> f0) mem)
- // result: (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
+ // match: (Store _ (StructMake ___) _)
+ // result: rewriteStructStore(v)
for {
- dst := v_0
- if v_1.Op != OpStructMake1 {
+ if v_1.Op != OpStructMake {
break
}
- t := v_1.Type
- f0 := v_1.Args[0]
- mem := v_2
- v.reset(OpStore)
- v.Aux = typeToAux(t.FieldType(0))
- v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v0.AuxInt = int64ToAuxInt(0)
- v0.AddArg(dst)
- v.AddArg3(v0, f0, mem)
- return true
- }
- // match: (Store dst (StructMake2 <t> f0 f1) mem)
- // result: (Store {t.FieldType(1)} (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem))
- for {
- dst := v_0
- if v_1.Op != OpStructMake2 {
- break
- }
- t := v_1.Type
- f1 := v_1.Args[1]
- f0 := v_1.Args[0]
- mem := v_2
- v.reset(OpStore)
- v.Aux = typeToAux(t.FieldType(1))
- v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v0.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v0.AddArg(dst)
- v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v1.Aux = typeToAux(t.FieldType(0))
- v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v2.AuxInt = int64ToAuxInt(0)
- v2.AddArg(dst)
- v1.AddArg3(v2, f0, mem)
- v.AddArg3(v0, f1, v1)
- return true
- }
- // match: (Store dst (StructMake3 <t> f0 f1 f2) mem)
- // result: (Store {t.FieldType(2)} (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst) f2 (Store {t.FieldType(1)} (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)))
- for {
- dst := v_0
- if v_1.Op != OpStructMake3 {
- break
- }
- t := v_1.Type
- f2 := v_1.Args[2]
- f0 := v_1.Args[0]
- f1 := v_1.Args[1]
- mem := v_2
- v.reset(OpStore)
- v.Aux = typeToAux(t.FieldType(2))
- v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
- v0.AuxInt = int64ToAuxInt(t.FieldOff(2))
- v0.AddArg(dst)
- v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v1.Aux = typeToAux(t.FieldType(1))
- v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v2.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v2.AddArg(dst)
- v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v3.Aux = typeToAux(t.FieldType(0))
- v4 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v4.AuxInt = int64ToAuxInt(0)
- v4.AddArg(dst)
- v3.AddArg3(v4, f0, mem)
- v1.AddArg3(v2, f1, v3)
- v.AddArg3(v0, f2, v1)
- return true
- }
- // match: (Store dst (StructMake4 <t> f0 f1 f2 f3) mem)
- // result: (Store {t.FieldType(3)} (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst) f3 (Store {t.FieldType(2)} (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst) f2 (Store {t.FieldType(1)} (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem))))
- for {
- dst := v_0
- if v_1.Op != OpStructMake4 {
- break
- }
- t := v_1.Type
- f3 := v_1.Args[3]
- f0 := v_1.Args[0]
- f1 := v_1.Args[1]
- f2 := v_1.Args[2]
- mem := v_2
- v.reset(OpStore)
- v.Aux = typeToAux(t.FieldType(3))
- v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(3).PtrTo())
- v0.AuxInt = int64ToAuxInt(t.FieldOff(3))
- v0.AddArg(dst)
- v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v1.Aux = typeToAux(t.FieldType(2))
- v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
- v2.AuxInt = int64ToAuxInt(t.FieldOff(2))
- v2.AddArg(dst)
- v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v3.Aux = typeToAux(t.FieldType(1))
- v4 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v4.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v4.AddArg(dst)
- v5 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v5.Aux = typeToAux(t.FieldType(0))
- v6 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v6.AuxInt = int64ToAuxInt(0)
- v6.AddArg(dst)
- v5.AddArg3(v6, f0, mem)
- v3.AddArg3(v4, f1, v5)
- v1.AddArg3(v2, f2, v3)
- v.AddArg3(v0, f3, v1)
+ v.copyOf(rewriteStructStore(v))
return true
}
// match: (Store dst (ArrayMake1 e) mem)
}
return false
}
-func rewriteValuedec_OpStructMake1(v *Value) bool {
- v_0 := v.Args[0]
- // match: (StructMake1 x)
+func rewriteValuedec_OpStructMake(v *Value) bool {
+ // match: (StructMake x)
// cond: x.Type.IsPtrShaped()
// result: x
for {
- x := v_0
+ if len(v.Args) != 1 {
+ break
+ }
+ x := v.Args[0]
if !(x.Type.IsPtrShaped()) {
break
}
v.AddArg(x)
return true
}
- // match: (StructSelect (StructMake1 x))
- // result: x
- for {
- if v_0.Op != OpStructMake1 {
- break
- }
- x := v_0.Args[0]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [0] (StructMake2 x _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpStructMake2 {
- break
- }
- x := v_0.Args[0]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [1] (StructMake2 _ x))
- // result: x
+ // match: (StructSelect [i] x:(StructMake ___))
+ // result: x.Args[i]
for {
- if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStructMake2 {
- break
- }
- x := v_0.Args[1]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [0] (StructMake3 x _ _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpStructMake3 {
- break
- }
- x := v_0.Args[0]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [1] (StructMake3 _ x _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStructMake3 {
- break
- }
- x := v_0.Args[1]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [2] (StructMake3 _ _ x))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 2 || v_0.Op != OpStructMake3 {
- break
- }
- x := v_0.Args[2]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [0] (StructMake4 x _ _ _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpStructMake4 {
- break
- }
- x := v_0.Args[0]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [1] (StructMake4 _ x _ _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStructMake4 {
- break
- }
- x := v_0.Args[1]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [2] (StructMake4 _ _ x _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 2 || v_0.Op != OpStructMake4 {
- break
- }
- x := v_0.Args[2]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [3] (StructMake4 _ _ _ x))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 3 || v_0.Op != OpStructMake4 {
+ i := auxIntToInt64(v.AuxInt)
+ x := v_0
+ if x.Op != OpStructMake {
break
}
- x := v_0.Args[3]
- v.copyOf(x)
+ v.copyOf(x.Args[i])
return true
}
// match: (StructSelect [0] x)
func rewriteValuegeneric_OpIMake(v *Value) bool {
v_1 := v.Args[1]
v_0 := v.Args[0]
- // match: (IMake _typ (StructMake1 val))
+ // match: (IMake _typ (StructMake val))
// result: (IMake _typ val)
for {
_typ := v_0
- if v_1.Op != OpStructMake1 {
+ if v_1.Op != OpStructMake || len(v_1.Args) != 1 {
break
}
val := v_1.Args[0]
return true
}
// match: (Load <t> _ _)
- // cond: t.IsStruct() && t.NumFields() == 0 && CanSSA(t)
- // result: (StructMake0)
+ // cond: t.IsStruct() && CanSSA(t)
+ // result: rewriteStructLoad(v)
for {
t := v.Type
- if !(t.IsStruct() && t.NumFields() == 0 && CanSSA(t)) {
+ if !(t.IsStruct() && CanSSA(t)) {
break
}
- v.reset(OpStructMake0)
- return true
- }
- // match: (Load <t> ptr mem)
- // cond: t.IsStruct() && t.NumFields() == 1 && CanSSA(t)
- // result: (StructMake1 (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem))
- for {
- t := v.Type
- ptr := v_0
- mem := v_1
- if !(t.IsStruct() && t.NumFields() == 1 && CanSSA(t)) {
- break
- }
- v.reset(OpStructMake1)
- v0 := b.NewValue0(v.Pos, OpLoad, t.FieldType(0))
- v1 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v1.AuxInt = int64ToAuxInt(0)
- v1.AddArg(ptr)
- v0.AddArg2(v1, mem)
- v.AddArg(v0)
- return true
- }
- // match: (Load <t> ptr mem)
- // cond: t.IsStruct() && t.NumFields() == 2 && CanSSA(t)
- // result: (StructMake2 (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem) (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem))
- for {
- t := v.Type
- ptr := v_0
- mem := v_1
- if !(t.IsStruct() && t.NumFields() == 2 && CanSSA(t)) {
- break
- }
- v.reset(OpStructMake2)
- v0 := b.NewValue0(v.Pos, OpLoad, t.FieldType(0))
- v1 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v1.AuxInt = int64ToAuxInt(0)
- v1.AddArg(ptr)
- v0.AddArg2(v1, mem)
- v2 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
- v3 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v3.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v3.AddArg(ptr)
- v2.AddArg2(v3, mem)
- v.AddArg2(v0, v2)
- return true
- }
- // match: (Load <t> ptr mem)
- // cond: t.IsStruct() && t.NumFields() == 3 && CanSSA(t)
- // result: (StructMake3 (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem) (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem) (Load <t.FieldType(2)> (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] ptr) mem))
- for {
- t := v.Type
- ptr := v_0
- mem := v_1
- if !(t.IsStruct() && t.NumFields() == 3 && CanSSA(t)) {
- break
- }
- v.reset(OpStructMake3)
- v0 := b.NewValue0(v.Pos, OpLoad, t.FieldType(0))
- v1 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v1.AuxInt = int64ToAuxInt(0)
- v1.AddArg(ptr)
- v0.AddArg2(v1, mem)
- v2 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
- v3 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v3.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v3.AddArg(ptr)
- v2.AddArg2(v3, mem)
- v4 := b.NewValue0(v.Pos, OpLoad, t.FieldType(2))
- v5 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
- v5.AuxInt = int64ToAuxInt(t.FieldOff(2))
- v5.AddArg(ptr)
- v4.AddArg2(v5, mem)
- v.AddArg3(v0, v2, v4)
- return true
- }
- // match: (Load <t> ptr mem)
- // cond: t.IsStruct() && t.NumFields() == 4 && CanSSA(t)
- // result: (StructMake4 (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem) (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem) (Load <t.FieldType(2)> (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] ptr) mem) (Load <t.FieldType(3)> (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] ptr) mem))
- for {
- t := v.Type
- ptr := v_0
- mem := v_1
- if !(t.IsStruct() && t.NumFields() == 4 && CanSSA(t)) {
- break
- }
- v.reset(OpStructMake4)
- v0 := b.NewValue0(v.Pos, OpLoad, t.FieldType(0))
- v1 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v1.AuxInt = int64ToAuxInt(0)
- v1.AddArg(ptr)
- v0.AddArg2(v1, mem)
- v2 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
- v3 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v3.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v3.AddArg(ptr)
- v2.AddArg2(v3, mem)
- v4 := b.NewValue0(v.Pos, OpLoad, t.FieldType(2))
- v5 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
- v5.AuxInt = int64ToAuxInt(t.FieldOff(2))
- v5.AddArg(ptr)
- v4.AddArg2(v5, mem)
- v6 := b.NewValue0(v.Pos, OpLoad, t.FieldType(3))
- v7 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(3).PtrTo())
- v7.AuxInt = int64ToAuxInt(t.FieldOff(3))
- v7.AddArg(ptr)
- v6.AddArg2(v7, mem)
- v.AddArg4(v0, v2, v4, v6)
+ v.copyOf(rewriteStructLoad(v))
return true
}
// match: (Load <t> _ _)
v.copyOf(mem)
return true
}
- // match: (Store _ (StructMake0) mem)
- // result: mem
- for {
- if v_1.Op != OpStructMake0 {
- break
- }
- mem := v_2
- v.copyOf(mem)
- return true
- }
- // match: (Store dst (StructMake1 <t> f0) mem)
- // result: (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
- for {
- dst := v_0
- if v_1.Op != OpStructMake1 {
- break
- }
- t := v_1.Type
- f0 := v_1.Args[0]
- mem := v_2
- v.reset(OpStore)
- v.Aux = typeToAux(t.FieldType(0))
- v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v0.AuxInt = int64ToAuxInt(0)
- v0.AddArg(dst)
- v.AddArg3(v0, f0, mem)
- return true
- }
- // match: (Store dst (StructMake2 <t> f0 f1) mem)
- // result: (Store {t.FieldType(1)} (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem))
- for {
- dst := v_0
- if v_1.Op != OpStructMake2 {
- break
- }
- t := v_1.Type
- f1 := v_1.Args[1]
- f0 := v_1.Args[0]
- mem := v_2
- v.reset(OpStore)
- v.Aux = typeToAux(t.FieldType(1))
- v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v0.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v0.AddArg(dst)
- v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v1.Aux = typeToAux(t.FieldType(0))
- v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v2.AuxInt = int64ToAuxInt(0)
- v2.AddArg(dst)
- v1.AddArg3(v2, f0, mem)
- v.AddArg3(v0, f1, v1)
- return true
- }
- // match: (Store dst (StructMake3 <t> f0 f1 f2) mem)
- // result: (Store {t.FieldType(2)} (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst) f2 (Store {t.FieldType(1)} (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)))
- for {
- dst := v_0
- if v_1.Op != OpStructMake3 {
- break
- }
- t := v_1.Type
- f2 := v_1.Args[2]
- f0 := v_1.Args[0]
- f1 := v_1.Args[1]
- mem := v_2
- v.reset(OpStore)
- v.Aux = typeToAux(t.FieldType(2))
- v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
- v0.AuxInt = int64ToAuxInt(t.FieldOff(2))
- v0.AddArg(dst)
- v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v1.Aux = typeToAux(t.FieldType(1))
- v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v2.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v2.AddArg(dst)
- v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v3.Aux = typeToAux(t.FieldType(0))
- v4 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v4.AuxInt = int64ToAuxInt(0)
- v4.AddArg(dst)
- v3.AddArg3(v4, f0, mem)
- v1.AddArg3(v2, f1, v3)
- v.AddArg3(v0, f2, v1)
- return true
- }
- // match: (Store dst (StructMake4 <t> f0 f1 f2 f3) mem)
- // result: (Store {t.FieldType(3)} (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst) f3 (Store {t.FieldType(2)} (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst) f2 (Store {t.FieldType(1)} (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store {t.FieldType(0)} (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem))))
+ // match: (Store _ (StructMake ___) _)
+ // result: rewriteStructStore(v)
for {
- dst := v_0
- if v_1.Op != OpStructMake4 {
+ if v_1.Op != OpStructMake {
break
}
- t := v_1.Type
- f3 := v_1.Args[3]
- f0 := v_1.Args[0]
- f1 := v_1.Args[1]
- f2 := v_1.Args[2]
- mem := v_2
- v.reset(OpStore)
- v.Aux = typeToAux(t.FieldType(3))
- v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(3).PtrTo())
- v0.AuxInt = int64ToAuxInt(t.FieldOff(3))
- v0.AddArg(dst)
- v1 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v1.Aux = typeToAux(t.FieldType(2))
- v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
- v2.AuxInt = int64ToAuxInt(t.FieldOff(2))
- v2.AddArg(dst)
- v3 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v3.Aux = typeToAux(t.FieldType(1))
- v4 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
- v4.AuxInt = int64ToAuxInt(t.FieldOff(1))
- v4.AddArg(dst)
- v5 := b.NewValue0(v.Pos, OpStore, types.TypeMem)
- v5.Aux = typeToAux(t.FieldType(0))
- v6 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
- v6.AuxInt = int64ToAuxInt(0)
- v6.AddArg(dst)
- v5.AddArg3(v6, f0, mem)
- v3.AddArg3(v4, f1, v5)
- v1.AddArg3(v2, f2, v3)
- v.AddArg3(v0, f3, v1)
+ v.copyOf(rewriteStructStore(v))
return true
}
// match: (Store {t} dst (Load src mem) mem)
func rewriteValuegeneric_OpStructSelect(v *Value) bool {
v_0 := v.Args[0]
b := v.Block
- // match: (StructSelect (StructMake1 x))
- // result: x
- for {
- if v_0.Op != OpStructMake1 {
- break
- }
- x := v_0.Args[0]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [0] (StructMake2 x _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpStructMake2 {
- break
- }
- x := v_0.Args[0]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [1] (StructMake2 _ x))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStructMake2 {
- break
- }
- x := v_0.Args[1]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [0] (StructMake3 x _ _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpStructMake3 {
- break
- }
- x := v_0.Args[0]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [1] (StructMake3 _ x _))
- // result: x
+ // match: (StructSelect [i] x:(StructMake ___))
+ // result: x.Args[i]
for {
- if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStructMake3 {
- break
- }
- x := v_0.Args[1]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [2] (StructMake3 _ _ x))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 2 || v_0.Op != OpStructMake3 {
- break
- }
- x := v_0.Args[2]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [0] (StructMake4 x _ _ _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 0 || v_0.Op != OpStructMake4 {
- break
- }
- x := v_0.Args[0]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [1] (StructMake4 _ x _ _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 1 || v_0.Op != OpStructMake4 {
- break
- }
- x := v_0.Args[1]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [2] (StructMake4 _ _ x _))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 2 || v_0.Op != OpStructMake4 {
- break
- }
- x := v_0.Args[2]
- v.copyOf(x)
- return true
- }
- // match: (StructSelect [3] (StructMake4 _ _ _ x))
- // result: x
- for {
- if auxIntToInt64(v.AuxInt) != 3 || v_0.Op != OpStructMake4 {
+ i := auxIntToInt64(v.AuxInt)
+ x := v_0
+ if x.Op != OpStructMake {
break
}
- x := v_0.Args[3]
- v.copyOf(x)
+ v.copyOf(x.Args[i])
return true
}
// match: (StructSelect [i] x:(Load <t> ptr mem))
old := s.expr(left.X)
// Make new structure.
- new := s.newValue0(ssa.StructMakeOp(t.NumFields()), t)
+ new := s.newValue0(ssa.OpStructMake, t)
// Add fields as args.
for i := 0; i < nf; i++ {
return s.constSlice(t)
case t.IsStruct():
n := t.NumFields()
- v := s.entryNewValue0(ssa.StructMakeOp(t.NumFields()), t)
+ v := s.entryNewValue0(ssa.OpStructMake, t)
for i := 0; i < n; i++ {
v.AddArg(s.zeroVal(t.FieldType(i)))
}