mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[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:
parent
3e7904b648
commit
35fb514596
7 changed files with 607 additions and 45 deletions
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue