1 | .once
|
2 |
|
3 | .include "control-flow.dl"
|
4 |
|
5 | // Facts and Relations (Inputs)
|
6 | // ============================
|
7 |
|
8 | // Statements can define and use variables.
|
9 | .type Reference = Variable { v: symbol }
|
10 | | Member { v: symbol, m: symbol }
|
11 |
|
12 | // Variable (or object) `r` is allocated, or assigned a literal value, in
|
13 | // statement `s` of `f`.
|
14 | .decl define(f:Function, s:Statement, r:Reference)
|
15 | .input define
|
16 |
|
17 | // Variable (or object) `b` is assigned to another variable `a` in statement `s`
|
18 | // of `f`.
|
19 | .decl assign(f:Function, s:Statement, a:Reference, b:Reference)
|
20 | .input assign
|
21 |
|
22 | // `a` (defined at statement `sf` in `f`) is aliased by `b` in statement `sg` in
|
23 | // `g`.
|
24 | .decl alias(f:Function, sf:Statement, a:Reference, g:Function, sg:Statement, b:Reference)
|
25 | .output alias
|
26 |
|
27 | // Rules and Outputs
|
28 | // =================
|
29 |
|
30 | // `r` is implicitly defined if it is assigned to.
|
31 | define(f, s, r) :- assign(f, s, r, _).
|
32 |
|
33 | // a = ...
|
34 | // b = a
|
35 | alias(f, s1, $Variable(v), f, s2, $Variable(v2)) :-
|
36 | define(f, s1, $Variable(v)),
|
37 | assign(f, s2, $Variable(v2), $Variable(v)),
|
38 | CFGraph.reachable(f, s1, f, s2).
|
39 |
|
40 | // a.b = ...
|
41 | // c = a.b
|
42 | alias("heap", -1, $Member(c, m), f, s2, r) :-
|
43 | assign(_, _, $Member(c, m), _),
|
44 | assign(f, s2, r, $Member(c, m)).
|
45 |
|
46 | // a = ...
|
47 | // b.c = a
|
48 | alias(f, s1, $Variable(v), "heap", -1, $Member(c, m)) :-
|
49 | define(f, s1, $Variable(v)),
|
50 | assign(f, s2, $Member(c, m), $Variable(v)),
|
51 | CFGraph.reachable(f, s1, f, s2).
|