MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
tail_rec_elim.cpp
Go to the documentation of this file.
2
3#include "mim/pass/beta_red.h"
4#include "mim/pass/eta_red.h"
5
6namespace mim {
7
9 if (auto [app, old] = isa_apped_mut_lam(def); old) {
10 if (auto i = old2rec_loop_.find(old); i != old2rec_loop_.end()) {
11 auto [rec, loop] = i->second;
12 auto args = app->args();
13 if (auto ret_var = rec->ret_var(); app->args().back() == ret_var)
14 return world().app(loop, args.view().rsubspan(1));
15 else
16 return world().app(rec, args);
17 }
18 }
19
20 return def;
21}
22
24 if (auto [app, old] = isa_apped_mut_lam(def); old) {
25 if (auto ret_var = old->ret_var(); ret_var && app->args().back() == ret_var) {
26 if (auto [i, ins] = old2rec_loop_.emplace(old, std::pair<Lam*, Lam*>(nullptr, nullptr)); ins) {
27 auto& [rec, loop] = i->second;
28 rec = old->stub(old->type());
29 auto doms = rec->doms();
30 auto loop_dom = doms.view().rsubspan(1);
31 loop = rec->stub(world().cn(loop_dom));
32 world().DLOG("old {} -> (rec: {}, loop: {})", old, rec, loop);
33
34 auto n = rec->num_doms();
35 DefVec loop_args(n - 1);
36 DefVec loop_vars(n);
37 for (size_t i = 0; i != n - 1; ++i) {
38 loop_args[i] = rec->var(i);
39 loop_vars[i] = loop->var(i);
40 }
41 loop_vars.back() = rec->vars().back();
42
43 loop->set(old->reduce(world().tuple(loop_vars)));
44 rec->app(false, loop, loop_args);
45 if (eta_red_) eta_red_->mark_irreducible(loop);
46
47 return undo_visit(old);
48 }
49 }
50 }
51
52 return No_Undo;
53}
54
55} // namespace mim
void mark_irreducible(Lam *lam)
Definition eta_red.h:22
undo_t undo_visit(Def *mut) const
Definition pass.h:273
World & world()
Definition pass.h:296
Helper class to retrieve Infer::arg if present.
Definition def.h:85
Ref rewrite(Ref) override
undo_t analyze(Ref) override
Ref app(Ref callee, Ref arg)
Definition world.cpp:187
Definition cfg.h:11
std::pair< const App *, Lam * > isa_apped_mut_lam(const Def *def)
Definition lam.h:238
size_t undo_t
Definition pass.h:14
static constexpr undo_t No_Undo
Definition pass.h:15