1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:54:40 -07:00
go/test/codegen/switch.go
Keith Randall cbcf8efa5f cmd/compile: use cache in front of type assert runtime call
That way we don't need to call into the runtime for every
type assertion (to an interface type).

name           old time/op  new time/op  delta
TypeAssert-24  3.78ns ± 3%  1.00ns ± 1%  -73.53%  (p=0.000 n=10+8)

Change-Id: I0ba308aaf0f24a5495b4e13c814d35af0c58bfde
Reviewed-on: https://go-review.googlesource.com/c/go/+/529316
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2023-10-06 17:02:53 +00:00

151 lines
2.8 KiB
Go

// asmcheck
// Copyright 2019 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.
// These tests check code generation of switch statements.
package codegen
// see issue 33934
func f(x string) int {
// amd64:-`cmpstring`
switch x {
case "":
return -1
case "1", "2", "3":
return -2
default:
return -3
}
}
// use jump tables for 8+ int cases
func square(x int) int {
// amd64:`JMP\s\(.*\)\(.*\)$`
// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
switch x {
case 1:
return 1
case 2:
return 4
case 3:
return 9
case 4:
return 16
case 5:
return 25
case 6:
return 36
case 7:
return 49
case 8:
return 64
default:
return x * x
}
}
// use jump tables for 8+ string lengths
func length(x string) int {
// amd64:`JMP\s\(.*\)\(.*\)$`
// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
switch x {
case "a":
return 1
case "bb":
return 2
case "ccc":
return 3
case "dddd":
return 4
case "eeeee":
return 5
case "ffffff":
return 6
case "ggggggg":
return 7
case "hhhhhhhh":
return 8
default:
return len(x)
}
}
// Use single-byte ordered comparisons for binary searching strings.
// See issue 53333.
func mimetype(ext string) string {
// amd64: `CMPB\s1\(.*\), \$104$`,-`cmpstring`
// arm64: `MOVB\s1\(R.*\), R.*$`, `CMPW\s\$104, R.*$`, -`cmpstring`
switch ext {
// amd64: `CMPL\s\(.*\), \$1836345390$`
// arm64: `MOVD\s\$1836345390`, `CMPW\sR.*, R.*$`
case ".htm":
return "A"
// amd64: `CMPL\s\(.*\), \$1953457454$`
// arm64: `MOVD\s\$1953457454`, `CMPW\sR.*, R.*$`
case ".eot":
return "B"
// amd64: `CMPL\s\(.*\), \$1735815982$`
// arm64: `MOVD\s\$1735815982`, `CMPW\sR.*, R.*$`
case ".svg":
return "C"
// amd64: `CMPL\s\(.*\), \$1718907950$`
// arm64: `MOVD\s\$1718907950`, `CMPW\sR.*, R.*$`
case ".ttf":
return "D"
default:
return ""
}
}
// use jump tables for type switches to concrete types.
func typeSwitch(x any) int {
// amd64:`JMP\s\(.*\)\(.*\)$`
// arm64:`MOVD\s\(R.*\)\(R.*<<3\)`,`JMP\s\(R.*\)$`
switch x.(type) {
case int:
return 0
case int8:
return 1
case int16:
return 2
case int32:
return 3
case int64:
return 4
}
return 7
}
type I interface {
foo()
}
type J interface {
bar()
}
// use a runtime call for type switches to interface types.
func interfaceSwitch(x any) int {
// amd64:`CALL\truntime.interfaceSwitch`,`MOVL\t16\(.*\)`,`MOVQ\t8\(.*\)(.*\*8)`
// arm64:`CALL\truntime.interfaceSwitch`,`LDAR`,`MOVWU`,`MOVD\t\(R.*\)\(R.*\)`
switch x.(type) {
case I:
return 1
case J:
return 2
default:
return 3
}
}
func interfaceCast(x any) int {
// amd64:`CALL\truntime.typeAssert`,`MOVL\t16\(.*\)`,`MOVQ\t8\(.*\)(.*\*1)`
// arm64:`CALL\truntime.typeAssert`,`LDAR`,`MOVWU`,`MOVD\t\(R.*\)\(R.*\)`
if _, ok := x.(I); ok {
return 3
}
return 5
}