Commit b679665a authored by Martin Möhrmann's avatar Martin Möhrmann Committed by Martin Möhrmann

cmd/compile: move stringtoslicebytetmp to the backend

- removes the runtime function stringtoslicebytetmp
- removes the generation of calls to stringtoslicebytetmp from the frontend
- adds handling of OSTRARRAYBYTETMP in the backend

This reduces binary sizes and avoids function call overhead.

Change-Id: Ib9988d48549cee663b685b4897a483f94727b940
Reviewed-on: https://go-review.googlesource.com/32158Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
Reviewed-by: 's avatarJosh Bleecher Snyder <josharian@gmail.com>
Run-TryBot: Martin Möhrmann <martisch@uos.de>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent f595848e
This diff is collapsed.
......@@ -51,7 +51,6 @@ func slicebytetostring(*[32]byte, []byte) string
func slicebytetostringtmp([]byte) string
func slicerunetostring(*[32]byte, []rune) string
func stringtoslicebyte(*[32]byte, string) []byte
func stringtoslicebytetmp(string) []byte
func stringtoslicerune(*[32]rune, string) []rune
func decoderune(string, int) (retv rune, retk int)
func slicecopy(to any, fr any, wid uintptr) int
......
......@@ -314,6 +314,10 @@ func instrumentnode(np **Node, init *Nodes, wr int, skip int) {
instrumentnode(&n.Left, init, 0, 0)
goto ret
case OSTRARRAYBYTETMP:
instrumentnode(&n.Left, init, 0, 0)
goto ret
// should not appear in AST by now
case OSEND,
ORECV,
......
......@@ -1428,6 +1428,11 @@ func (s *state) expr(n *Node) *ssa.Value {
ptr := s.newValue1(ssa.OpSlicePtr, ptrto(Types[TUINT8]), slice)
len := s.newValue1(ssa.OpSliceLen, Types[TINT], slice)
return s.newValue2(ssa.OpStringMake, n.Type, ptr, len)
case OSTRARRAYBYTETMP:
str := s.expr(n.Left)
ptr := s.newValue1(ssa.OpStringPtr, ptrto(Types[TUINT8]), str)
len := s.newValue1(ssa.OpStringLen, Types[TINT], str)
return s.newValue3(ssa.OpSliceMake, n.Type, ptr, len, len)
case OCFUNC:
aux := s.lookupSymbol(n, &ssa.ExternSymbol{Typ: n.Type, Sym: n.Left.Sym})
return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
......
......@@ -1660,9 +1660,15 @@ opswitch:
n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, Types[TSTRING]))
// stringtoslicebytetmp(string) []byte;
case OSTRARRAYBYTETMP:
n = mkcall("stringtoslicebytetmp", n.Type, init, conv(n.Left, Types[TSTRING]))
// []byte(string) conversion that creates a slice
// referring to the actual string bytes.
// This conversion is handled later by the backend and
// is only for use by internal compiler optimizations
// that know that the slice won't be mutated.
// The only such case today is:
// for i, c := range []byte(string)
n.Left = walkexpr(n.Left, init)
// stringtoslicerune(*[32]rune, string) []rune
case OSTRARRAYRUNE:
......
......@@ -147,18 +147,6 @@ func stringtoslicebyte(buf *tmpBuf, s string) []byte {
return b
}
func stringtoslicebytetmp(s string) []byte {
// Return a slice referring to the actual string bytes.
// This is only for use by internal compiler optimizations
// that know that the slice won't be mutated.
// The only such case today is:
// for i, c := range []byte(str)
str := stringStructOf(&s)
ret := slice{array: str.str, len: str.len, cap: str.len}
return *(*[]byte)(unsafe.Pointer(&ret))
}
func stringtoslicerune(buf *[tmpStringBufSize]rune, s string) []rune {
// two passes.
// unlike slicerunetostring, no race because strings are immutable.
......
......@@ -110,6 +110,30 @@ func testslice2() {
}
}
// test that range over []byte(string) only evaluates
// the expression after "range" once.
func makenumstring() string {
nmake++
return "\x01\x02\x03\x04\x05"
}
func testslice3() {
s := byte(0)
nmake = 0
for _, v := range []byte(makenumstring()) {
s += v
}
if nmake != 1 {
println("range called makenumstring", nmake, "times")
panic("fail")
}
if s != 15 {
println("wrong sum ranging over []byte(makenumstring)", s)
panic("fail")
}
}
// test that range over array only evaluates
// the expression after "range" once.
......@@ -392,6 +416,7 @@ func main() {
testslice()
testslice1()
testslice2()
testslice3()
teststring()
teststring1()
teststring2()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment