MimIR
0.5-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
using
RWPhase::RWPhase
;
38
39
private
:
40
/// A pending body rewrite: the initial mem tokens (old @c lvm, new @c lcm) plus the old and new Lam.
41
struct
Todo {
42
const
Def
* lvm;
43
const
Def
* lcm;
44
Lam
* old_lam;
45
Lam
* new_lam;
46
};
47
48
void
finalize
()
final
;
49
const
Def
*
rewrite
(
const
Def
* def)
final
;
50
const
Def
*
rewrite_imm
(
const
Def
* def)
final
;
51
const
Def
*
rewrite_imm_App
(
const
App
*)
final
;
52
53
/// Describes how the environment should be treated.
54
enum
Mode {
55
Box = 0,
///< Environment is boxed (default).
56
Unbox,
///< Environment is of primitive type (currently `iN`s) and directly stored in the pointer.
57
No_Env
///< Lambda has no environment (lifted, top-level).
58
};
59
60
/// Create a new Lam stub.
61
/// @p adjust_bb_type is true if the @p lam should be rewritten to a returning function.
62
Lam
* make_stub(
Lam
* lam, Mode mode,
bool
adjust_bb_type);
63
64
/// Pointer type used to represent environments.
65
const
Def
* env_type() {
return
new_world
().
call
<
mem::Ptr0
>(
new_world
().
sigma
()); }
66
67
/// Dummy return continuation.
68
const
Def
* dummy_ret() {
return
new_world
().
bot
(
new_world
().cn(
new_world
().call<mem::M>(0))); }
69
70
std::queue<Todo> worklist_;
71
72
/// @name memory-tokens
73
/// The mem token threaded through the body currently being rewritten.
74
///@{
75
const
Def
* lvm_ =
nullptr
;
///< Last visited memory token.
76
const
Def
* lcm_ =
nullptr
;
///< Last created memory token.
77
///@}
78
};
79
80
}
// namespace mim::plug::clos::phase
mim::App
Definition
lam.h:215
mim::Def
Base class for all Defs.
Definition
def.h:289
mim::Lam
A function.
Definition
lam.h:91
mim::RWPhase::new_world
World & new_world()
Create new Defs into this.
Definition
phase.h:379
mim::RWPhase::RWPhase
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition
phase.h:334
mim::World::call
const Def * call(const Def *callee, auto &&arg, Args &&... args)
Definition
world.h:674
mim::World::sigma
const Def * sigma(Defs ops)
Definition
world.cpp:506
mim::World::bot
const Def * bot(const Def *type)
Definition
world.h:604
mim::plug::clos::phase::LowerTypedClos
This pass lowers typed closures to untyped closures.
Definition
lower_typed_clos.h:35
mim::plug::clos::phase::LowerTypedClos::rewrite
const Def * rewrite(const Def *def) final
Definition
lower_typed_clos.cpp:101
mim::plug::clos::phase::LowerTypedClos::finalize
void finalize() final
Run after all roots have been walked but still before the two worlds are swapped.
Definition
lower_typed_clos.cpp:16
mim::plug::clos::phase::LowerTypedClos::RWPhase
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition
phase.h:334
mim::plug::clos::phase::LowerTypedClos::rewrite_imm
const Def * rewrite_imm(const Def *def) final
Definition
lower_typed_clos.cpp:164
mim::plug::clos::phase::LowerTypedClos::rewrite_imm_App
const Def * rewrite_imm_App(const App *) final
Definition
lower_typed_clos.cpp:153
clos.h
mem.h
mim::plug::clos::phase
Definition
branch_clos_elim.h:5
mim::plug::mem::Ptr0
Ptr0
Definition
autogen.h:19
phase.h
include
mim
plug
clos
phase
lower_typed_clos.h
Generated by
1.18.0