Skip to content

Commit 01a1eaa

Browse files
committed
cmd/compile: use innermost line number for -S
When functions are inlined, for instructions in the inlined body, does -S print the location of the call, or the location of the body? Right now, we do the former. I'd like to do the latter by default, it makes much more sense when reading disassembly. With mid-stack inlining enabled in more cases, this quandry will come up more often. The original behavior is still available with -S=2. Some tests use this mode (so they can find assembly generated by a particular source line). This helped me with understanding what the compiler was doing while fixing #29007. Change-Id: Id14a3a41e1b18901e7c5e460aa4caf6d940ed064 Reviewed-on: https://go-review.googlesource.com/c/153241 Reviewed-by: David Chase <drchase@google.com>
1 parent ec51004 commit 01a1eaa

File tree

8 files changed

+40
-21
lines changed

8 files changed

+40
-21
lines changed

src/cmd/asm/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func main() {
3636

3737
ctxt := obj.Linknew(architecture.LinkArch)
3838
if *flags.PrintOut {
39-
ctxt.Debugasm = true
39+
ctxt.Debugasm = 1
4040
}
4141
ctxt.Flag_dynlink = *flags.Dynlink
4242
ctxt.Flag_shared = *flags.Shared || *flags.Dynlink

src/cmd/compile/internal/gc/global_test.go

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"bytes"
99
"internal/testenv"
1010
"io/ioutil"
11-
"log"
1211
"os"
1312
"os/exec"
1413
"path/filepath"
@@ -24,15 +23,15 @@ func TestScanfRemoval(t *testing.T) {
2423
// Make a directory to work in.
2524
dir, err := ioutil.TempDir("", "issue6853a-")
2625
if err != nil {
27-
log.Fatalf("could not create directory: %v", err)
26+
t.Fatalf("could not create directory: %v", err)
2827
}
2928
defer os.RemoveAll(dir)
3029

3130
// Create source.
3231
src := filepath.Join(dir, "test.go")
3332
f, err := os.Create(src)
3433
if err != nil {
35-
log.Fatalf("could not create source file: %v", err)
34+
t.Fatalf("could not create source file: %v", err)
3635
}
3736
f.Write([]byte(`
3837
package main
@@ -50,17 +49,17 @@ func main() {
5049
cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", dst, src)
5150
out, err := cmd.CombinedOutput()
5251
if err != nil {
53-
log.Fatalf("could not build target: %v", err)
52+
t.Fatalf("could not build target: %v", err)
5453
}
5554

5655
// Check destination to see if scanf code was included.
5756
cmd = exec.Command(testenv.GoToolPath(t), "tool", "nm", dst)
5857
out, err = cmd.CombinedOutput()
5958
if err != nil {
60-
log.Fatalf("could not read target: %v", err)
59+
t.Fatalf("could not read target: %v", err)
6160
}
6261
if bytes.Contains(out, []byte("scanInt")) {
63-
log.Fatalf("scanf code not removed from helloworld")
62+
t.Fatalf("scanf code not removed from helloworld")
6463
}
6564
}
6665

@@ -71,15 +70,15 @@ func TestDashS(t *testing.T) {
7170
// Make a directory to work in.
7271
dir, err := ioutil.TempDir("", "issue14515-")
7372
if err != nil {
74-
log.Fatalf("could not create directory: %v", err)
73+
t.Fatalf("could not create directory: %v", err)
7574
}
7675
defer os.RemoveAll(dir)
7776

7877
// Create source.
7978
src := filepath.Join(dir, "test.go")
8079
f, err := os.Create(src)
8180
if err != nil {
82-
log.Fatalf("could not create source file: %v", err)
81+
t.Fatalf("could not create source file: %v", err)
8382
}
8483
f.Write([]byte(`
8584
package main
@@ -94,7 +93,7 @@ func main() {
9493
cmd := exec.Command(testenv.GoToolPath(t), "build", "-gcflags", "-S", "-o", filepath.Join(dir, "test"), src)
9594
out, err := cmd.CombinedOutput()
9695
if err != nil {
97-
log.Fatalf("could not build target: %v", err)
96+
t.Fatalf("could not build target: %v", err)
9897
}
9998

10099
patterns := []string{

src/cmd/compile/internal/gc/main.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ var (
3939

4040
var (
4141
Debug_append int
42-
Debug_asm bool
4342
Debug_closure int
4443
Debug_compilelater int
4544
debug_dclstack int
@@ -195,7 +194,7 @@ func Main(archInit func(*Arch)) {
195194
objabi.Flagcount("K", "debug missing line numbers", &Debug['K'])
196195
objabi.Flagcount("L", "show full file names in error messages", &Debug['L'])
197196
objabi.Flagcount("N", "disable optimizations", &Debug['N'])
198-
flag.BoolVar(&Debug_asm, "S", false, "print assembly listing")
197+
objabi.Flagcount("S", "print assembly listing", &Debug['S'])
199198
objabi.AddVersionFlag() // -V
200199
objabi.Flagcount("W", "debug parse tree after type checking", &Debug['W'])
201200
flag.StringVar(&asmhdr, "asmhdr", "", "write assembly header to `file`")
@@ -265,7 +264,7 @@ func Main(archInit func(*Arch)) {
265264
Ctxt.Flag_dynlink = flag_dynlink
266265
Ctxt.Flag_optimize = Debug['N'] == 0
267266

268-
Ctxt.Debugasm = Debug_asm
267+
Ctxt.Debugasm = Debug['S']
269268
Ctxt.Debugvlog = Debug_vlog
270269
if flagDWARF {
271270
Ctxt.DebugInfo = debuginfo
@@ -1330,6 +1329,7 @@ var concurrentFlagOK = [256]bool{
13301329
'l': true, // disable inlining
13311330
'w': true, // all printing happens before compilation
13321331
'W': true, // all printing happens before compilation
1332+
'S': true, // printing disassembly happens at the end (but see concurrentBackendAllowed below)
13331333
}
13341334

13351335
func concurrentBackendAllowed() bool {
@@ -1338,9 +1338,9 @@ func concurrentBackendAllowed() bool {
13381338
return false
13391339
}
13401340
}
1341-
// Debug_asm by itself is ok, because all printing occurs
1341+
// Debug['S'] by itself is ok, because all printing occurs
13421342
// while writing the object file, and that is non-concurrent.
1343-
// Adding Debug_vlog, however, causes Debug_asm to also print
1343+
// Adding Debug_vlog, however, causes Debug['S'] to also print
13441344
// while flushing the plist, which happens concurrently.
13451345
if Debug_vlog || debugstr != "" || debuglive > 0 {
13461346
return false

src/cmd/internal/obj/link.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ type Pcdata struct {
599599
type Link struct {
600600
Headtype objabi.HeadType
601601
Arch *LinkArch
602-
Debugasm bool
602+
Debugasm int
603603
Debugvlog bool
604604
Debugpcln string
605605
Flag_shared bool

src/cmd/internal/obj/objfile.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,13 @@ func (w *objWriter) writeSymDebug(s *LSym) {
240240
fmt.Fprintf(ctxt.Bso, "\n")
241241
if s.Type == objabi.STEXT {
242242
for p := s.Func.Text; p != nil; p = p.Link {
243-
fmt.Fprintf(ctxt.Bso, "\t%#04x %v\n", uint(int(p.Pc)), p)
243+
var s string
244+
if ctxt.Debugasm > 1 {
245+
s = p.String()
246+
} else {
247+
s = p.InnermostString()
248+
}
249+
fmt.Fprintf(ctxt.Bso, "\t%#04x %s\n", uint(int(p.Pc)), s)
244250
}
245251
}
246252
for i := 0; i < len(s.P); i += 16 {
@@ -283,7 +289,7 @@ func (w *objWriter) writeSymDebug(s *LSym) {
283289

284290
func (w *objWriter) writeSym(s *LSym) {
285291
ctxt := w.ctxt
286-
if ctxt.Debugasm {
292+
if ctxt.Debugasm > 0 {
287293
w.writeSymDebug(s)
288294
}
289295

src/cmd/internal/obj/plist.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc, myimportpath string
2727

2828
var plink *Prog
2929
for p := plist.Firstpc; p != nil; p = plink {
30-
if ctxt.Debugasm && ctxt.Debugvlog {
30+
if ctxt.Debugasm > 0 && ctxt.Debugvlog {
3131
fmt.Printf("obj: %v\n", p)
3232
}
3333
plink = p.Link

src/cmd/internal/obj/util.go

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ const REG_NONE = 0
1717
func (p *Prog) Line() string {
1818
return p.Ctxt.OutermostPos(p.Pos).Format(false, true)
1919
}
20+
func (p *Prog) InnermostLine() string {
21+
return p.Ctxt.InnermostPos(p.Pos).Format(false, true)
22+
}
2023

2124
// InnermostLineNumber returns a string containing the line number for the
2225
// innermost inlined function (if any inlining) at p's position
@@ -118,6 +121,16 @@ func (p *Prog) String() string {
118121
return fmt.Sprintf("%.5d (%v)\t%s", p.Pc, p.Line(), p.InstructionString())
119122
}
120123

124+
func (p *Prog) InnermostString() string {
125+
if p == nil {
126+
return "<nil Prog>"
127+
}
128+
if p.Ctxt == nil {
129+
return "<Prog without ctxt>"
130+
}
131+
return fmt.Sprintf("%.5d (%v)\t%s", p.Pc, p.InnermostLine(), p.InstructionString())
132+
}
133+
121134
// InstructionString returns a string representation of the instruction without preceding
122135
// program counter or file and line number.
123136
func (p *Prog) InstructionString() string {
@@ -177,7 +190,7 @@ func (ctxt *Link) NewProg() *Prog {
177190
}
178191

179192
func (ctxt *Link) CanReuseProgs() bool {
180-
return !ctxt.Debugasm
193+
return ctxt.Debugasm == 0
181194
}
182195

183196
func Dconv(p *Prog, a *Addr) string {

test/run.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -642,7 +642,8 @@ func (t *test) run() {
642642
// against a set of regexps in comments.
643643
ops := t.wantedAsmOpcodes(long)
644644
for _, env := range ops.Envs() {
645-
cmdline := []string{"build", "-gcflags", "-S"}
645+
// -S=2 forces outermost line numbers when disassembling inlined code.
646+
cmdline := []string{"build", "-gcflags", "-S=2"}
646647
cmdline = append(cmdline, flags...)
647648
cmdline = append(cmdline, long)
648649
cmd := exec.Command(goTool(), cmdline...)

0 commit comments

Comments
 (0)