aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/ssa/print.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/ssa/print.go')
-rw-r--r--src/cmd/compile/internal/ssa/print.go52
1 files changed, 42 insertions, 10 deletions
diff --git a/src/cmd/compile/internal/ssa/print.go b/src/cmd/compile/internal/ssa/print.go
index d917183c70..96cd2c7c90 100644
--- a/src/cmd/compile/internal/ssa/print.go
+++ b/src/cmd/compile/internal/ssa/print.go
@@ -6,6 +6,7 @@ package ssa
import (
"bytes"
+ "cmd/internal/src"
"crypto/sha256"
"fmt"
"io"
@@ -17,22 +18,30 @@ func printFunc(f *Func) {
func hashFunc(f *Func) []byte {
h := sha256.New()
- p := stringFuncPrinter{w: h}
+ p := stringFuncPrinter{w: h, printDead: true}
fprintFunc(p, f)
return h.Sum(nil)
}
func (f *Func) String() string {
var buf bytes.Buffer
- p := stringFuncPrinter{w: &buf}
+ p := stringFuncPrinter{w: &buf, printDead: true}
fprintFunc(p, f)
return buf.String()
}
+// rewriteHash returns a hash of f suitable for detecting rewrite cycles.
+func (f *Func) rewriteHash() string {
+ h := sha256.New()
+ p := stringFuncPrinter{w: h, printDead: false}
+ fprintFunc(p, f)
+ return fmt.Sprintf("%x", h.Sum(nil))
+}
+
type funcPrinter interface {
header(f *Func)
startBlock(b *Block, reachable bool)
- endBlock(b *Block)
+ endBlock(b *Block, reachable bool)
value(v *Value, live bool)
startDepCycle()
endDepCycle()
@@ -40,7 +49,8 @@ type funcPrinter interface {
}
type stringFuncPrinter struct {
- w io.Writer
+ w io.Writer
+ printDead bool
}
func (p stringFuncPrinter) header(f *Func) {
@@ -50,6 +60,9 @@ func (p stringFuncPrinter) header(f *Func) {
}
func (p stringFuncPrinter) startBlock(b *Block, reachable bool) {
+ if !p.printDead && !reachable {
+ return
+ }
fmt.Fprintf(p.w, " b%d:", b.ID)
if len(b.Preds) > 0 {
io.WriteString(p.w, " <-")
@@ -64,14 +77,33 @@ func (p stringFuncPrinter) startBlock(b *Block, reachable bool) {
io.WriteString(p.w, "\n")
}
-func (p stringFuncPrinter) endBlock(b *Block) {
+func (p stringFuncPrinter) endBlock(b *Block, reachable bool) {
+ if !p.printDead && !reachable {
+ return
+ }
fmt.Fprintln(p.w, " "+b.LongString())
}
+func StmtString(p src.XPos) string {
+ linenumber := "(?) "
+ if p.IsKnown() {
+ pfx := ""
+ if p.IsStmt() == src.PosIsStmt {
+ pfx = "+"
+ }
+ if p.IsStmt() == src.PosNotStmt {
+ pfx = "-"
+ }
+ linenumber = fmt.Sprintf("(%s%d) ", pfx, p.Line())
+ }
+ return linenumber
+}
+
func (p stringFuncPrinter) value(v *Value, live bool) {
- fmt.Fprint(p.w, " ")
- //fmt.Fprint(p.w, v.Block.Func.fe.Pos(v.Pos))
- //fmt.Fprint(p.w, ": ")
+ if !p.printDead && !live {
+ return
+ }
+ fmt.Fprintf(p.w, " %s", StmtString(v.Pos))
fmt.Fprint(p.w, v.LongString())
if !live {
fmt.Fprint(p.w, " DEAD")
@@ -103,7 +135,7 @@ func fprintFunc(p funcPrinter, f *Func) {
p.value(v, live[v.ID])
printed[v.ID] = true
}
- p.endBlock(b)
+ p.endBlock(b, reachable[b.ID])
continue
}
@@ -151,7 +183,7 @@ func fprintFunc(p funcPrinter, f *Func) {
}
}
- p.endBlock(b)
+ p.endBlock(b, reachable[b.ID])
}
for _, name := range f.Names {
p.named(*name, f.NamedValues[*name])