diff --git a/src/cmd/compile/internal/gc/main.go b/src/cmd/compile/internal/gc/main.go
index 5d074114ec..44cf75e7c9 100644
--- a/src/cmd/compile/internal/gc/main.go
+++ b/src/cmd/compile/internal/gc/main.go
@@ -428,6 +428,10 @@ func Main(archInit func(*Arch)) {
}
ssaDump = os.Getenv("GOSSAFUNC")
+ if strings.HasSuffix(ssaDump, "+") {
+ ssaDump = ssaDump[:len(ssaDump)-1]
+ ssaDumpStdout = true
+ }
trackScopes = flagDWARF
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index cabcf17ed1..2abd9448d4 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -23,7 +23,8 @@ import (
var ssaConfig *ssa.Config
var ssaCaches []ssa.Cache
-var ssaDump string // early copy of $GOSSAFUNC; the func name to dump output for
+var ssaDump string // early copy of $GOSSAFUNC; the func name to dump output for
+var ssaDumpStdout bool // whether to dump to stdout
const ssaDumpFile = "ssa.html"
func initssaconfig() {
@@ -125,7 +126,7 @@ func buildssa(fn *Node, worker int) *ssa.Func {
fe := ssafn{
curfn: fn,
- log: printssa,
+ log: printssa && ssaDumpStdout,
}
s.curfn = fn
@@ -4873,7 +4874,8 @@ func genssa(f *ssa.Func, pp *Progs) {
var progToBlock map[*obj.Prog]*ssa.Block
var valueToProgAfter []*obj.Prog // The first Prog following computation of a value v; v is visible at this point.
var logProgs = e.log
- if logProgs {
+ if f.HTMLWriter != nil {
+ // logProgs can be false, meaning that we do not dump to the Stdout.
progToValue = make(map[*obj.Prog]*ssa.Value, f.NumValues())
progToBlock = make(map[*obj.Prog]*ssa.Block, f.NumBlocks())
f.Logf("genssa %s\n", f.Name)
@@ -5042,42 +5044,36 @@ func genssa(f *ssa.Func, pp *Progs) {
}
f.Logf(" %-6s\t%.5d (%s)\t%s\n", s, p.Pc, p.InnermostLineNumber(), p.InstructionString())
}
- if f.HTMLWriter != nil {
- // LineHist is defunct now - this code won't do
- // anything.
- // TODO: fix this (ideally without a global variable)
- // saved := pp.Text.Ctxt.LineHist.PrintFilenameOnly
- // pp.Text.Ctxt.LineHist.PrintFilenameOnly = true
- var buf bytes.Buffer
- buf.WriteString("")
- buf.WriteString("")
- filename := ""
- for p := pp.Text; p != nil; p = p.Link {
- // Don't spam every line with the file name, which is often huge.
- // Only print changes, and "unknown" is not a change.
- if p.Pos.IsKnown() && p.InnermostFilename() != filename {
- filename = p.InnermostFilename()
- buf.WriteString("- ")
- buf.WriteString(html.EscapeString("# " + filename))
- buf.WriteString("
")
- }
-
- buf.WriteString("- ")
- if v, ok := progToValue[p]; ok {
- buf.WriteString(v.HTML())
- } else if b, ok := progToBlock[p]; ok {
- buf.WriteString("" + b.HTML() + "")
- }
- buf.WriteString("
")
- buf.WriteString("- ")
- buf.WriteString(fmt.Sprintf("%.5d (%s) %s", p.Pc, p.InnermostLineNumber(), p.InnermostLineNumberHTML(), html.EscapeString(p.InstructionString())))
+ }
+ if f.HTMLWriter != nil {
+ var buf bytes.Buffer
+ buf.WriteString("
")
+ buf.WriteString("")
+ filename := ""
+ for p := pp.Text; p != nil; p = p.Link {
+ // Don't spam every line with the file name, which is often huge.
+ // Only print changes, and "unknown" is not a change.
+ if p.Pos.IsKnown() && p.InnermostFilename() != filename {
+ filename = p.InnermostFilename()
+ buf.WriteString("- ")
+ buf.WriteString(html.EscapeString("# " + filename))
buf.WriteString("
")
}
- buf.WriteString("
")
- buf.WriteString("")
- f.HTMLWriter.WriteColumn("genssa", "genssa", "ssa-prog", buf.String())
- // pp.Text.Ctxt.LineHist.PrintFilenameOnly = saved
+
+ buf.WriteString(" - ")
+ if v, ok := progToValue[p]; ok {
+ buf.WriteString(v.HTML())
+ } else if b, ok := progToBlock[p]; ok {
+ buf.WriteString("" + b.HTML() + "")
+ }
+ buf.WriteString("
")
+ buf.WriteString("- ")
+ buf.WriteString(fmt.Sprintf("%.5d (%s) %s", p.Pc, p.InnermostLineNumber(), p.InnermostLineNumberHTML(), html.EscapeString(p.InstructionString())))
+ buf.WriteString("
")
}
+ buf.WriteString("
")
+ buf.WriteString("")
+ f.HTMLWriter.WriteColumn("genssa", "genssa", "ssa-prog", buf.String())
}
defframe(&s, e)
@@ -5435,7 +5431,7 @@ type ssafn struct {
scratchFpMem *Node // temp for floating point register / memory moves on some architectures
stksize int64 // stack size for current frame
stkptrsize int64 // prefix of stack containing pointers
- log bool
+ log bool // print ssa debug to the stdout
}
// StringData returns a symbol (a *types.Sym wrapped in an interface) which
diff --git a/src/cmd/compile/internal/ssa/compile.go b/src/cmd/compile/internal/ssa/compile.go
index 7f75dc4a03..8b5d6d94e8 100644
--- a/src/cmd/compile/internal/ssa/compile.go
+++ b/src/cmd/compile/internal/ssa/compile.go
@@ -42,7 +42,9 @@ func Compile(f *Func) {
}()
// Run all the passes
- printFunc(f)
+ if f.Log() {
+ printFunc(f)
+ }
f.HTMLWriter.WriteFunc("start", "start", f)
if BuildDump != "" && BuildDump == f.Name {
f.dumpFile("build")
@@ -84,8 +86,10 @@ func Compile(f *Func) {
stats = fmt.Sprintf("[%d ns]", time)
}
- f.Logf(" pass %s end %s\n", p.name, stats)
- printFunc(f)
+ if f.Log() {
+ f.Logf(" pass %s end %s\n", p.name, stats)
+ printFunc(f)
+ }
f.HTMLWriter.WriteFunc(phaseName, fmt.Sprintf("%s %s", phaseName, stats), f)
}
if p.time || p.mem {
diff --git a/src/cmd/compile/internal/ssa/html.go b/src/cmd/compile/internal/ssa/html.go
index 8125909349..2e48e8105b 100644
--- a/src/cmd/compile/internal/ssa/html.go
+++ b/src/cmd/compile/internal/ssa/html.go
@@ -11,12 +11,14 @@ import (
"html"
"io"
"os"
+ "path/filepath"
"strings"
)
type HTMLWriter struct {
Logger
- w io.WriteCloser
+ w io.WriteCloser
+ path string
}
func NewHTMLWriter(path string, logger Logger, funcname string) *HTMLWriter {
@@ -24,7 +26,11 @@ func NewHTMLWriter(path string, logger Logger, funcname string) *HTMLWriter {
if err != nil {
logger.Fatalf(src.NoXPos, "%v", err)
}
- html := HTMLWriter{w: out, Logger: logger}
+ pwd, err := os.Getwd()
+ if err != nil {
+ logger.Fatalf(src.NoXPos, "%v", err)
+ }
+ html := HTMLWriter{w: out, Logger: logger, path: filepath.Join(pwd, path)}
html.start(funcname)
return &html
}
@@ -439,6 +445,7 @@ func (w *HTMLWriter) Close() {
io.WriteString(w.w, "