MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
branch_clos_elim.cpp
Go to the documentation of this file.
2
4
6
7namespace {
8
9std::tuple<Vector<ClosLit>, const Def*> isa_branch(const Def* callee) {
10 if (auto closure_proj = callee->isa<Extract>()) {
11 auto inner_proj = closure_proj->tuple()->isa<Extract>();
12 if (inner_proj && inner_proj->tuple()->isa<Tuple>() && isa_clos_type(inner_proj->type())) {
13 auto branches = Vector<ClosLit>();
14 for (auto op : inner_proj->tuple()->ops())
15 if (auto c = isa_clos_lit(op))
16 branches.emplace_back(c);
17 else
18 return {};
19 return {branches, inner_proj->index()};
20 }
21 }
22 return {};
23}
24
25} // namespace
26
28 if (is_bootstrapping() || !Pi::isa_cn(app->callee_type())) return RWPhase::rewrite_imm_App(app);
29
30 auto& w = new_world();
31 if (auto [branches, index] = isa_branch(app->callee()); index) {
32 DLOG("FLATTEN BRANCH {}", app->callee());
33 auto ep = env_param(branches[0].fnc_type());
34 auto new_branches = w.tuple(DefVec(branches.size(), [&](size_t i) -> const Def* {
35 auto c = branches[i];
36 if (auto it = branch2dropped_.find(c); it != branch2dropped_.end()) return it->second;
37 // Specialize the closure's lam with its env inlined.
38 // The Pi is computed on the old-world closure type and then rewritten -
39 // rewriting the (mutable, existential) closure type itself does not survive the world change.
40 // Memoize the stub first: rewriting the lam below revisits this very branch.
41 auto dropped_lam = w.mut_lam(rewrite(clos_type_to_pi(c.type()))->as<Pi>())->set(c.fnc_as_lam()->dbg());
42 branch2dropped_[c] = dropped_lam;
43 auto clam = rewrite(c.fnc_as_lam())->as_mut<Lam>();
44 dropped_lam->set(clam->reduce(clos_insert_env(ep, rewrite(c.env()), dropped_lam->var())));
45 return dropped_lam;
46 }));
47 return w.app(w.extract(new_branches, rewrite(index)), clos_remove_env(ep, rewrite(app->arg())));
48 }
49
50 return RWPhase::rewrite_imm_App(app);
51}
52
53} // namespace mim::plug::clos::phase
const Pi * callee_type() const
Definition lam.h:278
const Def * callee() const
Definition lam.h:276
const Def * arg() const
Definition lam.h:285
Base class for all Defs.
Definition def.h:261
static const Pi * isa_cn(const Def *d)
Is this a continuation - i.e. is the Pi::codom mim::Bottom?
Definition lam.h:47
World & new_world()
Create new Defs into this.
Definition phase.h:368
bool is_bootstrapping() const
Returns whether we are currently bootstrapping (rewriting annexes).
Definition phase.h:356
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:56
const Def * rewrite_imm_App(const App *) final
#define DLOG(...)
Vaporizes to nothingness in Debug build.
Definition log.h:94
ClosLit isa_clos_lit(const Def *def, bool fn_isa_lam=true)
Tries to match a closure literal.
Definition clos.cpp:50
const Def * clos_remove_env(size_t ep, size_t i, std::function< const Def *(size_t)> f)
Definition clos.cpp:122
const Sigma * isa_clos_type(const Def *def)
Definition clos.cpp:88
size_t env_param(Defs doms)
Describes where the environment is placed in the argument list: right after a leading mem....
Definition clos.h:100
Vector< const Def * > DefVec
Definition def.h:79
@ Extract
Definition def.h:109
@ Tuple
Definition def.h:109
Vector(I, I, A=A()) -> Vector< typename std::iterator_traits< I >::value_type, Default_Inlined_Size< typename std::iterator_traits< I >::value_type >, A >