[go] cmd/compile: eliminate nil checks on .dict arg

1 view
Skip to first unread message

Gopher Robot (Gerrit)

unread,
Sep 30, 2025, 2:22:42 PM (2 days ago) Sep 30
to Jake Bailey, goph...@pubsubhelper.golang.org, golang-...@googlegroups.com, David Chase, Keith Randall, Keith Randall, Go LUCI, Junyang Shao, golang-co...@googlegroups.com

Gopher Robot submitted the change

Change information

Commit message:
cmd/compile: eliminate nil checks on .dict arg

The first arg of a generic function is the dictionary. This dictionary
is never nil, but it gets a nil check becuase the dict arg is treated as
a slice during construction.

cmp.Compare[go.shape.int] was:

00006 (+41) TESTB AX, (AX)
00007 (+52) CMPQ CX, BX
00008 (52) JGT 14
00009 (+55) JGE 12
00010 (+56) MOVL $1, AX
00011 (56) RET
00012 (+58) XORL AX, AX
00013 (58) RET
00014 (+53) MOVQ $-1, AX
00015 (53) RET

Note how the function begins with a TESTB that loads the dict to perform
the nil check.

This CL eliminates that nil check.

For most generic functions, this doesn't matter too much, but not
infrequently are generic functions written which never actually use the
dictionary (like cmp.Compare), so I suspect this might help in hot code
to avoid repeatedly touching the dictionary in memory, and in cases
where the generic function is not inlined (and thus the dict dropped).

compilecmp shows these changes (deduped):

cmp.Compare[go.shape.float64] 73 -> 72 (-1.37%)
cmp.Compare[go.shape.int] 26 -> 24 (-7.69%)
cmp.Compare[go.shape.int32] 25 -> 23 (-8.00%)
cmp.Compare[go.shape.int64] 26 -> 24 (-7.69%)
cmp.Compare[go.shape.string] 142 -> 141 (-0.70%)
cmp.Compare[go.shape.uint16] 26 -> 24 (-7.69%)
cmp.Compare[go.shape.uint] 26 -> 24 (-7.69%)
cmp.Compare[go.shape.uint32] 25 -> 23 (-8.00%)
cmp.Compare[go.shape.uint64] 26 -> 24 (-7.69%)
cmp.Compare[go.shape.uint8] 25 -> 23 (-8.00%)
cmp.Compare[go.shape.uintptr] 26 -> 24 (-7.69%)
cmp.Less[go.shape.float64] 35 -> 34 (-2.86%)
cmp.Less[go.shape.int32] 8 -> 6 (-25.00%)
cmp.Less[go.shape.int64] 9 -> 7 (-22.22%)
cmp.Less[go.shape.int] 9 -> 7 (-22.22%)
cmp.Less[go.shape.string] 112 -> 110 (-1.79%)
cmp.Less[go.shape.uint16] 9 -> 7 (-22.22%)
cmp.Less[go.shape.uint32] 8 -> 6 (-25.00%)
cmp.Less[go.shape.uint64] 9 -> 7 (-22.22%)
internal/synctest.Associate[go.shape.struct 114 -> 113 (-0.88%)
internal/trace.(*dataTable[go.shape.uint64,go.shape.string]).insert 805 -> 791 (-1.74%)
internal/trace.(*dataTable[go.shape.uint64,go.shape.struct 858 -> 852 (-0.70%)
main.(*gState[go.shape.int64]).stop 2111 -> 2085 (-1.23%)
main.(*gState[go.shape.int64]).unblock 941 -> 923 (-1.91%)
runtime.fmax[go.shape.float32] 85 -> 83 (-2.35%)
runtime.fmax[go.shape.float64] 89 -> 87 (-2.25%)
runtime.fmin[go.shape.float32] 85 -> 83 (-2.35%)
runtime.fmin[go.shape.float64] 89 -> 87 (-2.25%)
slices.BinarySearch[go.shape.[]string,go.shape.string] 346 -> 337 (-2.60%)
slices.Concat[go.shape.[]uint8,go.shape.uint8] 462 -> 453 (-1.95%)
slices.ContainsFunc[go.shape.[]*cmd/vendor/github.com/google/pprof/profile.Sample,go.shape.*uint8] 170 -> 169 (-0.59%)
slices.ContainsFunc[go.shape.[]*debug/dwarf.StructField,go.shape.*uint8] 170 -> 169 (-0.59%)
slices.ContainsFunc[go.shape.[]*go/ast.Field,go.shape.*uint8] 170 -> 169 (-0.59%)
slices.ContainsFunc[go.shape.[]string,go.shape.string] 186 -> 181 (-2.69%)
slices.Contains[go.shape.[]*cmd/compile/internal/syntax.BranchStmt,go.shape.*cmd/compile/internal/syntax.BranchStmt] 44 -> 42 (-4.55%)
slices.Contains[go.shape.[]cmd/compile/internal/syntax.Type,go.shape.interface 223 -> 219 (-1.79%)
slices.Contains[go.shape.[]crypto/tls.CurveID,go.shape.uint16] 44 -> 42 (-4.55%)
slices.Contains[go.shape.[]crypto/tls.SignatureScheme,go.shape.uint16] 44 -> 42 (-4.55%)
slices.Contains[go.shape.[]*go/ast.BranchStmt,go.shape.*go/ast.BranchStmt] 44 -> 42 (-4.55%)
slices.Contains[go.shape.[]go/types.Type,go.shape.interface 223 -> 219 (-1.79%)
slices.Contains[go.shape.[]int,go.shape.int] 44 -> 42 (-4.55%)
slices.Contains[go.shape.[]string,go.shape.string] 223 -> 219 (-1.79%)
slices.Contains[go.shape.[]uint16,go.shape.uint16] 44 -> 42 (-4.55%)
slices.Contains[go.shape.[]uint8,go.shape.uint8] 44 -> 42 (-4.55%)
slices.Insert[go.shape.[]string,go.shape.string] 1189 -> 1170 (-1.60%)
slices.medianCmpFunc[go.shape.struct 1118 -> 1113 (-0.45%)
slices.medianCmpFunc[go.shape.struct 1214 -> 1209 (-0.41%)
slices.medianCmpFunc[go.shape.struct 889 -> 887 (-0.22%)
slices.medianCmpFunc[go.shape.struct 901 -> 874 (-3.00%)
slices.order2Ordered[go.shape.float64] 89 -> 87 (-2.25%)
slices.order2Ordered[go.shape.uint16] 75 -> 70 (-6.67%)
slices.partialInsertionSortOrdered[go.shape.string] 1115 -> 1110 (-0.45%)
slices.partialInsertionSortOrdered[go.shape.uint16] 358 -> 352 (-1.68%)
slices.partitionEqualOrdered[go.shape.int] 208 -> 203 (-2.40%)
slices.partitionEqualOrdered[go.shape.int32] 208 -> 198 (-4.81%)
slices.partitionEqualOrdered[go.shape.int64] 208 -> 203 (-2.40%)
slices.partitionEqualOrdered[go.shape.uint32] 208 -> 198 (-4.81%)
slices.partitionEqualOrdered[go.shape.uint64] 208 -> 203 (-2.40%)
slices.partitionOrdered[go.shape.float64] 538 -> 533 (-0.93%)
slices.partitionOrdered[go.shape.int] 437 -> 427 (-2.29%)
slices.partitionOrdered[go.shape.int64] 437 -> 427 (-2.29%)
slices.partitionOrdered[go.shape.uint16] 447 -> 442 (-1.12%)
slices.partitionOrdered[go.shape.uint64] 437 -> 427 (-2.29%)
slices.rotateCmpFunc[go.shape.struct 1045 -> 1029 (-1.53%)
slices.rotateCmpFunc[go.shape.struct 1205 -> 1163 (-3.49%)
slices.rotateCmpFunc[go.shape.struct 1226 -> 1176 (-4.08%)
slices.rotateCmpFunc[go.shape.struct 1322 -> 1272 (-3.78%)
slices.rotateCmpFunc[go.shape.struct 1419 -> 1400 (-1.34%)
slices.rotateCmpFunc[go.shape.*uint8] 549 -> 538 (-2.00%)
slices.rotateLeft[go.shape.string] 603 -> 588 (-2.49%)
slices.rotateLeft[go.shape.uint8] 255 -> 250 (-1.96%)
slices.siftDownOrdered[go.shape.int] 181 -> 171 (-5.52%)
slices.siftDownOrdered[go.shape.int32] 181 -> 171 (-5.52%)
slices.siftDownOrdered[go.shape.int64] 181 -> 171 (-5.52%)
slices.siftDownOrdered[go.shape.string] 614 -> 592 (-3.58%)
slices.siftDownOrdered[go.shape.uint32] 181 -> 171 (-5.52%)
slices.siftDownOrdered[go.shape.uint64] 181 -> 171 (-5.52%)
time.parseRFC3339[go.shape.string] 1774 -> 1758 (-0.90%)
unique.(*canonMap[go.shape.struct 280 -> 276 (-1.43%)
unique.clone[go.shape.struct 311 -> 293 (-5.79%)
weak.Make[go.shape.6880e4598856efac32416085c0172278cf0fb9e5050ce6518bd9b7f7d1662440] 136 -> 134 (-1.47%)
weak.Make[go.shape.struct 136 -> 134 (-1.47%)
weak.Make[go.shape.uint8] 136 -> 134 (-1.47%)
Change-Id: I43dcea5f2aa37372f773e5edc6a2ef1dee0a8db7
Reviewed-by: David Chase <drc...@google.com>
Reviewed-by: Keith Randall <k...@golang.org>
Reviewed-by: Keith Randall <k...@google.com>
Auto-Submit: Keith Randall <k...@golang.org>
Files:
  • M src/cmd/compile/internal/ssa/_gen/generic.rules
  • M src/cmd/compile/internal/ssa/rewrite.go
  • M src/cmd/compile/internal/ssa/rewritegeneric.go
  • A test/codegen/generics.go
Change size: M
Delta: 4 files changed, 64 insertions(+), 0 deletions(-)
Branch: refs/heads/master
Submit Requirements:
  • requirement satisfiedCode-Review: +2 by David Chase, +1 by Keith Randall, +2 by Keith Randall
  • requirement satisfiedTryBots-Pass: LUCI-TryBot-Result+1 by Go LUCI
Open in Gerrit
Inspect html for hidden footers to help with email filtering. To unsubscribe visit settings. DiffyGerrit
Gerrit-MessageType: merged
Gerrit-Project: go
Gerrit-Branch: master
Gerrit-Change-Id: I43dcea5f2aa37372f773e5edc6a2ef1dee0a8db7
Gerrit-Change-Number: 706655
Gerrit-PatchSet: 3
Gerrit-Owner: Jake Bailey <jacob.b...@gmail.com>
Gerrit-Reviewer: David Chase <drc...@google.com>
Gerrit-Reviewer: Gopher Robot <go...@golang.org>
Gerrit-Reviewer: Jake Bailey <jacob.b...@gmail.com>
Gerrit-Reviewer: Junyang Shao <shaoj...@google.com>
Gerrit-Reviewer: Keith Randall <k...@golang.org>
Gerrit-Reviewer: Keith Randall <k...@google.com>
open
diffy
satisfied_requirement
Reply all
Reply to author
Forward
0 new messages