From: Josh Bleecher Snyder Date: Thu, 5 Feb 2015 23:38:53 +0000 (-0800) Subject: cmd/gc: eliminate dead code in switch statements X-Git-Tag: go1.5beta1~2099 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=4ce06f4b5caab3874f30f14551aa3f8e08f2de3e;p=gostls13.git cmd/gc: eliminate dead code in switch statements Ordinary switch statements are rewritten into a sequence of if statements. Staticly dead cases were not being eliminated because the rewrite introduced a temporary, which hid the fact that the case was a constant. Stop doing that. This eliminates dead code in the standard library at: runtime/cgocall.go:219 runtime/cgocall.go:269 debug/gosym/pclntab.go:175 debug/macho/file.go:208 math/big/nat.go:635 math/big/nat.go:850 math/big/nat.go:1058 cmd/pprof/internal/commands/commands.go:86 net/sock_bsd.go:19 cmd/go/build.go:2657 cmd/go/env.go:90 Fixes #9608. Change-Id: Ic23a05dfbb1ad91d5f62a6506b35a13e51b33e38 Reviewed-on: https://go-review.googlesource.com/3980 Reviewed-by: Keith Randall --- diff --git a/src/cmd/gc/swt.c b/src/cmd/gc/swt.c index ca5455d479..e75971d477 100644 --- a/src/cmd/gc/swt.c +++ b/src/cmd/gc/swt.c @@ -503,7 +503,7 @@ exprbsw(Case *c0, int ncase, int arg) /* * normal (expression) switch. - * rebulid case statements into if .. goto + * rebuild case statements into if .. goto */ static void exprswitch(Node *sw) @@ -533,12 +533,15 @@ exprswitch(Node *sw) */ exprname = N; cas = nil; - if(arg != Strue && arg != Sfalse) { + if(arg == Strue || arg == Sfalse) + exprname = nodbool(arg == Strue); + else if(consttype(sw->ntest) >= 0) + // leave constants to enable dead code elimination (issue 9608) + exprname = sw->ntest; + else { exprname = temp(sw->ntest->type); cas = list1(nod(OAS, exprname, sw->ntest)); typechecklist(cas, Etop); - } else { - exprname = nodbool(arg == Strue); } c0 = mkcaselist(sw, arg); diff --git a/test/fixedbugs/issue9608.dir/issue9608.go b/test/fixedbugs/issue9608.dir/issue9608.go new file mode 100644 index 0000000000..56b52cc606 --- /dev/null +++ b/test/fixedbugs/issue9608.dir/issue9608.go @@ -0,0 +1,73 @@ +// Copyright 2015 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 main + +func fail() // unimplemented, to test dead code elimination + +// Test dead code elimination in if statements +func init() { + if false { + fail() + } + if 0 == 1 { + fail() + } +} + +// Test dead code elimination in ordinary switch statements +func init() { + const x = 0 + switch x { + case 1: + fail() + } + + switch 1 { + case x: + fail() + } + + switch { + case false: + fail() + } + + const a = "a" + switch a { + case "b": + fail() + } + + const snowman = '☃' + switch snowman { + case '☀': + fail() + } + + const zero = float64(0.0) + const one = float64(1.0) + switch one { + case -1.0: + fail() + case zero: + fail() + } + + switch 1.0i { + case 1: + fail() + case -1i: + fail() + } + + const no = false + switch no { + case true: + fail() + } +} + +func main() { +} diff --git a/test/fixedbugs/issue9608.go b/test/fixedbugs/issue9608.go new file mode 100644 index 0000000000..92592d76ee --- /dev/null +++ b/test/fixedbugs/issue9608.go @@ -0,0 +1,14 @@ +// rundir + +// Copyright 2015 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. + +// Issue 9608: dead code elimination in switch statements. + +// This has to be done as a package rather than as a file, +// because run.go runs files with 'go run', which passes the +// -complete flag to compiler, causing it to complain about +// the intentionally unimplemented function fail. + +package ignored