MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
clos.cpp
Go to the documentation of this file.
2
3#include <mim/config.h>
4
5#include <mim/pass/eta_exp.h>
6#include <mim/pass/eta_red.h>
7#include <mim/pass/pass.h>
9
16
17using namespace mim;
18using namespace mim::plug;
19
36
37extern "C" MIM_EXPORT Plugin mim_get_plugin() { return {"clos", clos::register_normalizers, reg_stages, nullptr}; }
38
39namespace mim::plug::clos {
40
41/*
42 * ClosLit
43 */
44
45const Def* ClosLit::env() {
46 assert(def_);
47 return std::get<2_u64>(clos_unpack(def_));
48}
49
50const Def* ClosLit::fnc() {
51 assert(def_);
52 return std::get<1_u64>(clos_unpack(def_));
53}
54
56 auto f = fnc();
57 if (auto a = Axm::isa<attr>(f)) f = a->arg();
58 return f->isa_mut<Lam>();
59}
60
62
63ClosLit isa_clos_lit(const Def* def, bool lambda_or_branch) {
64 auto tpl = def->isa<Tuple>();
65 if (tpl && isa_clos_type(def->type())) {
66 auto a = attr::bottom;
67 auto fnc = std::get<1_u64>(clos_unpack(tpl));
68 if (auto fa = Axm::isa<attr>(fnc)) {
69 fnc = fa->arg();
70 a = fa.id();
71 }
72 if (!lambda_or_branch || fnc->isa<Lam>()) return ClosLit(tpl, a);
73 }
74 return ClosLit(nullptr, attr::bottom);
75}
76
77const Def* clos_pack(const Def* env, const Def* lam, const Def* ct) {
78 assert(env && lam);
79 assert(!ct || isa_clos_type(ct));
80 auto& w = env->world();
81 auto pi = lam->type()->as<Pi>();
82 assert(env->type() == pi->dom(Clos_Env_Param));
83 ct = (ct) ? ct : clos_type(w.cn(clos_remove_env(pi->dom())));
84 return w.tuple(ct, {env->type(), lam, env})->isa<Tuple>();
85}
86
87std::tuple<const Def*, const Def*, const Def*> clos_unpack(const Def* c) {
88 assert(c && isa_clos_type(c->type()));
89 // auto& w = c->world();
90 // auto env_type = c->proj(0_u64);
91 // // auto pi = clos_type_to_pi(c->type(), env_type);
92 // auto fn = w.extract(c, w.lit_idx(3, 1));
93 // auto env = w.extract(c, w.lit_idx(3, 2));
94 // return {env_type, fn, env};
95 auto [ty, pi, env] = c->projs<3>();
96 return {ty, pi, env};
97}
98
99const Def* clos_apply(const Def* closure, const Def* args) {
100 auto& w = closure->world();
101 auto [_, fn, env] = clos_unpack(closure);
102 auto pi = fn->type()->as<Pi>();
103 return w.app(fn, DefVec(pi->num_doms(), [&](auto i) { return clos_insert_env(i, env, args); }));
104}
105
106/*
107 * closure types
108 */
109
110const Sigma* isa_clos_type(const Def* def) {
111 auto& w = def->world();
112 auto sig = def->isa_mut<Sigma>();
113 if (!sig || sig->num_ops() < 3 || sig->op(0_u64) != w.type()) return nullptr;
114 auto var = sig->var(0_u64);
115 if (sig->op(2_u64) != var) return nullptr;
116 auto pi = sig->op(1_u64)->isa<Pi>();
117 return (pi && Pi::isa_cn(pi) && pi->num_ops() > 1_u64 && pi->dom(Clos_Env_Param) == var) ? sig : nullptr;
118}
119
120Sigma* clos_type(const Pi* pi) {
121 auto& w = pi->world();
122 auto doms = pi->doms();
123 return ctype(w, doms, nullptr)->as_mut<Sigma>();
124}
125
126const Pi* clos_type_to_pi(const Def* ct, const Def* new_env_type) {
127 assert(isa_clos_type(ct));
128 auto& w = ct->world();
129 auto pi = ct->op(1_u64)->as<Pi>();
130 auto new_dom = new_env_type ? clos_sub_env(pi->dom(), new_env_type) : clos_remove_env(pi->dom());
131 return w.cn(new_dom);
132}
133
134/*
135 * closure environments
136 */
137
138const Def* clos_insert_env(size_t i, const Def* env, std::function<const Def*(size_t)> f) {
139 return (i == Clos_Env_Param) ? env : f(shift_env(i));
140}
141
142const Def* clos_remove_env(size_t i, std::function<const Def*(size_t)> f) { return f(skip_env(i)); }
143
144const Def* ctype(World& w, Defs doms, const Def* env_type) {
145 if (!env_type) {
146 auto sigma = w.mut_sigma(w.type(), 3_u64)->set("Clos");
147 sigma->set(0_u64, w.type());
148 sigma->set(1_u64, ctype(w, doms, sigma->var(0_u64)));
149 sigma->set(2_u64, sigma->var(0_u64));
150 return sigma;
151 }
152 return w.cn(
153 DefVec(doms.size() + 1, [&](auto i) { return clos_insert_env(i, env_type, [&](auto j) { return doms[j]; }); }));
154}
155
156} // namespace mim::plug::clos
void reg_stages(Flags2Phases &, Flags2Passes &passes)
Definition affine.cpp:12
static auto isa(const Def *def)
Definition axm.h:107
Base class for all Defs.
Definition def.h:251
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
Definition def.h:491
World & world() const noexcept
Definition def.cpp:436
T * isa_mut() const
If this is mutable, it will cast constness away and perform a dynamic_cast to T.
Definition def.h:482
const Def * op(size_t i) const noexcept
Definition def.h:308
const Def * var(nat_t a, nat_t i) noexcept
Definition def.h:429
const Def * type() const noexcept
Yields the "raw" type of this Def (maybe nullptr).
Definition def.h:295
Performs η-reduction.
Definition eta_red.h:9
A function.
Definition lam.h:109
An optimizer that combines several optimizations in an optimal way.
Definition pass.h:111
static void hook(Flags2Passes &passes, Args &&... args)
Definition pass.h:157
P * add(Args &&... args)
Add a pass to this PassMan.
Definition pass.h:138
static void hook(Flags2Phases &phases, Args &&... args)
Definition phase.h:190
A dependent function type.
Definition lam.h:13
static const Pi * isa_cn(const Def *d)
Is this a continuation - i.e. is the Pi::codom mim::Bottom?
Definition lam.h:46
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:36
const Def * fnc()
Definition clos.cpp:50
const Def * env_var()
Definition clos.cpp:61
const Def * env()
Definition clos.cpp:45
void reg_stages(Flags2Phases &phases, Flags2Passes &passes)
Definition clos.cpp:20
#define MIM_EXPORT
Definition config.h:16
The clos Plugin
Definition clos.h:7
ClosLit isa_clos_lit(const Def *def, bool fn_isa_lam=true)
Tries to match a closure literal.
Definition clos.cpp:63
void register_normalizers(Normalizers &normalizers)
Sigma * clos_type(const Pi *pi)
Creates a typed closure type from pi.
Definition clos.cpp:120
size_t shift_env(size_t i)
Definition clos.h:110
const Def * clos_remove_env(size_t i, std::function< const Def *(size_t)> f)
Definition clos.cpp:142
const Def * clos_insert_env(size_t i, const Def *env, std::function< const Def *(size_t)> f)
Definition clos.cpp:138
const Def * ctype(World &w, Defs doms, const Def *env_type=nullptr)
Definition clos.cpp:144
static constexpr size_t Clos_Env_Param
Describes where the environment is placed in the argument list.
Definition clos.h:107
const Pi * clos_type_to_pi(const Def *ct, const Def *new_env_type=nullptr)
Convert a closure type to a Pi, where the environment type has been removed or replaced by new_env_ty...
Definition clos.cpp:126
std::tuple< const Def *, const Def *, const Def * > clos_unpack(const Def *c)
Deconstruct a closure into (env_type, function, env).
Definition clos.cpp:87
const Def * clos_sub_env(const Def *tup_or_sig, const Def *new_env)
Definition clos.h:139
size_t skip_env(size_t i)
Definition clos.h:113
const Def * clos_pack(const Def *env, const Def *fn, const Def *ct=nullptr)
Pack a typed closure. This assumes that fn expects the environment as its Clos_Env_Paramth argument.
Definition clos.cpp:77
const Def * clos_apply(const Def *closure, const Def *args)
Apply a closure to arguments.
Definition clos.cpp:99
const Sigma * isa_clos_type(const Def *def)
Definition clos.cpp:110
Definition ast.h:14
View< const Def * > Defs
Definition def.h:76
Vector< const Def * > DefVec
Definition def.h:77
absl::flat_hash_map< flags_t, std::function< void(PassMan &, const Def *)> > Flags2Passes
Definition plugin.h:24
auto assert_emplace(C &container, Args &&... args)
Invokes emplace on container, asserts that insertion actually happened, and returns the iterator.
Definition util.h:110
u64 flags_t
Definition types.h:45
mim::Plugin mim_get_plugin()
constexpr decltype(auto) get(Span< T, N > span) noexcept
Definition span.h:115
absl::flat_hash_map< flags_t, std::function< void(PhaseMan &, const Def *)> > Flags2Phases
Maps an an axiom of a Pass/Phaseto a function that appneds a new Pass/Phase to a PhaseMan.
Definition plugin.h:23
static constexpr flags_t Base
Definition plugin.h:123
Basic info and registration function pointer to be returned from a specific plugin.
Definition plugin.h:32