From ffc4cc05f596a38c19f0d7e1ee91f17527ac3b37 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 8 May 2023 20:23:40 -0400 Subject: cmd/compile: standardize on outer-to-inner for pos lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The call sites that cared all reversed inner-to-outer to outer-to-inner already. The ones that didn't care left it alone. No one explicitly wanted inner-to-outer. Also change to a callback-based interface, so that call sites aren't required to accumulate the results in a slice (the main reason for that before was to reverse the slice!). There were three places where these lists were printed: 1. -d=ssa/genssa/dump, explicitly reversing to outer-to-inner 2. node dumps like -W, leaving the default inner-to-outer 3. file positions for HashDebugs, explicitly reversing to outer-to-inner It makes no sense that (1) and (2) would differ. The reason they do is that the code for (2) was too lazy to bother to fix it to be the right way. Consider this program: package p func f() { g() } func g() { println() } Both before and after this change, the ssa dump for f looks like: # x.go:3 00000 (3) TEXT .f(SB), ABIInternal 00001 (3) FUNCDATA $0, gclocals·g2BeySu+wFnoycgXfElmcg==(SB) 00002 (3) FUNCDATA $1, gclocals·g2BeySu+wFnoycgXfElmcg==(SB) v4 00003 (-4) XCHGL AX, AX # x.go:4 # x.go:8 v5 00004 (+8) PCDATA $1, $0 v5 00005 (+8) CALL runtime.printlock(SB) v7 00006 (-8) CALL runtime.printnl(SB) v9 00007 (-8) CALL runtime.printunlock(SB) # x.go:5 b2 00008 (5) RET 00009 (?) END Note # x.go:4 (f) then # x.go:8 (g, called from f) between v4 and v5. The -W node dumps used the opposite order: before walk f . AS2 Def tc(1) # x.go:4:3 . INLMARK # +x.go:4:3 . PRINTN tc(1) # x.go:8:9,x.go:4:3 . LABEL p..i0 # x.go:4:3 Now they match the ssa dump order, and they use spaces as separators, to avoid potential problems with commas in some editors. before walk f . AS2 Def tc(1) # x.go:4:3 . INLMARK # +x.go:4:3 . PRINTN tc(1) # x.go:4:3 x.go:8:9 . LABEL p..i0 # x.go:4:3 I'm unaware of any argument for the old order other than it was easier to compute without allocation. The new code uses recursion to reverse the order without allocation. Now that the callers get the results outer-to-inner, most don't need any slices at all. This change is particularly important for HashDebug, which had been using a locked temporary slice to walk the inline stack without allocation. Now the temporary slice is gone. Change-Id: I5cb6d76b2f950db67b248acc928e47a0460569f9 Reviewed-on: https://go-review.googlesource.com/c/go/+/493735 TryBot-Result: Gopher Robot Reviewed-by: David Chase Run-TryBot: Russ Cox --- src/cmd/internal/obj/inl.go | 23 ++++++++++++----------- src/cmd/internal/obj/util.go | 5 ----- 2 files changed, 12 insertions(+), 16 deletions(-) (limited to 'src/cmd/internal') diff --git a/src/cmd/internal/obj/inl.go b/src/cmd/internal/obj/inl.go index 934f1c2657..7a22eb1efd 100644 --- a/src/cmd/internal/obj/inl.go +++ b/src/cmd/internal/obj/inl.go @@ -108,20 +108,21 @@ func (ctxt *Link) InnermostPos(xpos src.XPos) src.Pos { return ctxt.PosTable.Pos(xpos) } -// AllPos returns a slice of the positions inlined at xpos, from -// innermost (index zero) to outermost. To avoid allocation -// the input slice is truncated, and used for the result, extended -// as necessary. -func (ctxt *Link) AllPos(xpos src.XPos, result []src.Pos) []src.Pos { +// AllPos invokes do with every position in the inlining call stack for xpos, +// from outermost to innermost. That is, xpos corresponds to f inlining g inlining h, +// AllPos invokes do with the position in f, then the position in g, then the position in h. +func (ctxt *Link) AllPos(xpos src.XPos, do func(src.Pos)) { pos := ctxt.InnermostPos(xpos) - result = result[:0] - result = append(result, ctxt.PosTable.Pos(xpos)) - for ix := pos.Base().InliningIndex(); ix >= 0; { + ctxt.forAllPos(pos.Base().InliningIndex(), do) + do(ctxt.PosTable.Pos(xpos)) +} + +func (ctxt *Link) forAllPos(ix int, do func(src.Pos)) { + if ix >= 0 { call := ctxt.InlTree.nodes[ix] - ix = call.Parent - result = append(result, ctxt.PosTable.Pos(call.Pos)) + ctxt.forAllPos(call.Parent, do) + do(ctxt.PosTable.Pos(call.Pos)) } - return result } func dumpInlTree(ctxt *Link, tree InlTree) { diff --git a/src/cmd/internal/obj/util.go b/src/cmd/internal/obj/util.go index 14b09f43d4..3a071c21d4 100644 --- a/src/cmd/internal/obj/util.go +++ b/src/cmd/internal/obj/util.go @@ -6,7 +6,6 @@ package obj import ( "bytes" - "cmd/internal/src" "fmt" "internal/abi" "internal/buildcfg" @@ -48,10 +47,6 @@ func (p *Prog) InnermostFilename() string { return pos.Filename() } -func (p *Prog) AllPos(result []src.Pos) []src.Pos { - return p.Ctxt.AllPos(p.Pos, result) -} - var armCondCode = []string{ ".EQ", ".NE", -- cgit v1.3