Skip to content

Commit b2ef0af

Browse files
committed
Add description of type graph to documentation.
This updates the llvm2graph plots to show how a fifth "type graph" stage, and updates the README to describe how types are added to the graph. github.com//issues/82
1 parent 3709e9a commit b2ef0af

7 files changed

+165
-28
lines changed

README.md

+17-6
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ control flow in that `switch` instruction.
7474
<img src="/programl/Documentation/assets/llvm2graph-3-dfg.png" width=300>
7575

7676
Then we add a graph node for every variable and constant. In the drawing above,
77-
the diamonds are constants and the variables are ovals. We add data-flow edges
77+
the octagons are constants and the variables are ovals. We add data-flow edges
7878
to describe the relations between constants and the instructions that use them,
7979
and variables and the constants which define/use them. Like control edges, data
8080
edges have positions. In the case of data edges, the position encodes the order
@@ -84,11 +84,22 @@ of a data element in the list of instruction operands.
8484

8585
<img src="/programl/Documentation/assets/llvm2graph-4-cg.png" width=300>
8686

87-
Finally, we add call edges (green) from callsites to the function entry
88-
instruction, and return edges from function exits to the callsite. Since this is
89-
a graph of a recursive function, the callsites refer back to the entry of the
90-
function (the `switch`). The `external` node is used to represent a call from an
91-
external site.
87+
Then we add call edges (green) from callsites to the function entry
88+
instruction, and return edges from function exits to the callsite. Since this
89+
is a graph of a recursive function, the callsites refer back to the entry of
90+
the function (the `switch`). The `external` node is used to represent a call
91+
from an external site.
92+
93+
#### Step 5: Type graph
94+
95+
<img src="/programl/Documentation/assets/llvm2graph-5-types.png" width=300>
96+
97+
Finally, we add data types to the graph. Each unique type is represented as
98+
a node and connected to all instances of this type through type edges.
99+
Composite types such as structs, arrays, or pointers to types (not shown here)
100+
are composed of individual nodes for each primitive type that are then composed
101+
through type edges. For struct types, a numeric edge position indicates the
102+
position of each element in the struct's field list.
92103

93104
The process described above can be run locally using our
94105
[`clang2graph`](/programl/Documentation/cmd/clang2graph.txt) and

programl/Documentation/assets/llvm2graph-3-dfg.dot

+11-11
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ edge [
2323
external [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393" label="[external]", width=2];
2424

2525
// Constants:
26-
const_1 [shape=diamond, style=filled, fillcolor="#F4CCCC", width=1, color="#990000", fontcolor="#990000", label="i32"]; // 1
27-
const_0 [shape=diamond, style=filled, fillcolor="#F4CCCC", width=1, color="#990000", fontcolor="#990000", label="i32"]; // 0
28-
const_minus_1 [shape=diamond, style=filled, fillcolor="#F4CCCC", width=1, color="#990000", fontcolor="#990000", label="i32"]; // -1
29-
const_minus_2 [shape=diamond, style=filled, fillcolor="#F4CCCC", width=1, color="#990000", fontcolor="#990000", label="i32"]; // -2
26+
const_1 [shape=octagon, style=filled, fillcolor="#F4CCCC", width=1, color="#990000", fontcolor="#990000", label="val"]; // 1
27+
const_0 [shape=octagon, style=filled, fillcolor="#F4CCCC", width=1, color="#990000", fontcolor="#990000", label="val"]; // 0
28+
const_minus_1 [shape=octagon, style=filled, fillcolor="#F4CCCC", width=1, color="#990000", fontcolor="#990000", label="val"]; // -1
29+
const_minus_2 [shape=octagon, style=filled, fillcolor="#F4CCCC", width=1, color="#990000", fontcolor="#990000", label="val"]; // -2
3030

3131
// Instructions:
3232
inst_switch [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=2, label="switch"];
@@ -41,13 +41,13 @@ ret_2 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAF
4141
ret_1 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="ret"];
4242

4343
// Variables:
44-
arg_0 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="i32"]; // %0
45-
var_4 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="i32"]; // %4
46-
var_5 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="i32"]; // %5
47-
var_6 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="i32"]; // %6
48-
var_7 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="i32"]; // %7
49-
var_8 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="i32"]; // %8
50-
var_10 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="i32"]; // %10
44+
arg_0 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="var"]; // %0
45+
var_4 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="var"]; // %4
46+
var_5 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="var"]; // %5
47+
var_6 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="var"]; // %6
48+
var_7 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="var"]; // %7
49+
var_8 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="var"]; // %8
50+
var_10 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#990000", width=1, fontcolor="#990000", label="var"]; // %10
5151

5252

5353
// === Edges ===
Loading

programl/Documentation/assets/llvm2graph-4-cg.dot

+11-11
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ edge [
2323
external [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393" label="[external]", width=2];
2424

2525
// Constants:
26-
const_0 [shape=diamond, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="i32"]; // 0
27-
const_1 [shape=diamond, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="i32"]; // 1
28-
const_minus_1 [shape=diamond, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="i32"]; // -1
29-
const_minus_2 [shape=diamond, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="i32"]; // -2
26+
const_0 [shape=octagon, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="val"]; // 0
27+
const_1 [shape=octagon, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="val"]; // 1
28+
const_minus_1 [shape=octagon, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="val"]; // -1
29+
const_minus_2 [shape=octagon, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="val"]; // -2
3030

3131
// Instructions:
3232
inst_switch [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=2, label="switch"];
@@ -41,13 +41,13 @@ ret_2 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAF
4141
ret_1 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="ret"];
4242

4343
// Variables:
44-
arg_0 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="i32"]; // %0
45-
var_4 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="i32"]; // %4
46-
var_5 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="i32"]; // %5
47-
var_6 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="i32"]; // %6
48-
var_7 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="i32"]; // %7
49-
var_8 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="i32"]; // %8
50-
var_10 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="i32"]; // %10
44+
arg_0 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %0
45+
var_4 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %4
46+
var_5 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %5
47+
var_6 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %6
48+
var_7 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %7
49+
var_8 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %8
50+
var_10 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %10
5151

5252

5353
// === Edges ===
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
digraph main {
2+
margin=0;
3+
4+
graph [
5+
fontsize=100,
6+
nodesep=0.2,
7+
ranksep=0.2,
8+
];
9+
node [
10+
fontname=Inconsolata,
11+
fontsize=25,
12+
penwidth=2,
13+
margin=0,
14+
];
15+
edge [
16+
fontname=Inconsolata,
17+
fontsize=22,
18+
arrowsize=.8,
19+
penwidth=1,
20+
]
21+
22+
// === Nodes ===
23+
external [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393" label="[external]", width=2];
24+
25+
// Types:
26+
i32 [shape=diamond, margin=0, style=filled, fillcolor="#CCCCCC", width=1, color="#CCCCCC", fontcolor="#222222", label="i32"];
27+
28+
// Constants:
29+
const_0 [shape=octagon, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="val"]; // 0
30+
const_1 [shape=octagon, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="val"]; // 1
31+
const_minus_1 [shape=octagon, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="val"]; // -1
32+
const_minus_2 [shape=octagon, margin=0, style=filled, fillcolor="#F4CCCC", width=1, color="#F4CCCC", fontcolor="#990000", label="val"]; // -2
33+
34+
// Instructions:
35+
inst_switch [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=2, label="switch"];
36+
inst_br [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="br"];
37+
phi [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="phi"];
38+
inst_add_minus_1 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="add"];
39+
call_1 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="call"];
40+
inst_add_minus_2 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="add"];
41+
call_2 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="call"];
42+
add_3 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="add"];
43+
ret_2 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="ret"];
44+
ret_1 [shape=box, style=filled, fillcolor="#C0DAFF", color="#C0DAFF", fontcolor="#345393", width=1, label="ret"];
45+
46+
// Variables:
47+
arg_0 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %0
48+
var_4 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %4
49+
var_5 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %5
50+
var_6 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %6
51+
var_7 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %7
52+
var_8 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %8
53+
var_10 [shape=ellipse, style=filled, fillcolor="#E99C9C", color="#E99C9C", width=1, fontcolor="#990000", label="var"]; // %10
54+
55+
56+
// === Edges ===
57+
58+
// Control edges:
59+
inst_switch -> inst_add_minus_1 [color="#345393", weight=10, labelfontcolor="#345393", minlen=2];
60+
inst_switch -> phi [color="#345393", weight=10, labelfontcolor="#345393", minlen=2];
61+
inst_switch -> inst_br [color="#345393", weight=10, labelfontcolor="#345393", minlen=2];
62+
inst_br -> phi [color="#345393", weight=10];
63+
inst_add_minus_1 -> call_1 [color="#345393", weight=10];
64+
call_1 -> inst_add_minus_2 [color="#345393", weight=10];
65+
inst_add_minus_2 -> call_2 [color="#345393", weight=10];
66+
call_2 -> add_3 [color="#345393", weight=10];
67+
add_3 -> ret_2 [color="#345393", weight=10];
68+
phi -> ret_1 [color="#345393", weight=10];
69+
70+
// Data edges:
71+
inst_add_minus_1 -> var_4 [color="#EA9999", labelfontcolor="#990000", weight=0];
72+
call_1 -> var_5 [color="#EA9999", labelfontcolor="#990000", weight=0];
73+
var_4 -> call_1 [color="#EA9999", labelfontcolor="#990000", weight=0];
74+
inst_add_minus_2 -> var_6 [color="#EA9999", labelfontcolor="#990000", weight=0];
75+
call_2 -> var_7 [color="#EA9999", labelfontcolor="#990000", weight=0];
76+
var_6 -> call_2 [color="#EA9999", labelfontcolor="#990000", weight=0];
77+
add_3 -> var_8 [color="#EA9999", labelfontcolor="#990000", weight=0];
78+
var_7 -> add_3 [color="#EA9999", labelfontcolor="#990000", weight=0];
79+
var_5 -> add_3 [color="#EA9999", labelfontcolor="#990000", weight=0];
80+
var_8 -> ret_2 [color="#EA9999", labelfontcolor="#990000", weight=0];
81+
phi -> var_10 [color="#EA9999", labelfontcolor="#990000", weight=0];
82+
var_10 -> ret_1 [color="#EA9999", labelfontcolor="#990000", weight=0];
83+
arg_0 -> inst_switch [color="#EA9999", labelfontcolor="#990000", weight=0];
84+
arg_0 -> inst_add_minus_1 [color="#EA9999", labelfontcolor="#990000", weight=0];
85+
arg_0 -> inst_add_minus_2 [color="#EA9999", labelfontcolor="#990000", weight=0];
86+
arg_0 -> phi [color="#EA9999", labelfontcolor="#990000", weight=0];
87+
88+
// Data edges (constants):
89+
90+
const_0 -> inst_switch [color="#EA9999", labelfontcolor="#990000"];
91+
const_1 -> inst_switch [color="#EA9999", labelfontcolor="#990000"];
92+
const_1 -> phi [color="#EA9999", labelfontcolor="#990000"];
93+
const_minus_1 -> inst_add_minus_1 [color="#EA9999", labelfontcolor="#990000"];
94+
const_minus_2 -> inst_add_minus_2 [color="#EA9999", labelfontcolor="#990000"];
95+
96+
// Call edges
97+
external -> inst_switch [color="#5dba83", weight=0];
98+
ret_2 -> external [color="#5dba83", weight=0];
99+
ret_1 -> external [color="#5dba83", weight=0];
100+
ret_1 -> call_2 [color="#5dba83", weight=0];
101+
ret_1 -> call_1 [color="#5dba83", weight=0];
102+
call_1 -> inst_switch [color="#5dba83", weight=0];
103+
call_2 -> inst_switch [color="#5dba83", weight=0];
104+
ret_2 -> call_2 [color="#5dba83", weight=0];
105+
ret_2 -> call_1 [color="#5dba83", weight=0];
106+
107+
// Type edges
108+
i32 -> const_0 [color="#AAAAAA", penwidth=3, weight=1];
109+
i32 -> const_1 [color="#AAAAAA", penwidth=3, weight=1];
110+
i32 -> const_minus_1 [color="#AAAAAA", penwidth=3, weight=1];
111+
i32 -> const_minus_2 [color="#AAAAAA", penwidth=3, weight=1];
112+
i32 -> arg_0 [color="#AAAAAA", penwidth=3, weight=1];
113+
i32 -> var_4 [color="#AAAAAA", penwidth=3, weight=1];
114+
i32 -> var_5 [color="#AAAAAA", penwidth=3, weight=1];
115+
i32 -> var_6 [color="#AAAAAA", penwidth=3, weight=1];
116+
i32 -> var_7 [color="#AAAAAA", penwidth=3, weight=1];
117+
i32 -> var_8 [color="#AAAAAA", penwidth=3, weight=1];
118+
i32 -> var_10 [color="#AAAAAA", penwidth=3, weight=1];
119+
120+
rankdir = TB;
121+
{rank = same; inst_add_minus_1; phi; inst_br;}
122+
{rank = same; ret_1; call_1;}
123+
{rank = same; call_2, var_5, var_6;}
124+
{rank = same; add_3, var_7;}
125+
{rank = same; ret_2, var_8;}
126+
}
Loading

0 commit comments

Comments
 (0)