MimIR
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/def.h"
4#include "mim/phase.h"
5#include "mim/schedule.h"
6#include "mim/world.h"
7
8namespace mim {
9
10template<class Value, class Type, class BB, class Child>
11class Emitter : public NestPhase<Lam> {
12private:
13 constexpr const Child& child() const { return *static_cast<const Child*>(this); }
14 constexpr Child& child() { return *static_cast<Child*>(this); }
15
16 /// Internal wrapper for Emitter::emit that schedules @p def and invokes `child().emit_bb`.
17 Value emit_(const Def* def) {
18 auto place = scheduler_.smart(curr_lam_, def);
19 auto& bb = lam2bb_[place->mut()->template as<Lam>()];
20 return child().emit_bb(bb, def);
21 }
22
23public:
24 fe::Tab tab = fe::Tab::spaces();
25
26protected:
27 Emitter(World& world, std::string name, std::ostream& ostream, bool schedule = false)
28 : NestPhase<Lam>(world, std::move(name), false, schedule)
29 , ostream_(ostream) {}
30
31 virtual bool direct_style() { return false; }
32
33 std::ostream& ostream() const { return ostream_; }
34
35 /// Recursively emits code.
36 /// `mem`-typed @p def%s return sth that is `!child().is_valid(value)`.
37 /// This variant asserts in this case.
38 Value emit(const Def* def) {
39 auto res = emit_unsafe(def);
40 assert(child().is_valid(res));
41 return res;
42 }
43
44 /// As above but returning `!child().is_valid(value)` is permitted.
45 Value emit_unsafe(const Def* def) {
46 if (auto i = globals_.find(def); i != globals_.end()) return i->second;
47 if (auto i = locals_.find(def); i != locals_.end()) return i->second;
48
49 auto val = emit_(def);
50 return locals_[def] = val;
51 }
52
53 void visit(const Nest& nest) override {
54 if (!root()->is_set()) {
55 child().emit_imported(root());
56 return;
57 }
58
59 auto muts = Scheduler::schedule(nest); // TODO make sure to not compute twice
60
61 // make sure that we don't need to rehash later on
62 for (auto mut : muts)
63 if (auto lam = mut->isa<Lam>()) lam2bb_.try_emplace(lam, BB());
64 auto old_size = lam2bb_.size();
65
66 if (!child().direct_style()) assert(root()->ret_var());
67
68 auto fct = child().prepare();
69
70 Scheduler new_scheduler(nest);
71 swap(scheduler_, new_scheduler);
72
73 for (auto mut : muts) {
74 if (auto lam = mut->isa<Lam>()) {
75 curr_lam_ = lam;
76 if (!child().direct_style()) assert(lam == root() || Lam::isa_basicblock(lam));
77 child().emit_epilogue(lam);
78 }
79 }
80
81 child().finalize();
82 locals_.clear();
83 assert_unused(lam2bb_.size() == old_size && "really make sure we didn't trigger a rehash");
84 }
85
86 Lam* curr_lam_ = nullptr;
87 std::ostream& ostream_;
93};
94
95} // namespace mim
Lam * root() const
Definition phase.h:408
bool schedule() const
Definition phase.h:401
Base class for all Defs.
Definition def.h:246
Value emit(const Def *def)
Recursively emits code.
Definition emitter.h:38
virtual bool direct_style()
Definition emitter.h:31
Emitter(World &world, std::string name, std::ostream &ostream, bool schedule=false)
Definition emitter.h:27
Scheduler scheduler_
Definition emitter.h:88
Value emit_unsafe(const Def *def)
As above but returning !child().is_valid(value) is permitted.
Definition emitter.h:45
Lam * curr_lam_
Definition emitter.h:86
LamMap< BB > lam2bb_
Definition emitter.h:92
void visit(const Nest &nest) override
Definition emitter.h:53
A function.
Definition lam.h:110
static const Lam * isa_basicblock(const Def *d)
Definition lam.h:142
const Nest & nest() const
Definition phase.h:426
NestPhase(World &world, std::string name, bool elide_empty, bool schedule=false)
Definition phase.h:421
Builds a nesting tree for all mutables/binders.
Definition nest.h:18
static Schedule schedule(const Nest &)
Definition schedule.cpp:125
World & world()
Definition pass.h:77
std::string_view name() const
Definition pass.h:80
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:36
Definition ast.h:14
GIDMap< const Def *, To > DefMap
Definition def.h:75
GIDMap< Lam *, To > LamMap
Definition lam.h:219
Definition span.h:122