MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
dispatch_normalize.cpp
Go to the documentation of this file.
2
3#include "mim/lam.h"
4
5namespace mim {
6
8 auto new_lam = new_world().mut_lam(rewrite(old_lam->type())->as<Pi>());
9 map(old_lam, new_lam);
10 if (!old_lam->is_set()) return new_lam;
11
12 auto _ = enter(old_lam);
13 auto filter = rewrite(old_lam->filter());
14 auto body = rewrite(old_lam->body());
15 if (auto dispatch = Dispatch(body))
16 if (auto callee = normalize(dispatch); callee != dispatch.callee())
17 body = new_world().app(callee, dispatch.arg());
18 new_lam->set(filter, body);
19 return seal(old_lam, new_lam);
20}
21
22const Def* DispatchNormalize::normalize(Switch sw) {
23 auto& w = new_world();
24 auto etas = DefMap<const Def*>(); // one η-wrapper per distinct target keeps a uniform table a Pack
25 auto targets = DefVec(sw.num_targets(), [&](size_t i) {
26 auto target = sw.target(i);
27 auto& eta = etas[target];
28 if (!eta) eta = eta_expand(target);
29 return eta;
30 });
31
32 auto callee = w.extract(w.tuple(targets), sw.index());
33 if (callee != sw.extract()) log().d("dispatch-normalize: {} → {}", sw.extract(), callee);
34 return callee;
35}
36
37const Def* DispatchNormalize::eta_expand(const Def* f) {
38 if (f->isa<Lam>()) return f;
39 if (auto sw = Switch(f)) f = normalize(sw);
40 return Lam::eta_expand(f);
41}
42
43} // namespace mim
Base class for all Defs.
Definition def.h:289
bool is_set() const
Definition def.h:396
Def * set(size_t i, const Def *)
Successively set from left to right.
Definition def.cpp:188
const Def * rewrite_mut_Lam(Lam *) final
Dispatch(const Def *)
Definition tuple.cpp:105
A function.
Definition lam.h:91
const Def * filter() const
Definition lam.h:103
static Lam * eta_expand(Filter, const Def *f)
Definition lam.cpp:84
const Pi * type() const
Definition lam.h:112
const Def * body() const
Definition lam.h:104
const fe::Log & log() const
Definition phase.h:60
A dependent function type.
Definition lam.h:14
World & new_world()
Create new Defs into this.
Definition phase.h:379
const Def * map(const Def *old_def, const Def *new_def)
Definition rewrite.cpp:29
const Def * seal(Def *old_mut, Def *new_mut)
The tail of rewrite_stub: immutabilizes new_mut in hindsight, as rewriting may have made it vacuous.
Definition rewrite.cpp:280
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:62
auto enter(Def *new_mut)
Updates curr_mut() to new_mut and restores it at the end of the scope.
Definition rewrite.h:115
Matches a jump table (target_0, target_1, ...)#index where index is a non-Literal Idx n and n the ari...
Definition tuple.h:408
size_t num_targets() const
Definition tuple.h:418
Switch(const Def *)
Definition tuple.cpp:84
const Extract * extract() const
Definition tuple.h:414
const Def * index() const
Definition tuple.h:416
const Def * app(const Def *callee, const Def *arg)
Definition world.cpp:416
Lam * mut_lam(const Pi *pi)
Definition world.h:415
Definition ast.h:16
GIDMap< const Def *, To > DefMap
Definition def.h:93
fe::Vector< const Def * > DefVec
Definition def.h:98