MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lower_get_set.cpp
Go to the documentation of this file.
2
3#include "mim/def.h"
4#include "mim/lam.h"
5
6#include "mim/util/types.h"
7
9
11
12const Def* LowerGetSet::lower_get(const App* app) {
13 auto& w = new_world();
14 auto c = rewrite(app->callee());
15 auto arg = rewrite(app->arg());
16
17 auto [arr, index] = arg->projs<2>();
18 auto callee = c->as<App>();
19 auto [T, r, s] = callee->args<3>();
20
21 DLOG("lower_get");
22 DLOG(" arr = {} : {}", arr, arr->type());
23 if (auto arr_seq = arr->type()->isa<Seq>()) DLOG(" arr shape = {}", arr_seq->arity());
24 DLOG(" index = {} : {}", index, index->type());
25 DLOG(" T = {} : {}", T, T->type());
26 DLOG(" r = {} : {}", r, r->type());
27 DLOG(" s = {} : {}", s, s->type());
28
29 auto r_nat = Lit::isa<u64>(r);
30 if (!r_nat) {
31 WLOG("{} doesn't have a lowering-time known rank: {}", app, r);
32 return nullptr;
33 }
34 if (r_nat == 1) {
35 DLOG("index of size 1, extract");
36 return w.extract(arr, index);
37 }
38 auto curr_arr = arr;
39 for (auto ri = 0_u64; ri < *r_nat; ++ri) {
40 auto idx = index->proj(*r_nat, ri);
41 DLOG(" idx = {} : {}", idx, idx->type());
42 curr_arr = w.extract(curr_arr, idx);
43 }
44 return curr_arr;
45}
46
47const Def* LowerGetSet::lower_set(const App* app) {
48 auto& w = new_world();
49 auto c = rewrite(app->callee());
50 auto arg = rewrite(app->arg());
51
52 auto [arr, index, x] = arg->projs<3>();
53
54 DLOG("lower_set");
55 DLOG(" arr = {} : {}", arr, arr->type());
56 DLOG(" index = {} : {}", index, index->type());
57 DLOG(" x = {} : {}", x, x->type());
58
59 auto callee = c->as<App>();
60 auto [T, r, s] = callee->args<3>();
61 DLOG(" T = {} : {}", T, T->type());
62 DLOG(" r = {} : {}", r, r->type());
63 DLOG(" s = {} : {}", s, s->type());
64
65 auto r_nat = Lit::isa<u64>(r);
66 if (!r_nat) {
67 WLOG("{} doesn't have a lowering-time known rank: {}", app, r);
68 return nullptr;
69 }
70 if (r_nat == 1) {
71 DLOG("index of size 1, insert");
72 return w.insert(arr, index, x);
73 }
74
75 // r_nat will never be 0, as we would have normalized this case away already
76 DefVec arrs_to_insert_into(*r_nat);
77 arrs_to_insert_into[0] = arr;
78 for (auto ri = 0_u64; ri < *r_nat - 1; ++ri) {
79 auto idx = index->proj(*r_nat, ri);
80 DLOG(" extract idx = {} : {}", idx, idx->type());
81 arrs_to_insert_into[ri + 1] = w.extract(arrs_to_insert_into[ri], idx);
82 }
83
84 auto new_arr = x;
85 for (auto ri = static_cast<s64>(*r_nat - 1); ri >= 0; --ri) {
86 auto idx = index->proj(*r_nat, ri);
87 DLOG(" idx = {} : {}", idx, idx->type());
88 DLOG(" arr_to_insert_into = {} : {}", arrs_to_insert_into[ri], arrs_to_insert_into[ri]->type());
89
90 new_arr = w.insert(arrs_to_insert_into[ri], idx, new_arr);
91 }
92 return new_arr;
93}
94
96 if (auto get = Axm::isa<tensor::get>(app)) {
97 if (auto res = lower_get(get)) return res;
98 } else if (auto set = Axm::isa<tensor::set>(app)) {
99 if (auto res = lower_set(set)) return res;
100 }
101 return RWPhase::rewrite_imm_App(app);
102}
103
104} // namespace mim::plug::tensor::phase
static auto isa(const Def *def)
Definition axm.h:107
Base class for all Defs.
Definition def.h:261
static std::optional< T > isa(const Def *def)
Definition def.h:878
World & new_world()
Create new Defs into this.
Definition phase.h:368
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:56
const Def * rewrite_imm_App(const App *) final
#define WLOG(...)
Definition log.h:89
#define DLOG(...)
Vaporizes to nothingness in Debug build.
Definition log.h:94
Vector< const Def * > DefVec
Definition def.h:79
int64_t s64
Definition types.h:27
@ App
Definition def.h:109