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