seafoam 0.6 → 0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/bgv2isabelle +1 -5
- data/bin/bgv2json +1 -5
- data/bin/cfg2asm +1 -5
- data/bin/seafoam +1 -5
- data/lib/seafoam/bgv/bgv_parser.rb +10 -2
- data/lib/seafoam/commands.rb +107 -32
- data/lib/seafoam/graal/pi.rb +18 -0
- data/lib/seafoam/graph.rb +33 -1
- data/lib/seafoam/graphviz_writer.rb +24 -2
- data/lib/seafoam/json_writer.rb +1 -3
- data/lib/seafoam/{annotators → passes}/fallback.rb +4 -4
- data/lib/seafoam/{annotators → passes}/graal.rb +43 -15
- data/lib/seafoam/passes/truffle.rb +58 -0
- data/lib/seafoam/passes.rb +61 -0
- data/lib/seafoam/version.rb +1 -1
- data/lib/seafoam.rb +5 -4
- metadata +26 -62
- data/.github/probots.yml +0 -2
- data/.github/workflows/workflows.yml +0 -39
- data/.gitignore +0 -7
- data/.rubocop.yml +0 -37
- data/.ruby-version +0 -1
- data/.seafoam/config +0 -1
- data/CODE_OF_CONDUCT.md +0 -128
- data/CONTRIBUTING.md +0 -5
- data/Gemfile +0 -2
- data/LICENSE.md +0 -7
- data/README.md +0 -378
- data/demos/box-unbox-stats +0 -65
- data/docs/annotators.md +0 -43
- data/docs/bgv.md +0 -293
- data/docs/getting-graphs.md +0 -59
- data/docs/images/igv.png +0 -0
- data/docs/images/seafoam.png +0 -0
- data/docs/images/spotlight-igv.png +0 -0
- data/docs/images/spotlight-seafoam.png +0 -0
- data/docs/json.md +0 -35
- data/examples/Fib.java +0 -24
- data/examples/MatMult.java +0 -39
- data/examples/fib-java.bgv.gz +0 -0
- data/examples/fib.js +0 -15
- data/examples/fib.rb +0 -15
- data/examples/identity.rb +0 -13
- data/examples/java/Irreducible.class +0 -0
- data/examples/java/Irreducible.j +0 -35
- data/examples/java/IrreducibleDecompiled.java +0 -21
- data/examples/java/JavaExamples.java +0 -418
- data/examples/matmult.rb +0 -29
- data/examples/overflow.rb +0 -13
- data/examples/ruby/clamps.rb +0 -20
- data/examples/ruby/graal.patch +0 -15
- data/examples/ruby/ruby_examples.rb +0 -278
- data/lib/seafoam/annotators.rb +0 -54
- data/lib/seafoam/config.rb +0 -34
- data/seafoam.gemspec +0 -21
- data/spec/seafoam/annotators/fallback_spec.rb +0 -69
- data/spec/seafoam/annotators/graal_spec.rb +0 -96
- data/spec/seafoam/annotators_spec.rb +0 -61
- data/spec/seafoam/bgv/bgv_parser_spec.rb +0 -157
- data/spec/seafoam/binary/io_binary_reader_spec.rb +0 -176
- data/spec/seafoam/cfg/cfg_parser_spec.rb +0 -21
- data/spec/seafoam/cfg/disassembler_spec.rb +0 -32
- data/spec/seafoam/command_spec.rb +0 -316
- data/spec/seafoam/graph_spec.rb +0 -172
- data/spec/seafoam/graphviz_writer_spec.rb +0 -63
- data/spec/seafoam/json_writer_spec.rb +0 -14
- data/spec/seafoam/spec_helpers.rb +0 -34
- data/spec/seafoam/spotlight_spec.rb +0 -38
- data/tools/render-all +0 -36
data/README.md
DELETED
@@ -1,378 +0,0 @@
|
|
1
|
-
# Seafoam
|
2
|
-
|
3
|
-
*Seafoam* is a tool for working with compiler graphs. It's designed primarily
|
4
|
-
for working with the graph files dumped by the GraalVM compiler, such as in
|
5
|
-
TruffleRuby, but it could be used with other compilers and graph dump file
|
6
|
-
formats.
|
7
|
-
|
8
|
-
The *Ideal Graph Visualizer*, or *IGV*, is the tool usually used to work with
|
9
|
-
GraalVM compiler graphs. Seafoam aims to solve several problems with IGV. Unlike
|
10
|
-
IGV, Seafoam:
|
11
|
-
|
12
|
-
* is open source and can be used according to the MIT license
|
13
|
-
* supports gzip-compressed BGV files
|
14
|
-
* is able to some extent seek BGV files to load specific graphs without loading the rest of the file
|
15
|
-
* has a command-line interface
|
16
|
-
* can be used as a library
|
17
|
-
* has easy PDF, SVG, PNG and JSON output
|
18
|
-
* is designed for accessibility
|
19
|
-
* looks prettier, in our opinion
|
20
|
-
|
21
|
-
Additionally, Seafoam adds:
|
22
|
-
|
23
|
-
* support for disassembling CFG files
|
24
|
-
|
25
|
-
Admittedly, Seafoam does not yet have:
|
26
|
-
|
27
|
-
* an interactive user interface
|
28
|
-
* diffing of graphs
|
29
|
-
* visualization of basic blocks
|
30
|
-
* breaking of edges for very congested graphs
|
31
|
-
* the same speed in rendering big graphs - Seafoam is best suited for looking at graphs before lowering, which is what language developers are usually doing, or use spotlight
|
32
|
-
|
33
|
-
## Seafoam compared to IGV
|
34
|
-
|
35
|
-
<p>
|
36
|
-
<img src="docs/images/seafoam.png" width="350">
|
37
|
-
<img src="docs/images/igv.png" width="350">
|
38
|
-
</p>
|
39
|
-
|
40
|
-
## Installation
|
41
|
-
|
42
|
-
### macOS
|
43
|
-
|
44
|
-
```
|
45
|
-
% brew install graphviz
|
46
|
-
% gem install seafoam
|
47
|
-
% seafoam --version
|
48
|
-
seafoam 0.1
|
49
|
-
```
|
50
|
-
|
51
|
-
### Ubuntu
|
52
|
-
|
53
|
-
```
|
54
|
-
% sudo apt-get install ruby graphviz
|
55
|
-
% gem install seafoam
|
56
|
-
% seafoam --version
|
57
|
-
seafoam 0.1
|
58
|
-
```
|
59
|
-
|
60
|
-
### RedHat
|
61
|
-
|
62
|
-
```
|
63
|
-
% sudo yum install ruby graphviz
|
64
|
-
% gem install seafoam
|
65
|
-
% seafoam --version
|
66
|
-
seafoam 0.1
|
67
|
-
```
|
68
|
-
|
69
|
-
### Capstone
|
70
|
-
|
71
|
-
To use the `cfg2asm` disassembler, you'll then need to install Capstone.
|
72
|
-
|
73
|
-
```
|
74
|
-
% brew install capstone # macOS
|
75
|
-
% sudo apt-get install libcapstone3 # Ubuntu
|
76
|
-
```
|
77
|
-
|
78
|
-
## Quick-start demo
|
79
|
-
|
80
|
-
```
|
81
|
-
% seafoam examples/fib-java.bgv:0 render
|
82
|
-
```
|
83
|
-
|
84
|
-
## Getting compiler graphs
|
85
|
-
|
86
|
-
If you are just experimenting, there are example graphs such as
|
87
|
-
`examples/fib-java.bgv`.
|
88
|
-
|
89
|
-
This is just a quick summary - see more information on
|
90
|
-
[getting graphs out of compilers](docs/getting-graphs.md).
|
91
|
-
|
92
|
-
### GraalVM for Java
|
93
|
-
|
94
|
-
```
|
95
|
-
% javac Fib.java
|
96
|
-
% java -XX:CompileOnly=::fib -Dgraal.Dump=:2 Fib 14
|
97
|
-
```
|
98
|
-
|
99
|
-
### GraalVM Native Image
|
100
|
-
|
101
|
-
```
|
102
|
-
% native-image -H:Dump=:2 -H:MethodFilter=fib Fib
|
103
|
-
```
|
104
|
-
|
105
|
-
### TruffleRuby and other Truffle languages
|
106
|
-
|
107
|
-
```
|
108
|
-
% ruby --experimental-options --engine.CompileOnly=fib --engine.Inlining=false --engine.OSR=false --vm.Dgraal.Dump=Truffle:2 fib.rb 14
|
109
|
-
```
|
110
|
-
|
111
|
-
You will usually want to look at the *After TruffleTier* graph.
|
112
|
-
|
113
|
-
## Name syntax
|
114
|
-
|
115
|
-
When using a command-line interface, Seafoam refers to
|
116
|
-
`file.bgv[:graph][:node[-edge]]`, where `file.bgv` is a file, `graph` is a graph
|
117
|
-
index, `node` is a node index, and `to` is another node index to form an edge
|
118
|
-
from `node` to another node `edge`.
|
119
|
-
|
120
|
-
Note that a *graph ID* is an ID found in BGV files, but is not unique. A
|
121
|
-
*graph index* is what we use in names, and is unique.
|
122
|
-
|
123
|
-
## Use cases
|
124
|
-
|
125
|
-
#### Print information about a file
|
126
|
-
|
127
|
-
```
|
128
|
-
% seafoam examples/fib-java.bgv info
|
129
|
-
BGV 6.1
|
130
|
-
```
|
131
|
-
|
132
|
-
#### List graphs in a file
|
133
|
-
|
134
|
-
```
|
135
|
-
% seafoam examples/fib-java.bgv list
|
136
|
-
examples/fib-java.bgv:0 2:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhase
|
137
|
-
examples/fib-java.bgv:1 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.PhaseSuite
|
138
|
-
examples/fib-java.bgv:2 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.DeadCodeEliminationPhase
|
139
|
-
examples/fib-java.bgv:3 2:Fib.fib(int)/After parsing
|
140
|
-
examples/fib-java.bgv:4 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.CanonicalizerPhase
|
141
|
-
examples/fib-java.bgv:5 2:Fib.fib(int)/After phase org.graalvm.compiler.phases.common.inlining.InliningPhase
|
142
|
-
...
|
143
|
-
```
|
144
|
-
|
145
|
-
#### Search for strings in a graph, or node or edge within a graph
|
146
|
-
|
147
|
-
```
|
148
|
-
% seafoam examples/fib-java.bgv:0 search Start
|
149
|
-
examples/fib-java.bgv:0:0 ...node_class":"org.graalvm.compiler.nodes.StartNode","name_template":"Start","inputs":[...
|
150
|
-
examples/fib-java.bgv:0:0 ...piler.nodes.StartNode","name_template":"Start","inputs":[{"direct":true,"name":"state...
|
151
|
-
```
|
152
|
-
|
153
|
-
#### Print edges of a graph, or node or edge within a graph
|
154
|
-
|
155
|
-
```
|
156
|
-
% seafoam examples/fib-java.bgv:0 edges
|
157
|
-
22 nodes, 30 edges
|
158
|
-
% seafoam examples/fib-java.bgv:0:13 edges
|
159
|
-
Input:
|
160
|
-
13 (Call Fib.fib) <-() 6 (Begin)
|
161
|
-
13 (Call Fib.fib) <-() 14 (@{:declaring_class=>"Fib", :method_name=>"fib", :signature=>{:args=>["I"], :ret=>"I"}, :modifiers=>9}:13)
|
162
|
-
13 (Call Fib.fib) <-() 12 (MethodCallTarget)
|
163
|
-
Output:
|
164
|
-
13 (Call Fib.fib) ->() 18 (Call Fib.fib)
|
165
|
-
13 (Call Fib.fib) ->(values) 14 (@{:declaring_class=>"Fib", :method_name=>"fib", :signature=>{:args=>["I"], :ret=>"I"}, :modifiers=>9}:13)
|
166
|
-
13 (Call Fib.fib) ->(values) 19 (@{:declaring_class=>"Fib", :method_name=>"fib", :signature=>{:args=>["I"], :ret=>"I"}, :modifiers=>9}:19)
|
167
|
-
13 (Call Fib.fib) ->(x) 20 (+)
|
168
|
-
% seafoam examples/fib-java.bgv:0:13-20 edges
|
169
|
-
13 (Call Fib.fib) ->(x) 20 (+)
|
170
|
-
```
|
171
|
-
|
172
|
-
#### Print properties of a file, graph, or node or edge within a graph
|
173
|
-
|
174
|
-
```
|
175
|
-
% seafoam examples/fib-java.bgv:0 props
|
176
|
-
{
|
177
|
-
"group": [
|
178
|
-
{
|
179
|
-
"name": "2:Fib.fib(int)",
|
180
|
-
"short_name": "2:Fib.fib(int)",
|
181
|
-
"method": null,
|
182
|
-
...
|
183
|
-
% seafoam examples/fib-java.bgv:0:13 props
|
184
|
-
{
|
185
|
-
"nodeSourcePosition": {
|
186
|
-
"method": {
|
187
|
-
"declaring_class": "Fib",
|
188
|
-
"method_name": "fib",
|
189
|
-
"signature": {
|
190
|
-
...
|
191
|
-
% seafoam examples/fib-java.bgv:0:13-20 props
|
192
|
-
{
|
193
|
-
"direct": true,
|
194
|
-
"name": "x",
|
195
|
-
"type": "Value"
|
196
|
-
}
|
197
|
-
```
|
198
|
-
|
199
|
-
#### Print node source information
|
200
|
-
|
201
|
-
```
|
202
|
-
% seafoam examples/fib-ruby.bgv:8:2443 source
|
203
|
-
java.lang.Math#addExact
|
204
|
-
org.truffleruby.core.numeric.IntegerNodes$AddNode#add
|
205
|
-
org.truffleruby.core.numeric.IntegerNodesFactory$AddNodeFactory$AddNodeGen#executeAdd
|
206
|
-
org.truffleruby.core.inlined.InlinedAddNode#intAdd
|
207
|
-
org.truffleruby.core.inlined.InlinedAddNodeGen#execute
|
208
|
-
org.truffleruby.language.control.IfElseNode#execute
|
209
|
-
org.truffleruby.language.control.SequenceNode#execute
|
210
|
-
org.truffleruby.language.arguments.CheckArityNode#execute
|
211
|
-
org.truffleruby.language.control.SequenceNode#execute
|
212
|
-
org.truffleruby.language.methods.CatchForMethodNode#execute
|
213
|
-
org.truffleruby.language.methods.ExceptionTranslatingNode#execute
|
214
|
-
org.truffleruby.language.RubyRootNode#execute
|
215
|
-
org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#executeRootNode
|
216
|
-
org.graalvm.compiler.truffle.runtime.OptimizedCallTarget#profiledPERoot
|
217
|
-
```
|
218
|
-
|
219
|
-
#### Render a graph
|
220
|
-
|
221
|
-
Render a graph as a PDF image and have it opened automatically.
|
222
|
-
|
223
|
-
```
|
224
|
-
% seafoam examples/fib-java.bgv:0 render
|
225
|
-
```
|
226
|
-
|
227
|
-
Render a graph showing just a few nodes and those surrounding them, similar to
|
228
|
-
the IGV feature of gradually revealing nodes.
|
229
|
-
|
230
|
-
```
|
231
|
-
% seafoam examples/fib-java.bgv:0 render --spotlight 13,20
|
232
|
-
```
|
233
|
-
|
234
|
-
<p>
|
235
|
-
<img src="docs/images/spotlight-seafoam.png" width="200">
|
236
|
-
<img src="docs/images/spotlight-igv.png" width="350">
|
237
|
-
</p>
|
238
|
-
|
239
|
-
`render` supports these options:
|
240
|
-
|
241
|
-
* `--out filename.pdf` or `.pdf`, `.svg`, `.png`, `.dot`
|
242
|
-
* `--option key value` for custom annotators
|
243
|
-
|
244
|
-
#### Convert a file
|
245
|
-
|
246
|
-
Convert a BGV file to the Isabelle graph format.
|
247
|
-
|
248
|
-
```
|
249
|
-
% bgv2isabelle examples/fib-java.bgv
|
250
|
-
graph0 = # 2:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhase
|
251
|
-
(add_node 0 StartNode [2] [8]
|
252
|
-
(add_node 1 (ParameterNode 0) [] [2, 5, 9, 11, 14, 16]
|
253
|
-
(add_node 2 FrameState [1] [0]
|
254
|
-
(add_node 3 (ConstantNode 1) [] []
|
255
|
-
(add_node 4 (ConstantNode 2) [] [5]
|
256
|
-
(add_node 5 IntegerLessThanNode [1, 4] [8]
|
257
|
-
(add_node 6 BeginNode [8] [13]
|
258
|
-
(add_node 7 BeginNode [8] [9]
|
259
|
-
(add_node 8 IfNode [0, 5] [7, 6]
|
260
|
-
...
|
261
|
-
```
|
262
|
-
|
263
|
-
Convert a BGV file to JSON.
|
264
|
-
|
265
|
-
```
|
266
|
-
% bgv2json examples/fib-java.bgv
|
267
|
-
graph0 = # 2:Fib.fib(int)/After phase org.graalvm.compiler.java.GraphBuilderPhase
|
268
|
-
(add_node 0 StartNode [2] [8]
|
269
|
-
(add_node 1 (ParameterNode 0) [] [2, 5, 9, 11, 14, 16]
|
270
|
-
(add_node 2 FrameState [1] [0]
|
271
|
-
(add_node 3 (ConstantNode 1) [] []
|
272
|
-
(add_node 4 (ConstantNode 2) [] [5]
|
273
|
-
(add_node 5 IntegerLessThanNode [1, 4] [8]
|
274
|
-
(add_node 6 BeginNode [8] [13]
|
275
|
-
(add_node 7 BeginNode [8] [9]
|
276
|
-
(add_node 8 IfNode [0, 5] [7, 6]
|
277
|
-
...
|
278
|
-
```
|
279
|
-
|
280
|
-
#### Disassembling
|
281
|
-
|
282
|
-
```
|
283
|
-
% cfg2asm examples/java/exampleArithOperator.cfg
|
284
|
-
[examples/java/exampleArithOperator.cfg]
|
285
|
-
;Comment 0: 3
|
286
|
-
;Comment 0: 1
|
287
|
-
0x112e2f660: nop dword ptr [rax + rax]
|
288
|
-
;Comment 5: block B0 null
|
289
|
-
;Comment 5: 0 [rsi|DWORD, rdx|DWORD, rbp|QWORD] = LABEL numbPhis: 0 align: false label: ?
|
290
|
-
;Comment 5: 4 [] = HOTSPOTLOCKSTACK frameMapBuilder: org.graalvm.compiler.lir.amd64.AMD64FrameMapBuilder@143082de0 slotKind: QWORD
|
291
|
-
;Comment 5: 10 rsi|DWORD = ADD (x: rsi|DWORD, y: rdx|DWORD) size: DWORD
|
292
|
-
0x112e2f665: add esi, edx
|
293
|
-
;Comment 7: 12 rax|DWORD = MOVE rsi|DWORD moveKind: DWORD
|
294
|
-
0x112e2f667: mov eax, esi
|
295
|
-
;Comment 9: 14 RETURN (savedRbp: rbp|QWORD, value: rax|DWORD) isStub: false requiresReservedStackAccessCheck: false thread: r15 scratchForSafepointOnReturn: rcx config: org.graalvm.compiler.hotspot.GraalHotSpotVMConfig@137f187d8
|
296
|
-
;Comment 9: 12
|
297
|
-
0x112e2f669: test dword ptr [rip - 0x46c4669], eax
|
298
|
-
0x112e2f66f: vzeroupper
|
299
|
-
0x112e2f672: ret
|
300
|
-
...
|
301
|
-
```
|
302
|
-
|
303
|
-
## Options for GraalVM graphs
|
304
|
-
|
305
|
-
* `--show-frame-state` shows frame state nodes, which are hidden by default
|
306
|
-
* `--hide-floating` hides nodes that aren't fixed by control flow
|
307
|
-
* `--no-reduce-edges` turns off the option to reduce the number of edges by inlining simple nodes above their users
|
308
|
-
|
309
|
-
## Configuration
|
310
|
-
|
311
|
-
Seafoam loads and runs a Ruby script called `~/.seafoam/config` in the first
|
312
|
-
directory it finds starting with the current working directory and moving up.
|
313
|
-
You can require or configure extra [annotators](docs/annotators.md) in this
|
314
|
-
file.
|
315
|
-
|
316
|
-
## Debugging
|
317
|
-
|
318
|
-
Exception backtraces are printed if `$DEBUG` (`-d`) is set.
|
319
|
-
|
320
|
-
Use `seafoam file.bgv debug` to debug file parsing.
|
321
|
-
|
322
|
-
## More documentation
|
323
|
-
|
324
|
-
* [Graph annotators](docs/annotators.md)
|
325
|
-
* [Details of the BGV file format](docs/bgv.md)
|
326
|
-
* [How to get graphs from various compilers](docs/getting-graphs.md)
|
327
|
-
|
328
|
-
## Frequently asked questions
|
329
|
-
|
330
|
-
#### Why is it called *Seafoam*?
|
331
|
-
|
332
|
-
GraalVM graphs are *seas of nodes*. Seafoam is a shade of green, and Seafoam was
|
333
|
-
written at Shopify, which has green as a brand colour. Graphs can sometimes be
|
334
|
-
very complicated, appearing like a foam without any structure - Seafoam tries to
|
335
|
-
help you make sense of it all.
|
336
|
-
|
337
|
-
#### What do you mean by *graphs*, and *seas* or *soups* of nodes?
|
338
|
-
|
339
|
-
Graphs, as in edges and nodes, are the data structure some compilers use to
|
340
|
-
represent your program while they're compiling it. It's a form of *intermediate
|
341
|
-
representation*. Graphs are how the compiler understands the programs and if the
|
342
|
-
compiler isn't doing what you want you need to look at the graph and make sense
|
343
|
-
of it. Some graphs are loosely structured and large, making them like a sea or
|
344
|
-
soup of nodes.
|
345
|
-
|
346
|
-
#### Doesn't *reduce edges* actually introduce more edges?
|
347
|
-
|
348
|
-
Yes, but they're shorter edges, and it achieves the intended effect of less
|
349
|
-
edges crossing over the graph.
|
350
|
-
|
351
|
-
## Related work
|
352
|
-
|
353
|
-
The graph layout algorithm we use, via Graphviz, is
|
354
|
-
|
355
|
-
* E. R. Gansner, et al, [*A Technique for Drawing Directed Graphs*](http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.3.8982), IEEE Transactions on Software Engineering, 1993
|
356
|
-
|
357
|
-
IGV is the existing tool for working with Graal graphs. It uses a *hierarchical*
|
358
|
-
layout algorithm, rather than the *force directed* algorithm we use when we use
|
359
|
-
Graphviz. It's based on the NetBeans IDE platform. It's related to the *C1
|
360
|
-
Visualiser*, for control-flow graphs. The C1 Visualiser can also be used with
|
361
|
-
Graal as the backend of Graal is similar enough to C1. IGV is closed-source and
|
362
|
-
available under a proprietary licence.
|
363
|
-
|
364
|
-
* T. Würthinger, [*Visualization of Program Dependence Graphs*](http://www.ssw.uni-linz.ac.at/Research/Papers/Wuerthinger07Master/), Master Thesis, Linz 2007
|
365
|
-
* T. Würthinger, [*Visualization of Java Control Flow Graphs*](http://www.ssw.uni-linz.ac.at/General/Staff/TW/Wuerthinger06Bachelor.pdf), Bachelor Thesis, Linz 2006
|
366
|
-
|
367
|
-
[*Turbolizer*][turbolizer] is a similar tool for the intermediate representation
|
368
|
-
in the V8 JavaScript compiler.
|
369
|
-
|
370
|
-
[turbolizer]: https://github.com/v8/v8/blob/4b9b23521e6fd42373ebbcb20ebe03bf445494f9/tools/turbolizer
|
371
|
-
|
372
|
-
## Author
|
373
|
-
|
374
|
-
Seafoam was written by Chris Seaton at Shopify, chris.seaton@shopify.com.
|
375
|
-
|
376
|
-
## License
|
377
|
-
|
378
|
-
MIT
|
data/demos/box-unbox-stats
DELETED
@@ -1,65 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
# This demo analyses a directory full of graphs and looks for how many box nodes
|
4
|
-
# take their value directly from an unbox node.
|
5
|
-
|
6
|
-
require 'seafoam'
|
7
|
-
|
8
|
-
box_nodes_count = 0
|
9
|
-
box_nodes_from_unbox_count = 0
|
10
|
-
|
11
|
-
graph_count = 0
|
12
|
-
graph_match_count = 0
|
13
|
-
|
14
|
-
ARGV.each do |dir|
|
15
|
-
Dir.glob(['*.bgv', '*.bgv.gz'], base: dir) do |file|
|
16
|
-
parser = Seafoam::BGV::BGVParser.new(File.join(dir, file))
|
17
|
-
parser.read_file_header
|
18
|
-
parser.skip_document_props
|
19
|
-
|
20
|
-
loop do
|
21
|
-
index, = parser.read_graph_preheader
|
22
|
-
break unless index
|
23
|
-
|
24
|
-
parser.skip_graph_header
|
25
|
-
graph = parser.read_graph
|
26
|
-
|
27
|
-
contains_box_unbox = false
|
28
|
-
|
29
|
-
graph.nodes.each_value do |node|
|
30
|
-
next unless node.props.dig(:node_class, :node_class).start_with?('org.graalvm.compiler.nodes.extended.BoxNode')
|
31
|
-
|
32
|
-
box_node = node
|
33
|
-
box_nodes_count += 1
|
34
|
-
value_edge = node.edges.find { |e| e.props[:name] == 'value' }
|
35
|
-
raise unless value_edge
|
36
|
-
|
37
|
-
value_node = value_edge.from
|
38
|
-
next unless value_node.props.dig(:node_class, :node_class).start_with?('org.graalvm.compiler.nodes.extended.UnboxNode')
|
39
|
-
|
40
|
-
unbox_node = value_node
|
41
|
-
box_nodes_from_unbox_count += 1
|
42
|
-
contains_box_unbox = true
|
43
|
-
puts "seafoam '#{File.join(dir, file)}:#{index}' render --spotlight #{box_node.id},#{unbox_node.id}"
|
44
|
-
end
|
45
|
-
|
46
|
-
graph_count += 1
|
47
|
-
graph_match_count += 1 if contains_box_unbox
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
if box_nodes_count.positive?
|
53
|
-
box_nodes_percent = (box_nodes_from_unbox_count / box_nodes_count.to_f) * 100
|
54
|
-
else
|
55
|
-
box_nodes_percent = 0.0
|
56
|
-
end
|
57
|
-
|
58
|
-
if graph_count.positive?
|
59
|
-
graph_percent = (graph_match_count / graph_count.to_f) * 100
|
60
|
-
else
|
61
|
-
graph_percent = 0.0
|
62
|
-
end
|
63
|
-
|
64
|
-
puts " How many boxes take a value from an unbox? #{box_nodes_percent.round(1)}%"
|
65
|
-
puts "How many graphs contain at least one box-unbox? #{graph_percent.round(1)}%"
|
data/docs/annotators.md
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
# Annotators
|
2
|
-
|
3
|
-
The model of Seafoam is that it is a directed graph, with nodes annotated with a
|
4
|
-
bag of key-value properties. When graphs are read they'll have some initial
|
5
|
-
properties. Seafoam may add more properties. The output routines then draw the
|
6
|
-
graph using the graph structure itself and also the properties.
|
7
|
-
|
8
|
-
*Annotators* are routines that add extra properties to graphs to help the user
|
9
|
-
understand them. They usually have knowledge of how the graph is structured, and
|
10
|
-
use this to make the graph easier to read or to make important information in
|
11
|
-
them stand out.
|
12
|
-
|
13
|
-
We call properties with symbol keys *annotations*, as they're added by the
|
14
|
-
annotators.
|
15
|
-
|
16
|
-
Annotators are similar to filters in IGV.
|
17
|
-
|
18
|
-
Appropriate annotators are automatically selected and applied to graphs.
|
19
|
-
|
20
|
-
The rendering commands recognize these annotations, so annotators will probably
|
21
|
-
want to add them:
|
22
|
-
|
23
|
-
* `:label` on nodes and edges
|
24
|
-
* `:out_annotation` on nodes
|
25
|
-
* `:hidden` on nodes only, to not show them (*remove frame state* for example in IGV terminology)
|
26
|
-
* `:inlined` on nodes only, to indicate the node should be shown immediately above each node using it (*reduce edges* in IGV terminology)
|
27
|
-
* `:kind` on nodes only, which can be `info`, `input`, `control`, `effect`, `virtual`, `calc`, `guard`, or `other`
|
28
|
-
* `:kind` on edges only, which can be `info`, `control`, `loop`, or `data`
|
29
|
-
* `:reverse` on edges only
|
30
|
-
* `:spotlight` for nodes as part of spotlighting (`lit` are shown, `shaded` are shown but greyed out, and edges from `shaded` to `:hidden` nodes are also shown greyed out)
|
31
|
-
|
32
|
-
Seafoam ships with an annotator for generic GraalVM graphs. If you work with a
|
33
|
-
different compiler you'll probably want to write your own annotators - subclass
|
34
|
-
`Seafoam::Annotator` and implement `#annotate(graph)`. You can add custom
|
35
|
-
annotators by requiring them in your `.seafoam/config`. All subclasses of
|
36
|
-
`Annotator` will be found, so you just need to define the subclass.
|
37
|
-
|
38
|
-
A fallback annotator, run after all others, just labels the node with the
|
39
|
-
`'label'` property if there is one.
|
40
|
-
|
41
|
-
Options for annotations can be set on the command line with `--option key
|
42
|
-
value`. Some options are built into Seafoam commands, like `--show-frame-state`,
|
43
|
-
but they're doing the same thing as `--option hide_frame_state false`.
|