MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lower_ptr.cpp
Go to the documentation of this file.
2
3#include <mim/axm.h>
4#include <mim/def.h>
5
7#include "mim/plug/mem/mem.h"
8
9namespace mim::plug::buffer {
10
11namespace {
12
13/// Successively offsets `ptr` by each component of the index `tuple`, peeling one array dimension per `%mem.lea`.
14const Def* op_lea_tuple(const Def* ptr, const Def* tuple) {
15 auto n = tuple->num_projs();
16 auto element = ptr;
17 for (size_t i = 0; i < n; ++i)
18 element = mem::op_lea(element, tuple->proj(n, i));
19 return element;
20}
21
22/// Builds the nested array type `«s; T»` from a shape tuple `s` and element type `T`.
23const Def* arr_ty_of(const Def* s, const Def* T) {
24 auto& w = s->world();
25 auto n = s->num_projs();
26 auto arr_ty = T;
27 for (int i = (int)n - 1; i >= 0; --i)
28 arr_ty = w.arr(s->proj(n, i), arr_ty);
29 return arr_ty;
30}
31
32/// Builds the nested `pack` `‹s; val›` replicating `val` across every element.
33const Def* pack_tuple(const Def* s, const Def* val) {
34 auto& w = val->world();
35 auto n = s->num_projs();
36 auto element = val;
37 for (int i = (int)n - 1; i >= 0; --i)
38 element = w.pack(s->proj(n, i), element);
39 return element;
40}
41
42} // namespace
43
44const Def* LowerPtr::rewrite_imm_App(const App* app) {
45 if (is_bootstrapping()) return RWPhase::rewrite_imm_App(app);
46 auto& w = new_world();
47
48 if (auto buf_ax = Axm::isa<buffer::Buf>(app)) {
49 auto [r, s, T] = buf_ax->args<3>();
50 s = rewrite(s);
51 T = rewrite(T);
52 return w.call<mem::Ptr>(Defs{arr_ty_of(s, T), w.lit_nat_0()});
53 } else if (auto alloc_ax = Axm::isa<buffer::alloc>(app)) {
54 auto mem = rewrite(alloc_ax->arg());
55 auto [r, s, T] = alloc_ax->callee()->as<App>()->args<3>();
56 s = rewrite(s);
57 T = rewrite(T);
58 auto [mem2, ptr] = mem::op_alloc(arr_ty_of(s, T), mem)->projs<2>();
59 return w.tuple({mem2, ptr});
60 } else if (auto read_ax = Axm::isa<buffer::read>(app)) {
61 auto [mem, buf, idx] = read_ax->args<3>();
62 mem = rewrite(mem);
63 buf = rewrite(buf);
64 idx = rewrite(idx);
65 auto element_ptr = op_lea_tuple(buf, idx);
66 auto [mem2, val] = w.call<mem::load>(Defs{mem, element_ptr})->projs<2>();
67 return w.tuple({mem2, val});
68 } else if (auto write_ax = Axm::isa<buffer::write>(app)) {
69 auto [mem, buf, idx, val] = write_ax->args<4>();
70 mem = rewrite(mem);
71 buf = rewrite(buf);
72 idx = rewrite(idx);
73 val = rewrite(val);
74 auto element_ptr = op_lea_tuple(buf, idx);
75 auto mem2 = w.call<mem::store>(Defs{mem, element_ptr, val});
76 return w.tuple({mem2, buf});
77 } else if (auto copy_ax = Axm::isa<buffer::copy>(app)) {
78 auto [mem, dst, src] = copy_ax->args<3>();
79 mem = rewrite(mem);
80 dst = rewrite(dst);
81 src = rewrite(src);
82 // Whole-buffer copy: load the entire array out of `src` and store it into `dst`.
83 auto [mem2, val] = w.call<mem::load>(Defs{mem, src})->projs<2>();
84 return w.call<mem::store>(Defs{mem2, dst, val});
85 } else if (auto init_ax = Axm::isa<buffer::init>(app)) {
86 auto [mem, val] = init_ax->args<2>();
87 auto [r, s, T] = init_ax->callee()->as<App>()->args<3>();
88 mem = rewrite(mem);
89 val = rewrite(val);
90 s = rewrite(s);
91 T = rewrite(T);
92 auto [mem2, ptr] = mem::op_alloc(arr_ty_of(s, T), mem)->projs<2>();
93 auto mem3 = w.call<mem::store>(Defs{mem2, ptr, val});
94 return w.tuple({mem3, ptr});
95 } else if (auto const_ax = Axm::isa<buffer::constant>(app)) {
96 auto [mem, val] = const_ax->args<2>();
97 auto [r, s, T] = const_ax->callee()->as<App>()->args<3>();
98 mem = rewrite(mem);
99 val = rewrite(val);
100 s = rewrite(s);
101 T = rewrite(T);
102 auto [mem2, ptr] = mem::op_alloc(arr_ty_of(s, T), mem)->projs<2>();
103 auto mem3 = w.call<mem::store>(Defs{mem2, ptr, pack_tuple(s, val)});
104 return w.tuple({mem3, ptr});
105 }
106
107 return RWPhase::rewrite_imm_App(app);
108}
109
110} // namespace mim::plug::buffer
static auto isa(const Def *def)
Definition axm.h:107
Base class for all Defs.
Definition def.h:261
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:402
const Vector< std::string > & args()
Command-line arguments passed to this Phase's plugin via -X <plugin>:<arg>.
Definition phase.cpp:23
World & new_world()
Create new Defs into this.
Definition phase.h:368
bool is_bootstrapping() const
Returns whether we are currently bootstrapping (rewriting annexes).
Definition phase.h:356
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:56
const Def * rewrite_imm_App(const App *) override
Definition lower_ptr.cpp:44
The buffer Plugin
Definition buffer.h:7
The mem Plugin
Definition mem.h:11
const Def * op_lea(const Def *ptr, const Def *index)
Definition mem.h:112
const Def * op_alloc(const Def *type, const Def *as, const Def *mem)
Definition mem.h:129
View< const Def * > Defs
Definition def.h:78