aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/rewrite.go
diff options
context:
space:
mode:
authorThan McIntosh <thanm@google.com>2021-04-21 16:21:30 -0400
committerThan McIntosh <thanm@google.com>2021-04-26 14:55:26 +0000
commit00d42ffc895be17db72f195c1cf8f23be141a6fc (patch)
tree8a99392ec74b306fd72812efe213a1890d342ba8 /src/cmd/compile/internal/ssa/rewrite.go
parent70deaa33ebd91944484526ab368fa19c499ff29f (diff)
downloadgo-00d42ffc895be17db72f195c1cf8f23be141a6fc.tar.gz
go-00d42ffc895be17db72f195c1cf8f23be141a6fc.zip
cmd/compile: spos handling fixes to improve prolog debuggability
With the new register ABI, the compiler sometimes introduces spills of argument registers in function prologs; depending on the positions assigned to these spills and whether they have the IsStmt flag set, this can degrade the debugging experience. For example, in this function from one of the Delve regression tests: L13: func foo((eface interface{}) { L14: if eface != nil { L15: n++ L16: } L17 } we wind up with a prolog containing two spill instructions, the first with line 14, the second with line 13. The end result for the user is that if you set a breakpoint in foo and run to it, then do "step", execution will initially stop at L14, then jump "backwards" to L13. The root of the problem in this case is that an ArgIntReg pseudo-op is introduced during expand calls, then promoted (due to lowering) to a first-class statement (IsStmt flag set), which in turn causes downstream handling to propagate its position to the first of the register spills in the prolog. To help improve things, this patch changes the rewriter to avoid moving an "IsStmt" flag from a deleted/replaced instruction to an Arg{Int,Float}Reg value, and adds Arg{Int,Float}Reg to the list of opcodes not suitable for selection as statement boundaries, and suppresses generation of additional register spills in defframe() when optimization is disabled (since in that case things will get spilled in any case). This is not a comprehensive/complete fix; there are still cases where we get less-than-ideal source position markers (ex: issue 45680). Updates #40724. Change-Id: Ica8bba4940b2291bef6b5d95ff0cfd84412a2d40 Reviewed-on: https://go-review.googlesource.com/c/go/+/312989 Trust: Than McIntosh <thanm@google.com> Run-TryBot: Than McIntosh <thanm@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/ssa/rewrite.go')
-rw-r--r--src/cmd/compile/internal/ssa/rewrite.go2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/cmd/compile/internal/ssa/rewrite.go b/src/cmd/compile/internal/ssa/rewrite.go
index bdc4f799aa..375c4d5a56 100644
--- a/src/cmd/compile/internal/ssa/rewrite.go
+++ b/src/cmd/compile/internal/ssa/rewrite.go
@@ -159,7 +159,7 @@ func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValu
f.freeValue(v)
continue
}
- if v.Pos.IsStmt() != src.PosNotStmt && pendingLines.get(vl) == int32(b.ID) {
+ if v.Pos.IsStmt() != src.PosNotStmt && !notStmtBoundary(v.Op) && pendingLines.get(vl) == int32(b.ID) {
pendingLines.remove(vl)
v.Pos = v.Pos.WithIsStmt()
}