MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
emitter.h
Go to the documentation of this file.
1#pragma once
2
3#include "mim/schedule.h"
4#include "mim/world.h"
5
6#include "mim/phase/phase.h"
7
8namespace mim {
9
10template<class Value, class Type, class BB, class Child> class Emitter : public NestPhase<Lam> {
11private:
12 constexpr const Child& child() const { return *static_cast<const Child*>(this); }
13 constexpr Child& child() { return *static_cast<Child*>(this); }
14
15 /// Internal wrapper for Emitter::emit that schedules @p def and invokes `child().emit_bb`.
16 Value emit_(const Def* def) {
17 auto place = scheduler_.smart(curr_lam_, def);
18 auto& bb = lam2bb_[place->mut()->as<Lam>()];
19 return child().emit_bb(bb, def);
20 }
21
22public:
24
25protected:
26 Emitter(World& world, std::string_view name, std::ostream& ostream)
27 : NestPhase(world, name, false, false)
28 , ostream_(ostream) {}
29
30 std::ostream& ostream() const { return ostream_; }
31
32 /// Recursively emits code.
33 /// `mem`-typed @p def%s return sth that is `!child().is_valid(value)`.
34 /// This variant asserts in this case.
35 Value emit(const Def* def) {
36 auto res = emit_unsafe(def);
37 assert(child().is_valid(res));
38 return res;
39 }
40
41 /// As above but returning `!child().is_valid(value)` is permitted.
42 Value emit_unsafe(const Def* def) {
43 if (auto i = globals_.find(def); i != globals_.end()) return i->second;
44 if (auto i = locals_.find(def); i != locals_.end()) return i->second;
45
46 auto val = emit_(def);
47 return locals_[def] = val;
48 }
49
50 void visit(const Nest& nest) override {
51 if (!root()->is_set()) {
52 child().emit_imported(root());
53 return;
54 }
55
56 auto muts = Scheduler::schedule(nest); // TODO make sure to not compute twice
57
58 // make sure that we don't need to rehash later on
59 for (auto mut : muts)
60 if (auto lam = mut->isa<Lam>()) lam2bb_.emplace(lam, BB());
61 auto old_size = lam2bb_.size();
62
63 assert(root()->ret_var());
64
65 auto fct = child().prepare();
66
67 Scheduler new_scheduler(nest);
68 swap(scheduler_, new_scheduler);
69
70 for (auto mut : muts) {
71 if (auto lam = mut->isa<Lam>()) {
72 curr_lam_ = lam;
73 assert(lam == root() || Lam::isa_basicblock(lam));
74 child().emit_epilogue(lam);
75 }
76 }
77
78 child().finalize();
79 locals_.clear();
80 assert_unused(lam2bb_.size() == old_size && "really make sure we didn't triger a rehash");
81 }
82
83 Lam* curr_lam_ = nullptr;
84 std::ostream& ostream_;
90};
91
92} // namespace mim
Lam * root() const
Definition phase.h:172
Base class for all Defs.
Definition def.h:212
DefMap< Value > locals_
Definition emitter.h:86
Value emit(const Def *def)
Recursively emits code.
Definition emitter.h:35
std::ostream & ostream() const
Definition emitter.h:30
Scheduler scheduler_
Definition emitter.h:85
Value emit_unsafe(const Def *def)
As above but returning !child().is_valid(value) is permitted.
Definition emitter.h:42
DefMap< Value > globals_
Definition emitter.h:87
Lam * curr_lam_
Definition emitter.h:83
DefMap< Type > types_
Definition emitter.h:88
Emitter(World &world, std::string_view name, std::ostream &ostream)
Definition emitter.h:26
LamMap< BB > lam2bb_
Definition emitter.h:89
void visit(const Nest &nest) override
Definition emitter.h:50
std::ostream & ostream_
Definition emitter.h:84
A function.
Definition lam.h:105
static const Lam * isa_basicblock(Ref d)
Definition lam.h:137
Like ClosedMutPhase but computes a Nest for each NestPhase::visit.
Definition phase.h:198
const Nest & nest() const
Definition phase.h:203
Builds a nesting tree of all immutables‍/binders.
Definition nest.h:11
std::string_view name() const
Definition phase.h:28
World & world()
Definition phase.h:27
const Nest::Node * smart(Def *curr, const Def *)
Definition schedule.cpp:79
static Schedule schedule(const Nest &)
Definition schedule.cpp:114
Keeps track of indentation level.
Definition print.h:195
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:33
Definition ast.h:14
GIDMap< const Def *, To > DefMap
Definition def.h:58
GIDMap< Lam *, To > LamMap
Definition lam.h:196