]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: add flag for debugging PC-value tables
authorDavid Lazar <lazard@golang.org>
Fri, 17 Feb 2017 21:55:40 +0000 (16:55 -0500)
committerDavid Lazar <lazard@golang.org>
Fri, 3 Mar 2017 21:29:38 +0000 (21:29 +0000)
For example, `-d pctab=pctoinline` prints the PC-inline table and
inlining tree for every function.

Change-Id: Ia6b9ce4d83eed0b494318d40ffe06481ec5d58ab
Reviewed-on: https://go-review.googlesource.com/37235
Run-TryBot: David Lazar <lazard@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
src/cmd/compile/internal/gc/main.go
src/cmd/internal/obj/inl.go
src/cmd/internal/obj/link.go
src/cmd/internal/obj/pcln.go

index e9c80c514433b75d4b897c0693697d2591cbf82b..490ac7db406e12059626f0dfea6f9ce64dd01ceb 100644 (file)
@@ -37,6 +37,7 @@ var (
        Debug_panic    int
        Debug_slice    int
        Debug_wb       int
+       Debug_pctab    string
 )
 
 // Debug arguments.
@@ -59,6 +60,7 @@ var debugtab = []struct {
        {"typeassert", &Debug_typeassert}, // print information about type assertion inlining
        {"wb", &Debug_wb},                 // print information about write barriers
        {"export", &Debug_export},         // print export data
+       {"pctab", &Debug_pctab},           // print named pc-value table
 }
 
 func usage() {
@@ -319,6 +321,9 @@ func Main() {
                }
        }
 
+       // set via a -d flag
+       Ctxt.Debugpcln = Debug_pctab
+
        // enable inlining.  for now:
        //      default: inlining on.  (debug['l'] == 1)
        //      -l: inlining off  (debug['l'] == 0)
index f5e06959a25fc426b7528a3d99d8d1d9f518c192..116921995a97d5e92bf61d1f411ce21c078a9a0a 100644 (file)
@@ -76,3 +76,10 @@ func (ctxt *Link) OutermostPos(xpos src.XPos) src.Pos {
        }
        return ctxt.PosTable.Pos(outerxpos)
 }
+
+func dumpInlTree(ctxt *Link, tree InlTree) {
+       for i, call := range tree.nodes {
+               pos := ctxt.PosTable.Pos(call.Pos)
+               ctxt.Logf("%0d | %0d | %s (%s)\n", i, call.Parent, call.Func, pos)
+       }
+}
index 9de26a5a032561700530f83627e2af01da8ec92f..83a1f4cfbfb5a8c966230dbc3e28c511dea3083f 100644 (file)
@@ -716,7 +716,7 @@ type Link struct {
        Debugasm      int32
        Debugvlog     int32
        Debugdivmod   int32
-       Debugpcln     int32
+       Debugpcln     string
        Flag_shared   bool
        Flag_dynlink  bool
        Flag_optimize bool
index 8db7802d0cc983b16ccd0b2648a978b8ae6add8a..44be031dceb804366423529944fab0cec35cab5d 100644 (file)
@@ -24,31 +24,23 @@ func addvarint(d *Pcdata, v uint32) {
 // where func is the function, val is the current value, p is the instruction being
 // considered, and arg can be used to further parameterize valfunc.
 func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*Link, *LSym, int32, *Prog, int32, interface{}) int32, arg interface{}) {
-       // To debug a specific function, uncomment lines and change name.
-       dbg := 0
-
-       //if func_.Name == "main.main" || desc == "pctospadj" {
-       //      dbg = 1
-       //}
-
-       ctxt.Debugpcln += int32(dbg)
+       dbg := desc == ctxt.Debugpcln
 
        dst.P = dst.P[:0]
 
-       if ctxt.Debugpcln != 0 {
+       if dbg {
                ctxt.Logf("funcpctab %s [valfunc=%s]\n", func_.Name, desc)
        }
 
        val := int32(-1)
        oldval := val
        if func_.Text == nil {
-               ctxt.Debugpcln -= int32(dbg)
                return
        }
 
        pc := func_.Text.Pc
 
-       if ctxt.Debugpcln != 0 {
+       if dbg {
                ctxt.Logf("%6x %6d %v\n", uint64(pc), val, func_.Text)
        }
 
@@ -60,7 +52,7 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
 
                if val == oldval && started != 0 {
                        val = valfunc(ctxt, func_, val, p, 1, arg)
-                       if ctxt.Debugpcln != 0 {
+                       if dbg {
                                ctxt.Logf("%6x %6s %v\n", uint64(p.Pc), "", p)
                        }
                        continue
@@ -72,7 +64,7 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
                // for a true instruction boundary in the program.
                if p.Link != nil && p.Link.Pc == p.Pc {
                        val = valfunc(ctxt, func_, val, p, 1, arg)
-                       if ctxt.Debugpcln != 0 {
+                       if dbg {
                                ctxt.Logf("%6x %6s %v\n", uint64(p.Pc), "", p)
                        }
                        continue
@@ -92,7 +84,7 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
                // as variable-length little-endian base-128 integers,
                // where the 0x80 bit indicates that the integer continues.
 
-               if ctxt.Debugpcln != 0 {
+               if dbg {
                        ctxt.Logf("%6x %6d %v\n", uint64(p.Pc), val, p)
                }
 
@@ -114,22 +106,20 @@ func funcpctab(ctxt *Link, dst *Pcdata, func_ *LSym, desc string, valfunc func(*
        }
 
        if started != 0 {
-               if ctxt.Debugpcln != 0 {
+               if dbg {
                        ctxt.Logf("%6x done\n", uint64(func_.Text.Pc+func_.Size))
                }
                addvarint(dst, uint32((func_.Size-pc)/int64(ctxt.Arch.MinLC)))
                addvarint(dst, 0) // terminator
        }
 
-       if ctxt.Debugpcln != 0 {
+       if dbg {
                ctxt.Logf("wrote %d bytes to %p\n", len(dst.P), dst)
                for i := 0; i < len(dst.P); i++ {
                        ctxt.Logf(" %02x", dst.P[i])
                }
                ctxt.Logf("\n")
        }
-
-       ctxt.Debugpcln -= int32(dbg)
 }
 
 // pctofileline computes either the file number (arg == 0)
@@ -297,6 +287,11 @@ func linkpcln(ctxt *Link, cursym *LSym) {
        pcinlineState := new(pcinlineState)
        funcpctab(ctxt, &pcln.Pcinline, cursym, "pctoinline", pcinlineState.pctoinline, nil)
        pcln.InlTree = pcinlineState.localTree
+       if ctxt.Debugpcln == "pctoinline" && len(pcln.InlTree.nodes) > 0 {
+               ctxt.Logf("-- inlining tree for %s:\n", cursym)
+               dumpInlTree(ctxt, pcln.InlTree)
+               ctxt.Logf("--\n")
+       }
 
        // tabulate which pc and func data we have.
        havepc := make([]uint32, (npcdata+31)/32)