mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: emit OffPtr for first field in SSA'd structs
Given
(Store [c] (OffPtr <T1> [0] (Addr <T> _)) _
(Store [c] (Addr <T> _) _ _))
dead store elimination doesn't eliminate the inner
Store, because it addresses a type of a different width
than the first store.
When decomposing StructMake operations, always generate
an OffPtr to address struct fields so that dead stores to
the first field of the struct can be optimized away.
benchmarks affected on darwin/amd64:
HTTPClientServer-8 73.2µs ± 1% 72.7µs ± 1% -0.69% (p=0.022 n=9+10)
TimeParse-8 304ns ± 1% 300ns ± 0% -1.61% (p=0.000 n=9+9)
RegexpMatchEasy1_32-8 80.1ns ± 0% 79.5ns ± 1% -0.84% (p=0.000 n=8+9)
GobDecode-8 6.78ms ± 0% 6.81ms ± 1% +0.46% (p=0.000 n=9+10)
Gunzip-8 36.1ms ± 1% 36.2ms ± 0% +0.37% (p=0.019 n=10+10)
JSONEncode-8 15.6ms ± 0% 15.7ms ± 0% +0.69% (p=0.000 n=9+10)
Change-Id: Ia80d73fd047f9400c616ca64fdee4f438a0e7f21
Reviewed-on: https://go-review.googlesource.com/37769
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
cd6f18779f
commit
a6bd42f263
2 changed files with 96 additions and 66 deletions
|
|
@ -772,19 +772,19 @@
|
|||
(StructMake0)
|
||||
(Load <t> ptr mem) && t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t) ->
|
||||
(StructMake1
|
||||
(Load <t.FieldType(0)> ptr mem))
|
||||
(Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [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(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 && config.fe.CanSSA(t) ->
|
||||
(StructMake3
|
||||
(Load <t.FieldType(0)> ptr mem)
|
||||
(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 && config.fe.CanSSA(t) ->
|
||||
(StructMake4
|
||||
(Load <t.FieldType(0)> ptr mem)
|
||||
(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))
|
||||
|
|
@ -794,12 +794,14 @@
|
|||
|
||||
(Store _ (StructMake0) mem) -> mem
|
||||
(Store dst (StructMake1 <t> f0) mem) ->
|
||||
(Store [t.FieldType(0).Size()] dst f0 mem)
|
||||
(Store [t.FieldType(0).Size()] (OffPtr <t.FieldType(0).PtrTo()> [0] 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 [t.FieldType(0).Size()]
|
||||
(OffPtr <t.FieldType(0)> [0] 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)
|
||||
|
|
@ -807,7 +809,9 @@
|
|||
(Store [t.FieldType(1).Size()]
|
||||
(OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
|
||||
f1
|
||||
(Store [t.FieldType(0).Size()] dst f0 mem)))
|
||||
(Store [t.FieldType(0).Size()]
|
||||
(OffPtr <t.FieldType(0).PtrTo()> [0] 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)
|
||||
|
|
@ -818,7 +822,9 @@
|
|||
(Store [t.FieldType(1).Size()]
|
||||
(OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst)
|
||||
f1
|
||||
(Store [t.FieldType(0).Size()] dst f0 mem))))
|
||||
(Store [t.FieldType(0).Size()]
|
||||
(OffPtr <t.FieldType(0).PtrTo()> [0] dst)
|
||||
f0 mem))))
|
||||
|
||||
// Putting struct{*byte} and similar into direct interfaces.
|
||||
(IMake typ (StructMake1 val)) -> (IMake typ val)
|
||||
|
|
|
|||
|
|
@ -6733,7 +6733,7 @@ func rewriteValuegeneric_OpLoad(v *Value, config *Config) bool {
|
|||
}
|
||||
// match: (Load <t> ptr mem)
|
||||
// cond: t.IsStruct() && t.NumFields() == 1 && config.fe.CanSSA(t)
|
||||
// result: (StructMake1 (Load <t.FieldType(0)> ptr mem))
|
||||
// result: (StructMake1 (Load <t.FieldType(0)> (OffPtr <t.FieldType(0).PtrTo()> [0] ptr) mem))
|
||||
for {
|
||||
t := v.Type
|
||||
ptr := v.Args[0]
|
||||
|
|
@ -6743,14 +6743,17 @@ func rewriteValuegeneric_OpLoad(v *Value, config *Config) bool {
|
|||
}
|
||||
v.reset(OpStructMake1)
|
||||
v0 := b.NewValue0(v.Pos, OpLoad, t.FieldType(0))
|
||||
v0.AddArg(ptr)
|
||||
v1 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
|
||||
v1.AuxInt = 0
|
||||
v1.AddArg(ptr)
|
||||
v0.AddArg(v1)
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
return true
|
||||
}
|
||||
// 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))
|
||||
// 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.Args[0]
|
||||
|
|
@ -6760,21 +6763,24 @@ func rewriteValuegeneric_OpLoad(v *Value, config *Config) bool {
|
|||
}
|
||||
v.reset(OpStructMake2)
|
||||
v0 := b.NewValue0(v.Pos, OpLoad, t.FieldType(0))
|
||||
v0.AddArg(ptr)
|
||||
v1 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
|
||||
v1.AuxInt = 0
|
||||
v1.AddArg(ptr)
|
||||
v0.AddArg(v1)
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
|
||||
v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
|
||||
v2.AuxInt = t.FieldOff(1)
|
||||
v2.AddArg(ptr)
|
||||
v1.AddArg(v2)
|
||||
v1.AddArg(mem)
|
||||
v.AddArg(v1)
|
||||
v2 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
|
||||
v3 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
|
||||
v3.AuxInt = t.FieldOff(1)
|
||||
v3.AddArg(ptr)
|
||||
v2.AddArg(v3)
|
||||
v2.AddArg(mem)
|
||||
v.AddArg(v2)
|
||||
return true
|
||||
}
|
||||
// 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))
|
||||
// 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.Args[0]
|
||||
|
|
@ -6784,28 +6790,31 @@ func rewriteValuegeneric_OpLoad(v *Value, config *Config) bool {
|
|||
}
|
||||
v.reset(OpStructMake3)
|
||||
v0 := b.NewValue0(v.Pos, OpLoad, t.FieldType(0))
|
||||
v0.AddArg(ptr)
|
||||
v1 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
|
||||
v1.AuxInt = 0
|
||||
v1.AddArg(ptr)
|
||||
v0.AddArg(v1)
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
|
||||
v2 := b.NewValue0(v.Pos, OpOffPtr, 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.Pos, OpLoad, t.FieldType(2))
|
||||
v4 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
|
||||
v4.AuxInt = t.FieldOff(2)
|
||||
v4.AddArg(ptr)
|
||||
v3.AddArg(v4)
|
||||
v3.AddArg(mem)
|
||||
v.AddArg(v3)
|
||||
v2 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
|
||||
v3 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
|
||||
v3.AuxInt = t.FieldOff(1)
|
||||
v3.AddArg(ptr)
|
||||
v2.AddArg(v3)
|
||||
v2.AddArg(mem)
|
||||
v.AddArg(v2)
|
||||
v4 := b.NewValue0(v.Pos, OpLoad, t.FieldType(2))
|
||||
v5 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
|
||||
v5.AuxInt = t.FieldOff(2)
|
||||
v5.AddArg(ptr)
|
||||
v4.AddArg(v5)
|
||||
v4.AddArg(mem)
|
||||
v.AddArg(v4)
|
||||
return true
|
||||
}
|
||||
// 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))
|
||||
// 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.Args[0]
|
||||
|
|
@ -6815,30 +6824,33 @@ func rewriteValuegeneric_OpLoad(v *Value, config *Config) bool {
|
|||
}
|
||||
v.reset(OpStructMake4)
|
||||
v0 := b.NewValue0(v.Pos, OpLoad, t.FieldType(0))
|
||||
v0.AddArg(ptr)
|
||||
v1 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
|
||||
v1.AuxInt = 0
|
||||
v1.AddArg(ptr)
|
||||
v0.AddArg(v1)
|
||||
v0.AddArg(mem)
|
||||
v.AddArg(v0)
|
||||
v1 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
|
||||
v2 := b.NewValue0(v.Pos, OpOffPtr, 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.Pos, OpLoad, t.FieldType(2))
|
||||
v4 := b.NewValue0(v.Pos, OpOffPtr, 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.Pos, OpLoad, t.FieldType(3))
|
||||
v6 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(3).PtrTo())
|
||||
v6.AuxInt = t.FieldOff(3)
|
||||
v6.AddArg(ptr)
|
||||
v5.AddArg(v6)
|
||||
v5.AddArg(mem)
|
||||
v.AddArg(v5)
|
||||
v2 := b.NewValue0(v.Pos, OpLoad, t.FieldType(1))
|
||||
v3 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(1).PtrTo())
|
||||
v3.AuxInt = t.FieldOff(1)
|
||||
v3.AddArg(ptr)
|
||||
v2.AddArg(v3)
|
||||
v2.AddArg(mem)
|
||||
v.AddArg(v2)
|
||||
v4 := b.NewValue0(v.Pos, OpLoad, t.FieldType(2))
|
||||
v5 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(2).PtrTo())
|
||||
v5.AuxInt = t.FieldOff(2)
|
||||
v5.AddArg(ptr)
|
||||
v4.AddArg(v5)
|
||||
v4.AddArg(mem)
|
||||
v.AddArg(v4)
|
||||
v6 := b.NewValue0(v.Pos, OpLoad, t.FieldType(3))
|
||||
v7 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(3).PtrTo())
|
||||
v7.AuxInt = t.FieldOff(3)
|
||||
v7.AddArg(ptr)
|
||||
v6.AddArg(v7)
|
||||
v6.AddArg(mem)
|
||||
v.AddArg(v6)
|
||||
return true
|
||||
}
|
||||
// match: (Load <t> _ _)
|
||||
|
|
@ -14671,7 +14683,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
|
|||
}
|
||||
// match: (Store dst (StructMake1 <t> f0) mem)
|
||||
// cond:
|
||||
// result: (Store [t.FieldType(0).Size()] dst f0 mem)
|
||||
// result: (Store [t.FieldType(0).Size()] (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)
|
||||
for {
|
||||
dst := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
|
|
@ -14683,14 +14695,17 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
|
|||
mem := v.Args[2]
|
||||
v.reset(OpStore)
|
||||
v.AuxInt = t.FieldType(0).Size()
|
||||
v.AddArg(dst)
|
||||
v0 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
|
||||
v0.AuxInt = 0
|
||||
v0.AddArg(dst)
|
||||
v.AddArg(v0)
|
||||
v.AddArg(f0)
|
||||
v.AddArg(mem)
|
||||
return true
|
||||
}
|
||||
// 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))
|
||||
// result: (Store [t.FieldType(1).Size()] (OffPtr <t.FieldType(1).PtrTo()> [t.FieldOff(1)] dst) f1 (Store [t.FieldType(0).Size()] (OffPtr <t.FieldType(0)> [0] dst) f0 mem))
|
||||
for {
|
||||
dst := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
|
|
@ -14710,7 +14725,10 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
|
|||
v.AddArg(f1)
|
||||
v1 := b.NewValue0(v.Pos, OpStore, TypeMem)
|
||||
v1.AuxInt = t.FieldType(0).Size()
|
||||
v1.AddArg(dst)
|
||||
v2 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0))
|
||||
v2.AuxInt = 0
|
||||
v2.AddArg(dst)
|
||||
v1.AddArg(v2)
|
||||
v1.AddArg(f0)
|
||||
v1.AddArg(mem)
|
||||
v.AddArg(v1)
|
||||
|
|
@ -14718,7 +14736,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
|
|||
}
|
||||
// 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)))
|
||||
// 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()] (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem)))
|
||||
for {
|
||||
dst := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
|
|
@ -14746,7 +14764,10 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
|
|||
v1.AddArg(f1)
|
||||
v3 := b.NewValue0(v.Pos, OpStore, TypeMem)
|
||||
v3.AuxInt = t.FieldType(0).Size()
|
||||
v3.AddArg(dst)
|
||||
v4 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
|
||||
v4.AuxInt = 0
|
||||
v4.AddArg(dst)
|
||||
v3.AddArg(v4)
|
||||
v3.AddArg(f0)
|
||||
v3.AddArg(mem)
|
||||
v1.AddArg(v3)
|
||||
|
|
@ -14755,7 +14776,7 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
|
|||
}
|
||||
// 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))))
|
||||
// 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()] (OffPtr <t.FieldType(0).PtrTo()> [0] dst) f0 mem))))
|
||||
for {
|
||||
dst := v.Args[0]
|
||||
v_1 := v.Args[1]
|
||||
|
|
@ -14791,7 +14812,10 @@ func rewriteValuegeneric_OpStore(v *Value, config *Config) bool {
|
|||
v3.AddArg(f1)
|
||||
v5 := b.NewValue0(v.Pos, OpStore, TypeMem)
|
||||
v5.AuxInt = t.FieldType(0).Size()
|
||||
v5.AddArg(dst)
|
||||
v6 := b.NewValue0(v.Pos, OpOffPtr, t.FieldType(0).PtrTo())
|
||||
v6.AuxInt = 0
|
||||
v6.AddArg(dst)
|
||||
v5.AddArg(v6)
|
||||
v5.AddArg(f0)
|
||||
v5.AddArg(mem)
|
||||
v3.AddArg(v5)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue