mirror of
https://github.com/golang/go
synced 2024-11-22 20:24:47 -07:00
91d07ac71c
Tested that on loong64, the optimization effect is negative for constant size cases greater than 512. So only enable inlining for constant size cases less than 512. goos: linux goarch: loong64 pkg: runtime cpu: Loongson-3A6000 @ 2500.00MHz | bench.old | bench.new | | sec/op | sec/op vs base | MemclrKnownSize1 2.4070n ± 0% 0.4004n ± 0% -83.37% (p=0.000 n=20) MemclrKnownSize2 2.1365n ± 0% 0.4004n ± 0% -81.26% (p=0.000 n=20) MemclrKnownSize4 2.4445n ± 0% 0.4004n ± 0% -83.62% (p=0.000 n=20) MemclrKnownSize8 2.4200n ± 0% 0.4004n ± 0% -83.45% (p=0.000 n=20) MemclrKnownSize16 2.8030n ± 0% 0.8007n ± 0% -71.43% (p=0.000 n=20) MemclrKnownSize32 2.803n ± 0% 1.602n ± 0% -42.85% (p=0.000 n=20) MemclrKnownSize64 3.250n ± 0% 2.402n ± 0% -26.08% (p=0.000 n=20) MemclrKnownSize112 6.006n ± 0% 2.819n ± 0% -53.06% (p=0.000 n=20) MemclrKnownSize128 6.006n ± 0% 3.240n ± 0% -46.05% (p=0.000 n=20) MemclrKnownSize192 6.807n ± 0% 5.205n ± 0% -23.53% (p=0.000 n=20) MemclrKnownSize248 7.608n ± 0% 6.301n ± 0% -17.19% (p=0.000 n=20) MemclrKnownSize256 7.608n ± 0% 6.707n ± 0% -11.84% (p=0.000 n=20) MemclrKnownSize512 13.61n ± 0% 13.61n ± 0% ~ (p=0.374 n=20) MemclrKnownSize1024 26.43n ± 0% 26.43n ± 0% ~ (p=0.826 n=20) MemclrKnownSize4096 103.3n ± 0% 103.3n ± 0% ~ (p=1.000 n=20) MemclrKnownSize512KiB 26.29µ ± 0% 26.29µ ± 0% -0.00% (p=0.012 n=20) geomean 10.05n 5.006n -50.18% | bench.old | bench.new | | B/s | B/s vs base | MemclrKnownSize1 396.2Mi ± 0% 2381.9Mi ± 0% +501.21% (p=0.000 n=20) MemclrKnownSize2 892.8Mi ± 0% 4764.0Mi ± 0% +433.59% (p=0.000 n=20) MemclrKnownSize4 1.524Gi ± 0% 9.305Gi ± 0% +510.56% (p=0.000 n=20) MemclrKnownSize8 3.079Gi ± 0% 18.609Gi ± 0% +504.42% (p=0.000 n=20) MemclrKnownSize16 5.316Gi ± 0% 18.609Gi ± 0% +250.05% (p=0.000 n=20) MemclrKnownSize32 10.63Gi ± 0% 18.61Gi ± 0% +75.00% (p=0.000 n=20) MemclrKnownSize64 18.34Gi ± 0% 24.81Gi ± 0% +35.27% (p=0.000 n=20) MemclrKnownSize112 17.37Gi ± 0% 37.01Gi ± 0% +113.08% (p=0.000 n=20) MemclrKnownSize128 19.85Gi ± 0% 36.80Gi ± 0% +85.39% (p=0.000 n=20) MemclrKnownSize192 26.27Gi ± 0% 34.35Gi ± 0% +30.77% (p=0.000 n=20) MemclrKnownSize248 30.36Gi ± 0% 36.66Gi ± 0% +20.75% (p=0.000 n=20) MemclrKnownSize256 31.34Gi ± 0% 35.55Gi ± 0% +13.43% (p=0.000 n=20) MemclrKnownSize512 35.02Gi ± 0% 35.03Gi ± 0% +0.00% (p=0.030 n=20) MemclrKnownSize1024 36.09Gi ± 0% 36.09Gi ± 0% ~ (p=0.101 n=20) MemclrKnownSize4096 36.93Gi ± 0% 36.93Gi ± 0% +0.00% (p=0.003 n=20) MemclrKnownSize512KiB 18.57Gi ± 0% 18.57Gi ± 0% +0.00% (p=0.041 n=20) geomean 10.13Gi 20.33Gi +100.72% Change-Id: I460a56f7ccc9f820ca2c1934c1c517b9614809ac Reviewed-on: https://go-review.googlesource.com/c/go/+/621355 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: abner chenc <chenguoqi@loongson.cn> Reviewed-by: Michael Pratt <mpratt@google.com>
432 lines
10 KiB
Go
432 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
|
|
// Some of the clears get inlined, see #56997
|
|
|
|
func SliceClear(s []int) []int {
|
|
// amd64:`.*memclrNoHeapPointers`
|
|
// ppc64x:`.*memclrNoHeapPointers`
|
|
for i := range s {
|
|
s[i] = 0
|
|
}
|
|
return s
|
|
}
|
|
|
|
func SliceClearPointers(s []*int) []*int {
|
|
// amd64:`.*memclrHasPointers`
|
|
// ppc64x:`.*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`
|
|
// amd64:"MOVUPS\tX15"
|
|
// loong64:-`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*runtime\.makeslice`
|
|
// ppc64x:-`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]int, 1<<2)...)
|
|
}
|
|
|
|
func SliceExtensionConstInt64(s []int) []int {
|
|
// amd64:-`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:-`.*runtime\.panicmakeslicelen`
|
|
// amd64:"MOVUPS\tX15"
|
|
// loong64:-`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*runtime\.makeslice`
|
|
// ppc64x:-`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]int, int64(1<<2))...)
|
|
}
|
|
|
|
func SliceExtensionConstUint64(s []int) []int {
|
|
// amd64:-`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:-`.*runtime\.panicmakeslicelen`
|
|
// amd64:"MOVUPS\tX15"
|
|
// loong64:-`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*runtime\.makeslice`
|
|
// ppc64x:-`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]int, uint64(1<<2))...)
|
|
}
|
|
|
|
func SliceExtensionConstUint(s []int) []int {
|
|
// amd64:-`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// amd64:-`.*runtime\.panicmakeslicelen`
|
|
// amd64:"MOVUPS\tX15"
|
|
// loong64:-`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*runtime\.makeslice`
|
|
// ppc64x:-`.*runtime\.panicmakeslicelen`
|
|
return append(s, make([]int, uint(1<<2))...)
|
|
}
|
|
|
|
// On ppc64x and loong64 continue to use memclrNoHeapPointers
|
|
// for sizes >= 512.
|
|
func SliceExtensionConst512(s []int) []int {
|
|
// amd64:-`.*runtime\.memclrNoHeapPointers`
|
|
// loong64:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:`.*runtime\.memclrNoHeapPointers`
|
|
return append(s, make([]int, 1<<9)...)
|
|
}
|
|
|
|
func SliceExtensionPointer(s []*int, l int) []*int {
|
|
// amd64:`.*runtime\.memclrHasPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// ppc64x:`.*runtime\.memclrHasPointers`
|
|
// ppc64x:-`.*runtime\.makeslice`
|
|
return append(s, make([]*int, l)...)
|
|
}
|
|
|
|
func SliceExtensionVar(s []byte, l int) []byte {
|
|
// amd64:`.*runtime\.memclrNoHeapPointers`
|
|
// amd64:-`.*runtime\.makeslice`
|
|
// ppc64x:`.*runtime\.memclrNoHeapPointers`
|
|
// ppc64x:-`.*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`
|
|
// ppc64x:`.*runtime\.mallocgc`
|
|
// ppc64x:`.*runtime\.memmove`
|
|
// ppc64x:-`.*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
|
|
// ppc64x:`.*runtime\.makeslicecopy`
|
|
// ppc64x:-`.*runtime\.makeslice\(`
|
|
// ppc64x:-`.*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) {
|
|
// ppc64x:-"NEG"
|
|
return c[b:]
|
|
}
|
|
return a
|
|
}
|
|
|
|
func SliceWithSubtractBound(a []int, b int) []int {
|
|
// ppc64x:"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)
|
|
}
|