Skip to content

Commit 27ff0f2

Browse files
jakebaileycherrymui
authored andcommitted
cmd/compile/internal/ssa: eliminate string copies for calls to unique.Make
unique.Make always copies strings passed into it, so it's safe to not copy byte slices converted to strings either. Handle this just like map accesses with string(b) as keys. This CL only handles unique.Make(string(b)), not nested cases like unique.Make([2]string{string(b1), string(b2)}); this could be done in a followup CL but the map lookup code in walk is sufficiently different than the call handling code that I didn't attempt it. (SSA is much easier). Fixes #71926 Change-Id: Ic2f82f2f91963d563b4ddb1282bd49fc40da8b85 Reviewed-on: https://go-review.googlesource.com/c/go/+/672135 Reviewed-by: David Chase <[email protected]> Reviewed-by: Cherry Mui <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent d2db237 commit 27ff0f2

File tree

4 files changed

+72
-2
lines changed

4 files changed

+72
-2
lines changed

src/cmd/compile/internal/ssa/_gen/generic.rules

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2832,3 +2832,14 @@
28322832
&& clobber(sbts)
28332833
&& clobber(key)
28342834
=> (StaticLECall {f} [argsize] typ_ map_ (StringMake <typ.String> ptr len) mem)
2835+
2836+
// Similarly to map lookups, also handle unique.Make for strings, which unique.Make will clone.
2837+
(StaticLECall {f} [argsize] dict_ key:(SelectN [0] sbts:(StaticLECall {g} _ ptr len mem)) m:(SelectN [1] sbts))
2838+
&& isSameCall(f, "unique.Make[go.shape.string]")
2839+
&& isSameCall(g, "runtime.slicebytetostring")
2840+
&& key.Uses == 1
2841+
&& sbts.Uses == 2
2842+
&& resetCopy(m, mem)
2843+
&& clobber(sbts)
2844+
&& clobber(key)
2845+
=> (StaticLECall {f} [argsize] dict_ (StringMake <typ.String> ptr len) mem)

src/cmd/compile/internal/ssa/rewritegeneric.go

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/unique/handle_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,15 @@ func TestMakeAllocs(t *testing.T) {
233233
stringHandle = Make(string(b[:]))
234234
}},
235235

236-
{name: "bytes", allocs: 1, f: func() {
236+
{name: "bytes", allocs: 0, f: func() {
237237
stringHandle = Make(string(heapBytes))
238238
}},
239239

240240
{name: "bytes truncated short", allocs: 0, f: func() {
241241
stringHandle = Make(string(heapBytes[:16]))
242242
}},
243243

244-
{name: "bytes truncated long", allocs: 1, f: func() {
244+
{name: "bytes truncated long", allocs: 0, f: func() {
245245
stringHandle = Make(string(heapBytes[:40]))
246246
}},
247247

test/codegen/unique.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// asmcheck
2+
3+
// Copyright 2015 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package codegen
8+
9+
import "unique"
10+
11+
func BytesToHandle(b []byte) unique.Handle[string] {
12+
// amd64:-`.*runtime\.slicebytetostring\(`
13+
return unique.Make(string(b))
14+
}
15+
16+
type Pair struct {
17+
S1 string
18+
S2 string
19+
}
20+
21+
func BytesPairToHandle(b1, b2 []byte) unique.Handle[Pair] {
22+
// TODO: should not copy b1 and b2.
23+
return unique.Make(Pair{string(b1), string(b2)})
24+
}

0 commit comments

Comments
 (0)