mirror of
https://github.com/golang/go
synced 2024-11-05 19:56:11 -07:00
4711299661
For large interface -> concrete type switches, we can use a jump table on some bits of the type hash instead of a binary search on the type hash. name old time/op new time/op delta SwitchTypePredictable-24 1.99ns ± 2% 1.78ns ± 5% -10.87% (p=0.000 n=10+10) SwitchTypeUnpredictable-24 11.0ns ± 1% 9.1ns ± 2% -17.55% (p=0.000 n=7+9) Change-Id: Ida4768e5d62c3ce1c2701288b72664aaa9e64259 Reviewed-on: https://go-review.googlesource.com/c/go/+/521497 Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Keith Randall <khr@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Keith Randall <khr@golang.org>
121 lines
2.2 KiB
Go
121 lines
2.2 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
|
|
}
|