github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/cmd/internal/obj/inl.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package obj 6 7 import "cmd/internal/src" 8 9 // InlTree s a collection of inlined calls. The Parent field of an 10 // InlinedCall is the index of another InlinedCall in InlTree. 11 // 12 // The compiler maintains a global inlining tree and adds a node to it 13 // every time a function is inlined. For example, suppose f() calls g() 14 // and g has two calls to h(), and that f, g, and h are inlineable: 15 // 16 // 1 func main() { 17 // 2 f() 18 // 3 } 19 // 4 func f() { 20 // 5 g() 21 // 6 } 22 // 7 func g() { 23 // 8 h() 24 // 9 h() 25 // 10 } 26 // 27 // Assuming the global tree starts empty, inlining will produce the 28 // following tree: 29 // 30 // []InlinedCall{ 31 // {Parent: -1, Func: "f", Pos: <line 2>}, 32 // {Parent: 0, Func: "g", Pos: <line 5>}, 33 // {Parent: 1, Func: "h", Pos: <line 8>}, 34 // {Parent: 1, Func: "h", Pos: <line 9>}, 35 // } 36 // 37 // The nodes of h inlined into main will have inlining indexes 2 and 3. 38 // 39 // Eventually, the compiler extracts a per-function inlining tree from 40 // the global inlining tree (see pcln.go). 41 type InlTree struct { 42 nodes []InlinedCall 43 } 44 45 // InlinedCall is a node in an InlTree. 46 type InlinedCall struct { 47 Parent int // index of the parent in the InlTree or < 0 if outermost call 48 Pos src.XPos // position of the inlined call 49 Func *LSym // function that was inlined 50 } 51 52 // Add adds a new call to the tree, returning its index. 53 func (tree *InlTree) Add(parent int, pos src.XPos, func_ *LSym) int { 54 r := len(tree.nodes) 55 call := InlinedCall{ 56 Parent: parent, 57 Pos: pos, 58 Func: func_, 59 } 60 tree.nodes = append(tree.nodes, call) 61 return r 62 } 63 64 // OutermostPos returns the outermost position corresponding to xpos, 65 // which is where xpos was ultimately inlined to. In the example for 66 // InlTree, main() contains inlined AST nodes from h(), but the 67 // outermost position for those nodes is line 2. 68 func (ctxt *Link) OutermostPos(xpos src.XPos) src.Pos { 69 pos := ctxt.PosTable.Pos(xpos) 70 71 outerxpos := xpos 72 for ix := pos.Base().InliningIndex(); ix >= 0; { 73 call := ctxt.InlTree.nodes[ix] 74 ix = call.Parent 75 outerxpos = call.Pos 76 } 77 return ctxt.PosTable.Pos(outerxpos) 78 } 79 80 func dumpInlTree(ctxt *Link, tree InlTree) { 81 for i, call := range tree.nodes { 82 pos := ctxt.PosTable.Pos(call.Pos) 83 ctxt.Logf("%0d | %0d | %s (%s)\n", i, call.Parent, call.Func, pos) 84 } 85 }