forked from gorgonia/gorgonia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanalysis.go
99 lines (80 loc) · 1.86 KB
/
analysis.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package gorgonia
import (
"bytes"
"fmt"
)
// dataflow analysis
type dataflow struct {
uniques map[uint32]*Node
replacements map[*Node]*Node
intervals map[*Node]*interval
}
func newdataflow() *dataflow {
df := new(dataflow)
df.uniques = make(map[uint32]*Node)
return df
}
// equivalent to the value numbering algorithm
// it returns true if it is unique
func (df *dataflow) vn(n *Node) (retVal *Node, unique bool) {
compileLogf("Value numbering")
enterLoggingContext()
defer leaveLoggingContext()
node, ok := df.uniques[n.Hashcode()]
if ok {
return node, false
}
compileLogf("adding a new unique")
// otherwise, add it to uniques, and then return itself
df.uniques[n.Hashcode()] = n
return n, true
}
func analyze(g *ExprGraph, sorted Nodes) *dataflow {
compileLogf("Performing dataflow analysis")
enterLoggingContext()
defer leaveLoggingContext()
compileLogf("Finding unique leaves")
df := newdataflow()
for _, n := range g.leaves {
df.uniques[n.Hashcode()] = n
}
compileLogf("Common subexpression elimination")
// common subexpression elimination
replacements := make(map[*Node]*Node)
var buf bytes.Buffer
for i := len(sorted) - 1; i >= 0; i-- {
n := sorted[i]
fmt.Fprintf(&buf, "%d, ", n.ID())
r, _ := df.vn(n)
replacements[n] = r
}
df.replacements = replacements
compileLogf("replacements: %+p", FmtNodeMap(replacements))
compileLogf("%v", buf.String())
// TODO
// constant propagation
/*
for _, node := range g.nodes {
n := node.(*Node)
if len(n.Children) > 0 {
allConst := true
for _, child := range n.Children {
if _, ok := child.Op.(constant); !ok {
allConst = false
break
}
}
}
}
*/
return df
}
func analyzeMem(g *ExprGraph, sorted Nodes) {
for _, node := range sorted {
switch {
case node.isArg():
case node.op.OverwritesInput() >= 0:
case node.op.ReturnsPtr():
}
}
}