MimIR
0.4-dev
MimIR is my Intermediate Representation
Toggle main menu visibility
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.h
>
6
7
#include <
mim/plug/mem/mem.h
>
8
9
#include "
mim/plug/clos/clos.h
"
10
11
namespace
mim::plug::clos::phase
{
12
13
/// This pass lowers *typed closures* to *untyped closures*.
14
/// For details on typed closures, see ClosConv.
15
/// In general, untyped closure have the form `(pointer-to-environment, code)` with the following exceptions:
16
/// * Lam%s in callee-position should be λ-lifted and thus don't receive an environment.
17
/// * External and imported (not set) Lam%s also don't receive an environment.
18
/// They are appropriately η-wrapped by ClosConv.
19
/// * If the environment is of integer type, it's directly stored in the environment-pointer ("unboxed").
20
/// @note In theory this should work for other primitive types as well, but the LL backend does not handle the
21
/// required conversion correctly.
22
///
23
/// Further, first class continuations are rewritten to returning functions.
24
/// They receive `⊥` as a dummy continuation.
25
/// Therefore Clos2SJLJ should have taken place prior to this pass.
26
///
27
/// This pass will heap-allocate ClosKind::esc closures and stack-allocate everything else.
28
/// These annotations are introduced by LowerTypedClosPrep.
29
///
30
/// The rewrite carries a *mem token* along each function body (LowerTypedClos::lvm_ / LowerTypedClos::lcm_) so
31
/// that the `mem.alloc`/`mem.store` it inserts for boxed environments are threaded into the mem chain.
32
/// This stateful, order-sensitive threading is why LowerTypedClos::rewrite intercepts whole classes of nodes
33
/// instead of relying on the per-node hooks alone.
34
/// A converted Lam's body is enqueued and rewritten later, seeded with that body's own initial mem token.
35
class
LowerTypedClos
:
public
RWPhase
{
36
public
:
37
LowerTypedClos
(
World
&
world
,
flags_t
annex
)
38
:
RWPhase
(
world
,
annex
) {}
39
40
private
:
41
/// A pending body rewrite: the initial mem tokens (old @c lvm, new @c lcm) plus the old and new Lam.
42
struct
Todo {
43
const
Def
* lvm;
44
const
Def
* lcm;
45
Lam
* old_lam;
46
Lam
* new_lam;
47
};
48
49
void
rewrite_external
(
Def
*)
final
;
50
void
finalize
() final;
51
const
Def
*
rewrite
(const
Def
* def) final;
52
const
Def
*
rewrite_imm
(const
Def
* def) final;
53
const
Def
*
rewrite_imm_App
(const
App
*) final;
54
55
/// Describes how the environment should be treated.
56
enum Mode {
57
Box = 0,
///< Environment is boxed (default).
58
Unbox,
///< Environment is of primitive type (currently `iN`s) and directly stored in the pointer.
59
No_Env
///< Lambda has no environment (lifted, top-level).
60
};
61
62
/// Create a new Lam stub.
63
/// @p adjust_bb_type is true if the @p lam should be rewritten to a returning function.
64
Lam
* make_stub(
Lam
* lam, Mode mode,
bool
adjust_bb_type);
65
66
/// Pointer type used to represent environments.
67
const
Def
* env_type() {
return
new_world
().
call
<
mem::Ptr0
>(
new_world
().
sigma
()); }
68
69
/// Dummy return continuation.
70
/// @note Not cached: `mem::M` resolves through new_world()'s annex table, which is only populated once
71
/// bootstrapping is done - and by then everything is hash-consed anyway.
72
const
Def
* dummy_ret() {
return
new_world
().
bot
(
new_world
().cn(
new_world
().call<mem::M>(0))); }
73
74
std::queue<Todo> worklist_;
75
76
/// @name memory-tokens
77
/// The mem token threaded through the body currently being rewritten.
78
///@{
79
const
Def* lvm_ =
nullptr
;
///< Last visited memory token.
80
const
Def* lcm_ =
nullptr
;
///< Last created memory token.
81
///@}
82
};
83
84
}
// namespace mim::plug::clos::phase
mim::App
Definition
lam.h:224
mim::Def
Base class for all Defs.
Definition
def.h:273
mim::Lam
A function.
Definition
lam.h:113
mim::Phase::annex
flags_t annex() const
Definition
phase.h:81
mim::RWPhase::new_world
World & new_world()
Create new Defs into this.
Definition
phase.h:452
mim::RWPhase::RWPhase
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition
phase.h:431
mim::RWPhase::world
World & world()=delete
Hides both and forbids direct access.
mim::World
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition
world.h:40
mim::World::sigma
const Def * sigma(Defs ops)
Definition
world.cpp:316
mim::World::bot
const Def * bot(const Def *type)
Definition
world.h:591
mim::World::call
const Def * call(const Def *callee, T &&arg, Args &&... args)
Definition
world.h:662
mim::plug::clos::phase::LowerTypedClos::rewrite
const Def * rewrite(const Def *def) final
Definition
lower_typed_clos.cpp:102
mim::plug::clos::phase::LowerTypedClos::finalize
void finalize() final
Run after all roots have been walked - but for an RWPhase still before the two worlds are swapped.
Definition
lower_typed_clos.cpp:22
mim::plug::clos::phase::LowerTypedClos::LowerTypedClos
LowerTypedClos(World &world, flags_t annex)
Definition
lower_typed_clos.h:37
mim::plug::clos::phase::LowerTypedClos::rewrite_external
void rewrite_external(Def *) final
Definition
lower_typed_clos.cpp:15
mim::plug::clos::phase::LowerTypedClos::rewrite_imm
const Def * rewrite_imm(const Def *def) final
Definition
lower_typed_clos.cpp:168
mim::plug::clos::phase::LowerTypedClos::rewrite_imm_App
const Def * rewrite_imm_App(const App *) final
Definition
lower_typed_clos.cpp:155
clos.h
mem.h
mim::plug::clos::phase
Definition
branch_clos_elim.h:5
mim::plug::mem::Ptr0
Ptr0
Definition
autogen.h:28
mim::flags_t
u64 flags_t
Definition
types.h:39
phase.h
include
mim
plug
clos
phase
lower_typed_clos.h
Generated by
1.18.0