Commit 566e72d0 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/compile: ignore some dead code when deciding whether to inline

Constant evaluation provides some rudimentary
knowledge of dead code at inlining decision time.
Use it.

This CL addresses only dead code inside if statements.
For statements are never inlined anyway,
and dead code inside for statements is rare.
Analyzing switch statements is worth doing,
but it is more complicated, since we would have
to evaluate each case; leave it for later.

Fixes #9274

After this CL, the following functions in std+cmd
can be newly inlined:

cmd/internal/obj/x86/asm6.go:3122: can inline subreg
cmd/vendor/golang.org/x/arch/x86/x86asm/decode.go:172: can inline instPrefix
cmd/vendor/golang.org/x/arch/x86/x86asm/decode.go:202: can inline truncated
go/constant/value.go:234: can inline makeFloat
go/types/labels.go:52: can inline (*block).insert
math/big/float.go:231: can inline (*Float).Sign
math/bits/bits.go:57: can inline OnesCount
net/http/server.go:597: can inline (*Server).newConn
runtime/hashmap.go:1165: can inline reflect_maplen
runtime/proc.go:207: can inline os_beforeExit
runtime/signal_unix.go:55: can inline init.5
runtime/stack.go:1081: can inline gostartcallfn

Change-Id: I4c92fb96aa0c3d33df7b3f2da548612e79b56b5b
Reviewed-on: https://go-review.googlesource.com/37499Reviewed-by: default avatarMatthew Dempsky <mdempsky@google.com>
parent c7894924
......@@ -115,11 +115,20 @@ type NilVal struct{}
// n must be an integer or rune constant.
func (n *Node) Int64() int64 {
if !Isconst(n, CTINT) {
Fatalf("Int(%v)", n)
Fatalf("Int64(%v)", n)
}
return n.Val().U.(*Mpint).Int64()
}
// Bool returns n as a bool.
// n must be a boolean constant.
func (n *Node) Bool() bool {
if !Isconst(n, CTBOOL) {
Fatalf("Bool(%v)", n)
}
return n.Val().U.(bool)
}
// truncate float literal fv to 32-bit or 64-bit precision
// according to type; return truncated value.
func truncfltlit(oldv *Mpflt, t *Type) *Mpflt {
......
......@@ -277,6 +277,16 @@ func ishairy(n *Node, budget *int32, reason *string) bool {
return true
}
if n.Op == OIF && Isconst(n.Left, CTBOOL) {
var taken Nodes // statements for the branch that is always taken
if n.Left.Bool() {
taken = n.Nbody // then case
} else {
taken = n.Rlist // else case
}
return ishairylist(n.Ninit, budget, reason) || ishairylist(taken, budget, reason)
}
return ishairy(n.Left, budget, reason) || ishairy(n.Right, budget, reason) ||
ishairylist(n.List, budget, reason) || ishairylist(n.Rlist, budget, reason) ||
ishairylist(n.Ninit, budget, reason) || ishairylist(n.Nbody, budget, reason)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment