MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
mem.h
Go to the documentation of this file.
1#pragma once
2
3#include <mim/axiom.h>
4#include <mim/lam.h>
6#include <mim/world.h>
7
9
10namespace mim::plug::mem {
11
12/// @name %%mem.M
13///@{
14
15inline Lam* mut_con(World& w) { return w.mut_con(w.annex<M>()); } ///< Yields `.con[%mem.M]`.
16
17/// Yields `.con[%mem.M, dom]`.
18inline Lam* mut_con(Ref dom) {
19 World& w = dom->world();
20 return w.mut_con({w.annex<M>(), dom});
21}
22
23/// Returns the (first) element of type mem::M from the given tuple.
24inline Ref mem_def(Ref def) {
25 if (match<mem::M>(def->type())) return def;
26 if (def->type()->isa<Arr>()) return {}; // don't look into possibly gigantic arrays
27
28 if (def->num_projs() > 1) {
29 for (auto proj : def->projs())
30 if (auto mem = mem_def(proj)) return mem;
31 }
32
33 return {};
34}
35
36/// Returns the memory argument of a function if it has one.
37inline Ref mem_var(Lam* lam) { return mem_def(lam->var()); }
38
39/// Swaps the memory occurrences in the given def with the given memory.
40inline Ref replace_mem(Ref mem, Ref arg) {
41 // TODO: maybe use rebuild instead?
42 if (arg->num_projs() > 1) {
43 auto& w = mem->world();
44 return w.tuple(DefVec(arg->num_projs(), [&](auto i) { return replace_mem(mem, arg->proj(i)); }));
45 }
46
47 if (match<mem::M>(arg->type())) return mem;
48
49 return arg;
50}
51
52/// Removes recusively all occurences of mem from a type (sigma).
53inline Ref strip_mem_ty(Ref def) {
54 auto& world = def->world();
55
56 if (auto sigma = def->isa<Sigma>()) {
57 DefVec new_ops;
58 for (auto op : sigma->ops())
59 if (auto new_op = strip_mem_ty(op); new_op != world.sigma()) new_ops.push_back(new_op);
60
61 return world.sigma(new_ops);
62 } else if (match<mem::M>(def)) {
63 return world.sigma();
64 }
65
66 return def;
67}
68
69/// Recursively removes all occurrences of mem from a tuple.
70/// Returns an empty tuple if applied with mem alone.
71inline Ref strip_mem(Ref def) {
72 auto& world = def->world();
73
74 if (auto tuple = def->isa<Tuple>()) {
75 DefVec new_ops;
76 for (auto op : tuple->ops())
77 if (auto new_op = strip_mem(op); new_op != world.tuple()) new_ops.push_back(new_op);
78
79 return world.tuple(new_ops);
80 } else if (match<mem::M>(def->type())) {
81 return world.tuple();
82 } else if (auto extract = def->isa<Extract>()) {
83 // The case that this one element is a mem and should return () is handled above.
84 if (extract->num_projs() == 1) return extract;
85
86 DefVec new_ops;
87 for (auto op : extract->projs())
88 if (auto new_op = strip_mem(op); new_op != world.tuple()) new_ops.push_back(new_op);
89
90 return world.tuple(new_ops);
91 }
92
93 return def;
94}
95///@}
96
97/// @name %%mem.Ptr
98///@{
99enum class AddrSpace : nat_t {
100 Generic = 0,
101 Global = 1,
102 Texture = 2,
103 Shared = 3,
104 Constant = 4,
105};
106///@}
107
108/// @name %%mem.lea
109///@{
110inline Ref op_lea(Ref ptr, Ref index) {
111 World& w = ptr->world();
112 auto [pointee, addr_space] = force<Ptr>(ptr->type())->args<2>();
113 auto Ts = tuple_of_types(pointee);
114 return w.app(w.app(w.annex<lea>(), {pointee->arity(), Ts, addr_space}), {ptr, index});
115}
116
117inline Ref op_lea_unsafe(Ref ptr, Ref i) {
118 World& w = ptr->world();
119 return op_lea(ptr, w.call(core::conv::u, force<Ptr>(ptr->type())->arg(0)->arity(), i));
120}
121
122inline Ref op_lea_unsafe(Ref ptr, u64 i) { return op_lea_unsafe(ptr, ptr->world().lit_i64(i)); }
123///@}
124
125/// @name %%mem.remem
126///@{
128 World& w = mem->world();
129 return w.app(w.annex<remem>(), mem);
130}
131///@}
132
133/// @name %%mem.alloc
134///@{
135inline Ref op_alloc(Ref type, Ref mem) {
136 World& w = type->world();
137 return w.app(w.app(w.annex<alloc>(), {type, w.lit_nat_0()}), mem);
138}
139///@}
140
141/// @name %%mem.slot
142///@{
143inline Ref op_slot(Ref type, Ref mem) {
144 World& w = type->world();
145 return w.app(w.app(w.annex<slot>(), {type, w.lit_nat_0()}), {mem, w.lit_nat(w.curr_gid())});
146}
147///@}
148
149/// @name %%mem.malloc
150///@{
151inline Ref op_malloc(Ref type, Ref mem) {
152 World& w = type->world();
153 auto size = w.call(core::trait::size, type);
154 return w.app(w.app(w.annex<malloc>(), {type, w.lit_nat_0()}), {mem, size});
155}
156///@}
157
158/// @name %%mem.mslot
159///@{
160inline Ref op_mslot(Ref type, Ref mem, Ref id) {
161 World& w = type->world();
162 auto size = w.call(core::trait::size, type);
163 return w.app(w.app(w.annex<mslot>(), {type, w.lit_nat_0()}), {mem, size, id});
164}
165///@}
166
167} // namespace mim::plug::mem
A (possibly paramterized) Array.
Definition tuple.h:51
World & world() const
Definition def.cpp:417
Ref var(nat_t a, nat_t i)
Definition def.h:398
auto projs(F f) const
Splits this Def via Def::projections into an Array (if A == -1_n) or std::array (otherwise).
Definition def.h:364
auto ops() const
Definition def.h:265
const Def * type() const
Definition def.h:245
nat_t num_projs() const
Definition def.h:354
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:119
A function.
Definition lam.h:96
Helper class to retrieve Infer::arg if present.
Definition def.h:85
A dependent tuple type.
Definition tuple.h:9
Data constructor for a Sigma.
Definition tuple.h:40
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
const Lit * lit_i64()
Definition world.h:398
The mem Plugin
Definition mem.h:10
Ref replace_mem(Ref mem, Ref arg)
Swaps the memory occurrences in the given def with the given memory.
Definition mem.h:40
Ref op_mslot(Ref type, Ref mem, Ref id)
Definition mem.h:160
Ref op_malloc(Ref type, Ref mem)
Definition mem.h:151
Ref strip_mem_ty(Ref def)
Removes recusively all occurences of mem from a type (sigma).
Definition mem.h:53
Ref op_remem(Ref mem)
Definition mem.h:127
Lam * mut_con(World &w)
Yields .con[mem.M].
Definition mem.h:15
Ref op_alloc(Ref type, Ref mem)
Definition mem.h:135
Ref mem_def(Ref def)
Returns the (first) element of type mem::M from the given tuple.
Definition mem.h:24
Ref mem_var(Lam *lam)
Returns the memory argument of a function if it has one.
Definition mem.h:37
Ref op_lea(Ref ptr, Ref index)
Definition mem.h:110
Ref op_lea_unsafe(Ref ptr, Ref i)
Definition mem.h:117
Ref strip_mem(Ref def)
Recursively removes all occurrences of mem from a tuple.
Definition mem.h:71
Ref op_slot(Ref type, Ref mem)
Definition mem.h:143
u64 nat_t
Definition types.h:43
Vector< const Def * > DefVec
Definition def.h:61
auto match(Ref def)
Definition axiom.h:105
auto force(Ref def)
Definition axiom.h:126
Ref tuple_of_types(Ref t)
Definition tuple.cpp:109
uint64_t u64
Definition types.h:34