1
0
mirror of https://github.com/golang/go synced 2024-11-18 19:54:44 -07:00

cmd/compile: pick position of implicit break statements more carefully

The previous version used the position of the switch statement,
which makes for potentially jumpy stepping and introduces a large
number of statements repeating the line (tricky for inserting
breaks).  It also shared a single OBREAK node and this was not
really a syntax "tree".

This improves both the nostmt test (by 6 lines) and
reduces the total badness score from dwarf-goodness (by about 200).

Change-Id: I1f71b231a26f152bdb6ce9bc8f95828bb222f665
Reviewed-on: https://go-review.googlesource.com/c/go/+/188218
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
David Chase 2019-09-25 15:20:10 -04:00
parent f7f85bdc2c
commit 6139019efa

View File

@ -268,7 +268,6 @@ func walkExprSwitch(sw *Node) {
exprname: cond,
}
br := nod(OBREAK, nil, nil)
var defaultGoto *Node
var body Nodes
for _, ncase := range sw.List.Slice() {
@ -290,13 +289,17 @@ func walkExprSwitch(sw *Node) {
// Process body.
body.Append(npos(ncase.Pos, nodSym(OLABEL, nil, label)))
body.Append(ncase.Nbody.Slice()...)
if !hasFall(ncase.Nbody.Slice()) {
if fall, pos := hasFall(ncase.Nbody.Slice()); !fall {
br := nod(OBREAK, nil, nil)
br.Pos = pos
body.Append(br)
}
}
sw.List.Set(nil)
if defaultGoto == nil {
br := nod(OBREAK, nil, nil)
br.Pos = br.Pos.WithNotStmt()
defaultGoto = br
}
@ -469,7 +472,7 @@ func allCaseExprsAreSideEffectFree(sw *Node) bool {
}
// hasFall reports whether stmts ends with a "fallthrough" statement.
func hasFall(stmts []*Node) bool {
func hasFall(stmts []*Node) (bool, src.XPos) {
// Search backwards for the index of the fallthrough
// statement. Do not assume it'll be in the last
// position, since in some cases (e.g. when the statement
@ -480,7 +483,10 @@ func hasFall(stmts []*Node) bool {
for i >= 0 && stmts[i].Op == OVARKILL {
i--
}
return i >= 0 && stmts[i].Op == OFALL
if i < 0 {
return false, src.NoXPos
}
return stmts[i].Op == OFALL, stmts[i].Pos
}
// walkTypeSwitch generates an AST that implements sw, where sw is a