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, Ref elem, Ref sigma, Ref 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, Ref elem, Ref tuple, Ref 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
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
Def * set(size_t i, const Def *def)
Successively set from left to right.
Definition def.cpp:246
auto vars(F f)
Definition def.h:401
T * isa_mut() const
If this is *mut*able, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:447
A function.
Definition lam.h:103
Lam * set(Filter filter, const Def *body)
Definition lam.h:166
World & world()
Definition pass.h:296
Lam * curr_mut() const
Definition pass.h:232
Helper class to retrieve Infer::arg if present.
Definition def.h:86
This is a thin wrapper for std::span<T, N> with the following additional features:
Definition span.h:28
Ref tuple(Defs ops)
Definition world.cpp:238
Lam * mut_con(Ref dom)
Definition world.h:296
Ref var(Ref type, Def *mut)
Definition world.cpp:156
Ref app(Ref callee, Ref arg)
Definition world.cpp:186
const Def * call(Id id, Args &&... args)
Definition world.h:518
Ref sigma(Defs ops)
Definition world.cpp:230
const Type * type(Ref level)
Definition world.cpp:94
Ref rewrite(Ref) override
Definition lower_for.cpp:32
The affine Plugin
Definition affine.h:7
The mem Plugin
Definition mem.h:11
Ref mem_def(Ref def)
Returns the (first) element of type mem::M from the given tuple.
Definition mem.h:25
Ref mem_var(Lam *lam)
Returns the memory argument of a function if it has one.
Definition mem.h:38
auto match(Ref def)
Definition axiom.h:112
const Def * merge_sigma(const Def *def, Defs defs)
Definition tuple.cpp:93
const Def * merge_tuple(const Def *def, Defs defs)
Definition tuple.cpp:98