| 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).
|