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, "") io.WriteString(w.w, "") w.w.Close() + fmt.Printf("dumped SSA to %v\n", w.path) } // WriteFunc writes f in a column headed by title.