aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/compile.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/ssa/compile.go')
-rw-r--r--src/cmd/compile/internal/ssa/compile.go59
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 cd8eba405d5..f87ea5b893e 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 ""
}