MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lower_index.cpp
Go to the documentation of this file.
2
3#include <mim/def.h>
4#include <mim/lam.h>
5#include <mim/tuple.h>
6
8
10
12
13const Def* LowerIndex::rewrite(const Def* def) {
14 // The opaque affine index type lowers to the wide `Idx 0` (i64) carrier.
15 if (Axm::isa<affine::index>(def)) return new_world().type_i64();
16 return RWPhase::rewrite(def);
17}
18
20 if (is_bootstrapping()) return RWPhase::rewrite_imm_App(app);
21
22 auto& w = new_world();
23
24 // The affine index algebra is computed on the wide `Idx 0` carrier with wrap-around (`Mode::none`) arithmetic, so that
25 // negation/subtraction are correct via two's complement; the boundary `%affine.map` casts in/out with `%core.conv.u`.
26
27 // %affine.constant n ↦ the `Nat` n reinterpreted as an `Idx 0`.
28 if (Axm::isa<affine::constant>(app)) return w.call<core::bitcast>(w.type_i64(), rewrite(app->arg()));
29
30 if (auto op = Axm::isa<affine::op>(app)) {
31 switch (op.id()) {
32 case affine::op::add: {
33 auto [a, b] = rewrite(app->arg())->projs<2>();
34 return w.call(core::wrap::add, core::Mode::none, Defs{a, b});
35 }
36 case affine::op::sub: {
37 auto [a, b] = rewrite(app->arg())->projs<2>();
38 return w.call(core::wrap::sub, core::Mode::none, Defs{a, b});
39 }
40 case affine::op::neg: {
41 auto a = rewrite(app->arg());
42 return w.call(core::wrap::sub, core::Mode::none, Defs{w.lit(w.type_i64(), 0), a});
43 }
44 case affine::op::mul: {
45 error("affine.op.mul should have been rewritten to affine.semiop.mul and then to core.mul");
46 }
47 }
48 }
49
50 if (auto semiop = Axm::isa<affine::semiop>(app)) {
51 switch (semiop.id()) {
53 auto [a, c] = rewrite(app->arg())->projs<2>();
54 // `c` is a `Nat` constant; reinterpret it on the `Idx 0` carrier.
55 return w.call(core::wrap::mul, core::Mode::none, Defs{a, w.call<core::bitcast>(w.type_i64(), c)});
56 }
60 error("affine: lowering of semiop `{}` is not yet implemented (needs %core.div with a %mem.M token)",
61 app);
62 }
63 }
64
65 // %affine.map f idxs ↦ widen idxs to `Idx 0`, apply f, narrow each result back to its target `Idx (sout#j)`.
66 if (Axm::isa<affine::map>(app)) {
67 auto f = rewrite(app->callee()->as<App>()->arg()); // «n; Idx 0» → «m; Idx 0»
68 auto idxs = rewrite(app->arg()); // «n; Idx (sin#i)»
69 auto res_ty = rewrite(app->type()); // «m; Idx (sout#j)»
70
71 auto ins = idxs->projs();
72 auto lifted = w.tuple(
73 DefVec(ins.size(), [&](size_t i) { return w.call(core::conv::u, w.lit_i64(), ins[i]); }));
74
75 auto outs = w.app(f, lifted)->projs(); // «m; Idx 0»
76 return w.tuple(DefVec(outs.size(), [&](size_t j) {
77 // `res_ty#j` is `Idx (sout#j)`, i.e. `%Idx sout#j`; recover the destination size for `%core.conv.u`.
78 auto sout_j = res_ty->proj(outs.size(), j)->as<App>()->arg();
79 return w.call(core::conv::u, sout_j, outs[j]);
80 }));
81 }
82
83 return RWPhase::rewrite_imm_App(app);
84}
85
86} // namespace mim::plug::affine::phase
const Def * callee() const
Definition lam.h:276
const Def * arg() const
Definition lam.h:285
static auto isa(const Def *def)
Definition axm.h:107
Base class for all Defs.
Definition def.h:246
auto projs(F f) const
Splits this Def via Def::projections into an Array (if A == std::dynamic_extent) or std::array (other...
Definition def.h:386
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.cpp:452
World & new_world()
Create new Defs into this.
Definition phase.h:243
bool is_bootstrapping() const
Returns whether we are currently bootstrapping (rewriting annexes).
Definition phase.h:231
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:56
const Def * type_i64()
Definition world.h:630
const Def * rewrite_imm_App(const App *) final
const Def * rewrite(const Def *) final
@ none
Wrap around.
Definition core.h:16
View< const Def * > Defs
Definition def.h:78
Vector< const Def * > DefVec
Definition def.h:79
void error(std::format_string< Args... > fmt, Args &&... args)
Wraps std::format to throw T with a formatted message.
Definition dbg.h:17