MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
sccp.cpp
Go to the documentation of this file.
1#include "mim/phase/sccp.h"
2
3#include <absl/container/fixed_array.h>
4
5namespace mim {
6
7const Def* SCCP::Analysis::join(const Def* top, const Def* def) {
8 auto [i, ins] = lattice_.emplace(top, def);
9 if (ins) {
10 todo_ = true;
11 return def;
12 }
13
14 auto cur = i->second;
15 if (def->isa<Bot>() || cur == def || cur == top) return cur;
16
17 todo_ = true;
18 if (cur->isa<Bot>()) return i->second = def;
19 return i->second = top;
20}
21
22Def* SCCP::Analysis::rewrite_mut(Def* mut) {
23 map(mut, mut);
24
25 if (auto var = mut->has_var()) {
26 map(var, var);
27
28 if (mut->isa<Lam>())
29 for (auto var : mut->tvars()) {
30 map(var, var);
31 join(var, var);
32 }
33 }
34
35 for (auto d : mut->deps())
36 rewrite(d);
37
38 return mut;
39}
40
41const Def* SCCP::Analysis::rewrite_imm_App(const App* app) {
42 if (auto lam = app->callee()->isa_mut<Lam>(); isa_optimizable(lam)) {
43 auto n = app->num_targs();
44 auto abstr_args = absl::FixedArray<const Def*>(n);
45 auto abstr_vars = absl::FixedArray<const Def*>(n);
46 for (size_t i = 0; i != n; ++i) {
47 auto abstr = rewrite(app->targ(i));
48 abstr_vars[i] = join(lam->tvar(i), abstr);
49 abstr_args[i] = abstr;
50 }
51
52 auto abstr_var = world().tuple(abstr_vars);
53 map(lam->var(), abstr_var);
54 lattice_[lam->var()] = abstr_var;
55
56 if (!lookup(lam))
57 for (auto d : lam->deps())
58 rewrite(d);
59
60 return world().app(lam, abstr_args);
61 }
62
63 return Rewriter::rewrite_imm_App(app);
64}
65
66const Def* SCCP::rewrite_imm_App(const App* old_app) {
67 if (auto old_lam = old_app->callee()->isa_mut<Lam>()) {
68 if (auto l = lattice(old_lam->var()); l && l != old_lam->var()) {
69 todo_ = true;
70
71 size_t num_old = old_lam->num_tvars();
72 Lam* new_lam;
73 if (auto i = lam2lam_.find(old_lam); i != lam2lam_.end())
74 new_lam = i->second;
75 else {
76 // build new dom
77 auto new_doms = DefVec();
78 for (size_t i = 0; i != num_old; ++i) {
79 auto old_var = old_lam->var(num_old, i);
80 auto abstr = lattice(old_var);
81 if (abstr == old_var) new_doms.emplace_back(rewrite(old_lam->dom(num_old, i)));
82 }
83
84 // build new lam
85 size_t num_new = new_doms.size();
86 auto new_vars = absl::FixedArray<const Def*>(num_old);
87 new_lam = new_world().mut_lam(new_doms, rewrite(old_lam->codom()))->set(old_lam->dbg());
88 lam2lam_[old_lam] = new_lam;
89
90 // build new var
91 for (size_t i = 0, j = 0; i != num_old; ++i) {
92 auto old_var = old_lam->var(num_old, i);
93 auto abstr = lattice(old_var);
94 new_vars[i] = abstr == old_var ? new_lam->var(num_new, j++) : rewrite(abstr);
95 }
96
97 map(old_lam->var(), new_vars);
98 new_lam->set(rewrite(old_lam->filter()), rewrite(old_lam->body()));
99 }
100
101 // build new app
102 size_t num_new = new_lam->num_vars();
103 auto new_args = absl::FixedArray<const Def*>(num_new);
104 for (size_t i = 0, j = 0; i != num_old; ++i) {
105 auto old_var = old_lam->var(num_old, i);
106 auto abstr = lattice(old_var);
107 if (abstr == old_var) new_args[j++] = rewrite(old_app->targ(i));
108 }
109
110 return map(old_app, new_world().app(new_lam, new_args));
111 }
112 }
113
114 return Rewriter::rewrite_imm_App(old_app);
115}
116
117} // namespace mim
const Def * callee() const
Definition lam.h:276
Base class for all Defs.
Definition def.h:251
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:486
const Def * var(nat_t a, nat_t i) noexcept
Definition def.h:429
nat_t num_vars() noexcept
Definition def.h:429
A function.
Definition lam.h:110
Lam * set(Filter filter, const Def *body)
Definition lam.cpp:29
bool todo_
Set to true to indicate that you want to rerun all Phasees in your current fixed-point PhaseMan.
Definition phase.h:57
World & new_world()
Create new Defs into this.
Definition phase.h:143
World & world()=delete
Hides both and forbids direct access.
virtual const Def * map(const Def *old_def, const Def *new_def)
Definition rewrite.h:59
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:27
virtual const Def * lookup(const Def *old_def)
Lookup old_def by searching in reverse through the stack of maps.
Definition rewrite.h:69
const Def * rewrite_imm_App(const App *) final
Definition sccp.cpp:66
const Def * app(const Def *callee, const Def *arg)
Definition world.cpp:201
const Def * tuple(Defs ops)
Definition world.cpp:293
Lam * mut_lam(const Pi *pi)
Definition world.h:322
Definition ast.h:14
Vector< const Def * > DefVec
Definition def.h:77
Lam * isa_optimizable(Lam *lam)
These are Lams that are.
Definition lam.h:352
TExt< false > Bot
Definition lattice.h:171
@ Lam
Definition def.h:114
@ App
Definition def.h:114