return s.newValue2(ssa.OpLoad, n.Type, p, s.mem())
case ODOT:
- // TODO: fix when we can SSA struct types.
+ t := n.Left.Type
+ if canSSAType(t) {
+ v := s.expr(n.Left)
+ return s.newValue1I(ssa.OpStructSelect, n.Type, fieldIdx(n), v)
+ }
p := s.addr(n, false)
return s.newValue2(ssa.OpLoad, n.Type, p, s.mem())
// such types being spilled.
// So here we ensure that we are selecting the underlying pointer
// when we build an eface.
+ // TODO: get rid of this now that structs can be SSA'd?
for !data.Type.IsPtr() {
switch {
case data.Type.IsArray():
// eface type could also be struct{p *byte; q [0]int}
continue
}
- data = s.newValue1I(ssa.OpStructSelect, f, data.Type.FieldOff(i), data)
+ data = s.newValue1I(ssa.OpStructSelect, f, i, data)
break
}
default:
}
right = s.zeroVal(t)
}
- if left.Op == ONAME && canSSA(left) {
+ if canSSA(left) {
+ if left.Op == ODOT {
+ // We're assigning to a field of an ssa-able value.
+ // We need to build a new structure with the new value for the
+ // field we're assigning and the old values for the other fields.
+ // For instance:
+ // type T struct {a, b, c int}
+ // var T x
+ // x.b = 5
+ // For the x.b = 5 assignment we want to generate x = T{x.a, 5, x.c}
+
+ // Grab information about the structure type.
+ t := left.Left.Type
+ nf := t.NumFields()
+ idx := fieldIdx(left)
+
+ // Grab old value of structure.
+ old := s.expr(left.Left)
+
+ // Make new structure.
+ new := s.newValue0(ssa.StructMakeOp(t.NumFields()), t)
+
+ // Add fields as args.
+ for i := int64(0); i < nf; i++ {
+ if i == idx {
+ new.AddArg(right)
+ } else {
+ new.AddArg(s.newValue1I(ssa.OpStructSelect, t.FieldType(i), i, old))
+ }
+ }
+
+ // Recursively assign the new value we've made to the base of the dot op.
+ s.assign(left.Left, new, false, line)
+ // TODO: do we need to update named values here?
+ return
+ }
// Update variable assignment.
s.vars[left] = right
s.addNamedValue(left, right)
return s.entryNewValue0(ssa.OpConstInterface, t)
case t.IsSlice():
return s.entryNewValue0(ssa.OpConstSlice, t)
+ case t.IsStruct():
+ n := t.NumFields()
+ v := s.entryNewValue0(ssa.StructMakeOp(t.NumFields()), t)
+ for i := int64(0); i < n; i++ {
+ v.AddArg(s.zeroVal(t.FieldType(i).(*Type)))
+ }
+ return v
}
s.Unimplementedf("zero for type %v not implemented", t)
return nil
}
// canSSA reports whether n is SSA-able.
-// n must be an ONAME.
+// n must be an ONAME (or an ODOT sequence with an ONAME base).
func canSSA(n *Node) bool {
+ for n.Op == ODOT {
+ n = n.Left
+ }
if n.Op != ONAME {
return false
}
// introduced by the compiler for variadic functions.
return false
case TSTRUCT:
- if countfield(t) > 4 {
- // 4 is an arbitrary constant. Same reasoning
- // as above, lots of small fields would waste
- // register space needed by other values.
+ if countfield(t) > ssa.MaxStruct {
return false
}
for t1 := t.Type; t1 != nil; t1 = t1.Down {
return false
}
}
- return false // until it is implemented
- //return true
+ return true
default:
return true
}
return loc.N.(*Node), loc.Off
}
+// fieldIdx finds the index of the field referred to by the ODOT node n.
+func fieldIdx(n *Node) int64 {
+ t := n.Left.Type
+ f := n.Right
+ if t.Etype != TSTRUCT {
+ panic("ODOT's LHS is not a struct")
+ }
+
+ var i int64
+ for t1 := t.Type; t1 != nil; t1 = t1.Down {
+ if t1.Etype != TFIELD {
+ panic("non-TFIELD in TSTRUCT")
+ }
+ if t1.Sym != f.Sym {
+ i++
+ continue
+ }
+ if t1.Width != n.Xoffset {
+ panic("field offset doesn't match")
+ }
+ return i
+ }
+ panic(fmt.Sprintf("can't find field in expr %s\n", n))
+
+ // TODO: keep the result of this fucntion somewhere in the ODOT Node
+ // so we don't have to recompute it each time we need it.
+}
+
// ssaExport exports a bunch of compiler services for the ssa backend.
type ssaExport struct {
log bool
(ArrayIndex (Load ptr mem) idx) && b == v.Args[0].Block -> (Load (PtrIndex <v.Type.PtrTo()> ptr idx) mem)
(PtrIndex <t> ptr idx) && config.PtrSize == 4 -> (AddPtr ptr (Mul32 <config.fe.TypeInt()> idx (Const32 <config.fe.TypeInt()> [t.Elem().Size()])))
(PtrIndex <t> ptr idx) && config.PtrSize == 8 -> (AddPtr ptr (Mul64 <config.fe.TypeInt()> idx (Const64 <config.fe.TypeInt()> [t.Elem().Size()])))
-(StructSelect [idx] (Load ptr mem)) -> @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
+
+// 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 && config.fe.CanSSA(t) ->
+ (StructMake0)
+(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t) ->
+ (StructMake1
+ (Load <t.FieldType(0)> ptr mem))
+(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 2 && config.fe.CanSSA(t) ->
+ (StructMake2
+ (Load <t.FieldType(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 && config.fe.CanSSA(t) ->
+ (StructMake3
+ (Load <t.FieldType(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 && config.fe.CanSSA(t) ->
+ (StructMake4
+ (Load <t.FieldType(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] (Load <t> ptr mem)) && !config.fe.CanSSA(t) ->
+ @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(i)] ptr) mem)
+
+(Store _ (StructMake0) mem) -> mem
+(Store dst (StructMake1 <t> f0) mem) ->
+ (Store [t.FieldType(0).Size()] dst f0 mem)
+(Store dst (StructMake2 <t> f0 f1) mem) ->
+ (Store [t.FieldType(1).Size()]
+ (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
+ f1
+ (Store [t.FieldType(0).Size()] dst f0 mem))
+(Store dst (StructMake3 <t> f0 f1 f2) mem) ->
+ (Store [t.FieldType(2).Size()]
+ (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
+ f2
+ (Store [t.FieldType(1).Size()]
+ (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
+ f1
+ (Store [t.FieldType(0).Size()] dst f0 mem)))
+(Store dst (StructMake4 <t> f0 f1 f2 f3) mem) ->
+ (Store [t.FieldType(3).Size()]
+ (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst)
+ f3
+ (Store [t.FieldType(2).Size()]
+ (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst)
+ f2
+ (Store [t.FieldType(1).Size()]
+ (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
+ f1
+ (Store [t.FieldType(0).Size()] dst f0 mem))))
// complex ops
(ComplexReal (ComplexMake real _ )) -> real
(ComplexMake
(Arg <config.fe.TypeFloat32()> {n} [off])
(Arg <config.fe.TypeFloat32()> {n} [off+4]))
+
+(Arg <t>) && t.IsStruct() && t.NumFields() == 0 && config.fe.CanSSA(t) ->
+ (StructMake0)
+(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t) ->
+ (StructMake1
+ (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]))
+(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 2 && config.fe.CanSSA(t) ->
+ (StructMake2
+ (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)])
+ (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)]))
+(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 3 && config.fe.CanSSA(t) ->
+ (StructMake3
+ (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)])
+ (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)])
+ (Arg <t.FieldType(2)> {n} [off+t.FieldOff(2)]))
+(Arg <t> {n} [off]) && t.IsStruct() && t.NumFields() == 4 && config.fe.CanSSA(t) ->
+ (StructMake4
+ (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)])
+ (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)])
+ (Arg <t.FieldType(2)> {n} [off+t.FieldOff(2)])
+ (Arg <t.FieldType(3)> {n} [off+t.FieldOff(3)]))
}
goto enda348e93e0036873dd7089a2939c22e3e
enda348e93e0036873dd7089a2939c22e3e:
+ ;
+ // match: (Arg <t>)
+ // cond: t.IsStruct() && t.NumFields() == 0 && config.fe.CanSSA(t)
+ // result: (StructMake0)
+ {
+ t := v.Type
+ if !(t.IsStruct() && t.NumFields() == 0 && config.fe.CanSSA(t)) {
+ goto ende233eeefa826638b0e541bcca531d701
+ }
+ v.Op = OpStructMake0
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ return true
+ }
+ goto ende233eeefa826638b0e541bcca531d701
+ende233eeefa826638b0e541bcca531d701:
+ ;
+ // match: (Arg <t> {n} [off])
+ // cond: t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t)
+ // result: (StructMake1 (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]))
+ {
+ t := v.Type
+ n := v.Aux
+ off := v.AuxInt
+ if !(t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t)) {
+ goto ende953e77a0617051dd3f7ad4d58c9ab37
+ }
+ v.Op = OpStructMake1
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v0.Type = t.FieldType(0)
+ v0.Aux = n
+ v0.AuxInt = off + t.FieldOff(0)
+ v.AddArg(v0)
+ return true
+ }
+ goto ende953e77a0617051dd3f7ad4d58c9ab37
+ende953e77a0617051dd3f7ad4d58c9ab37:
+ ;
+ // match: (Arg <t> {n} [off])
+ // cond: t.IsStruct() && t.NumFields() == 2 && config.fe.CanSSA(t)
+ // result: (StructMake2 (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]) (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)]))
+ {
+ t := v.Type
+ n := v.Aux
+ off := v.AuxInt
+ if !(t.IsStruct() && t.NumFields() == 2 && config.fe.CanSSA(t)) {
+ goto end9a008048978aabad9de0723212e60631
+ }
+ v.Op = OpStructMake2
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v0.Type = t.FieldType(0)
+ v0.Aux = n
+ v0.AuxInt = off + t.FieldOff(0)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v1.Type = t.FieldType(1)
+ v1.Aux = n
+ v1.AuxInt = off + t.FieldOff(1)
+ v.AddArg(v1)
+ return true
+ }
+ goto end9a008048978aabad9de0723212e60631
+end9a008048978aabad9de0723212e60631:
+ ;
+ // match: (Arg <t> {n} [off])
+ // cond: t.IsStruct() && t.NumFields() == 3 && config.fe.CanSSA(t)
+ // result: (StructMake3 (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]) (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)]) (Arg <t.FieldType(2)> {n} [off+t.FieldOff(2)]))
+ {
+ t := v.Type
+ n := v.Aux
+ off := v.AuxInt
+ if !(t.IsStruct() && t.NumFields() == 3 && config.fe.CanSSA(t)) {
+ goto end0196e61dbeebc6402f3aa1e9a182210b
+ }
+ v.Op = OpStructMake3
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v0.Type = t.FieldType(0)
+ v0.Aux = n
+ v0.AuxInt = off + t.FieldOff(0)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v1.Type = t.FieldType(1)
+ v1.Aux = n
+ v1.AuxInt = off + t.FieldOff(1)
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v2.Type = t.FieldType(2)
+ v2.Aux = n
+ v2.AuxInt = off + t.FieldOff(2)
+ v.AddArg(v2)
+ return true
+ }
+ goto end0196e61dbeebc6402f3aa1e9a182210b
+end0196e61dbeebc6402f3aa1e9a182210b:
+ ;
+ // match: (Arg <t> {n} [off])
+ // cond: t.IsStruct() && t.NumFields() == 4 && config.fe.CanSSA(t)
+ // result: (StructMake4 (Arg <t.FieldType(0)> {n} [off+t.FieldOff(0)]) (Arg <t.FieldType(1)> {n} [off+t.FieldOff(1)]) (Arg <t.FieldType(2)> {n} [off+t.FieldOff(2)]) (Arg <t.FieldType(3)> {n} [off+t.FieldOff(3)]))
+ {
+ t := v.Type
+ n := v.Aux
+ off := v.AuxInt
+ if !(t.IsStruct() && t.NumFields() == 4 && config.fe.CanSSA(t)) {
+ goto end6bc133c93e50cb14c2e6cc9401850738
+ }
+ v.Op = OpStructMake4
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v0.Type = t.FieldType(0)
+ v0.Aux = n
+ v0.AuxInt = off + t.FieldOff(0)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v1.Type = t.FieldType(1)
+ v1.Aux = n
+ v1.AuxInt = off + t.FieldOff(1)
+ v.AddArg(v1)
+ v2 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v2.Type = t.FieldType(2)
+ v2.Aux = n
+ v2.AuxInt = off + t.FieldOff(2)
+ v.AddArg(v2)
+ v3 := b.NewValue0(v.Line, OpArg, TypeInvalid)
+ v3.Type = t.FieldType(3)
+ v3.Aux = n
+ v3.AuxInt = off + t.FieldOff(3)
+ v.AddArg(v3)
+ return true
+ }
+ goto end6bc133c93e50cb14c2e6cc9401850738
+end6bc133c93e50cb14c2e6cc9401850738:
;
return false
}
func rewriteValuegeneric_OpLoad(v *Value, config *Config) bool {
b := v.Block
_ = b
+ // match: (Load <t> _ _)
+ // cond: t.IsStruct() && t.NumFields() == 0 && config.fe.CanSSA(t)
+ // result: (StructMake0)
+ {
+ t := v.Type
+ if !(t.IsStruct() && t.NumFields() == 0 && config.fe.CanSSA(t)) {
+ goto end8d25f5c949948132921b6be29ede6bde
+ }
+ v.Op = OpStructMake0
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ return true
+ }
+ goto end8d25f5c949948132921b6be29ede6bde
+end8d25f5c949948132921b6be29ede6bde:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t)
+ // result: (StructMake1 (Load <t.FieldType(0)> ptr mem))
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t)) {
+ goto endfe908e5a8617dd39df2f9b2b92e93ae5
+ }
+ v.Op = OpStructMake1
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v0.Type = t.FieldType(0)
+ v0.AddArg(ptr)
+ v0.AddArg(mem)
+ v.AddArg(v0)
+ return true
+ }
+ goto endfe908e5a8617dd39df2f9b2b92e93ae5
+endfe908e5a8617dd39df2f9b2b92e93ae5:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: t.IsStruct() && t.NumFields() == 2 && config.fe.CanSSA(t)
+ // result: (StructMake2 (Load <t.FieldType(0)> ptr mem) (Load <t.FieldType(1)> (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] ptr) mem))
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(t.IsStruct() && t.NumFields() == 2 && config.fe.CanSSA(t)) {
+ goto end20e20e64004b765012cfb80c575ef27b
+ }
+ v.Op = OpStructMake2
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v0.Type = t.FieldType(0)
+ v0.AddArg(ptr)
+ v0.AddArg(mem)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v1.Type = t.FieldType(1)
+ v2 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v2.Type = t.FieldType(1).PtrTo()
+ v2.AuxInt = t.FieldOff(1)
+ v2.AddArg(ptr)
+ v1.AddArg(v2)
+ v1.AddArg(mem)
+ v.AddArg(v1)
+ return true
+ }
+ goto end20e20e64004b765012cfb80c575ef27b
+end20e20e64004b765012cfb80c575ef27b:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: t.IsStruct() && t.NumFields() == 3 && config.fe.CanSSA(t)
+ // result: (StructMake3 (Load <t.FieldType(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))
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(t.IsStruct() && t.NumFields() == 3 && config.fe.CanSSA(t)) {
+ goto ende612bf71067ed67541735cdc8b5a3288
+ }
+ v.Op = OpStructMake3
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v0.Type = t.FieldType(0)
+ v0.AddArg(ptr)
+ v0.AddArg(mem)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v1.Type = t.FieldType(1)
+ v2 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v2.Type = t.FieldType(1).PtrTo()
+ v2.AuxInt = t.FieldOff(1)
+ v2.AddArg(ptr)
+ v1.AddArg(v2)
+ v1.AddArg(mem)
+ v.AddArg(v1)
+ v3 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v3.Type = t.FieldType(2)
+ v4 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v4.Type = t.FieldType(2).PtrTo()
+ v4.AuxInt = t.FieldOff(2)
+ v4.AddArg(ptr)
+ v3.AddArg(v4)
+ v3.AddArg(mem)
+ v.AddArg(v3)
+ return true
+ }
+ goto ende612bf71067ed67541735cdc8b5a3288
+ende612bf71067ed67541735cdc8b5a3288:
+ ;
+ // match: (Load <t> ptr mem)
+ // cond: t.IsStruct() && t.NumFields() == 4 && config.fe.CanSSA(t)
+ // result: (StructMake4 (Load <t.FieldType(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))
+ {
+ t := v.Type
+ ptr := v.Args[0]
+ mem := v.Args[1]
+ if !(t.IsStruct() && t.NumFields() == 4 && config.fe.CanSSA(t)) {
+ goto end46c66c64d9030f2cc9a7a767f67953d1
+ }
+ v.Op = OpStructMake4
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v0 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v0.Type = t.FieldType(0)
+ v0.AddArg(ptr)
+ v0.AddArg(mem)
+ v.AddArg(v0)
+ v1 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v1.Type = t.FieldType(1)
+ v2 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v2.Type = t.FieldType(1).PtrTo()
+ v2.AuxInt = t.FieldOff(1)
+ v2.AddArg(ptr)
+ v1.AddArg(v2)
+ v1.AddArg(mem)
+ v.AddArg(v1)
+ v3 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v3.Type = t.FieldType(2)
+ v4 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v4.Type = t.FieldType(2).PtrTo()
+ v4.AuxInt = t.FieldOff(2)
+ v4.AddArg(ptr)
+ v3.AddArg(v4)
+ v3.AddArg(mem)
+ v.AddArg(v3)
+ v5 := b.NewValue0(v.Line, OpLoad, TypeInvalid)
+ v5.Type = t.FieldType(3)
+ v6 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v6.Type = t.FieldType(3).PtrTo()
+ v6.AuxInt = t.FieldOff(3)
+ v6.AddArg(ptr)
+ v5.AddArg(v6)
+ v5.AddArg(mem)
+ v.AddArg(v5)
+ return true
+ }
+ goto end46c66c64d9030f2cc9a7a767f67953d1
+end46c66c64d9030f2cc9a7a767f67953d1:
+ ;
// match: (Load <t> ptr mem)
// cond: t.IsComplex() && t.Size() == 8
// result: (ComplexMake (Load <config.fe.TypeFloat32()> ptr mem) (Load <config.fe.TypeFloat32()> (OffPtr <config.fe.TypeFloat32().PtrTo()> [4] ptr) mem) )
func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
b := v.Block
_ = b
+ // match: (Store _ (StructMake0) mem)
+ // cond:
+ // result: mem
+ {
+ if v.Args[1].Op != OpStructMake0 {
+ goto endd4f364b0adfc229d8c200af183d4c808
+ }
+ mem := v.Args[2]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = mem.Type
+ v.AddArg(mem)
+ return true
+ }
+ goto endd4f364b0adfc229d8c200af183d4c808
+endd4f364b0adfc229d8c200af183d4c808:
+ ;
+ // match: (Store dst (StructMake1 <t> f0) mem)
+ // cond:
+ // result: (Store [t.FieldType(0).Size()] dst f0 mem)
+ {
+ dst := v.Args[0]
+ if v.Args[1].Op != OpStructMake1 {
+ goto end2cff6d06f4440132f48ca374b6b1e9d8
+ }
+ t := v.Args[1].Type
+ f0 := v.Args[1].Args[0]
+ mem := v.Args[2]
+ v.Op = OpStore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = t.FieldType(0).Size()
+ v.AddArg(dst)
+ v.AddArg(f0)
+ v.AddArg(mem)
+ return true
+ }
+ goto end2cff6d06f4440132f48ca374b6b1e9d8
+end2cff6d06f4440132f48ca374b6b1e9d8:
+ ;
+ // match: (Store dst (StructMake2 <t> f0 f1) mem)
+ // cond:
+ // result: (Store [t.FieldType(1).Size()] (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store [t.FieldType(0).Size()] dst f0 mem))
+ {
+ dst := v.Args[0]
+ if v.Args[1].Op != OpStructMake2 {
+ goto end4e8ede6cc575a287795971da6b637973
+ }
+ t := v.Args[1].Type
+ f0 := v.Args[1].Args[0]
+ f1 := v.Args[1].Args[1]
+ mem := v.Args[2]
+ v.Op = OpStore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = t.FieldType(1).Size()
+ v0 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v0.Type = t.FieldType(1).PtrTo()
+ v0.AuxInt = t.FieldOff(1)
+ v0.AddArg(dst)
+ v.AddArg(v0)
+ v.AddArg(f1)
+ v1 := b.NewValue0(v.Line, OpStore, TypeInvalid)
+ v1.AuxInt = t.FieldType(0).Size()
+ v1.AddArg(dst)
+ v1.AddArg(f0)
+ v1.AddArg(mem)
+ v1.Type = TypeMem
+ v.AddArg(v1)
+ return true
+ }
+ goto end4e8ede6cc575a287795971da6b637973
+end4e8ede6cc575a287795971da6b637973:
+ ;
+ // match: (Store dst (StructMake3 <t> f0 f1 f2) mem)
+ // cond:
+ // result: (Store [t.FieldType(2).Size()] (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst) f2 (Store [t.FieldType(1).Size()] (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store [t.FieldType(0).Size()] dst f0 mem)))
+ {
+ dst := v.Args[0]
+ if v.Args[1].Op != OpStructMake3 {
+ goto end6ad675267724a87c8f852dd1e185e911
+ }
+ t := v.Args[1].Type
+ f0 := v.Args[1].Args[0]
+ f1 := v.Args[1].Args[1]
+ f2 := v.Args[1].Args[2]
+ mem := v.Args[2]
+ v.Op = OpStore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = t.FieldType(2).Size()
+ v0 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v0.Type = t.FieldType(2).PtrTo()
+ v0.AuxInt = t.FieldOff(2)
+ v0.AddArg(dst)
+ v.AddArg(v0)
+ v.AddArg(f2)
+ v1 := b.NewValue0(v.Line, OpStore, TypeInvalid)
+ v1.AuxInt = t.FieldType(1).Size()
+ v2 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v2.Type = t.FieldType(1).PtrTo()
+ v2.AuxInt = t.FieldOff(1)
+ v2.AddArg(dst)
+ v1.AddArg(v2)
+ v1.AddArg(f1)
+ v3 := b.NewValue0(v.Line, OpStore, TypeInvalid)
+ v3.AuxInt = t.FieldType(0).Size()
+ v3.AddArg(dst)
+ v3.AddArg(f0)
+ v3.AddArg(mem)
+ v3.Type = TypeMem
+ v1.AddArg(v3)
+ v1.Type = TypeMem
+ v.AddArg(v1)
+ return true
+ }
+ goto end6ad675267724a87c8f852dd1e185e911
+end6ad675267724a87c8f852dd1e185e911:
+ ;
+ // match: (Store dst (StructMake4 <t> f0 f1 f2 f3) mem)
+ // cond:
+ // result: (Store [t.FieldType(3).Size()] (OffPtr <t.FieldType(3).PtrTo()> [t.FieldOff(3)] dst) f3 (Store [t.FieldType(2).Size()] (OffPtr <t.FieldType(2).PtrTo()> [t.FieldOff(2)] dst) f2 (Store [t.FieldType(1).Size()] (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store [t.FieldType(0).Size()] dst f0 mem))))
+ {
+ dst := v.Args[0]
+ if v.Args[1].Op != OpStructMake4 {
+ goto end7ea91abd44794f7653374502a5a405ea
+ }
+ t := v.Args[1].Type
+ f0 := v.Args[1].Args[0]
+ f1 := v.Args[1].Args[1]
+ f2 := v.Args[1].Args[2]
+ f3 := v.Args[1].Args[3]
+ mem := v.Args[2]
+ v.Op = OpStore
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.AuxInt = t.FieldType(3).Size()
+ v0 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v0.Type = t.FieldType(3).PtrTo()
+ v0.AuxInt = t.FieldOff(3)
+ v0.AddArg(dst)
+ v.AddArg(v0)
+ v.AddArg(f3)
+ v1 := b.NewValue0(v.Line, OpStore, TypeInvalid)
+ v1.AuxInt = t.FieldType(2).Size()
+ v2 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v2.Type = t.FieldType(2).PtrTo()
+ v2.AuxInt = t.FieldOff(2)
+ v2.AddArg(dst)
+ v1.AddArg(v2)
+ v1.AddArg(f2)
+ v3 := b.NewValue0(v.Line, OpStore, TypeInvalid)
+ v3.AuxInt = t.FieldType(1).Size()
+ v4 := b.NewValue0(v.Line, OpOffPtr, TypeInvalid)
+ v4.Type = t.FieldType(1).PtrTo()
+ v4.AuxInt = t.FieldOff(1)
+ v4.AddArg(dst)
+ v3.AddArg(v4)
+ v3.AddArg(f1)
+ v5 := b.NewValue0(v.Line, OpStore, TypeInvalid)
+ v5.AuxInt = t.FieldType(0).Size()
+ v5.AddArg(dst)
+ v5.AddArg(f0)
+ v5.AddArg(mem)
+ v5.Type = TypeMem
+ v3.AddArg(v5)
+ v3.Type = TypeMem
+ v1.AddArg(v3)
+ v1.Type = TypeMem
+ v.AddArg(v1)
+ return true
+ }
+ goto end7ea91abd44794f7653374502a5a405ea
+end7ea91abd44794f7653374502a5a405ea:
+ ;
// match: (Store [8] dst (ComplexMake real imag) mem)
// cond:
// result: (Store [4] (OffPtr <config.fe.TypeFloat32().PtrTo()> [4] dst) imag (Store [4] dst real mem))
func rewriteValuegeneric_OpStructSelect(v *Value, config *Config) bool {
b := v.Block
_ = b
- // match: (StructSelect [idx] (Load ptr mem))
+ // match: (StructSelect (StructMake1 x))
+ // cond:
+ // result: x
+ {
+ if v.Args[0].Op != OpStructMake1 {
+ goto end17af582e7eba5216b4a51fe6c9206d3c
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end17af582e7eba5216b4a51fe6c9206d3c
+end17af582e7eba5216b4a51fe6c9206d3c:
+ ;
+ // match: (StructSelect [0] (StructMake2 x _))
// cond:
- // result: @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [idx] ptr) mem)
+ // result: x
{
- idx := v.AuxInt
+ if v.AuxInt != 0 {
+ goto end355cfff99c8e9af975c3ae450d49b7f9
+ }
+ if v.Args[0].Op != OpStructMake2 {
+ goto end355cfff99c8e9af975c3ae450d49b7f9
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end355cfff99c8e9af975c3ae450d49b7f9
+end355cfff99c8e9af975c3ae450d49b7f9:
+ ;
+ // match: (StructSelect [1] (StructMake2 _ x))
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 1 {
+ goto end69baa65e494ef9ae154e0943b53734f9
+ }
+ if v.Args[0].Op != OpStructMake2 {
+ goto end69baa65e494ef9ae154e0943b53734f9
+ }
+ x := v.Args[0].Args[1]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end69baa65e494ef9ae154e0943b53734f9
+end69baa65e494ef9ae154e0943b53734f9:
+ ;
+ // match: (StructSelect [0] (StructMake3 x _ _))
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 0 {
+ goto endb0d98e2c46bb51c9abd4c3543392e0ec
+ }
+ if v.Args[0].Op != OpStructMake3 {
+ goto endb0d98e2c46bb51c9abd4c3543392e0ec
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endb0d98e2c46bb51c9abd4c3543392e0ec
+endb0d98e2c46bb51c9abd4c3543392e0ec:
+ ;
+ // match: (StructSelect [1] (StructMake3 _ x _))
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 1 {
+ goto end2e40457286d26c2f14ad4fd127946773
+ }
+ if v.Args[0].Op != OpStructMake3 {
+ goto end2e40457286d26c2f14ad4fd127946773
+ }
+ x := v.Args[0].Args[1]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end2e40457286d26c2f14ad4fd127946773
+end2e40457286d26c2f14ad4fd127946773:
+ ;
+ // match: (StructSelect [2] (StructMake3 _ _ x))
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 2 {
+ goto end3e3b96ad431206175d002ece87aa1409
+ }
+ if v.Args[0].Op != OpStructMake3 {
+ goto end3e3b96ad431206175d002ece87aa1409
+ }
+ x := v.Args[0].Args[2]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end3e3b96ad431206175d002ece87aa1409
+end3e3b96ad431206175d002ece87aa1409:
+ ;
+ // match: (StructSelect [0] (StructMake4 x _ _ _))
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 0 {
+ goto end09f8a1ffa3d8c3124bc6d4083b941108
+ }
+ if v.Args[0].Op != OpStructMake4 {
+ goto end09f8a1ffa3d8c3124bc6d4083b941108
+ }
+ x := v.Args[0].Args[0]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end09f8a1ffa3d8c3124bc6d4083b941108
+end09f8a1ffa3d8c3124bc6d4083b941108:
+ ;
+ // match: (StructSelect [1] (StructMake4 _ x _ _))
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 1 {
+ goto endd3ef25e605a927e9251be6d9221f4acf
+ }
+ if v.Args[0].Op != OpStructMake4 {
+ goto endd3ef25e605a927e9251be6d9221f4acf
+ }
+ x := v.Args[0].Args[1]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto endd3ef25e605a927e9251be6d9221f4acf
+endd3ef25e605a927e9251be6d9221f4acf:
+ ;
+ // match: (StructSelect [2] (StructMake4 _ _ x _))
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 2 {
+ goto end0438e22cc8f41123fa42009a81ee723a
+ }
+ if v.Args[0].Op != OpStructMake4 {
+ goto end0438e22cc8f41123fa42009a81ee723a
+ }
+ x := v.Args[0].Args[2]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end0438e22cc8f41123fa42009a81ee723a
+end0438e22cc8f41123fa42009a81ee723a:
+ ;
+ // match: (StructSelect [3] (StructMake4 _ _ _ x))
+ // cond:
+ // result: x
+ {
+ if v.AuxInt != 3 {
+ goto end56a7c7781fee35eeff0a3652dc206012
+ }
+ if v.Args[0].Op != OpStructMake4 {
+ goto end56a7c7781fee35eeff0a3652dc206012
+ }
+ x := v.Args[0].Args[3]
+ v.Op = OpCopy
+ v.AuxInt = 0
+ v.Aux = nil
+ v.resetArgs()
+ v.Type = x.Type
+ v.AddArg(x)
+ return true
+ }
+ goto end56a7c7781fee35eeff0a3652dc206012
+end56a7c7781fee35eeff0a3652dc206012:
+ ;
+ // match: (StructSelect [i] (Load <t> ptr mem))
+ // cond: !config.fe.CanSSA(t)
+ // result: @v.Args[0].Block (Load <v.Type> (OffPtr <v.Type.PtrTo()> [t.FieldOff(i)] ptr) mem)
+ {
+ i := v.AuxInt
if v.Args[0].Op != OpLoad {
- goto end27abc5bf0299ce1bd5457af6ce8e3fba
+ goto end2afd47b4fcaaab7a73325bd8a75e3e8e
}
+ t := v.Args[0].Type
ptr := v.Args[0].Args[0]
mem := v.Args[0].Args[1]
+ if !(!config.fe.CanSSA(t)) {
+ goto end2afd47b4fcaaab7a73325bd8a75e3e8e
+ }
v0 := v.Args[0].Block.NewValue0(v.Line, OpLoad, TypeInvalid)
v.Op = OpCopy
v.AuxInt = 0
v0.Type = v.Type
v1 := v.Args[0].Block.NewValue0(v.Line, OpOffPtr, TypeInvalid)
v1.Type = v.Type.PtrTo()
- v1.AuxInt = idx
+ v1.AuxInt = t.FieldOff(i)
v1.AddArg(ptr)
v0.AddArg(v1)
v0.AddArg(mem)
return true
}
- goto end27abc5bf0299ce1bd5457af6ce8e3fba
-end27abc5bf0299ce1bd5457af6ce8e3fba:
+ goto end2afd47b4fcaaab7a73325bd8a75e3e8e
+end2afd47b4fcaaab7a73325bd8a75e3e8e:
;
return false
}