diff options
author | Matthew Dempsky <mdempsky@google.com> | 2021-01-09 23:12:56 -0800 |
---|---|---|
committer | Matthew Dempsky <mdempsky@google.com> | 2021-01-12 02:16:30 +0000 |
commit | 106aa941dfda45d4aa5235b12317124aaf8941a0 (patch) | |
tree | 9977c0ca22451038ccfa37c449ca43e46ad12415 /src/cmd/compile/internal/noder/noder.go | |
parent | 6a56c6c870a2ac8bae9e570641521ba5aa83ba51 (diff) | |
download | go-106aa941dfda45d4aa5235b12317124aaf8941a0.tar.gz go-106aa941dfda45d4aa5235b12317124aaf8941a0.zip |
[dev.typeparams] cmd/compile: refactor DWARF scope marking
This CL extracts and simplifies noder's DWARF scope tracking code to
make it easier for reuse by irgen.
The previous code tried to be really clever about avoid recording
multiple scope boundaries at the same position (as happens at the end
of "if" and "for" statements). I had a really hard time remember how
this code worked exactly, so I've reimplemented a simpler algorithm
that just tracks all scope marks, and then compacts them at the end
before saving them to the ir.Func.
Passes toolstash -cmp.
Change-Id: Ibeb37997b77dc5179360d7db557c82ae1682e127
Reviewed-on: https://go-review.googlesource.com/c/go/+/282918
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Trust: Robert Griesemer <gri@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/noder/noder.go')
-rw-r--r-- | src/cmd/compile/internal/noder/noder.go | 79 |
1 files changed, 29 insertions, 50 deletions
diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go index b3f3c23c29..71a5df082b 100644 --- a/src/cmd/compile/internal/noder/noder.go +++ b/src/cmd/compile/internal/noder/noder.go @@ -19,6 +19,7 @@ import ( "unicode/utf8" "cmd/compile/internal/base" + "cmd/compile/internal/dwarfgen" "cmd/compile/internal/importer" "cmd/compile/internal/ir" "cmd/compile/internal/syntax" @@ -292,22 +293,17 @@ type noder struct { linknames []linkname pragcgobuf [][]string err chan syntax.Error - scope ir.ScopeID importedUnsafe bool importedEmbed bool + trackScopes bool - // scopeVars is a stack tracking the number of variables declared in the - // current function at the moment each open scope was opened. - trackScopes bool - scopeVars []int + funcState *funcState // typeInfo provides access to the type information computed by the new // typechecker. It is only present if -G is set, and all noders point to // the same types.Info. For now this is a local field, if need be we can // make it global. typeInfo *types2.Info - - lastCloseScopePos syntax.Pos } // For now we provide these basic accessors to get to type and object @@ -335,9 +331,20 @@ func (p *noder) sel(x *syntax.SelectorExpr) *types2.Selection { return p.typeInfo.Selections[x] } +// funcState tracks all per-function state to make handling nested +// functions easier. +type funcState struct { + // scopeVars is a stack tracking the number of variables declared in + // the current function at the moment each open scope was opened. + scopeVars []int + marker dwarfgen.ScopeMarker + + lastCloseScopePos syntax.Pos +} + func (p *noder) funcBody(fn *ir.Func, block *syntax.BlockStmt) { - oldScope := p.scope - p.scope = 0 + outerFuncState := p.funcState + p.funcState = new(funcState) typecheck.StartFuncBody(fn) if block != nil { @@ -352,62 +359,34 @@ func (p *noder) funcBody(fn *ir.Func, block *syntax.BlockStmt) { } typecheck.FinishFuncBody() - p.scope = oldScope + p.funcState.marker.WriteTo(fn) + p.funcState = outerFuncState } func (p *noder) openScope(pos syntax.Pos) { + fs := p.funcState types.Markdcl() if p.trackScopes { - ir.CurFunc.Parents = append(ir.CurFunc.Parents, p.scope) - p.scopeVars = append(p.scopeVars, len(ir.CurFunc.Dcl)) - p.scope = ir.ScopeID(len(ir.CurFunc.Parents)) - - p.markScope(pos) + fs.scopeVars = append(fs.scopeVars, len(ir.CurFunc.Dcl)) + fs.marker.Push(p.makeXPos(pos)) } } func (p *noder) closeScope(pos syntax.Pos) { - p.lastCloseScopePos = pos + fs := p.funcState + fs.lastCloseScopePos = pos types.Popdcl() if p.trackScopes { - scopeVars := p.scopeVars[len(p.scopeVars)-1] - p.scopeVars = p.scopeVars[:len(p.scopeVars)-1] + scopeVars := fs.scopeVars[len(fs.scopeVars)-1] + fs.scopeVars = fs.scopeVars[:len(fs.scopeVars)-1] if scopeVars == len(ir.CurFunc.Dcl) { // no variables were declared in this scope, so we can retract it. - - if int(p.scope) != len(ir.CurFunc.Parents) { - base.Fatalf("scope tracking inconsistency, no variables declared but scopes were not retracted") - } - - p.scope = ir.CurFunc.Parents[p.scope-1] - ir.CurFunc.Parents = ir.CurFunc.Parents[:len(ir.CurFunc.Parents)-1] - - nmarks := len(ir.CurFunc.Marks) - ir.CurFunc.Marks[nmarks-1].Scope = p.scope - prevScope := ir.ScopeID(0) - if nmarks >= 2 { - prevScope = ir.CurFunc.Marks[nmarks-2].Scope - } - if ir.CurFunc.Marks[nmarks-1].Scope == prevScope { - ir.CurFunc.Marks = ir.CurFunc.Marks[:nmarks-1] - } - return + fs.marker.Unpush() + } else { + fs.marker.Pop(p.makeXPos(pos)) } - - p.scope = ir.CurFunc.Parents[p.scope-1] - - p.markScope(pos) - } -} - -func (p *noder) markScope(pos syntax.Pos) { - xpos := p.makeXPos(pos) - if i := len(ir.CurFunc.Marks); i > 0 && ir.CurFunc.Marks[i-1].Pos == xpos { - ir.CurFunc.Marks[i-1].Scope = p.scope - } else { - ir.CurFunc.Marks = append(ir.CurFunc.Marks, ir.Mark{Pos: xpos, Scope: p.scope}) } } @@ -416,7 +395,7 @@ func (p *noder) markScope(pos syntax.Pos) { // "if" statements, as their implicit blocks always end at the same // position as an explicit block. func (p *noder) closeAnotherScope() { - p.closeScope(p.lastCloseScopePos) + p.closeScope(p.funcState.lastCloseScopePos) } // linkname records a //go:linkname directive. |