MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lower_for.cpp
Go to the documentation of this file.
2
3#include <mim/lam.h>
4#include <mim/tuple.h>
5
6#include <mim/plug/mem/mem.h>
7
9
10namespace mim::plug::affine {
11
12namespace {
13
14const Def* merge_s(World& w, const Def* elem, const Def* sigma, const Def* mem) {
15 if (mem) {
16 auto elems = sigma->projs();
17 return merge_sigma(elem, elems);
18 }
19 return w.sigma({elem, sigma});
20}
21
22const Def* merge_t(World& w, const Def* elem, const Def* tuple, const Def* mem) {
23 if (mem) {
24 auto elems = tuple->projs();
25 return merge_tuple(elem, elems);
26 }
27 return w.tuple({elem, tuple});
28}
29
30} // namespace
31
32const Def* LowerFor::rewrite(const Def* def) {
33 if (auto i = rewritten_.find(def); i != rewritten_.end()) return i->second;
34
35 if (auto for_ax = match<affine::For>(def)) {
36 world().DLOG("rewriting for axiom: {} within {}", for_ax, curr_mut());
37 auto [begin, end, step, init, body, exit] = for_ax->args<6>();
38
39 auto body_lam = body->isa_mut<Lam>();
40 auto exit_lam = exit->isa_mut<Lam>();
41 if (!body_lam || !exit_lam) return def;
42
43 auto mem = mem::mem_def(init);
44 auto head_lam = world().mut_con(merge_s(world(), begin->type(), init->type(), mem))->set("head");
45 auto phis = head_lam->vars();
46 auto iter = phis.front();
47 auto acc = world().tuple(phis.view().subspan(1));
48 mem = mem::mem_var(head_lam);
49 auto bb_dom = mem ? mem->type() : world().sigma();
50 auto new_body = world().mut_con(bb_dom)->set("new_body");
51 auto new_exit = world().mut_con(bb_dom)->set("new_exit");
52 auto new_yield = world().mut_con(init->type())->set("new_yield");
53 auto cmp = world().call(core::icmp::ul, Defs{iter, end});
54 auto new_iter = world().call(core::wrap::add, core::Mode::nusw, Defs{iter, step});
55
56 head_lam->branch(false, cmp, new_body, new_exit, mem);
57 new_yield->app(false, head_lam, merge_t(world(), new_iter, new_yield->var(), mem));
58 new_body->set(false, body->reduce(world().tuple({iter, acc, new_yield})).back());
59 new_exit->set(false, exit->reduce(acc).back());
60
61 return rewritten_[def] = world().app(head_lam, merge_t(world(), begin, init, mem));
62 }
63
64 return def;
65}
66
67} // namespace mim::plug::affine
Base class for all Defs.
Definition def.h:198
Def * set(size_t i, const Def *)
Successively set from left to right.
Definition def.cpp:266
T * isa_mut() const
If this is *mut*able, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:430
auto vars(F f) noexcept
Definition def.h:379
A function.
Definition lam.h:105
Lam * set(Filter filter, const Def *body)
Definition lam.h:164
World & world()
Definition pass.h:296
Lam * curr_mut() const
Definition pass.h:232
const Type * type(const Def *level)
Definition world.cpp:105
const Def * sigma(Defs ops)
Definition world.cpp:238
const Def * app(const Def *callee, const Def *arg)
Definition world.cpp:181
const Def * tuple(Defs ops)
Definition world.cpp:246
const Def * var(const Def *type, Def *mut)
Definition world.cpp:167
const Def * call(Id id, Args &&... args)
Complete curried call of annexes obeying implicits.
Definition world.h:506
Lam * mut_con(const Def *dom)
Definition world.h:292
const Def * rewrite(const Def *) override
Definition lower_for.cpp:32
The affine Plugin
Definition affine.h:7
The mem Plugin
Definition mem.h:11
const Def * mem_var(Lam *lam)
Returns the memory argument of a function if it has one.
Definition mem.h:38
const Def * mem_def(const Def *def)
Returns the (first) element of type mem::M from the given tuple.
Definition mem.h:25
View< const Def * > Defs
Definition def.h:49
const Def * merge_sigma(const Def *def, Defs defs)
Definition tuple.cpp:93
auto match(const Def *def)
Definition axiom.h:112
const Def * merge_tuple(const Def *def, Defs defs)
Definition tuple.cpp:98