MimIR
0.4-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
Loading...
Searching...
No Matches
normalizers.cpp
Go to the documentation of this file.
1
#include <absl/container/btree_set.h>
2
#include <absl/container/fixed_array.h>
3
4
#include <
mim/tuple.h
>
5
#include <
mim/world.h
>
6
7
#include <
mim/plug/core/core.h
>
8
9
#include "
mim/plug/vec/vec.h
"
10
11
namespace
mim::plug::vec
{
12
13
template
<fold
id
>
14
const
Def
*
normalize_fold
(
const
Def
* type,
const
Def
* c,
const
Def
* arg) {
15
auto
& w = c->world();
16
auto
callee = c->as<
App
>();
17
auto
f = callee->arg();
18
19
auto
[acc,
vec
] = arg->
projs
<2>();
20
if
constexpr
(
id
==
fold::r
) std::swap(acc,
vec
);
21
22
if
(
auto
tuple
=
vec
->isa<
Tuple
>()) {
23
if
constexpr
(
id
==
fold::l
)
24
for
(
auto
op :
tuple
->ops())
25
acc = w.app(f, {acc, op});
26
else
// fold::r
27
for
(
auto
op :
tuple
->ops() | std::views::reverse)
28
acc = w.app(f, {op, acc});
29
return
acc;
30
}
31
32
if
(
auto
seq =
vec
->isa<
Seq
>()) {
33
if
(
auto
n =
Lit::isa<u64>
(seq->arity()); n && type->isa<
Nat
>()) {
34
if
constexpr
(
id
==
fold::l
)
35
for
(
auto
proj : seq->projs(*n))
36
acc = w.app(f, {acc, proj});
37
else
// fold::r
38
for
(
auto
proj : seq->projs(*n) | std::views::reverse)
39
acc = w.app(f, {proj, acc});
40
return
acc;
41
}
42
w.log().w(
"Pack of non-literal arity not yet implemented: {}"
, seq);
43
}
44
45
if
(
auto
l =
vec
->isa<
Lit
>()) {
46
if
constexpr
(
id
==
fold::l
)
47
return
w.app(f, {acc, l});
48
else
49
return
w.app(f, {l, acc});
50
}
51
52
return
nullptr
;
53
}
54
55
const
Def
*
normalize_zip
(
const
Def
* type,
const
Def
* c,
const
Def
* arg) {
56
if
(arg->
is_open
())
return
{};
57
auto
& w = type->world();
58
auto
[ni_n, _, f] =
App::uncurry_args<3>
(c);
59
auto
[ni, n] = ni_n->projs<2>([](
const
Def
* def) {
return
Lit::isa
(def); });
60
61
if
(!ni || !n)
return
{};
62
if
(ni >= w.flags().scalarize_threshold || n >= w.flags().scalarize_threshold)
return
{};
63
64
auto
res = absl::FixedArray<const Def*>(*n);
65
auto
tup = absl::FixedArray<const Def*>(*ni);
66
67
for
(
size_t
j = 0; j != n; ++j) {
68
for
(
size_t
i = 0; i != ni; ++i)
69
tup[i] = arg->
proj
(*ni, i)->
proj
(*n, j);
70
71
res[j] = w.app(f, tup);
72
}
73
74
return
w.tuple(res);
75
}
76
77
template
<scan
id
>
78
const
Def
*
normalize_scan
(
const
Def
*,
const
Def
* c,
const
Def
*
vec
) {
79
auto
& w = c->world();
80
auto
callee = c->as<
App
>();
81
auto
p = callee->
arg
();
82
83
if
(
auto
tuple
=
vec
->isa<
Tuple
>()) {
84
const
Def
* acc = w.lit_bool(
id
!=
scan::exists
);
85
for
(
auto
op :
tuple
->ops())
86
acc = w.call(
id
==
scan::exists
?
core::bit2::or_
:
core::bit2::and_
, 0_n,
Defs
{acc, w.app(p, op)});
87
return
acc;
88
}
89
90
if
(
auto
pack =
vec
->isa_imm<
Pack
>()) w.log().w(
"Pack not yet implemented: {}"
, pack);
91
92
return
nullptr
;
93
}
94
95
const
Def
*
normalize_is_unique
(
const
Def
*,
const
Def
*,
const
Def
*
vec
) {
96
auto
& w =
vec
->world();
97
98
if
(
auto
tuple
=
vec
->isa<
Tuple
>()) {
99
auto
seen =
DefSet
();
100
for
(
auto
op :
tuple
->ops()) {
101
auto
[_, ins] = seen.emplace(op);
102
if
(!ins)
return
w.lit_ff();
103
}
104
return
tuple
->is_closed() ? w.lit_tt() :
nullptr
;
105
}
106
107
if
(
auto
pack =
vec
->isa_imm<
Pack
>()) {
108
if
(
auto
l =
Lit::isa
(pack->arity()))
return
w.lit_ff();
109
}
110
111
if
(
vec
->isa<
Lit
>())
return
w.lit_tt();
112
113
return
nullptr
;
114
}
115
116
const
Def
*
normalize_cat
(
const
Def
*,
const
Def
* callee,
const
Def
* arg) {
117
auto
[a, b] = arg->
projs
<2>();
118
auto
[n, m] = callee->as<
App
>()->decurry()->args<2>([](
auto
def) {
return
Lit::isa
(def); });
119
if
(n && *n == 0)
return
b;
120
if
(m && *m == 0)
return
a;
121
if
(n && m)
return
mim::cat_tuple
(*n, *m, a, b);
122
return
nullptr
;
123
}
124
125
const
Def
*
normalize_diff
(
const
Def
* type,
const
Def
* c,
const
Def
* arg) {
126
if
(
auto
arr = type->isa<
Arr
>()) {
127
if
(arr->arity()->isa<
Bot
>())
return
nullptr
;
// ack error
128
}
129
130
auto
& w = type->world();
131
auto
callee = c->as<
App
>();
132
auto
[n, m] = callee->args<2>([](
auto
def) {
return
Lit::isa
(def); });
133
auto
[
vec
, is] = arg->
projs
<2>();
134
135
if
(!n || !m)
return
nullptr
;
136
if
(n == 1 && m == 1)
return
w.tuple();
137
138
if
(
auto
tup_vec =
vec
->isa<
Tuple
>()) {
139
if
(
auto
tup_is = is->isa<
Tuple
>(); tup_is && tup_is->
is_closed
()) {
140
auto
defs =
DefVec
();
141
auto
set = absl::btree_set<nat_t>();
142
for
(
auto
opi : tup_is->ops())
143
set.emplace(
Lit::as
(opi));
144
145
for
(
size_t
i = 0, e = tup_vec->num_ops(); i != e; ++i)
146
if
(!set.contains(i)) defs.emplace_back(tup_vec->op(i));
147
return
w.tuple(defs);
148
}
149
if
(
auto
lit_is =
Lit::isa
(is)) {
150
auto
defs =
DefVec
();
151
152
for
(
size_t
i = 0, e = tup_vec->num_ops(); i != e; ++i)
153
if
(i != lit_is) defs.emplace_back(tup_vec->op(i));
154
return
w.tuple(defs);
155
}
156
}
157
158
if
(
auto
tup_pack =
vec
->isa_imm<
Pack
>())
return
w.pack(*n - *m, tup_pack->body());
159
160
return
nullptr
;
161
}
162
163
MIM_vec_NORMALIZER_IMPL
164
165
}
// namespace mim::plug::vec
mim::App
Definition
lam.h:224
mim::App::uncurry_args
auto uncurry_args() const
Definition
lam.h:329
mim::App::arg
const Def * arg() const
Definition
lam.h:284
mim::Arr
A (possibly paramterized) Array.
Definition
tuple.h:110
mim::Def
Base class for all Defs.
Definition
def.h:273
mim::Def::proj
const Def * proj(nat_t a, nat_t i) const
Similar to World::extract while assuming an arity of a, but also works on Sigmas and Arrays.
Definition
def.cpp:623
mim::Def::projs
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:440
mim::Def::is_open
bool is_open() const
Same as has_free_vars().
Definition
def.h:521
mim::Def::is_closed
bool is_closed() const
Same as !has_free_vars().
Definition
def.cpp:353
mim::Lit
Definition
def.h:913
mim::Lit::isa
static std::optional< T > isa(const Def *def)
Definition
def.h:937
mim::Lit::as
static T as(const Def *def)
Definition
def.h:943
mim::Nat
Definition
def.h:961
mim::Pack
A (possibly paramterized) Tuple.
Definition
tuple.h:137
mim::Seq
Base class for Arr and Pack.
Definition
tuple.h:75
mim::Tuple
Data constructor for a Sigma.
Definition
tuple.h:61
core.h
mim::plug::core::bit2::and_
@ and_
Definition
autogen.h:108
mim::plug::core::bit2::or_
@ or_
Definition
autogen.h:114
mim::plug::tuple
The tuple Plugin
Definition
normalizers.cpp:6
mim::plug::vec
The vec Plugin
Definition
normalizers.cpp:11
mim::plug::vec::normalize_scan
const Def * normalize_scan(const Def *, const Def *c, const Def *vec)
Definition
normalizers.cpp:78
mim::plug::vec::fold::l
@ l
Definition
autogen.h:15
mim::plug::vec::fold::r
@ r
Definition
autogen.h:16
mim::plug::vec::normalize_cat
const Def * normalize_cat(const Def *, const Def *callee, const Def *arg)
Definition
normalizers.cpp:116
mim::plug::vec::normalize_fold
const Def * normalize_fold(const Def *type, const Def *c, const Def *arg)
Definition
normalizers.cpp:14
mim::plug::vec::normalize_is_unique
const Def * normalize_is_unique(const Def *, const Def *, const Def *vec)
Definition
normalizers.cpp:95
mim::plug::vec::normalize_diff
const Def * normalize_diff(const Def *type, const Def *c, const Def *arg)
Definition
normalizers.cpp:125
mim::plug::vec::normalize_zip
const Def * normalize_zip(const Def *type, const Def *c, const Def *arg)
Definition
normalizers.cpp:55
mim::plug::vec::scan::exists
@ exists
Definition
autogen.h:36
mim::cat_tuple
const Def * cat_tuple(nat_t n, nat_t m, const Def *a, const Def *b)
Definition
tuple.cpp:92
mim::Defs
fe::View< const Def * > Defs
Definition
def.h:91
mim::DefVec
fe::Vector< const Def * > DefVec
Definition
def.h:93
mim::DefSet
GIDSet< const Def * > DefSet
Definition
def.h:89
mim::Bot
TExt< false > Bot
Definition
lattice.h:164
tuple.h
MIM_vec_NORMALIZER_IMPL
#define MIM_vec_NORMALIZER_IMPL
Definition
autogen.h:91
vec.h
world.h
src
mim
plug
vec
normalizers.cpp
Generated by
1.18.0