MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
ret_wrap.cpp
Go to the documentation of this file.
2
3namespace mim {
4
6 for (auto def : old_world().externals())
7 visit(def);
8 return false; // no fixed-point neccessary
9}
10
11void 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
24void 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 DLOG("{} → {}", 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->mut()->as_mut<Lam>();
40 DLOG("split: `{}`", lam);
41 split_.emplace(lam);
42 def2lattice_[i->second] = Eta;
43 }
44 }
45 }
46
47 analyze(def);
48}
49
50const 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 DLOG("eta-expand: `{}` → `{}`", old_def, i->second);
55 return i->second;
56 }
57 return Rewriter::rewrite(old_def);
58}
59
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 Rewriter::rewrite_mut_Lam(old_lam);
76}
77
78} // namespace mim
Base class for all Defs.
Definition def.h:251
Defs deps() const noexcept
Definition def.cpp:464
const Def * var(nat_t a, nat_t i) noexcept
Definition def.h:429
auto vars(F f) noexcept
Definition def.h:429
A function.
Definition lam.h:111
static Lam * eta_expand(Filter, const Def *f)
Definition lam.cpp:51
const Pi * type() const
Definition lam.h:131
const Def * ret_var()
Yields the Lam::var of the Lam::ret_pi.
Definition lam.h:157
A dependent function type.
Definition lam.h:15
World & new_world()
Create new Defs into this.
Definition phase.h:100
World & old_world()
Get old Defs from here.
Definition phase.h:99
const Def * rewrite_mut_Lam(Lam *) final
Definition ret_wrap.cpp:60
bool analyze() final
You can do an optional fixed-point loop on the RWPhase::old_world before rewriting.
Definition ret_wrap.cpp:5
const Def * rewrite(const Def *) final
Definition ret_wrap.cpp:50
virtual const Def * rewrite_stub(Def *, Def *)
Definition rewrite.cpp:152
const Def * map(const Def *old_def, const Def *new_def)
Map old_def to new_def and returns new_def.
Definition rewrite.h:46
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:14
Lam * mut_lam(const Pi *pi)
Definition world.h:297
#define DLOG(...)
Vaporizes to nothingness in Debug build.
Definition log.h:95
Definition ast.h:14
bool visit(IndexSet< Indexer, Key > &set, const Key &key)
Definition indexset.h:100
@ Lam
Definition def.h:114
@ Var
Definition def.h:114
@ App
Definition def.h:114