diff options
| author | qmuntal <quimmuntal@gmail.com> | 2026-03-18 10:34:00 +0100 |
|---|---|---|
| committer | Quim Muntal <quimmuntal@gmail.com> | 2026-04-03 16:46:16 -0700 |
| commit | 2a902c8a8a37935abc4adc93605276c9d2103e45 (patch) | |
| tree | 1839e4648eda10c54e5fdc94d511dcdbce266fc3 /src/cmd/compile/internal/test/testdata/ctl_test.go | |
| parent | f4b87f314dd7a890e9d3b42d7d6427cc7f51f9a2 (diff) | |
| download | go-2a902c8a8a37935abc4adc93605276c9d2103e45.tar.xz | |
cmd/compile: optimize switch statements using lookup tables
Switch statement containing integer constant cases and case bodies just
returning a constant should be optimizable to a simpler and faster table
lookup instead of a jump table.
That is, a switch like this:
switch x {
case 0: return 10
case 1: return 20
case 2: return 30
case 3: return 40
default: return -1
}
Could be optimized to this:
var table = [4]int{10, 20, 30, 40}
if uint(x) < 4 { return table[x] }
return -1
The resulting code is smaller and faster, especially on platforms where
jump tables are not supported.
goos: windows
goarch: arm64
pkg: cmd/compile/internal/test
│ .\old.txt │ .\new.txt │
│ sec/op │ sec/op vs base │
SwitchLookup8Predictable-12 2.708n ± 6% 2.249n ± 5% -16.97% (p=0.000 n=10)
SwitchLookup8Unpredictable-12 8.758n ± 7% 3.272n ± 4% -62.65% (p=0.000 n=10)
SwitchLookup32Predictable-12 2.672n ± 5% 2.373n ± 6% -11.21% (p=0.000 n=10)
SwitchLookup32Unpredictable-12 9.372n ± 7% 3.385n ± 6% -63.89% (p=0.000 n=10)
geomean 4.937n 2.772n -43.84%
Fixes #78203
Change-Id: I74fa3d77ef618412951b2e5c3cb6ebc760ce4ff1
Reviewed-on: https://go-review.googlesource.com/c/go/+/756340
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/cmd/compile/internal/test/testdata/ctl_test.go')
| -rw-r--r-- | src/cmd/compile/internal/test/testdata/ctl_test.go | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/test/testdata/ctl_test.go b/src/cmd/compile/internal/test/testdata/ctl_test.go index 501f79eee1..608bdcf6b9 100644 --- a/src/cmd/compile/internal/test/testdata/ctl_test.go +++ b/src/cmd/compile/internal/test/testdata/ctl_test.go @@ -72,6 +72,22 @@ func switch_ssa(a int) int { return ret } +func switch_nonconstcase(n, c int) int { + switch n { + case 1: + return 1 + case 2: + return 2 + case c: + return 9 + case 3: + return 3 + case 4: + return 4 + } + return 0 +} + func fallthrough_ssa(a int) int { ret := 0 switch a { @@ -107,6 +123,9 @@ func testSwitch(t *testing.T) { t.Errorf("switch_ssa(i) = %d, wanted %d", got, i) } } + if got := switch_nonconstcase(3, 3); got != 9 { + t.Errorf("switch_nonconstcase(3, 3) = %d, wanted 9", got) + } } type junk struct { |
