| 1 | .once
|
| 2 |
|
| 3 | .include "control-flow.dl"
|
| 4 |
|
| 5 | // Types
|
| 6 | // =====
|
| 7 |
|
| 8 | // Objects can live in either local variables or object members.
|
| 9 | .type Place = LocalVariable { f: Function, v: symbol }
|
| 10 | | ObjectMember { o: symbol, m: symbol }
|
| 11 |
|
| 12 | // Places can be referenced by variables and object members.
|
| 13 | .type Reference = VariableRef { v: symbol }
|
| 14 | | MemberRef { o: symbol, m: symbol }
|
| 15 |
|
| 16 | // Facts and Relations (Inputs)
|
| 17 | // ============================
|
| 18 |
|
| 19 | // Place `p` is allocated, or assigned a literal value, in statement `s` of `f`.
|
| 20 | .decl define(f:Function, s:Statement, p:Place)
|
| 21 | .input define
|
| 22 |
|
| 23 | // Reference `r` is assigned to a place `p` in statement `s` of `f`.
|
| 24 | .decl assign(f:Function, s:Statement, p:Place, r:Reference)
|
| 25 | .input assign
|
| 26 |
|
| 27 | // Place `a` is aliased by place `b`.
|
| 28 | .decl alias(a: Place, b: Place)
|
| 29 | .output alias
|
| 30 |
|
| 31 | // Rules and Outputs
|
| 32 | // =================
|
| 33 |
|
| 34 | // `p` is implicitly defined when it is assigned to.
|
| 35 | define(f, s, p) :- assign(f, s, p, _).
|
| 36 |
|
| 37 | // Simple aliasing with locals.
|
| 38 | // a = ...
|
| 39 | // b = a
|
| 40 | alias($LocalVariable(f, a), $LocalVariable(f, b)) :-
|
| 41 | define(f, s1, $LocalVariable(f, a)),
|
| 42 | assign(f, s2, $LocalVariable(f, b), $VariableRef(a)),
|
| 43 | CFGraph.reachable(f, s1, f, s2).
|
| 44 |
|
| 45 | // LocalVariables can also be aliased by object members.
|
| 46 | // a = ...
|
| 47 | // b.m = a
|
| 48 | alias($LocalVariable(f, a), $ObjectMember(b, m)) :-
|
| 49 | define(f, s1, $LocalVariable(f, a)),
|
| 50 | assign(f, s2, $ObjectMember(b, m), $VariableRef(a)),
|
| 51 | CFGraph.reachable(f, s1, f, s2).
|
| 52 |
|
| 53 | // Objects members can be aliased too.
|
| 54 | // a.m = ...
|
| 55 | // b = a.m
|
| 56 | alias($ObjectMember(a, m), $LocalVariable(f, b)) :-
|
| 57 | assign(f, _, $LocalVariable(f, b), $MemberRef(a, m)).
|
| 58 | // a.m = ...
|
| 59 | // b.m2 = a.m1
|
| 60 | alias($ObjectMember(a, m1), $ObjectMember(b, m2)) :-
|
| 61 | assign(_, _, $ObjectMember(b, m2), $MemberRef(a, m1)).
|
| 62 |
|
| 63 | // Inductive case.
|
| 64 | alias(a, c) :- alias(a, b), alias(b, c).
|