mirror of
https://github.com/golang/go
synced 2024-11-24 19:00:13 -07:00
fc814056aa
make\(\[\][a-zA-Z0-9]+, 0\) is seen 52 times in the go source. And at least 391 times on internet: https://grep.app/search?q=make%5C%28%5C%5B%5C%5D%5Ba-zA-Z0-9%5D%2B%2C%200%5C%29®exp=true This used to compile to calling runtime.makeslice. However we can copy what we do for []T{}, just use a zerobase pointer. On my machine this is 10x faster (from 3ns to 0.3ns). Note that an empty loop also runs in 0.3ns, so this really is free when you count superscallar execution. Change-Id: I1cfe7e69f5a7a4dabbc71912ce6a4f8a2d4a7f3c Reviewed-on: https://go-review.googlesource.com/c/go/+/454036 Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Jakub Ciolek <jakub@ciolek.dev>
440 lines
10 KiB
Go
440 lines
10 KiB
Go
// asmcheck
|
|
|
|
// Copyright 2018 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 "unsafe"
|
|
|
|
// This file contains code generation tests related to the handling of
|
|
// slice types.
|
|
|
|
// ------------------ //
|
|
// Clear //
|
|
// ------------------ //
|
|
|
|
// Issue #5373 optimize memset idiom
|
|
|
|
func SliceClear(s []int) []int {
|
|
// amd64:`.*memclrNoHeapPointers`
|
|
// ppc64le:`.*memclrNoHeapPointers`
|
|
// ppc64:`.*memclrNoHeapPointers`
|
|
for i := range s {
|
|
s[i] = 0
|
|
}
|
|
return s
|
|
}
|
|
|
|
func SliceClearPointers(s []*int) []*int {
|
|
// amd64:`.*memclrHasPointers`
|
|
// ppc64le:`.*memclrHasPointers`
|
|
// ppc64:`.*memclrHasPointers`
|
|
for i := range s {
|
|
s[i] = nil
|
|
}
|
|
return s
|
|
}
|
|
|
|
// ------------------ //
|
|
// Extension //
|
|
// ------------------ //
|
|
|
|
// Issue #21266 - avoid makeslice in append(x, make([]T, y)...)
|
|
|
|
func SliceExtensionConst(s []int) []int {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:-`.*runtime\.panicmakeslicelen`
|
|
// ppc64le:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64le:-`.*runtime\.makeslice`
|
|
// ppc64le:-`.*runtime\.panicmakeslicelen`
|
|
// ppc64:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64:-`.*runtime\.makeslice`
|
|
// ppc64:-`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]int, 1<<2)...)
|
|
}
|
|
|
|
func SliceExtensionConstInt64(s []int) []int {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:-`.*runtime\.panicmakeslicelen`
|
|
// ppc64le:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64le:-`.*runtime\.makeslice`
|
|
// ppc64le:-`.*runtime\.panicmakeslicelen`
|
|
// ppc64:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64:-`.*runtime\.makeslice`
|
|
// ppc64:-`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]int, int64(1<<2))...)
|
|
}
|
|
|
|
func SliceExtensionConstUint64(s []int) []int {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:-`.*runtime\.panicmakeslicelen`
|
|
// ppc64le:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64le:-`.*runtime\.makeslice`
|
|
// ppc64le:-`.*runtime\.panicmakeslicelen`
|
|
// ppc64:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64:-`.*runtime\.makeslice`
|
|
// ppc64:-`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]int, uint64(1<<2))...)
|
|
}
|
|
|
|
func SliceExtensionConstUint(s []int) []int {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:-`.*runtime\.panicmakeslicelen`
|
|
// ppc64le:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64le:-`.*runtime\.makeslice`
|
|
// ppc64le:-`.*runtime\.panicmakeslicelen`
|
|
// ppc64:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64:-`.*runtime\.makeslice`
|
|
// ppc64:-`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]int, uint(1<<2))...)
|
|
}
|
|
|
|
func SliceExtensionPointer(s []*int, l int) []*int {
|
|
// amd64:`.*runtime\.memclrHasPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// ppc64le:`.*runtime\.memclrHasPointers`
|
|
// ppc64le:-`.*runtime\.makeslice`
|
|
// ppc64:`.*runtime\.memclrHasPointers`
|
|
// ppc64:-`.*runtime\.makeslice`
|
|
return append(s, make([]*int, l)...)
|
|
}
|
|
|
|
func SliceExtensionVar(s []byte, l int) []byte {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// ppc64le:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64le:-`.*runtime\.makeslice`
|
|
// ppc64:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64:-`.*runtime\.makeslice`
|
|
return append(s, make([]byte, l)...)
|
|
}
|
|
|
|
func SliceExtensionVarInt64(s []byte, l int64) []byte {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]byte, l)...)
|
|
}
|
|
|
|
func SliceExtensionVarUint64(s []byte, l uint64) []byte {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]byte, l)...)
|
|
}
|
|
|
|
func SliceExtensionVarUint(s []byte, l uint) []byte {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]byte, l)...)
|
|
}
|
|
|
|
func SliceExtensionInt64(s []int, l64 int64) []int {
|
|
// 386:`.*runtime\.makeslice`
|
|
// 386:-`.*runtime\.memclr`
|
|
return append(s, make([]int, l64)...)
|
|
}
|
|
|
|
// ------------------ //
|
|
// Make+Copy //
|
|
// ------------------ //
|
|
|
|
// Issue #26252 - avoid memclr for make+copy
|
|
|
|
func SliceMakeCopyLen(s []int) []int {
|
|
// amd64:`.*runtime\.mallocgc`
|
|
// amd64:`.*runtime\.memmove`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// ppc64le:`.*runtime\.mallocgc`
|
|
// ppc64le:`.*runtime\.memmove`
|
|
// ppc64le:-`.*runtime\.makeslice`
|
|
// ppc64:`.*runtime\.mallocgc`
|
|
// ppc64:`.*runtime\.memmove`
|
|
// ppc64:-`.*runtime\.makeslice`
|
|
a := make([]int, len(s))
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyLenPtr(s []*int) []*int {
|
|
// amd64:`.*runtime\.makeslicecopy`
|
|
// amd64:-`.*runtime\.makeslice\(`
|
|
// amd64:-`.*runtime\.typedslicecopy
|
|
// ppc64le:`.*runtime\.makeslicecopy`
|
|
// ppc64le:-`.*runtime\.makeslice\(`
|
|
// ppc64le:-`.*runtime\.typedslicecopy
|
|
// ppc64:`.*runtime\.makeslicecopy`
|
|
// ppc64:-`.*runtime\.makeslice\(`
|
|
// ppc64:-`.*runtime\.typedslicecopy
|
|
a := make([]*int, len(s))
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyConst(s []int) []int {
|
|
// amd64:`.*runtime\.makeslicecopy`
|
|
// amd64:-`.*runtime\.makeslice\(`
|
|
// amd64:-`.*runtime\.memmove`
|
|
a := make([]int, 4)
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyConstPtr(s []*int) []*int {
|
|
// amd64:`.*runtime\.makeslicecopy`
|
|
// amd64:-`.*runtime\.makeslice\(`
|
|
// amd64:-`.*runtime\.typedslicecopy
|
|
a := make([]*int, 4)
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptNoDeref(s []*int) []*int {
|
|
a := new([]*int)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
*a = make([]*int, 4)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
copy(*a, s)
|
|
return *a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptNoVar(s []*int) []*int {
|
|
a := make([][]*int, 1)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
a[0] = make([]*int, 4)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
copy(a[0], s)
|
|
return a[0]
|
|
}
|
|
|
|
func SliceMakeCopyNoOptBlank(s []*int) []*int {
|
|
var a []*int
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
_ = make([]*int, 4)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptNoMake(s []*int) []*int {
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:-`.*runtime\.objectnew`
|
|
a := *new([]*int)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptNoHeapAlloc(s []*int) int {
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
a := make([]*int, 4)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
copy(a, s)
|
|
return cap(a)
|
|
}
|
|
|
|
func SliceMakeCopyNoOptNoCap(s []*int) []*int {
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
a := make([]*int, 0, 4)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptNoCopy(s []*int) []*int {
|
|
copy := func(x, y []*int) {}
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
a := make([]*int, 4)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptWrongOrder(s []*int) []*int {
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
a := make([]*int, 4)
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
copy(s, a)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptWrongAssign(s []*int) []*int {
|
|
var a []*int
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
s = make([]*int, 4)
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
copy(a, s)
|
|
return s
|
|
}
|
|
|
|
func SliceMakeCopyNoOptCopyLength(s []*int) (int, []*int) {
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
a := make([]*int, 4)
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
n := copy(a, s)
|
|
return n, a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptSelfCopy(s []*int) []*int {
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
a := make([]*int, 4)
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
copy(a, a)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptTargetReference(s []*int) []*int {
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
a := make([]*int, 4)
|
|
// amd64:`.*runtime\.typedslicecopy`
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
copy(a, s[:len(a)])
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoOptCap(s []int) []int {
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.makeslice\(`
|
|
a := make([]int, len(s), 9)
|
|
// amd64:-`.*runtime\.makeslicecopy`
|
|
// amd64:`.*runtime\.memmove`
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeCopyNoMemmoveDifferentLen(s []int) []int {
|
|
// amd64:`.*runtime\.makeslicecopy`
|
|
// amd64:-`.*runtime\.memmove`
|
|
a := make([]int, len(s)-1)
|
|
// amd64:-`.*runtime\.memmove`
|
|
copy(a, s)
|
|
return a
|
|
}
|
|
|
|
func SliceMakeEmptyPointerToZerobase() []int {
|
|
// amd64:`LEAQ.+runtime\.zerobase`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
return make([]int, 0)
|
|
}
|
|
|
|
// ---------------------- //
|
|
// Nil check of &s[0] //
|
|
// ---------------------- //
|
|
// See issue 30366
|
|
func SliceNilCheck(s []int) {
|
|
p := &s[0]
|
|
// amd64:-`TESTB`
|
|
_ = *p
|
|
}
|
|
|
|
// ---------------------- //
|
|
// Init slice literal //
|
|
// ---------------------- //
|
|
// See issue 21561
|
|
func InitSmallSliceLiteral() []int {
|
|
// amd64:`MOVQ\t[$]42`
|
|
return []int{42}
|
|
}
|
|
|
|
func InitNotSmallSliceLiteral() []int {
|
|
// amd64:`LEAQ\t.*stmp_`
|
|
return []int{
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
42,
|
|
}
|
|
}
|
|
|
|
// --------------------------------------- //
|
|
// Test PPC64 SUBFCconst folding rules //
|
|
// triggered by slice operations. //
|
|
// --------------------------------------- //
|
|
|
|
func SliceWithConstCompare(a []int, b int) []int {
|
|
var c []int = []int{1, 2, 3, 4, 5}
|
|
if b+len(a) < len(c) {
|
|
// ppc64le:-"NEG"
|
|
// ppc64:-"NEG"
|
|
return c[b:]
|
|
}
|
|
return a
|
|
}
|
|
|
|
func SliceWithSubtractBound(a []int, b int) []int {
|
|
// ppc64le:"SUBC",-"NEG"
|
|
// ppc64:"SUBC",-"NEG"
|
|
return a[(3 - b):]
|
|
}
|
|
|
|
// --------------------------------------- //
|
|
// Code generation for unsafe.Slice //
|
|
// --------------------------------------- //
|
|
|
|
func Slice1(p *byte, i int) []byte {
|
|
// amd64:-"MULQ"
|
|
return unsafe.Slice(p, i)
|
|
}
|
|
func Slice0(p *struct{}, i int) []struct{} {
|
|
// amd64:-"MULQ"
|
|
return unsafe.Slice(p, i)
|
|
}
|