MimIR 0.1
MimIR is my Intermediate Representation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
core.h
Go to the documentation of this file.
1#pragma once
2
3#include <mim/axiom.h>
4#include <mim/world.h>
5
7
8namespace mim::plug::core {
9
10/// @name Mode
11///@{
12/// What should happen if Idx arithmetic overflows?
13enum class Mode : nat_t {
14 none = 0, ///< Wrap around.
15 nsw = 1 << 0, ///< No Signed Wrap around.
16 nuw = 1 << 1, ///< No Unsigned Wrap around.
18};
19
20/// Give Mode as mim::plug::math::Mode, mim::nat_t or const Def*.
21using VMode = std::variant<Mode, nat_t, const Def*>;
22
23/// mim::plug::core::VMode -> const Def*.
24inline const Def* mode(World& w, VMode m) {
25 if (auto def = std::get_if<const Def*>(&m)) return *def;
26 if (auto nat = std::get_if<nat_t>(&m)) return w.lit_nat(*nat);
27 return w.lit_nat((nat_t)std::get<Mode>(m));
28}
29///@}
30
31/// @name %%core.trait
32///@{
33inline const Def* op(trait o, const Def* type) {
34 World& w = type->world();
35 return w.app(w.annex(o), type);
36}
37///@}
38
39/// @name %%core.pe
40///@{
41inline const Def* op(pe o, const Def* def) {
42 World& w = def->world();
43 return w.app(w.app(w.annex(o), def->type()), def);
44}
45///@}
46
47/// @name %%core.bit2
48///@{
49/// Use like this: `a op b = tab[a][b]`
50constexpr std::array<std::array<u64, 2>, 2> make_truth_table(bit2 id) {
51 return {
52 {{sub_t(id) & sub_t(0b0001) ? u64(-1) : 0, sub_t(id) & sub_t(0b0100) ? u64(-1) : 0},
53 {sub_t(id) & sub_t(0b0010) ? u64(-1) : 0, sub_t(id) & sub_t(0b1000) ? u64(-1) : 0}}
54 };
55}
56///@}
57
58/// @name extract_unsafe
59///@{
60inline const Def* extract_unsafe(const Def* d, const Def* i) {
61 World& w = d->world();
62 return w.extract(d, w.call(conv::u, d->unfold_type()->arity(), i));
63}
64inline const Def* extract_unsafe(const Def* d, u64 i) {
65 World& w = d->world();
66 return extract_unsafe(d, w.lit_idx(0_u64, i));
67}
68///@}
69
70/// @name insert_unsafe
71///@{
72inline const Def* insert_unsafe(const Def* d, const Def* i, const Def* val) {
73 World& w = d->world();
74 return w.insert(d, w.call(conv::u, d->unfold_type()->arity(), i), val);
75}
76inline const Def* insert_unsafe(const Def* d, u64 i, const Def* val) {
77 World& w = d->world();
78 return insert_unsafe(d, w.lit_idx(0_u64, i), val);
79}
80///@}
81
82/// @name Convert TBound to Sigma
83/// This is WIP.
84///@{
85template<bool up> const Sigma* convert(const TBound<up>* b);
86inline const Sigma* convert(const Bound* b) { return b->isa<Join>() ? convert(b->as<Join>()) : convert(b->as<Meet>()); }
87///@}
88
89} // namespace mim::plug::core
90
91namespace mim {
92
93/// @name is_commutative/is_associative
94///@{
95// clang-format off
96constexpr bool is_commutative(plug::core::nat id) { return id == plug::core::nat ::add || id == plug::core::nat ::mul; }
97constexpr bool is_commutative(plug::core::ncmp id) { return id == plug::core::ncmp:: e || id == plug::core::ncmp:: ne; }
99constexpr bool is_commutative(plug::core::icmp id) { return id == plug::core::icmp:: e || id == plug::core::icmp:: ne; }
100// clang-format off
101
103 auto tab = make_truth_table(id);
104 return tab[0][1] == tab[1][0];
105}
106
108 switch (id) {
116 case plug::core::bit2::f: return true;
117 default: return false;
118 }
119}
120
121// clang-format off
122constexpr bool is_associative(plug::core::nat id) { return is_commutative(id); }
123constexpr bool is_associative(plug::core::ncmp id) { return is_commutative(id); }
124constexpr bool is_associative(plug::core::icmp id) { return is_commutative(id); }
125constexpr bool is_associative(plug::core::wrap id) { return is_commutative(id); }
126// clang-format on
127///@}
128
129} // namespace mim
130
131#ifndef DOXYGEN
132template<> struct fe::is_bit_enum<mim::plug::core::Mode> : std::true_type {};
133#endif
Common base for TBound.
Definition lattice.h:11
Base class for all Defs.
Definition def.h:198
World & world() const noexcept
Definition def.cpp:413
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:242
A dependent tuple type.
Definition tuple.h:9
Specific Bound depending on Up.
Definition lattice.h:31
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
The core Plugin
Definition core.h:8
const Def * extract_unsafe(const Def *d, const Def *i)
Definition core.h:60
const Sigma * convert(const TBound< up > *b)
Definition core.cpp:19
std::variant< Mode, nat_t, const Def * > VMode
Give Mode as mim::plug::math::Mode, mim::nat_t or const Def*.
Definition core.h:21
const Def * op(trait o, const Def *type)
Definition core.h:33
constexpr std::array< std::array< u64, 2 >, 2 > make_truth_table(bit2 id)
Definition core.h:50
const Def * insert_unsafe(const Def *d, const Def *i, const Def *val)
Definition core.h:72
@ nuw
No Unsigned Wrap around.
Definition core.h:16
@ none
Wrap around.
Definition core.h:14
@ nsw
No Signed Wrap around.
Definition core.h:15
Definition ast.h:14
u64 nat_t
Definition types.h:43
u8 sub_t
Definition types.h:48
TBound< true > Join
Definition lattice.h:180
constexpr bool is_commutative(Id)
Definition axiom.h:139
constexpr bool is_associative(Id id)
Definition axiom.h:142
uint64_t u64
Definition types.h:34
TBound< false > Meet
Definition lattice.h:179