MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lattice.h
Go to the documentation of this file.
1#pragma once
2
3#include "mim/def.h"
4
5namespace mim {
6
7class Lam;
8class Sigma;
9
10/// Common base for TBound.
11class Bound : public Def {
12protected:
14 : Def(node, type, ops, 0) {} ///< Constructor for an *immutable* Bound.
15 Bound(node_t node, const Def* type, size_t size)
16 : Def(node, type, size, 0) {} ///< Constructor for a *mutable* Bound.
17
18public:
19 /// @name Get Element by Type
20 ///@{
21 size_t find(const Def* type) const;
22 const Def* get(const Def* type) const { return op(find(type)); }
23 ///@}
24};
25
26/// Specific [Bound](https://en.wikipedia.org/wiki/Join_and_meet) depending on @p Up.
27/// The name @p Up refers to the property that a [Join](@ref mim::Join) **ascends** in the underlying
28/// [lattice](https://en.wikipedia.org/wiki/Lattice_(order)) while a [Meet](@ref mim::Meet) descends.
29/// * @p Up = `true`: [Join](@ref mim::Join) (aka least Upper bound/supremum/union)
30/// * @p Up = `false`: [Meet](@ref mim::Meet) (aka greatest lower bound/infimum/intersection)
31template<bool Up> class TBound : public Bound, public Setters<TBound<Up>> {
32private:
33 TBound(const Def* type, Defs ops)
34 : Bound(Node, type, ops) {} ///< Constructor for an *immutable* Bound.
35 TBound(const Def* type, size_t size)
36 : Bound(Node, type, size) {} ///< Constructor for a *mutable* Bound.
37
38public:
40
41 TBound* stub(Ref type) { return stub_(world(), type)->set(dbg()); }
42
43 static constexpr auto Node = Up ? Node::Join : Node::Meet;
44
45private:
46 Ref rebuild_(World&, Ref, Defs) const override;
47 TBound* stub_(World&, Ref) override;
48
49 friend class World;
50};
51
52/// Constructs a [Meet](@ref mim::Meet) **value**.
53/// @remark [Ac](https://en.wikipedia.org/wiki/Wedge_(symbol)) is Latin and means *and*.
54class Ac : public Def, public Setters<Ac> {
55public:
56 using Setters<Ac>::set;
57 static constexpr auto Node = Node::Ac;
58
59private:
60 Ac(const Def* type, Defs defs)
61 : Def(Node, type, defs, 0) {}
62
63 Ref rebuild_(World&, Ref, Defs) const override;
64
65 friend class World;
66};
67
68/// Constructs a [Join](@ref mim::Join) **value**.
69/// @remark [Vel](https://en.wikipedia.org/wiki/Wedge_(symbol)) is Latin and means *or*.
70class Vel : public Def, public Setters<Vel> {
71private:
72 Vel(const Def* type, const Def* value)
73 : Def(Node, type, {value}, 0) {}
74
75public:
76 using Setters<Vel>::set;
77
78 /// @name ops
79 ///@{
80 const Def* value() const { return op(0); }
81 ///@}
82
83 static constexpr auto Node = Node::Vel;
84
85private:
86 Ref rebuild_(World&, Ref, Defs) const override;
87
88 friend class World;
89};
90
91/// Picks the aspect of a Meet [value](Pick::value) by its [type](Def::type).
92class Pick : public Def, public Setters<Pick> {
93private:
94 Pick(const Def* type, const Def* value)
95 : Def(Node, type, {value}, 0) {}
96
97public:
98 using Setters<Pick>::set;
99
100 /// @name ops
101 ///@{
102 const Def* value() const { return op(0); }
103 ///@}
104
105 static constexpr auto Node = Node::Pick;
106
107private:
108 Ref rebuild_(World&, Ref, Defs) const override;
109
110 friend class World;
111};
112
113/// Test whether Test::value currently holds **type** Test::probe:
114/// ```
115/// test value, probe, match, clash
116/// ```
117/// @note
118/// * Test::probe is a **type**!
119/// * This operation yields Test::match, if `tt`, and Test::clash otherwise.
120/// @invariant
121/// * Test::value must be of type Join.
122/// * Test::match must be of type `A -> B`.
123/// * Test::clash must be of type `[A, probe] -> C`.
124/// @remark This operation is usually known as `case` but named `Test` since `case` is a keyword in C++.
125class Test : public Def, public Setters<Test> {
126private:
127 Test(const Def* type, const Def* value, const Def* probe, const Def* match, const Def* clash)
128 : Def(Node, type, {value, probe, match, clash}, 0) {}
129
130public:
131 using Setters<Test>::set;
132 static constexpr auto Node = Node::Test;
133
134 /// @name ops
135 ///@{
136 const Def* value() const { return op(0); }
137 const Def* probe() const { return op(1); }
138 const Def* match() const { return op(2); }
139 const Def* clash() const { return op(3); }
140 ///@}
141
142private:
143 Ref rebuild_(World&, Ref, Defs) const override;
144
145 friend class World;
146};
147
148/// Common base for TExt%remum.
149class Ext : public Def {
150protected:
152 : Def(node, type, Defs{}, 0) {}
153};
154
155/// Ext%remum. Either Top (@p Up) or Bot%tom.
156template<bool Up> class TExt : public Ext, public Setters<TExt<Up>> {
157private:
158 TExt(const Def* type)
159 : Ext(Node, type) {}
160
161public:
162 using Setters<TExt<Up>>::set;
163
164 TExt* stub(Ref type) { return stub_(world(), type)->set(dbg()); }
165
166 static constexpr auto Node = Up ? Node::Top : Node::Bot;
167
168private:
169 Ref rebuild_(World&, Ref, Defs) const override;
170 TExt* stub_(World&, Ref) override;
171
172 friend class World;
173};
174
175/// @name Lattice
176///@{
181/// @}
182
183/// A singleton wraps a type into a higher order type.
184/// Therefore any type can be the only inhabitant of a singleton.
185/// Use in conjunction with @ref mim::Join.
186class Singleton : public Def, public Setters<Singleton> {
187private:
188 Singleton(const Def* type, const Def* inner_type)
189 : Def(Node, type, {inner_type}, 0) {}
190
191public:
192 using Setters<Singleton>::set;
193
194 /// @name ops
195 ///@{
196 const Def* inhabitant() const { return op(0); }
197 ///@}
198
199 static constexpr auto Node = Node::Singleton;
200
201private:
202 Ref rebuild_(World&, Ref, Defs) const override;
203
204 friend class World;
205};
206
207} // namespace mim
Constructs a Meet value.
Definition lattice.h:54
static constexpr auto Node
Definition lattice.h:57
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:94
Common base for TBound.
Definition lattice.h:11
Bound(node_t node, const Def *type, size_t size)
Constructor for a mutable Bound.
Definition lattice.h:15
size_t find(const Def *type) const
Definition lattice.cpp:7
const Def * get(const Def *type) const
Definition lattice.h:22
Bound(node_t node, const Def *type, Defs ops)
Constructor for an immutable Bound.
Definition lattice.h:13
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
node_t node() const
Definition def.h:241
Dbg dbg() const
Definition def.h:466
Common base for TExtremum.
Definition lattice.h:149
Ext(node_t node, const Def *type)
Definition lattice.h:151
Picks the aspect of a Meet [value](Pick::value) by its [type](Def::type).
Definition lattice.h:92
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:103
static constexpr auto Node
Definition lattice.h:105
const Def * value() const
Definition lattice.h:102
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
const TBound< Up > * set(Loc l) const
Definition def.h:193
A singleton wraps a type into a higher order type.
Definition lattice.h:186
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:106
const Def * inhabitant() const
Definition lattice.h:196
static constexpr auto Node
Definition lattice.h:199
This is a thin wrapper for std::span<T, N> with the following additional features:
Definition span.h:28
Specific Bound depending on Up.
Definition lattice.h:31
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:122
TBound * stub_(World &, Ref) override
Definition def.cpp:136
TBound * stub(Ref type)
Definition lattice.h:41
static constexpr auto Node
Definition lattice.h:43
Extremum. Either Top (Up) or Bottom.
Definition lattice.h:156
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:121
static constexpr auto Node
Definition lattice.h:166
TExt * stub(Ref type)
Definition lattice.h:164
TExt * stub_(World &, Ref) override
Definition def.cpp:137
Test whether Test::value currently holds type Test::probe:
Definition lattice.h:125
const Def * clash() const
Definition lattice.h:139
const Def * probe() const
Definition lattice.h:137
const Def * match() const
Definition lattice.h:138
const Def * value() const
Definition lattice.h:136
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:108
static constexpr auto Node
Definition lattice.h:132
Constructs a Join value.
Definition lattice.h:70
static constexpr auto Node
Definition lattice.h:83
const Def * value() const
Definition lattice.h:80
Ref rebuild_(World &, Ref, Defs) const override
Definition def.cpp:113
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
@ Test
Definition def.h:40
@ Sigma
Definition def.h:40
@ Join
Definition def.h:40
@ Singleton
Definition def.h:40
@ Pick
Definition def.h:40
@ Bot
Definition def.h:40
@ Top
Definition def.h:40
@ Ac
Definition def.h:40
@ Vel
Definition def.h:40
@ Lam
Definition def.h:40
@ Meet
Definition def.h:40
Definition cfg.h:11
u8 node_t
Definition types.h:44