[dev.ssa] cmd/compile: add HTML SSA printer
This is an initial implementation.
There are many rough edges and TODOs,
which will hopefully be polished out
with use.
Fixes #12071.
Change-Id: I1d6fd5a343063b5200623bceef2c2cfcc885794e
Reviewed-on: https://go-review.googlesource.com/13472
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/compile/internal/gc/ssa.go b/src/cmd/compile/internal/gc/ssa.go
index c8ec01f..882efc0 100644
--- a/src/cmd/compile/internal/gc/ssa.go
+++ b/src/cmd/compile/internal/gc/ssa.go
@@ -5,7 +5,9 @@
package gc
import (
+ "bytes"
"fmt"
+ "html"
"os"
"strings"
@@ -40,6 +42,18 @@
s.f = s.config.NewFunc()
s.f.Name = name
+ if name == os.Getenv("GOSSAFUNC") {
+ // TODO: tempfile? it is handy to have the location
+ // of this file be stable, so you can just reload in the browser.
+ s.config.HTML = ssa.NewHTMLWriter("ssa.html", &s, name)
+ // TODO: generate and print a mapping from nodes to values and blocks
+ }
+ defer func() {
+ if !usessa {
+ s.config.HTML.Close()
+ }
+ }()
+
// If SSA support for the function is incomplete,
// assume that any panics are due to violated
// invariants. Swallow them silently.
@@ -1811,6 +1825,30 @@
}
f.Logf("%s\t%s\n", s, p)
}
+ if f.Config.HTML != nil {
+ saved := ptxt.Ctxt.LineHist.PrintFilenameOnly
+ ptxt.Ctxt.LineHist.PrintFilenameOnly = true
+ var buf bytes.Buffer
+ buf.WriteString("<code>")
+ buf.WriteString("<dl class=\"ssa-gen\">")
+ for p := ptxt; p != nil; p = p.Link {
+ buf.WriteString("<dt class=\"ssa-prog-src\">")
+ if v, ok := valueProgs[p]; ok {
+ buf.WriteString(v.HTML())
+ } else if b, ok := blockProgs[p]; ok {
+ buf.WriteString(b.HTML())
+ }
+ buf.WriteString("</dt>")
+ buf.WriteString("<dd class=\"ssa-prog\">")
+ buf.WriteString(html.EscapeString(p.String()))
+ buf.WriteString("</dd>")
+ buf.WriteString("</li>")
+ }
+ buf.WriteString("</dl>")
+ buf.WriteString("</code>")
+ f.Config.HTML.WriteColumn("genssa", buf.String())
+ ptxt.Ctxt.LineHist.PrintFilenameOnly = saved
+ }
}
// Emit static data
@@ -1834,6 +1872,8 @@
ggloblsym(gcargs, 4, obj.RODATA|obj.DUPOK)
duint32(gclocals, 0, 0)
ggloblsym(gclocals, 4, obj.RODATA|obj.DUPOK)
+
+ f.Config.HTML.Close()
}
func genValue(v *ssa.Value) {