MimIR
0.5-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
Loading...
Searching...
No Matches
lam_spec.cpp
Go to the documentation of this file.
1
#include "
mim/phase/lam_spec.h
"
2
3
#include "
mim/nest.h
"
4
5
// TODO This is supposed to recreate what lower2cff did, but we should really consider another strategy and nuke this.
6
7
namespace
mim
{
8
9
const
Def
*
LamSpec::rewrite_imm_App
(
const
App
* old_app) {
10
auto
old_lam =
Lam::isa_rewritable
(old_app->
callee
());
11
if
(!old_lam)
return
RWPhase::rewrite_imm_App
(old_app);
12
13
// Skip recursion to avoid infinite inlining if not "aggressive_lam_spec".
14
// This is a hack - but we want to get rid off this stage anyway.
15
Nest
nest(old_lam);
16
if
(!
old_world
().flags().aggressive_lam_spec && nest.
is_recursive
())
return
RWPhase::rewrite_imm_App
(old_app);
17
18
// Specialize the ordinary new-world copy of old_lam; everything below happens in the new world.
19
auto
lam =
rewrite
(old_lam)->
as_mut
<
Lam
>();
20
21
DefVec
new_doms, new_vars, new_args;
22
auto
skip = lam->ret_var() && lam->is_closed();
23
auto
doms = lam->doms();
24
25
for
(
auto
dom : doms.view().rsubspan(skip))
26
if
(!dom->isa<
Pi
>()) new_doms.emplace_back(dom);
27
28
if
(skip) new_doms.emplace_back(doms.back());
29
if
(new_doms.size() == lam->num_doms())
return
RWPhase::rewrite_imm_App
(old_app);
30
31
auto
& w =
new_world
();
32
auto
new_lam = w.mut_lam(w.cn(new_doms))->set(lam->dbg_key());
33
34
// Project new_lam's var with the explicit arity new_doms.size():
35
// a single remaining sigma dom is flattened by cn(), so new_lam->var(i) would project into that sigma.
36
auto
num_new = new_doms.size();
37
auto
num_old = old_app->
num_args
();
38
39
for
(
size_t
arg_i = 0, var_i = 0, n = num_old - skip; arg_i != n; ++arg_i) {
40
auto
arg =
rewrite
(old_app->
arg
(num_old, arg_i));
41
if
(doms[arg_i]->isa<Pi>()) {
42
new_vars.emplace_back(arg);
43
}
else
{
44
new_vars.emplace_back(new_lam->var(num_new, var_i++));
45
new_args.emplace_back(arg);
46
}
47
}
48
49
if
(skip) {
50
new_vars.emplace_back(new_lam->var(num_new, num_new - 1));
51
new_args.emplace_back(
rewrite
(old_app->
arg
(num_old, num_old - 1)));
52
}
53
54
new_lam->set(lam->reduce(w.tuple(new_vars)));
55
log
().d(
"specialize {} → {}: {} → {}"
, lam, new_lam, lam->dom(), new_lam->dom());
56
57
return
w.app(new_lam, new_args);
58
}
59
60
}
// namespace mim
mim::App
Definition
lam.h:215
mim::App::num_args
nat_t num_args() const noexcept
Definition
lam.h:252
mim::App::callee
const Def * callee() const
Definition
lam.h:237
mim::App::arg
const Def * arg() const
Definition
lam.h:251
mim::Def
Base class for all Defs.
Definition
def.h:289
mim::Def::as_mut
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
Definition
def.h:597
mim::LamSpec::rewrite_imm_App
const Def * rewrite_imm_App(const App *) final
Definition
lam_spec.cpp:9
mim::Lam
A function.
Definition
lam.h:91
mim::Lam::isa_rewritable
static Lam * isa_rewritable(const Def *def)
Yields def as a mutable Lam, if it is_rewritable() and nullptr otherwise.
Definition
lam.h:193
mim::Nest
Builds a nesting tree for all mutables/binders.
Definition
nest.h:25
mim::Nest::is_recursive
bool is_recursive() const
Definition
nest.h:198
mim::Phase::log
const fe::Log & log() const
Definition
phase.h:60
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:379
mim::RWPhase::old_world
World & old_world()
Get old Defs from here.
Definition
phase.h:378
mim::RWPhase::rewrite_imm_App
const Def * rewrite_imm_App(const App *) override
Definition
phase.cpp:223
mim::Rewriter::rewrite
virtual const Def * rewrite(const Def *)
Definition
rewrite.cpp:62
lam_spec.h
mim
Definition
ast.h:16
mim::DefVec
fe::Vector< const Def * > DefVec
Definition
def.h:98
nest.h
src
mim
phase
lam_spec.cpp
Generated by
1.18.0