MimIR
0.4-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
Loading...
Searching...
No Matches
branch_clos_elim.cpp
Go to the documentation of this file.
1
#include "
mim/plug/clos/phase/branch_clos_elim.h
"
2
3
#include "
mim/plug/clos/clos.h
"
4
5
namespace
mim::plug::clos::phase
{
6
7
namespace
{
8
9
std::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
27
const
Def
*
BranchClosElim::rewrite_imm_App
(
const
App
* app) {
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
branch_clos_elim.h
mim::App
Definition
lam.h:224
mim::App::callee_type
const Pi * callee_type() const
Definition
lam.h:277
mim::App::callee
const Def * callee() const
Definition
lam.h:275
mim::App::arg
const Def * arg() const
Definition
lam.h:284
mim::Def
Base class for all Defs.
Definition
def.h:273
mim::Phase::log
const fe::Log & log() const
Definition
phase.h:79
mim::Pi::isa_cn
static const Pi * isa_cn(const Def *d)
Definition
lam.h:46
mim::RWBase::is_bootstrapping
bool is_bootstrapping() const
Returns whether we are currently bootstrapping (rewriting annexes).
Definition
phase.h:403
mim::RWPhase::new_world
World & new_world()
Create new Defs into this.
Definition
phase.h:452
mim::Rewriter::rewrite
virtual const Def * rewrite(const Def *)
Definition
rewrite.cpp:55
mim::plug::clos::phase::BranchClosElim::rewrite_imm_App
const Def * rewrite_imm_App(const App *) final
Definition
branch_clos_elim.cpp:27
clos.h
mim::plug::clos::phase
Definition
branch_clos_elim.h:5
mim::plug::clos::isa_clos_lit
ClosLit isa_clos_lit(const Def *def, bool fn_isa_lam=true)
Tries to match a closure literal.
Definition
clos.cpp:52
mim::plug::clos::clos_remove_env
const Def * clos_remove_env(size_t ep, size_t i, std::function< const Def *(size_t)> f)
Definition
clos.cpp:124
mim::plug::clos::isa_clos_type
const Sigma * isa_clos_type(const Def *def)
Definition
clos.cpp:90
mim::plug::clos::env_param
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
mim::DefVec
fe::Vector< const Def * > DefVec
Definition
def.h:93
mim::Node::Extract
@ Extract
Definition
def.h:122
src
mim
plug
clos
phase
branch_clos_elim.cpp
Generated by
1.18.0