1
2
3
4
5 package ssa
6
7 import (
8 "bytes"
9 "crypto/sha256"
10 "fmt"
11 "io"
12 )
13
14 func printFunc(f *Func) {
15 f.Logf("%s", f)
16 }
17
18 func hashFunc(f *Func) []byte {
19 h := sha256.New()
20 p := stringFuncPrinter{w: h}
21 fprintFunc(p, f)
22 return h.Sum(nil)
23 }
24
25 func (f *Func) String() string {
26 var buf bytes.Buffer
27 p := stringFuncPrinter{w: &buf}
28 fprintFunc(p, f)
29 return buf.String()
30 }
31
32 type funcPrinter interface {
33 header(f *Func)
34 startBlock(b *Block, reachable bool)
35 endBlock(b *Block)
36 value(v *Value, live bool)
37 startDepCycle()
38 endDepCycle()
39 named(n LocalSlot, vals []*Value)
40 }
41
42 type stringFuncPrinter struct {
43 w io.Writer
44 }
45
46 func (p stringFuncPrinter) header(f *Func) {
47 fmt.Fprint(p.w, f.Name)
48 fmt.Fprint(p.w, " ")
49 fmt.Fprintln(p.w, f.Type)
50 }
51
52 func (p stringFuncPrinter) startBlock(b *Block, reachable bool) {
53 fmt.Fprintf(p.w, " b%d:", b.ID)
54 if len(b.Preds) > 0 {
55 io.WriteString(p.w, " <-")
56 for _, e := range b.Preds {
57 pred := e.b
58 fmt.Fprintf(p.w, " b%d", pred.ID)
59 }
60 }
61 if !reachable {
62 fmt.Fprint(p.w, " DEAD")
63 }
64 io.WriteString(p.w, "\n")
65 }
66
67 func (p stringFuncPrinter) endBlock(b *Block) {
68 fmt.Fprintln(p.w, " "+b.LongString())
69 }
70
71 func (p stringFuncPrinter) value(v *Value, live bool) {
72 fmt.Fprint(p.w, " ")
73
74
75 fmt.Fprint(p.w, v.LongString())
76 if !live {
77 fmt.Fprint(p.w, " DEAD")
78 }
79 fmt.Fprintln(p.w)
80 }
81
82 func (p stringFuncPrinter) startDepCycle() {
83 fmt.Fprintln(p.w, "dependency cycle!")
84 }
85
86 func (p stringFuncPrinter) endDepCycle() {}
87
88 func (p stringFuncPrinter) named(n LocalSlot, vals []*Value) {
89 fmt.Fprintf(p.w, "name %s: %v\n", n, vals)
90 }
91
92 func fprintFunc(p funcPrinter, f *Func) {
93 reachable, live := findlive(f)
94 defer f.retDeadcodeLive(live)
95 p.header(f)
96 printed := make([]bool, f.NumValues())
97 for _, b := range f.Blocks {
98 p.startBlock(b, reachable[b.ID])
99
100 if f.scheduled {
101
102 for _, v := range b.Values {
103 p.value(v, live[v.ID])
104 printed[v.ID] = true
105 }
106 p.endBlock(b)
107 continue
108 }
109
110
111 n := 0
112 for _, v := range b.Values {
113 if v.Op != OpPhi {
114 continue
115 }
116 p.value(v, live[v.ID])
117 printed[v.ID] = true
118 n++
119 }
120
121
122 for n < len(b.Values) {
123 m := n
124 outer:
125 for _, v := range b.Values {
126 if printed[v.ID] {
127 continue
128 }
129 for _, w := range v.Args {
130
131
132 if w != nil && w.Block == b && !printed[w.ID] {
133 continue outer
134 }
135 }
136 p.value(v, live[v.ID])
137 printed[v.ID] = true
138 n++
139 }
140 if m == n {
141 p.startDepCycle()
142 for _, v := range b.Values {
143 if printed[v.ID] {
144 continue
145 }
146 p.value(v, live[v.ID])
147 printed[v.ID] = true
148 n++
149 }
150 p.endDepCycle()
151 }
152 }
153
154 p.endBlock(b)
155 }
156 for _, name := range f.Names {
157 p.named(name, f.NamedValues[name])
158 }
159 }
160
View as plain text