MimIR
0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
lower_typed_clos.h
Go to the documentation of this file.
1
#pragma once
2
3
#include <queue>
4
5
#include "
mim/phase/phase.h
"
6
7
#include "
mim/plug/clos/clos.h
"
8
#include "
mim/plug/mem/mem.h
"
9
10
namespace
mim::plug::clos
{
11
12
/// This pass lowers *typed closures* to *untyped closures*.
13
/// For details on typed closures, see ClosConv.
14
/// In general, untyped closure have the form `(pointer-to-environment, code)` with the following exceptions:
15
/// * Lam%s in callee-position should be λ-lifted and thus don't receive an environment.
16
/// * External and imported (not set) Lam%s also don't receive an environment.
17
/// They are appropriately η-wrapped by ClosConv.
18
/// * If the environment is of integer type, it's directly stored in the environment-pointer ("unboxed").
19
/// @note In theory this should work for other primitive types as well, but the LL backend does not handle the
20
/// required conversion correctly.
21
///
22
/// Further, first class continuations are rewritten to returning functions.
23
/// They receive `⊥` as a dummy continuation.
24
/// Therefore Clos2SJLJ should have taken place prior to this pass.
25
///
26
/// This pass will heap-allocate ClosKind::esc closures and stack-allocate everything else.
27
/// These annotations are introduced by LowerTypedClosPrep.
28
class
LowerTypedClos
:
public
Phase
{
29
public
:
30
LowerTypedClos
(
World
&
world
)
31
:
Phase
(
world
,
"lower_typed_clos"
, true) {}
32
33
void
start
()
override
;
34
35
private
:
36
using
StubQueue = std::queue<std::tuple<const Def*, const Def*, Lam*>>;
37
38
/// Recursively rewrites a Def.
39
const
Def
* rewrite(
const
Def
* def);
40
41
/// Describes how the environment should be treated.
42
enum
Mode {
43
Box = 0,
//< Environment is boxed (default).
44
Unbox,
//< Environments is of primitive type (currently `iN`s) and directly stored in the pointer.
45
No_Env
//< Lambda has no environment (lifted, top-level).
46
};
47
48
/// Create a new Lam stub.
49
/// @p adjust_bb_type is true if the @p lam should be rewritten to a returning function.
50
Lam
* make_stub(
Lam
* lam,
enum
Mode mode,
bool
adjust_bb_type);
51
52
/// @name Helpers
53
///@{
54
/// wrapper arround old2new_
55
const
Def
* map(
const
Def
* old_def,
const
Def
* new_def) {
return
old2new_[old_def] = new_def; }
56
Def
* map(
const
Def
* old_def,
Def
* new_def) {
57
old2new_[old_def] = new_def;
58
return
new_def;
59
}
60
61
/// Pointer type used to represent environments
62
const
Def* env_type() {
63
auto
& w =
world
();
64
return
w.call<
mem::Ptr0
>(w.sigma());
65
}
66
///@}
67
68
Def2Def
old2new_;
69
StubQueue worklist_;
70
71
const
Def* dummy_ret_ =
nullptr
;
//< dummy return continuation
72
73
/// @name memory-tokens
74
///@{
75
const
Def* lvm_;
//< Last visited memory token
76
const
Def* lcm_;
//< Last created memory token
77
///@}
78
79
std::vector<Lam*> new_externals_;
80
};
81
82
}
// namespace mim::plug::clos
mim::Def
Base class for all Defs.
Definition
def.h:223
mim::Lam
A function.
Definition
lam.h:103
mim::Phase
As opposed to a Pass, a Phase does one thing at a time and does not mix with other Phases.
Definition
phase.h:15
mim::Phase::world
World & world()
Definition
phase.h:25
mim::World
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition
world.h:33
mim::plug::clos::LowerTypedClos
This pass lowers typed closures to untyped closures.
Definition
lower_typed_clos.h:28
mim::plug::clos::LowerTypedClos::LowerTypedClos
LowerTypedClos(World &world)
Definition
lower_typed_clos.h:30
mim::plug::clos::LowerTypedClos::start
void start() override
Actual entry.
Definition
lower_typed_clos.cpp:17
clos.h
mem.h
mim::plug::clos
The clos Plugin
Definition
clos.h:7
mim::plug::mem::Ptr0
Ptr0
Definition
autogen.h:28
mim::Def2Def
DefMap< const Def * > Def2Def
Definition
def.h:60
phase.h
include
mim
plug
clos
phase
lower_typed_clos.h
Generated by
1.12.0