MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
tuple.h
Go to the documentation of this file.
1#pragma once
2
3#include "mim/def.h"
4
5namespace mim {
6
7/// A [dependent tuple type](https://en.wikipedia.org/wiki/Dependent_type#%CE%A3_type).
8/// @see Tuple, Arr, Pack
9class Sigma : public Def, public Setters<Sigma> {
10private:
11 Sigma(const Def* type, Defs ops)
12 : Def(Node, type, ops, 0) {} ///< Constructor for an *immutable* Sigma.
13 Sigma(const Def* type, size_t size)
14 : Def(Node, type, size, 0) {} ///< Constructor for a *mutable* Sigma.
15
16public:
17 /// @name Setters
18 /// @see @ref set_ops "Setting Ops"
19 ///@{
20 using Setters<Sigma>::set;
21 Sigma* set(size_t i, const Def* def) { return Def::set(i, def)->as<Sigma>(); }
22 Sigma* set(Defs ops) { return Def::set(ops)->as<Sigma>(); }
23 Sigma* unset() { return Def::unset()->as<Sigma>(); }
24 ///@}
25
26 /// @name Rebuild
27 ///@{
28 const Def* immutabilize() override;
29 Sigma* stub(Ref type) { return stub_(world(), type)->set(dbg()); }
30 ///@}
31
32 /// @name Type Checking
33 ///@{
34 void check() override;
35 static Ref infer(World&, Defs);
36 ///@}
37
38 static constexpr auto Node = Node::Sigma;
39
40private:
41 Ref rebuild_(World&, Ref, Defs) const override;
42 Sigma* stub_(World&, Ref) override;
43
44 friend class World;
45};
46
47/// Data constructor for a Sigma.
48/// @see Sigma, Arr, Pack
49class Tuple : public Def, public Setters<Tuple> {
50public:
51 using Setters<Tuple>::set;
52 static constexpr auto Node = Node::Tuple;
53
54private:
55 Tuple(const Def* type, Defs args)
56 : Def(Node, type, args, 0) {}
57
58 Ref rebuild_(World&, Ref, Defs) const override;
59
60 friend class World;
61};
62
63/// A (possibly paramterized) Arr%ay.
64/// Arr%ays are usually homogenous but they can be *inhomogenous* as well: `«i: N; T#i»`
65/// @see Sigma, Tuple, Pack
66class Arr : public Def, public Setters<Arr> {
67private:
68 Arr(const Def* type, const Def* shape, const Def* body)
69 : Def(Node, type, {shape, body}, 0) {} ///< Constructor for an *immutable* Arr.
70 Arr(const Def* type)
71 : Def(Node, type, 2, 0) {} ///< Constructor for a *mut*able Arr.
72
73public:
74 /// @name ops
75 ///@{
76 const Def* shape() const { return op(0); }
77 const Def* body() const { return op(1); }
78 ///@}
79
80 /// @name Setters
81 /// @see @ref set_ops "Setting Ops"
82 ///@{
83 using Setters<Arr>::set;
84 Arr* set_shape(const Def* shape) { return Def::set(0, shape)->as<Arr>(); }
85 Arr* set_body(const Def* body) { return Def::set(1, body)->as<Arr>(); }
86 Arr* unset() { return Def::unset()->as<Arr>(); }
87 ///@}
88
89 /// @name Rebuild
90 ///@{
91 const Def* reduce(const Def* arg) const;
92 Arr* stub(Ref type) { return stub_(world(), type)->set(dbg()); }
93 const Def* immutabilize() override;
94 ///@}
95
96 /// @name Type Checking
97 ///@{
98 void check() override;
99 ///@}
100
101 static constexpr auto Node = Node::Arr;
102
103private:
104 Ref rebuild_(World&, Ref, Defs) const override;
105 Arr* stub_(World&, Ref) override;
106
107 friend class World;
108};
109
110/// A (possibly paramterized) Tuple.
111/// @see Sigma, Tuple, Arr
112class Pack : public Def, public Setters<Pack> {
113private:
114 Pack(const Def* type, const Def* body)
115 : Def(Node, type, {body}, 0) {} ///< Constructor for an *immutable* Pack.
116 Pack(const Def* type)
117 : Def(Node, type, 1, 0) {} ///< Constructor for a *mut*ablel Pack.
118
119public:
120 /// @name ops
121 ///@{
122 const Def* body() const { return op(0); }
123 const Def* shape() const;
124 ///@}
125
126 /// @name Setters
127 /// @see @ref set_ops "Setting Ops"
128 ///@{
129 using Setters<Pack>::set;
130 Pack* set(const Def* body) { return Def::set(0, body)->as<Pack>(); }
131 Pack* reset(const Def* body) { return unset()->set(body); }
132 Pack* unset() { return Def::unset()->as<Pack>(); }
133 ///@}
134
135 /// @name Rebuild
136 ///@{
137 const Def* reduce(const Def* arg) const;
138 Pack* stub(Ref type) { return stub_(world(), type)->set(dbg()); }
139 const Def* immutabilize() override;
140 ///@}
141
142 static constexpr auto Node = Node::Pack;
143
144private:
145 Ref rebuild_(World&, Ref, Defs) const override;
146 Pack* stub_(World&, Ref) override;
147
148 friend class World;
149};
150
151/// Extracts from a Sigma or Arr%ay-typed Extract::tuple the element at position Extract::index.
152class Extract : public Def, public Setters<Extract> {
153private:
154 Extract(const Def* type, const Def* tuple, const Def* index)
155 : Def(Node, type, {tuple, index}, 0) {}
156
157public:
158 using Setters<Extract>::set;
159
160 /// @name ops
161 ///@{
162 const Def* tuple() const { return op(0); }
163 const Def* index() const { return op(1); }
164 ///@}
165
166 static constexpr auto Node = Node::Extract;
167
168private:
169 Ref rebuild_(World&, Ref, Defs) const override;
170
171 friend class World;
172};
173
174/// Creates a new Tuple / Pack by inserting Insert::value at position Insert::index into Insert::tuple.
175/// @attention This is a *functional* Insert.
176/// The Insert::tuple itself remains untouched.
177/// The Insert itself is a *new* Tuple / Pack which contains the inserted Insert::value.
178class Insert : public Def, public Setters<Insert> {
179private:
180 Insert(const Def* tuple, const Def* index, const Def* value)
181 : Def(Node, tuple->type(), {tuple, index, value}, 0) {}
182
183public:
184 using Setters<Insert>::set;
185
186 /// @name ops
187 ///@{
188 const Def* tuple() const { return op(0); }
189 const Def* index() const { return op(1); }
190 const Def* value() const { return op(2); }
191 ///@}
192
193 static constexpr auto Node = Node::Insert;
194
195private:
196 Ref rebuild_(World&, Ref, Defs) const override;
197
198 friend class World;
199};
200
201/// @name Helpers to work with Tulpes/Sigmas/Arrays/Packs
202///@{
203bool is_unit(const Def*);
204std::string tuple2str(const Def*);
205
206/// Flattens a sigma/array/pack/tuple.
207const Def* flatten(const Def* def);
208/// Same as unflatten, but uses the operands of a flattened Pack / Tuple directly.
209size_t flatten(DefVec& ops, const Def* def, bool flatten_sigmas = true);
210
211/// Applies the reverse transformation on a Pack / Tuple, given the original type.
212const Def* unflatten(const Def* def, const Def* type);
213/// Same as unflatten, but uses the operands of a flattened Pack / Tuple directly.
214const Def* unflatten(Defs ops, const Def* type, bool flatten_muts = true);
215
217DefVec merge(const Def* def, Defs defs);
218const Def* merge_sigma(const Def* def, Defs defs);
219const Def* merge_tuple(const Def* def, Defs defs);
220
222///@}
223
224} // namespace mim
A (possibly paramterized) Array.
Definition tuple.h:66
Arr * stub(Ref type)
Definition tuple.h:92
const Def * immutabilize() override
Tries to make an immutable from a mutable.
Definition def.cpp:172
void check() override
Definition check.cpp:225
const Def * body() const
Definition tuple.h:77
static constexpr auto Node
Definition tuple.h:101
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:96
Arr * unset()
Definition tuple.h:86
Arr * set_body(const Def *body)
Definition tuple.h:85
Arr * stub_(World &, Ref) override
Definition def.cpp:128
Arr * set_shape(const Def *shape)
Definition tuple.h:84
const Def * shape() const
Definition tuple.h:76
const Def * reduce(const Def *arg) const
Definition def.cpp:196
Base class for all Defs.
Definition def.h:223
Def * set(size_t i, const Def *def)
Successively set from left to right.
Definition def.cpp:246
const Def * op(size_t i) const
Definition def.h:269
World & world() const
Definition def.cpp:415
auto ops() const
Definition def.h:268
const Def * type() const
Definition def.h:248
Def * unset()
Unsets all Def::ops; works even, if not set at all or partially.
Definition def.cpp:264
Dbg dbg() const
Definition def.h:466
Extracts from a Sigma or Array-typed Extract::tuple the element at position Extract::index.
Definition tuple.h:152
const Def * tuple() const
Definition tuple.h:162
static constexpr auto Node
Definition tuple.h:166
const Def * index() const
Definition tuple.h:163
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:97
Creates a new Tuple / Pack by inserting Insert::value at position Insert::index into Insert::tuple.
Definition tuple.h:178
static constexpr auto Node
Definition tuple.h:193
const Def * tuple() const
Definition tuple.h:188
const Def * index() const
Definition tuple.h:189
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:98
const Def * value() const
Definition tuple.h:190
A (possibly paramterized) Tuple.
Definition tuple.h:112
const Def * body() const
Definition tuple.h:122
Pack * reset(const Def *body)
Definition tuple.h:131
Pack * stub_(World &, Ref) override
Definition def.cpp:132
Pack * unset()
Definition tuple.h:132
const Def * shape() const
Definition tuple.cpp:40
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:101
const Def * reduce(const Def *arg) const
Definition def.cpp:201
const Def * immutabilize() override
Tries to make an immutable from a mutable.
Definition def.cpp:182
static constexpr auto Node
Definition tuple.h:142
Pack * set(const Def *body)
Definition tuple.h:130
Pack * stub(Ref type)
Definition tuple.h:138
Helper class to retrieve Infer::arg if present.
Definition def.h:86
CRTP-based Mixin to declare setters for Def::loc & Def::name using a covariant return type.
Definition def.h:186
A dependent tuple type.
Definition tuple.h:9
Sigma * unset()
Definition tuple.h:23
const Def * immutabilize() override
Tries to make an immutable from a mutable.
Definition def.cpp:166
static Ref infer(World &, Defs)
Definition check.cpp:232
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:105
Sigma * set(Defs ops)
Definition tuple.h:22
Sigma * stub(Ref type)
Definition tuple.h:29
Sigma * stub_(World &, Ref) override
Definition def.cpp:134
void check() override
Definition check.cpp:238
static constexpr auto Node
Definition tuple.h:38
Sigma * set(size_t i, const Def *def)
Definition tuple.h:21
This is a thin wrapper for std::span<T, N> with the following additional features:
Definition span.h:28
Data constructor for a Sigma.
Definition tuple.h:49
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:109
static constexpr auto Node
Definition tuple.h:52
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
@ Sigma
Definition def.h:40
@ Pack
Definition def.h:40
@ Tuple
Definition def.h:40
@ Arr
Definition def.h:40
@ Extract
Definition def.h:40
@ Insert
Definition def.h:40
Definition cfg.h:11
const Def * flatten(const Def *def)
Flattens a sigma/array/pack/tuple.
Definition tuple.cpp:66
bool is_unit(const Def *)
Definition tuple.cpp:46
const Def * merge_sigma(const Def *def, Defs defs)
Definition tuple.cpp:93
std::string tuple2str(const Def *)
Definition tuple.cpp:48
DefVec merge(Defs, Defs)
Definition tuple.cpp:86
const Def * unflatten(const Def *def, const Def *type)
Applies the reverse transformation on a Pack / Tuple, given the original type.
Definition tuple.cpp:80
Ref tuple_of_types(Ref t)
Definition tuple.cpp:109
const Def * merge_tuple(const Def *def, Defs defs)
Definition tuple.cpp:98