MimIR
0.4-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
Loading...
Searching...
No Matches
ret_wrap.cpp
Go to the documentation of this file.
1
#include "
mim/phase/ret_wrap.h
"
2
3
namespace
mim
{
4
5
bool
RetWrap::analyze
() {
6
for
(
auto
def :
old_world
().roots())
7
visit(def);
8
return
false
;
// no fixed-point necessary
9
}
10
11
void
RetWrap::analyze
(
const
Def
* def) {
12
if
(
auto
[_, ins] = analyzed_.emplace(def); !ins)
return
;
13
14
if
(
auto
app = def->isa<
App
>()) {
15
visit(app->type());
16
visit(app->callee(), Lattice::Single);
17
visit(app->arg());
18
}
else
{
19
for
(
auto
d : def->
deps
())
20
visit(d);
21
}
22
}
23
24
void
RetWrap::visit(
const
Def
* def, Lattice l) {
25
if
(
auto
lam = def->isa_mut<Lam>()) {
26
if
(
auto
ret_var = lam->ret_var()) {
27
auto
var = lam->has_var();
// must be set due to lam->ret_var() above
28
join(ret_var, Bot);
29
if
(ret_var != lam->var()) {
30
log
().d(
"{} → {}"
, var, ret_var);
31
var2def_[var] = ret_var;
32
}
33
}
34
}
else
if
(
auto
i = def2lattice_.find(def); i != def2lattice_.end()) {
35
i->second = join(i->second, l);
36
}
else
if
(
auto
app = def->isa<App>()) {
37
if
(
auto
var = app->arg()->isa<Var>()) {
38
if
(
auto
i = var2def_.find(var); i != var2def_.end()) {
39
auto
lam = var->binder()->as_mut<
Lam
>();
40
log
().d(
"split {}"
, lam);
41
split_.emplace(lam);
42
def2lattice_[i->second] = Eta;
43
}
44
}
45
}
46
47
analyze
(def);
48
}
49
50
const
Def
*
RetWrap::rewrite
(
const
Def
* old_def) {
51
if
(lattice(old_def) == Eta) {
52
auto
[i, ins] = def2eta_.emplace(old_def,
nullptr
);
53
if
(ins) i->second =
Lam::eta_expand
(rewrite_no_eta(old_def));
54
log
().d(
"eta-expand {} → {}"
, old_def, i->second);
55
return
i->second;
56
}
57
return
RWPhase::rewrite
(old_def);
58
}
59
60
const
Def
*
RetWrap::rewrite_mut_Lam
(
Lam
* old_lam) {
61
if
(split_.contains(old_lam)) {
62
// rebuild a new "var" that substitutes the actual ret_var with ret_cont
63
auto
split_vars = old_lam->
vars
();
64
auto
ret_var = old_lam->
ret_var
();
65
assert(split_vars.back() == ret_var &&
"we assume that the last element is the ret_var"
);
66
67
auto
ret_cont =
Lam::eta_expand
(ret_var);
68
split_vars.back() = ret_cont;
69
auto
new_lam =
new_world
().
mut_lam
(
rewrite
(old_lam->
type
())->as<
Pi
>());
70
map
(old_lam, new_lam);
71
map
(old_lam->
var
(),
rewrite
(
old_world
().tuple(split_vars)));
72
return
rewrite_stub
(old_lam, new_lam);
73
}
74
75
return
RWPhase::rewrite_mut_Lam(old_lam);
76
}
77
78
}
// namespace mim
mim::App
Definition
lam.h:224
mim::Def
Base class for all Defs.
Definition
def.h:273
mim::Def::deps
Defs deps() const noexcept
Definition
def.cpp:468
mim::Def::var
const Def * var(nat_t a, nat_t i) noexcept
Definition
def.h:479
mim::Def::vars
auto vars(F f) noexcept
Definition
def.h:479
mim::Lam
A function.
Definition
lam.h:113
mim::Lam::eta_expand
static Lam * eta_expand(Filter, const Def *f)
Definition
lam.cpp:56
mim::Lam::type
const Pi * type() const
Definition
lam.h:133
mim::Lam::ret_var
const Def * ret_var()
Yields the Lam::var of the Lam::ret_pi.
Definition
lam.h:159
mim::Phase::log
const fe::Log & log() const
Definition
phase.h:79
mim::Pi
A dependent function type.
Definition
lam.h:14
mim::RWPhase::new_world
World & new_world()
Create new Defs into this.
Definition
phase.h:452
mim::RWPhase::old_world
World & old_world()
Get old Defs from here.
Definition
phase.h:451
mim::RetWrap::rewrite_mut_Lam
const Def * rewrite_mut_Lam(Lam *) final
Definition
ret_wrap.cpp:60
mim::RetWrap::analyze
bool analyze() final
Runs the optional pre-analysis on Phase::world, typically to a fixed point, before rewriting begins.
Definition
ret_wrap.cpp:5
mim::RetWrap::rewrite
const Def * rewrite(const Def *) final
Definition
ret_wrap.cpp:50
mim::Rewriter::rewrite_stub
virtual const Def * rewrite_stub(Def *, Def *)
Definition
rewrite.cpp:265
mim::Rewriter::map
virtual const Def * map(const Def *old_def, const Def *new_def)
Definition
rewrite.h:47
mim::Rewriter::rewrite
virtual const Def * rewrite(const Def *)
Definition
rewrite.cpp:55
mim::World::mut_lam
Lam * mut_lam(const Pi *pi)
Definition
world.h:402
mim
Definition
ast.h:16
mim::Node::Lam
@ Lam
Definition
def.h:122
ret_wrap.h
src
mim
phase
ret_wrap.cpp
Generated by
1.18.0