&& clobber(sbts)
&& clobber(key)
=> (StaticLECall {f} [argsize] typ_ map_ (StringMake <typ.String> ptr len) mem)
+
+// Similarly to map lookups, also handle unique.Make for strings, which unique.Make will clone.
+(StaticLECall {f} [argsize] dict_ key:(SelectN [0] sbts:(StaticLECall {g} _ ptr len mem)) m:(SelectN [1] sbts))
+ && isSameCall(f, "unique.Make[go.shape.string]")
+ && isSameCall(g, "runtime.slicebytetostring")
+ && key.Uses == 1
+ && sbts.Uses == 2
+ && resetCopy(m, mem)
+ && clobber(sbts)
+ && clobber(key)
+=> (StaticLECall {f} [argsize] dict_ (StringMake <typ.String> ptr len) mem)
v.AddArg4(typ_, map_, v0, mem)
return true
}
+ // match: (StaticLECall {f} [argsize] dict_ key:(SelectN [0] sbts:(StaticLECall {g} _ ptr len mem)) m:(SelectN [1] sbts))
+ // cond: isSameCall(f, "unique.Make[go.shape.string]") && isSameCall(g, "runtime.slicebytetostring") && key.Uses == 1 && sbts.Uses == 2 && resetCopy(m, mem) && clobber(sbts) && clobber(key)
+ // result: (StaticLECall {f} [argsize] dict_ (StringMake <typ.String> ptr len) mem)
+ for {
+ if len(v.Args) != 3 {
+ break
+ }
+ argsize := auxIntToInt32(v.AuxInt)
+ f := auxToCall(v.Aux)
+ _ = v.Args[2]
+ dict_ := v.Args[0]
+ key := v.Args[1]
+ if key.Op != OpSelectN || auxIntToInt64(key.AuxInt) != 0 {
+ break
+ }
+ sbts := key.Args[0]
+ if sbts.Op != OpStaticLECall || len(sbts.Args) != 4 {
+ break
+ }
+ g := auxToCall(sbts.Aux)
+ mem := sbts.Args[3]
+ ptr := sbts.Args[1]
+ len := sbts.Args[2]
+ m := v.Args[2]
+ if m.Op != OpSelectN || auxIntToInt64(m.AuxInt) != 1 || sbts != m.Args[0] || !(isSameCall(f, "unique.Make[go.shape.string]") && isSameCall(g, "runtime.slicebytetostring") && key.Uses == 1 && sbts.Uses == 2 && resetCopy(m, mem) && clobber(sbts) && clobber(key)) {
+ break
+ }
+ v.reset(OpStaticLECall)
+ v.AuxInt = int32ToAuxInt(argsize)
+ v.Aux = callToAux(f)
+ v0 := b.NewValue0(v.Pos, OpStringMake, typ.String)
+ v0.AddArg2(ptr, len)
+ v.AddArg3(dict_, v0, mem)
+ return true
+ }
return false
}
func rewriteValuegeneric_OpStore(v *Value) bool {
stringHandle = Make(string(b[:]))
}},
- {name: "bytes", allocs: 1, f: func() {
+ {name: "bytes", allocs: 0, f: func() {
stringHandle = Make(string(heapBytes))
}},
stringHandle = Make(string(heapBytes[:16]))
}},
- {name: "bytes truncated long", allocs: 1, f: func() {
+ {name: "bytes truncated long", allocs: 0, f: func() {
stringHandle = Make(string(heapBytes[:40]))
}},
--- /dev/null
+// asmcheck
+
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package codegen
+
+import "unique"
+
+func BytesToHandle(b []byte) unique.Handle[string] {
+ // amd64:-`.*runtime\.slicebytetostring\(`
+ return unique.Make(string(b))
+}
+
+type Pair struct {
+ S1 string
+ S2 string
+}
+
+func BytesPairToHandle(b1, b2 []byte) unique.Handle[Pair] {
+ // TODO: should not copy b1 and b2.
+ return unique.Make(Pair{string(b1), string(b2)})
+}