[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>
This commit is contained in:
Josh Bleecher Snyder 2015-08-10 12:15:52 -07:00
parent 3e7904b648
commit 35fb514596
7 changed files with 607 additions and 45 deletions

View file

@ -16,33 +16,77 @@ func printFunc(f *Func) {
func (f *Func) String() string {
var buf bytes.Buffer
fprintFunc(&buf, f)
p := stringFuncPrinter{w: &buf}
fprintFunc(p, f)
return buf.String()
}
func fprintFunc(w io.Writer, f *Func) {
fmt.Fprint(w, f.Name)
fmt.Fprint(w, " ")
fmt.Fprintln(w, f.Type)
type funcPrinter interface {
header(f *Func)
startBlock(b *Block, reachable bool)
endBlock(b *Block)
value(v *Value, live bool)
startDepCycle()
endDepCycle()
}
type stringFuncPrinter struct {
w io.Writer
}
func (p stringFuncPrinter) header(f *Func) {
fmt.Fprint(p.w, f.Name)
fmt.Fprint(p.w, " ")
fmt.Fprintln(p.w, f.Type)
}
func (p stringFuncPrinter) startBlock(b *Block, reachable bool) {
fmt.Fprintf(p.w, " b%d:", b.ID)
if len(b.Preds) > 0 {
io.WriteString(p.w, " <-")
for _, pred := range b.Preds {
fmt.Fprintf(p.w, " b%d", pred.ID)
}
}
if !reachable {
fmt.Fprint(p.w, " DEAD")
}
io.WriteString(p.w, "\n")
}
func (p stringFuncPrinter) endBlock(b *Block) {
fmt.Fprintln(p.w, " "+b.LongString())
}
func (p stringFuncPrinter) value(v *Value, live bool) {
fmt.Fprint(p.w, " ")
fmt.Fprint(p.w, v.LongString())
if !live {
fmt.Fprint(p.w, " DEAD")
}
fmt.Fprintln(p.w)
}
func (p stringFuncPrinter) startDepCycle() {
fmt.Fprintln(p.w, "dependency cycle!")
}
func (p stringFuncPrinter) endDepCycle() {}
func fprintFunc(p funcPrinter, f *Func) {
reachable, live := findlive(f)
p.header(f)
printed := make([]bool, f.NumValues())
for _, b := range f.Blocks {
fmt.Fprintf(w, " b%d:", b.ID)
if len(b.Preds) > 0 {
io.WriteString(w, " <-")
for _, pred := range b.Preds {
fmt.Fprintf(w, " b%d", pred.ID)
}
}
io.WriteString(w, "\n")
p.startBlock(b, reachable[b.ID])
if f.scheduled {
// Order of Values has been decided - print in that order.
for _, v := range b.Values {
fmt.Fprint(w, " ")
fmt.Fprintln(w, v.LongString())
p.value(v, live[v.ID])
printed[v.ID] = true
}
fmt.Fprintln(w, " "+b.LongString())
p.endBlock(b)
continue
}
@ -52,8 +96,7 @@ func fprintFunc(w io.Writer, f *Func) {
if v.Op != OpPhi {
continue
}
fmt.Fprint(w, " ")
fmt.Fprintln(w, v.LongString())
p.value(v, live[v.ID])
printed[v.ID] = true
n++
}
@ -73,25 +116,24 @@ func fprintFunc(w io.Writer, f *Func) {
continue outer
}
}
fmt.Fprint(w, " ")
fmt.Fprintln(w, v.LongString())
p.value(v, live[v.ID])
printed[v.ID] = true
n++
}
if m == n {
fmt.Fprintln(w, "dependency cycle!")
p.startDepCycle()
for _, v := range b.Values {
if printed[v.ID] {
continue
}
fmt.Fprint(w, " ")
fmt.Fprintln(w, v.LongString())
p.value(v, live[v.ID])
printed[v.ID] = true
n++
}
p.endDepCycle()
}
}
fmt.Fprintln(w, " "+b.LongString())
p.endBlock(b)
}
}