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