aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/deadcode/deadcode.go
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2023-04-13 14:51:05 +0700
committerCuong Manh Le <cuong.manhle.vn@gmail.com>2023-04-14 17:58:01 +0000
commit74b52d9519f4060514e897e90bfc5a50e049bc78 (patch)
treeddae98963ee9761663dd9d0d05962316ff38d763 /src/cmd/compile/internal/deadcode/deadcode.go
parent47e2d7495fabaae8cfe2e1a0f0ff1e38f6e7b851 (diff)
downloadgo-74b52d9519f4060514e897e90bfc5a50e049bc78.tar.xz
cmd/compile: better code generation for constant-fold switch
CL 399694 added constant-fold switch early in compilation. So function: func f() string { switch intSize { case 32: return "32" case 64: return "64" default: panic("unreachable") } } will be constant-fold to: func f() string { switch intSize { case 64: return "64" } } When this function get inlined, there is a check whether we can delay declaring the result parameter until the "return" statement. For the original function, we can't delay the result, because there's more than one return statement. However, the constant-fold one can, because there's on one return statement in the body now. The result parameter ~R0 ends up declaring inside the switch statement scope. Now, when walking the switch statement, it's re-written into if-else statement. Without typecheck.EvalConst, the if condition "if 64 == 64" is passed as-is to the ssa generation pass. Because "64 == 64" is not a constant, the ssagen creates normal blocks for branching the results. This confuses the liveness analysis, because ~R0 is only live inside the if block. With typecheck.EvalConst, "64 == 64" is evaluated to "true", so ssagen can branch the result without emitting conditional blocks. Instead, the constant-fold can be re-written as: switch { case true: // Body } So it does not depend on the delay results check during inlining. Adding a test, which will fail when typecheck.EvalConst is removed, so we can do the cleanup without breaking things. Change-Id: I638730bb147140de84260653741431b807ff2f15 Reviewed-on: https://go-review.googlesource.com/c/go/+/484316 Reviewed-by: Keith Randall <khr@google.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/deadcode/deadcode.go')
-rw-r--r--src/cmd/compile/internal/deadcode/deadcode.go8
1 files changed, 4 insertions, 4 deletions
diff --git a/src/cmd/compile/internal/deadcode/deadcode.go b/src/cmd/compile/internal/deadcode/deadcode.go
index decd261183..46a2239f48 100644
--- a/src/cmd/compile/internal/deadcode/deadcode.go
+++ b/src/cmd/compile/internal/deadcode/deadcode.go
@@ -122,16 +122,16 @@ func stmts(nn *ir.Nodes) {
// This switch entry is the one that always triggers.
for _, cas2 := range n.Cases {
for _, c2 := range cas2.List {
- if cas2 != cas || c2 != c {
- ir.Visit(c2, markHiddenClosureDead)
- }
+ ir.Visit(c2, markHiddenClosureDead)
}
if cas2 != cas {
ir.VisitList(cas2.Body, markHiddenClosureDead)
}
}
- cas.List[0] = c
+ // Rewrite to switch { case true: ... }
+ n.Tag = nil
+ cas.List[0] = ir.NewBool(c.Pos(), true)
cas.List = cas.List[:1]
n.Cases[0] = cas
n.Cases = n.Cases[:1]