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<fe::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 = fe::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 log().d("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_key());
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:277
const Def * callee() const
Definition lam.h:275
const Def * arg() const
Definition lam.h:284
Base class for all Defs.
Definition def.h:273
const fe::Log & log() const
Definition phase.h:79
static const Pi * isa_cn(const Def *d)
Definition lam.h:46
bool is_bootstrapping() const
Returns whether we are currently bootstrapping (rewriting annexes).
Definition phase.h:403
World & new_world()
Create new Defs into this.
Definition phase.h:452
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:55
const Def * rewrite_imm_App(const App *) final
ClosLit isa_clos_lit(const Def *def, bool fn_isa_lam=true)
Tries to match a closure literal.
Definition clos.cpp:52
const Def * clos_remove_env(size_t ep, size_t i, std::function< const Def *(size_t)> f)
Definition clos.cpp:124
const Sigma * isa_clos_type(const Def *def)
Definition clos.cpp:90
size_t env_param(Defs doms)
Describes where the environment is placed in the argument list: right after a leading mem....
Definition clos.h:101
fe::Vector< const Def * > DefVec
Definition def.h:93
@ Extract
Definition def.h:122