Commit 6139019e authored by David Chase's avatar David Chase

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