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/axm.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, nat_t a = 0) { return w.mut_con(w.call<M>(a)); } ///< Yields `con[%mem.M 0]`.
17
18/// Yields `con[%mem.M 0, dom]`.
19inline Lam* mut_con(const Def* dom) {
20 World& w = dom->world();
21 return w.mut_con({w.call<M>(0), dom});
22}
23
24/// Returns the (first) element of type `%mem.M a` from the given tuple.
25inline const Def* mem_def(const Def* def) {
26 if (Axm::isa<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 const Def* mem_var(Lam* lam) { return mem_def(lam->var()); }
39
40/// Removes recusively all occurences of mem from a type (sigma).
41inline const Def* strip_mem_ty(const Def* def) {
42 auto& world = def->world();
43
44 if (auto sigma = def->isa<Sigma>()) {
45 DefVec new_ops;
46 for (auto op : sigma->ops())
47 if (auto new_op = strip_mem_ty(op); new_op != world.sigma()) new_ops.push_back(new_op);
48
49 return world.sigma(new_ops);
50 } else if (Axm::isa<mem::M>(def)) {
51 return world.sigma();
52 }
53
54 return def;
55}
56
57/// Recursively removes all occurrences of mem from a tuple.
58/// Returns an empty tuple if applied with mem alone.
59inline const Def* strip_mem(const Def* def) {
60 auto& world = def->world();
61
62 if (auto tuple = def->isa<Tuple>()) {
63 DefVec new_ops;
64 for (auto op : tuple->ops())
65 if (auto new_op = strip_mem(op); new_op != world.tuple()) new_ops.push_back(new_op);
66
67 return world.tuple(new_ops);
68 } else if (Axm::isa<mem::M>(def->type())) {
69 return world.tuple();
70 } else if (auto extract = def->isa<Extract>()) {
71 // The case that this one element is a mem and should return () is handled above.
72 if (extract->num_projs() == 1) return extract;
73
74 DefVec new_ops;
75 for (auto op : extract->projs())
76 if (auto new_op = strip_mem(op); new_op != world.tuple()) new_ops.push_back(new_op);
77
78 return world.tuple(new_ops);
79 }
80
81 return def;
82}
83///@}
84
85/// @name %%mem.Ptr
86///@{
87enum class AddrSpace : nat_t {
89 Global = 1,
91 Shared = 3,
93};
94///@}
95
96/// @name %%mem.lea
97///@{
98inline const Def* op_lea(const Def* ptr, const Def* index) {
99 World& w = ptr->world();
100 auto [pointee, addr_space] = Axm::as<Ptr>(ptr->type())->args<2>();
101 auto Ts = tuple_of_types(pointee);
102 return w.app(w.app(w.annex<lea>(), {pointee->arity(), Ts, addr_space}), {ptr, index});
103}
104
105inline const Def* op_lea_unsafe(const Def* ptr, const Def* i) {
106 World& w = ptr->world();
107 return op_lea(ptr, w.call(core::conv::u, Axm::as<Ptr>(ptr->type())->arg(0)->arity(), i));
108}
109
110inline const Def* op_lea_unsafe(const Def* ptr, u64 i) { return op_lea_unsafe(ptr, ptr->world().lit_i64(i)); }
111///@}
112
113/// @name %%mem.alloc
114///@{
115inline const Def* op_alloc(const Def* type, const Def* mem) {
116 World& w = type->world();
117 return w.app(w.app(w.annex<alloc>(), {type, w.lit_nat_0()}), mem);
118}
119///@}
120
121/// @name %%mem.slot
122///@{
123inline const Def* op_slot(const Def* type, const Def* mem) {
124 World& w = type->world();
125 return w.app(w.app(w.annex<slot>(), {type, w.lit_nat_0()}), {mem, w.lit_nat(w.curr_gid())});
126}
127///@}
128
129/// @name %%mem.malloc
130///@{
131inline const Def* op_malloc(const Def* type, const Def* mem) {
132 World& w = type->world();
133 auto size = w.call(core::trait::size, type);
134 return w.app(w.app(w.annex<malloc>(), {type, w.lit_nat_0()}), {mem, size});
135}
136///@}
137
138/// @name %%mem.mslot
139///@{
140inline const Def* op_mslot(const Def* type, const Def* mem, const Def* id) {
141 World& w = type->world();
142 auto size = w.call(core::trait::size, type);
143 return w.app(w.app(w.annex<mslot>(), {type, w.lit_nat_0()}), {mem, size, id});
144}
145///@}
146
147} // namespace mim::plug::mem
A (possibly paramterized) Array.
Definition tuple.h:117
static auto isa(const Def *def)
Definition axm.h:107
static auto as(const Def *def)
Definition axm.h:129
Base class for all Defs.
Definition def.h:251
World & world() const noexcept
Definition def.cpp:438
constexpr auto ops() const noexcept
Definition def.h:305
const Def * var(nat_t a, nat_t i) noexcept
Definition def.h:429
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:390
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.cpp:446
nat_t num_projs() const
Yields Def::arity(), if it is a Lit, or 1 otherwise.
Definition def.cpp:580
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:206
A function.
Definition lam.h:110
A dependent tuple type.
Definition tuple.h:20
Data constructor for a Sigma.
Definition tuple.h:68
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:31
const Lit * lit_i64()
Definition world.h:464
The mem Plugin
Definition mem.h:11
const Def * op_slot(const Def *type, const Def *mem)
Definition mem.h:123
const Def * mem_var(Lam *lam)
Returns the memory argument of a function if it has one.
Definition mem.h:38
const Def * mem_def(const Def *def)
Returns the (first) element of type mem.M a from the given tuple.
Definition mem.h:25
const Def * op_mslot(const Def *type, const Def *mem, const Def *id)
Definition mem.h:140
const Def * op_malloc(const Def *type, const Def *mem)
Definition mem.h:131
const Def * strip_mem_ty(const Def *def)
Removes recusively all occurences of mem from a type (sigma).
Definition mem.h:41
const Def * op_lea(const Def *ptr, const Def *index)
Definition mem.h:98
const Def * op_alloc(const Def *type, const Def *mem)
Definition mem.h:115
const Def * op_lea_unsafe(const Def *ptr, const Def *i)
Definition mem.h:105
Lam * mut_con(World &w, nat_t a=0)
Yields con[mem.M 0].
Definition mem.h:16
const Def * strip_mem(const Def *def)
Recursively removes all occurrences of mem from a tuple.
Definition mem.h:59
The tuple Plugin
u64 nat_t
Definition types.h:43
Vector< const Def * > DefVec
Definition def.h:77
const Def * tuple_of_types(const Def *t)
Definition tuple.cpp:162
uint64_t u64
Definition types.h:34