cmd/compile: avoid stack temporary for struct literal assignment to addressable targets#78598
cmd/compile: avoid stack temporary for struct literal assignment to addressable targets#78598chabbimilind wants to merge 1 commit intogolang:masterfrom
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
dc90b0e to
846ac1c
Compare
|
This PR (HEAD: 846ac1c) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/764680. Important tips:
|
|
Message from Gopher Robot: Patch Set 1: (1 comment) Please don’t reply on this GitHub thread. Visit golang.org/cl/764680. |
|
Message from Daniel Morsing: Patch Set 2: (2 comments) Please don’t reply on this GitHub thread. Visit golang.org/cl/764680. |
846ac1c to
ad20214
Compare
|
This PR (HEAD: ad20214) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/764680. Important tips:
|
…ddressable targets
When assigning a struct/array literal to a non-local addressable target
(slice index, global, pointer deref, struct field through pointer), the
compiler previously created a stack temporary, zeroed it, filled fields,
then bulk-copied to the destination. This was because oaslit() required
LHS to be isSimpleName() (stack-local variable).
Extend oaslit with oaslitAddr, which takes the address of the destination
once and decomposes the literal into direct field stores through that
pointer. For partially-initialized literals, the destination is zeroed
in-place before filling fields, eliminating the bulk copy entirely.
Safety is ensured by compLitFieldsSafe/exprSafeForDirectStore, which
conservatively accept only constants, nil, and stack-local non-addrtaken
names as RHS values — these cannot alias with any addressable destination.
When nested struct literals are partially initialized, compLitAllFieldsSet
detects this and ensures the destination is zeroed before field stores.
│ baseline │ optimized │
│ sec/op │ sec/op vs base │
StructLitAssign/SliceLiteral 8.91n ± 1% 4.57n ± 2% -48.75% (p=0.000)
StructLitAssign/Global 8.04n ± 1% 3.97n ± 1% -50.55% (p=0.000)
StructLitAssign/PtrDeref 8.22n ± 0% 3.84n ± 1% -53.37% (p=0.000)
StructLitAssign/Nested 3.99n ± 1% 2.93n ± 2% -26.62% (p=0.000)
StructLitAssign/Embedded 4.01n ± 1% 2.91n ± 1% -27.32% (p=0.000)
StructLitAssign/FuncCallRHS 9.17n ± 1% 5.62n ± 1% -38.75% (p=0.000)
StructLitAssign/PartialHalf 5.79n ± 1% 4.12n ± 1% -28.74% (p=0.000)
Fixes golang#78597
ad20214 to
b958db1
Compare
|
This PR (HEAD: b958db1) has been imported to Gerrit for code review. Please visit Gerrit at https://go-review.googlesource.com/c/go/+/764680. Important tips:
|
When assigning a struct/array literal to a non-local addressable target
(slice index, global, pointer deref, struct field through pointer), the
compiler previously created a stack temporary, zeroed it, filled fields,
then bulk-copied to the destination. This was because oaslit() required
LHS to be isSimpleName() (stack-local variable).
Extend oaslit with oaslitAddr, which takes the address of the destination
once and decomposes the literal into direct field stores through that
pointer. For partially-initialized literals, the destination is zeroed
in-place before filling fields, eliminating the bulk copy entirely.
Safety is ensured by compLitFieldsSafe/exprSafeForDirectStore, which
conservatively accept only constants, nil, and stack-local non-addrtaken
names as RHS values -- these cannot alias with any addressable destination.
When nested struct literals are partially initialized, compLitAllFieldsSet
detects this and ensures the destination is zeroed before field stores.
Benchmark results (arm64, Apple M1 Max):
StructLitAssign/SliceLiteral 8.91n +/- 1% 4.57n +/- 2% -48.75% (p=0.000)
StructLitAssign/Global 8.04n +/- 1% 3.97n +/- 1% -50.55% (p=0.000)
StructLitAssign/PtrDeref 8.22n +/- 0% 3.84n +/- 1% -53.37% (p=0.000)
StructLitAssign/Nested 3.99n +/- 1% 2.93n +/- 2% -26.62% (p=0.000)
StructLitAssign/Embedded 4.01n +/- 1% 2.91n +/- 1% -27.32% (p=0.000)
StructLitAssign/FuncCallRHS 9.17n +/- 1% 5.62n +/- 1% -38.75% (p=0.000)
StructLitAssign/PartialHalf 5.79n +/- 1% 4.12n +/- 1% -28.74% (p=0.000)
StructLitAssign/AliasRHS 7.93n +/- 1% 7.94n +/- 2% ~ (no regression)
Test plan:
Fixes #78597