diff options
author | David Chase <drchase@google.com> | 2021-09-09 16:34:02 -0400 |
---|---|---|
committer | David Chase <drchase@google.com> | 2021-09-20 19:36:41 +0000 |
commit | af72ddfcd7826df9aefb2207b8ac270bb91fea2f (patch) | |
tree | 02ab2c2d431013722bce686d8147eb483fc80ef1 /src/cmd/compile/internal/ssa/compile.go | |
parent | 3c764babe7b5e01a4e04b1a2c7975cdb5c5651a0 (diff) | |
download | go-af72ddfcd7826df9aefb2207b8ac270bb91fea2f.tar.gz go-af72ddfcd7826df9aefb2207b8ac270bb91fea2f.zip |
cmd/compile: extend dump-to-file to handle "genssa" (asm) case.
Extend the existing dump-to-file to also do assembly output
to make it easier to write debug-information tests that check
for line-numbering in particular orders.
Includes POC test (which is silent w/o -v):
go test -v -run TestDebugLines cmd/compile/internal/ssa
=== RUN TestDebugLines
Preserving temporary directory /var/folders/v6/xyzzy/T/debug_lines_test321
About to run (cd /var/folders/v6/xyzzy/T/debug_lines_test321; \
GOSSADIR=/var/folders/v6/xyzzy/T/debug_lines_test321 \
/Users/drchase/work/go/bin/go build -o foo.o \
'-gcflags=-N -l -d=ssa/genssa/dump=sayhi' \
/Users/drchase/work/go/src/cmd/compile/internal/ssa/testdata/sayhi.go )
Saw stmt# 8 for submatch '8' on dump line #7 = ' v107 00005 (+8) MOVQ AX, "".n(SP)'
Saw stmt# 9 for submatch '9' on dump line #9 = ' v87 00007 (+9) MOVUPS X15, ""..autotmp_2-32(SP)'
Saw stmt# 10 for submatch '10' on dump line #46 = ' v65 00044 (+10) MOVUPS X15, ""..autotmp_2-32(SP)'
Saw stmt# 11 for submatch '11' on dump line #83 = ' v131 00081 (+11) MOVQ "".wg+8(SP), AX'
--- PASS: TestDebugLines (4.95s)
PASS
ok cmd/compile/internal/ssa 5.685s
Includes a test to ensure that inlining information is printed correctly.
Updates #47880.
Change-Id: I83b596476a88687d71d5b65dbb94641a576d747e
Reviewed-on: https://go-review.googlesource.com/c/go/+/348970
Trust: David Chase <drchase@google.com>
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/ssa/compile.go')
-rw-r--r-- | src/cmd/compile/internal/ssa/compile.go | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go index cd8eba405d..f87ea5b893 100644 --- a/src/cmd/compile/internal/ssa/compile.go +++ b/src/cmd/compile/internal/ssa/compile.go @@ -10,9 +10,11 @@ import ( "fmt" "hash/crc32" "internal/buildcfg" + "io" "log" "math/rand" "os" + "path/filepath" "regexp" "runtime" "sort" @@ -59,7 +61,7 @@ func Compile(f *Func) { printFunc(f) } f.HTMLWriter.WritePhase("start", "start") - if BuildDump != "" && BuildDump == f.Name { + if BuildDump[f.Name] { f.dumpFile("build") } if checkEnabled { @@ -163,25 +165,37 @@ func Compile(f *Func) { phaseName = "" } -// dumpFile creates a file from the phase name and function name -// Dumping is done to files to avoid buffering huge strings before -// output. -func (f *Func) dumpFile(phaseName string) { +// DumpFileForPhase creates a file from the function name and phase name, +// warning and returning nil if this is not possible. +func (f *Func) DumpFileForPhase(phaseName string) io.WriteCloser { f.dumpFileSeq++ fname := fmt.Sprintf("%s_%02d__%s.dump", f.Name, int(f.dumpFileSeq), phaseName) fname = strings.Replace(fname, " ", "_", -1) fname = strings.Replace(fname, "/", "_", -1) fname = strings.Replace(fname, ":", "_", -1) + if ssaDir := os.Getenv("GOSSADIR"); ssaDir != "" { + fname = filepath.Join(ssaDir, fname) + } + fi, err := os.Create(fname) if err != nil { f.Warnl(src.NoXPos, "Unable to create after-phase dump file %s", fname) - return + return nil } + return fi +} - p := stringFuncPrinter{w: fi} - fprintFunc(p, f) - fi.Close() +// dumpFile creates a file from the phase name and function name +// Dumping is done to files to avoid buffering huge strings before +// output. +func (f *Func) dumpFile(phaseName string) { + fi := f.DumpFileForPhase(phaseName) + if fi != nil { + p := stringFuncPrinter{w: fi} + fprintFunc(p, f) + fi.Close() + } } type pass struct { @@ -224,7 +238,9 @@ var IntrinsicsDisable bool var BuildDebug int var BuildTest int var BuildStats int -var BuildDump string // name of function to dump after initial build of ssa +var BuildDump map[string]bool = make(map[string]bool) // names of functions to dump after initial build of ssa + +var GenssaDump map[string]bool = make(map[string]bool) // names of functions to dump after ssa has been converted to asm // PhaseOption sets the specified flag in the specified ssa phase, // returning empty string if this was successful or a string explaining @@ -248,7 +264,7 @@ func PhaseOption(phase, flag string, val int, valString string) string { switch phase { case "", "help": lastcr := 0 - phasenames := " check, all, build, intrinsics" + phasenames := " check, all, build, intrinsics, genssa" for _, p := range passes { pn := strings.Replace(p.name, " ", "_", -1) if len(pn)+len(phasenames)-lastcr > 70 { @@ -278,6 +294,7 @@ where: Phase "all" supports flags "time", "mem", and "dump". Phase "intrinsics" supports flags "on", "off", and "debug". +Phase "genssa" (assembly generation) supports the flag "dump". If the "dump" flag is specified, the output is written on a file named <phase>__<function_name>_<seq>.dump; otherwise it is directed to stdout. @@ -339,10 +356,11 @@ commas. For example: case "dump": alldump = val != 0 if alldump { - BuildDump = valString + BuildDump[valString] = true + GenssaDump[valString] = true } default: - return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option", flag, phase) + return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option (expected ssa/all/{time,mem,dump=function_name})", flag, phase) } } @@ -355,7 +373,7 @@ commas. For example: case "debug": IntrinsicsDebug = val default: - return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option", flag, phase) + return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option (expected ssa/intrinsics/{on,off,debug})", flag, phase) } return "" } @@ -368,9 +386,18 @@ commas. For example: case "stats": BuildStats = val case "dump": - BuildDump = valString + BuildDump[valString] = true + default: + return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option (expected ssa/build/{debug,test,stats,dump=function_name})", flag, phase) + } + return "" + } + if phase == "genssa" { + switch flag { + case "dump": + GenssaDump[valString] = true default: - return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option", flag, phase) + return fmt.Sprintf("Did not find a flag matching %s in -d=ssa/%s debug option (expected ssa/genssa/dump=function_name)", flag, phase) } return "" } |