MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lam_spec.cpp
Go to the documentation of this file.
1#include "mim/pass/lam_spec.h"
2
4#include "mim/pass/beta_red.h"
5#include "mim/pass/eta_exp.h"
6#include "mim/util/util.h"
7
8// TODO This is supposed to recreate what lower2cff did, but we should really consider another strategy and nuke this.
9
10namespace mim {
11
13 if (auto i = old2new_.find(def); i != old2new_.end()) return i->second;
14
15 auto [app, old_lam] = isa_apped_mut_lam(def);
16 if (!isa_workable(old_lam)) return def;
17
18 // Skip recursion to avoid infinite inlining if not "aggressive_lam_spec".
19 // This is a hack - but we want to get rid off this Pass anyway.
20 Scope scope(old_lam);
21 if (!world().flags().aggressive_lam_spec && scope.free_defs().contains(old_lam)) return def;
22
23 DefVec new_doms, new_vars, new_args;
24 auto skip = old_lam->ret_var() && old_lam->is_closed();
25 auto old_doms = old_lam->doms();
26
27 for (auto dom : old_doms.view().rsubspan(skip))
28 if (!dom->isa<Pi>()) new_doms.emplace_back(dom);
29
30 if (skip) new_doms.emplace_back(old_lam->doms().back());
31 if (new_doms.size() == old_lam->num_doms()) return def;
32
33 auto new_lam = old_lam->stub(world().cn(new_doms));
34
35 for (size_t arg_i = 0, var_i = 0, n = app->num_args() - skip; arg_i != n; ++arg_i) {
36 auto arg = app->arg(arg_i);
37 if (old_lam->dom(arg_i)->isa<Pi>()) {
38 new_vars.emplace_back(arg);
39 } else {
40 new_vars.emplace_back(new_lam->var(var_i++));
41 new_args.emplace_back(arg);
42 }
43 }
44
45 if (skip) {
46 new_vars.emplace_back(new_lam->vars().back());
47 new_args.emplace_back(app->args().back());
48 }
49
50 new_lam->set(old_lam->reduce(world().tuple(new_vars)));
51 world().DLOG("{} -> {}: {} -> {})", old_lam, new_lam, old_lam->dom(), new_lam->dom());
52
53 return old2new_[def] = world().app(new_lam, new_args);
54}
55
56} // namespace mim
Def * set(size_t i, const Def *def)
Successively set from left to right.
Definition def.cpp:246
Def * stub(World &w, Ref type)
Definition def.h:505
Ref rewrite(Ref) override
Definition lam_spec.cpp:12
World & world()
Definition pass.h:296
A dependent function type.
Definition lam.h:11
Helper class to retrieve Infer::arg if present.
Definition def.h:86
A Scope represents a region of Defs that are live from the view of an entry's Var.
Definition scope.h:20
const DefSet & free_defs() const
All non-const Defs directly referenced but not bound within this Scope. May also include Vars or muts...
Definition scope.h:41
Ref app(Ref callee, Ref arg)
Definition world.cpp:186
Definition cfg.h:11
std::pair< const App *, Lam * > isa_apped_mut_lam(const Def *def)
Definition lam.h:256
Lam * isa_workable(Lam *lam)
These are Lams that are neither nullptr, nor Lam::is_external, nor Lam::is_unset.
Definition lam.h:251