]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: generalize struct load/store
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 5 Sep 2024 07:56:43 +0000 (14:56 +0700)
committerGopher Robot <gobot@golang.org>
Thu, 26 Sep 2024 13:18:08 +0000 (13:18 +0000)
The SSA backend currently only handle struct with up to 4 fields. Thus,
there are different operations corresponding to number fields of the
struct.

This CL generalizes these with just one OpStructMake, allow struct types
with arbitrary number of fields.

However, the ssa.MaxStruct is still kept as-is, and future CL will
increase this value to optimize large structs.

Updates #24416

Change-Id: I192ffbea881186693584476b5639394e79be45c5
Reviewed-on: https://go-review.googlesource.com/c/go/+/611075
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Auto-Submit: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
12 files changed:
src/cmd/compile/internal/ssa/_gen/dec.rules
src/cmd/compile/internal/ssa/_gen/generic.rules
src/cmd/compile/internal/ssa/_gen/genericOps.go
src/cmd/compile/internal/ssa/copyelim.go
src/cmd/compile/internal/ssa/decompose.go
src/cmd/compile/internal/ssa/expand_calls.go
src/cmd/compile/internal/ssa/numberlines.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewrite.go
src/cmd/compile/internal/ssa/rewritedec.go
src/cmd/compile/internal/ssa/rewritegeneric.go
src/cmd/compile/internal/ssagen/ssa.go

index 7944947e062b9134a320c82ac57327bb95f2ea4e..5309a7f6b49f1edc9c9ccdcc5736f08ba6395b78 100644 (file)
 // 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)
index 243c54e5a8f61f572b0510f13c48ca2921d645fd..7228acd14e213d58a2221d0f7228889e3ff29f22 100644 (file)
 (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
index cf472dd208f0709f9c8d417e9446044535d259e3..9baceb19203faee3e21439fe29657d8f28b2e244 100644 (file)
@@ -521,11 +521,7 @@ var genericOps = []opData{
        {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
index ea888f46f9f51234ab035d9d86d0346a6c95173d..09df63565be29c84f60cceab73ce14286ff5c63f 100644 (file)
@@ -106,7 +106,7 @@ func phielim(f *Func) {
                                // 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)
                                        }
index 250b2321afd30fc56bbd0c325c2b65a1324340d8..cf9285741ed085150a257125f475b9079358bdf1 100644 (file)
@@ -318,11 +318,10 @@ func decomposeUserStructInto(f *Func, name *LocalSlot, slots []*LocalSlot) []*Lo
                }
        }
 
-       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
                }
@@ -373,7 +372,7 @@ func decomposeStructPhi(v *Value) {
                        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.
@@ -408,24 +407,6 @@ func decomposeArrayPhi(v *Value) {
 // 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
 }
index b0788f1db4bba556b05f93d36705b90f2c975f09..f589db419903ccff3a4861d914f9b7ecb650f633 100644 (file)
@@ -425,7 +425,7 @@ func (x *expandState) decomposeAsNecessary(pos src.XPos, b *Block, a, m0 *Value,
                // 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))
@@ -505,7 +505,7 @@ func (x *expandState) rewriteSelectOrArg(pos src.XPos, b *Block, container, a, m
                        return makeOf(a, OpArrayMake0, nil)
                }
                if at.IsStruct() {
-                       return makeOf(a, OpStructMake0, nil)
+                       return makeOf(a, OpStructMake, nil)
                }
                return a
        }
@@ -559,7 +559,7 @@ func (x *expandState) rewriteSelectOrArg(pos src.XPos, b *Block, container, a, m
                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
 
index b4eca324d5200590b89c13796f085db9b4ce4439..bd7794042a280b072705035cbe5d259398e483d8 100644 (file)
@@ -15,7 +15,7 @@ func isPoorStatementOp(op Op) bool {
        // 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
index 9e6f8b9a97b46b299f13605bb27f277a8f9c004c..574bbbdc613e30a2113eca0504a41e683cb0a205 100644 (file)
@@ -3197,11 +3197,7 @@ const (
        OpIMake
        OpITab
        OpIData
-       OpStructMake0
-       OpStructMake1
-       OpStructMake2
-       OpStructMake3
-       OpStructMake4
+       OpStructMake
        OpStructSelect
        OpArrayMake0
        OpArrayMake1
@@ -40862,28 +40858,8 @@ var opcodeTable = [...]opInfo{
                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,
        },
        {
index 045e571652b391b7e81570aefd035514e998fbd7..71b8f09daf3fdeddbaee0deb76bee745e3bb4a29 100644 (file)
@@ -2356,3 +2356,41 @@ func isNonNegative(v *Value) bool {
        }
        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
+}
index 3c481adc15879f92dac313e50c7bbbb1976e3e1b..16d02692105b55a8620b495d869a3bc56e42fa60 100644 (file)
@@ -36,8 +36,8 @@ func rewriteValuedec(v *Value) bool {
                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)
        }
@@ -279,11 +279,11 @@ func rewriteValuedec_OpIData(v *Value) bool {
 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]
@@ -718,118 +718,13 @@ func rewriteValuedec_OpStore(v *Value) bool {
                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)
@@ -924,13 +819,15 @@ func rewriteValuedec_OpStringPtr(v *Value) bool {
        }
        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
                }
@@ -953,104 +850,15 @@ func rewriteValuedec_OpStructSelect(v *Value) bool {
                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)
index 760c55fca8a6081e2bf782b2a68bebc12fb4c8b0..f0685c205e925751e5ebc43820a52382f03d2310 100644 (file)
@@ -10556,11 +10556,11 @@ func rewriteValuegeneric_OpFloor(v *Value) bool {
 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]
@@ -13991,120 +13991,14 @@ func rewriteValuegeneric_OpLoad(v *Value) bool {
                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> _ _)
@@ -29772,128 +29666,13 @@ func rewriteValuegeneric_OpStore(v *Value) bool {
                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)
@@ -30407,104 +30186,15 @@ func rewriteValuegeneric_OpStringPtr(v *Value) bool {
 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))
index 97681214e72e2b92c23583d63661c6d33dda3247..d086b74e827dfb989b1c7587d69918525415fec6 100644 (file)
@@ -3943,7 +3943,7 @@ func (s *state) assignWhichMayOverlap(left ir.Node, right *ssa.Value, deref bool
                        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++ {
@@ -4071,7 +4071,7 @@ func (s *state) zeroVal(t *types.Type) *ssa.Value {
                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)))
                }