MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
sccp_analysis.cpp
Go to the documentation of this file.
1#include "mim/phase/sccp.h"
2
3namespace mim {
4
5const Def* SCCP::Analysis::propagate(Lam* lam, const Def* var, const Def* def) {
6 // `⊥ ⊔ x` is `x`, but unusable if lam nests it.
7 if (lam->nests(def)) return pin(var), var;
8
9 auto cur = lattice(var);
10 if (!cur) { // ⊥ ⊔ def = def; lattice(var, def) invalidates, as it inserts a fresh non-⊤ fact
11 lattice(var, def);
12 log().d("propagate {} → {}", var, def);
13 return def;
14 }
15
16 if (cur == var) return cur; // ⊤ stays ⊤
17
18 // cur ⊔ ⊥ = cur, but the ⊥-site's caller must see cur as well.
19 if (def->isa<Bot>()) {
20 if (auto caller = curr_mut(); caller && !cur->in_scope(caller)) return pin(var), var;
21 return cur;
22 }
23
24 if (cur == def) return cur; // cur ⊔ cur = cur
25
26 if (cur->isa<Bot>()) { // ⊥ ⊔ def = def; lattice(var, def) invalidates, as it overwrites cur
27 lattice(var, def);
28 return def;
29 }
30
31 return pin(var), var; // two different values join to ⊤; lattice(var, var) therein invalidates, as it overwrites cur
32}
33
34const Def* SCCP::Analysis::rewrite_imm_App(const App* app) {
35 if (auto lam = Lam::isa_rewritable(app->callee())) {
36 auto n = app->num_targs();
37 auto abstr_args = DefVec(n);
38 auto abstr_vars = DefVec(n);
39
40 // propagate
41 for (size_t i = 0; i != n; ++i) {
42 auto abstr = rewrite(app->targ(i));
43 abstr_vars[i] = propagate(lam, lam->tvar(i), abstr);
44 abstr_args[i] = abstr;
45 }
46
47 lattice(lam->var(), world().tuple(abstr_vars)); // set new abstract var
48 return world().raw_app(rewrite(app->type()), rewrite(lam), world().tuple(abstr_args));
49 }
50
52}
53
54} // namespace mim
const auto & lattice() const
The whole map; used e.g. to diff two fixed-point runs.
Definition phase.h:165
bool pin(const Def *def)
Monotonically forces def to ⊤ (keep as is).
Definition phase.h:227
Base class for all Defs.
Definition def.h:289
A function.
Definition lam.h:91
static Lam * isa_rewritable(const Def *def)
Yields def as a mutable Lam, if it is_rewritable() and nullptr otherwise.
Definition lam.h:193
const fe::Log & log() const
Definition phase.h:60
World & world()
Definition phase.h:58
const Def * lattice(const Def *old_def) const
Returns the abstract value computed by the associated Analysis for the given old-world Def,...
Definition phase.h:347
D * curr_mut() const
Definition rewrite.h:98
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:62
virtual const Def * rewrite_imm_App(const App *)
const Def * raw_app(const Axm *axm, u8 curry, u8 trip, const Def *type, const Def *callee, const Def *arg)
Definition world.cpp:501
Definition ast.h:16
fe::Vector< const Def * > DefVec
Definition def.h:98
TExt< false > Bot
Definition union.h:39