MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
add_mem.h
Go to the documentation of this file.
1#pragma once
2
3#include <mim/phase.h>
4
6
7/// Threads the `%mem.M` memory monad through the world:
8/// mem-extends continuations and rewires every memory operand to the *current* memory at that program point.
9/// It's primarily to be used as preparation for other phases that rely on all continuations having a mem.
10/// It also splices the `⊥ : %mem.M 0` memory placeholders of freshly emitted memory operations into the
11/// global memory chain (see mim::plug::tensor::phase::LowerToMem, which runs this phase embedded).
12///
13/// The rewrite is a plain RWPhase.
14/// Memory is a linear resource, so at any program point exactly one memory token is live - the *current* memory.
15/// We track it in AddMem::curr_mem_ while rewriting a continuation's body:
16/// - it starts out as the continuation's (leading or grouped) mem parameter,
17/// - a rewritten memory operation advances it to the operation's result mem, and
18/// - every memory-typed *operand* is rewritten to the current memory.
19///
20/// Because the Rewriter visits operands before their users, the current memory naturally threads through the
21/// data-dependency order - no separate schedule is required.
22/// Independent `⊥`/`⊤` placeholder chains are thereby linearized into one chain in encounter order.
23///
24/// Three rules keep the rewrite type-correct in the presence of axiom-pinned ABIs:
25/// - Only continuations (Pi::isa_cn) are mem-extended; direct-style functions (e.g. the affine index
26/// mappings passed to `%matrix.map_reduce_aff`) keep their signature.
27/// - A pi whose leading parameter carries the memory *grouped* (the `Fn [%mem.M 0, To, ins] → …` shape of
28/// a mem-threaded combiner) counts as already mem-threaded.
29/// - Lams reachable from axm-app arguments are preserved untouched: axioms pin their arguments' ABI
30/// (e.g. the combiner slot of `%matrix.map_reduce_aff`), so mem-extending them would be ill-typed.
31class AddMem : public RWPhase {
32public:
35
36private:
37 void start() override;
38 const Def* rewrite(const Def*) override;
39 const Def* rewrite_mut_Lam(Lam*) override;
40 const Def* rewrite_imm_App(const App*) override;
41 const Def* rewrite_imm_Tuple(const Tuple*) override;
42 const Def* rewrite_imm_Pi(const Pi*) override;
43
44 /// Advances AddMem::curr_mem_ if @p def produces a memory (a bare `%mem.M` or a `[%mem.M, …]` tuple).
45 void advance_mem(const Def* def);
46
47 /// The current memory token in the continuation being rewritten (new world), or `nullptr` outside any mem context.
48 const Def* curr_mem_ = nullptr;
49 /// `true` while rewriting a pinned-ABI subtree (an axm-app argument): no memory is threaded or added there.
50 bool preserving_ = false;
51 /// Lams (transitively) reachable from axm-app arguments: their ABI is pinned by the axiom.
52 LamSet preserved_;
53};
54
55} // namespace mim::plug::mem::phase
Base class for all Defs.
Definition def.h:261
A function.
Definition lam.h:110
flags_t annex() const
Definition phase.h:81
A dependent function type.
Definition lam.h:14
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
Definition phase.h:316
World & world()=delete
Hides both and forbids direct access.
Data constructor for a Sigma.
Definition tuple.h:70
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:36
const Def * rewrite_imm_Tuple(const Tuple *) override
Definition add_mem.cpp:144
const Def * rewrite_imm_Pi(const Pi *) override
Definition add_mem.cpp:48
const Def * rewrite(const Def *) override
Definition add_mem.cpp:40
const Def * rewrite_mut_Lam(Lam *) override
Definition add_mem.cpp:85
const Def * rewrite_imm_App(const App *) override
Definition add_mem.cpp:115
void start() override
Actual entry.
Definition add_mem.cpp:11
AddMem(World &world, flags_t annex)
Definition add_mem.h:33
GIDSet< Lam * > LamSet
Definition lam.h:220
u64 flags_t
Definition types.h:39