MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
phase.cpp
Go to the documentation of this file.
1#include "mim/phase.h"
2
3#include <memory>
4
5#include "mim/driver.h"
6
7namespace mim {
8
9/*
10 * Phase
11 */
12
13void Phase::run() {
14 world().verify().ILOG("🚀 Phase launch: `{}`", name());
15 start();
16 world().verify().ILOG("🏁 Phase finish: `{}`", name());
17}
18
19/*
20 * Analyzer
21 */
22
24 old2news_.clear();
25 push();
26 todo_ = false;
27}
28
30 for (const auto& [f, def] : world().flags2annex())
31 rewrite_annex(f, def);
32
33 bootstrapping_ = false;
34
35 for (auto mut : world().externals().muts())
37}
38
39void Analysis::rewrite_annex(flags_t, const Def* def) { rewrite(def); }
41
43 map(mut, mut);
44
45 if (auto var = mut->has_var()) {
46 map(var, var);
47
48 if (mut->isa<Lam>())
49 for (auto var : mut->tvars()) {
50 map(var, var);
51 lattice_[var] = var;
52 }
53 }
54
55 for (auto d : mut->deps())
56 rewrite(d);
57
58 return mut;
59}
60
61/*
62 * RWPhase
63 */
64
66 int i = 0;
67 for (bool todo = true; todo;) {
68 VLOG("iteration: {}", i++);
69 todo = false;
70 todo |= analyze();
71 }
72
73 for (const auto& [f, def] : old_world().flags2annex())
74 rewrite_annex(f, def);
75
76 bootstrapping_ = false;
77
78 for (auto mut : old_world().externals().muts())
80
82}
83
85 if (analysis_) {
86 analysis_->reset();
87 analysis_->run();
88 return analysis_->todo();
89 }
90
91 return false;
92}
93
95
97 auto new_mut = rewrite(old_mut)->as_mut();
98 if (old_mut->is_external()) new_mut->externalize();
99}
100
101/*
102 * ReplMan
103 */
104
106 for (auto&& repl : repls)
107 if (auto&& man = repl->isa<ReplMan>())
108 apply(std::move(man->repls_));
109 else
110 add(std::move(repl));
111}
112
113void ReplMan::apply(const App* app) {
114 auto repls = Repls();
115 for (auto arg : app->args())
116 if (auto stage = Stage::create(driver().stages(), arg))
117 repls.emplace_back(std::unique_ptr<Repl>(static_cast<Repl*>(stage.release())));
118
119 apply(std::move(repls));
120}
121
122/*
123 * ReplManPhase
124 */
125
126void ReplManPhase::apply(const App* app) {
127 man_ = std::make_unique<ReplMan>(old_world(), annex());
128 auto repls = Repls();
129 for (auto arg : app->args())
130 if (auto stage = Phase::create(driver().stages(), arg))
131 repls.emplace_back(std::unique_ptr<Repl>(static_cast<Repl*>(stage.release())));
132 man_->apply(std::move(repls));
133}
134
136 auto& rmp = static_cast<ReplManPhase&>(stage);
137 swap(man_, rmp.man_);
138}
139
141 old_world().verify().ILOG("🔥 run");
142 for (auto&& repl : man().repls())
143 ILOG(" 🔹 `{}`", repl->name());
146}
147
148const Def* ReplManPhase::rewrite(const Def* def) {
149 for (bool todo = true; todo;) {
150 todo = false;
151 for (auto&& repl : man().repls())
152 if (auto subst = repl->replace(def)) todo = true, def = subst;
153 }
154
155 return Rewriter::rewrite(def);
156}
157
158/*
159 * PhaseMan
160 */
161
162void PhaseMan::apply(bool fp, Phases&& phases) {
163 fixed_point_ = fp;
164 phases_ = std::move(phases);
165 name_ += fixed_point_ ? " tt" : " ff";
166}
167
168void PhaseMan::apply(const App* app) {
169 auto [fp, args] = app->uncurry_args<2>();
170
171 auto phases = Phases();
172 for (auto arg : args->projs())
173 if (auto stage = create(driver().stages(), arg)) {
174 // clang-format off
175 if (auto pm = stage->isa<PassManPhase>(); pm && pm-> man().empty()) continue;
176 if (auto rp = stage->isa<ReplMan >(); rp && rp->repls().empty()) continue;
177 // clang-format on
178 phases.emplace_back(std::unique_ptr<Phase>(static_cast<Phase*>(stage.release())));
179 }
180
181 apply(Lit::as<bool>(fp), std::move(phases));
182}
183
184void PhaseMan::apply(Stage& stage) {
185 auto& man = static_cast<PhaseMan&>(stage);
186 Phases new_phases;
187 for (auto& old_phase : man.phases())
188 new_phases.emplace_back(std::unique_ptr<Phase>(static_cast<Phase*>(old_phase->recreate().release())));
189 apply(man.fixed_point(), std::move(new_phases));
190}
191
193 int iter = 0;
194 for (bool todo = true; todo; ++iter) {
195 todo = false;
196
197 if (fixed_point()) VLOG("🔄 fixed-point iteration: {}", iter);
198
199 for (auto& phase : phases()) {
200 phase->run();
201 todo |= phase->todo();
202 }
203
204 todo &= fixed_point();
205
206 if (todo) {
207 for (auto& old_phase : phases()) {
208 auto new_phase = std::unique_ptr<Phase>(static_cast<Phase*>(old_phase->recreate().release()));
209 swap(new_phase, old_phase);
210 }
211 }
212
214 }
215}
216
217/*
218 * PassManPhase
219 */
220
221void PassManPhase::apply(const App* app) {
222 man_ = std::make_unique<PassMan>(world(), annex());
223 auto passes = Passes();
224 for (auto arg : app->args())
225 if (auto stage = Phase::create(driver().stages(), arg))
226 passes.emplace_back(std::unique_ptr<Pass>(static_cast<Pass*>(stage.release())));
227
228 man_->apply(std::move(passes));
229}
230
232 auto& pmp = static_cast<PassManPhase&>(stage);
233 swap(man_, pmp.man_);
234}
235
236} // namespace mim
void start() override
Actual entry.
Definition phase.cpp:29
World & world()
Definition phase.h:114
Def2Def lattice_
Definition phase.h:120
virtual void rewrite_external(Def *)
Definition phase.cpp:40
virtual void reset()
Clears rewriter state, analysis state, and resets Phase::todo() for the next fixed-point iteration.
Definition phase.cpp:23
virtual void rewrite_annex(flags_t, const Def *)
Definition phase.cpp:39
Def * rewrite_mut(Def *) override
Keeps old muts/vars.
Definition phase.cpp:42
static auto uncurry_args(const Def *def)
Definition lam.h:329
Base class for all Defs.
Definition def.h:252
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
Definition def.h:507
Defs deps() const noexcept
Definition def.cpp:475
bool is_external() const noexcept
Definition def.h:479
auto tvars(F f) noexcept
Definition def.h:430
const Var * has_var()
Only returns not nullptr, if Var of this mutable has ever been created.
Definition def.h:434
A function.
Definition lam.h:110
static T as(const Def *def)
Definition def.h:849
Wraps a PassMan pipeline as a Phase.
Definition phase.h:284
PassManPhase(World &world, std::unique_ptr< PassMan > &&man)
Definition phase.h:288
void apply(const App *) final
Invoked if your Stage has additional args.
Definition phase.cpp:221
All Passes that want to be registered in the PassMan must implement this interface.
Definition pass.h:83
PhaseMan(World &world, flags_t annex)
Definition phase.h:313
bool fixed_point() const
Definition phase.h:323
auto & phases()
Definition phase.h:324
void start() final
Actual entry.
Definition phase.cpp:192
void apply(bool, Phases &&)
Definition phase.cpp:162
void invalidate(bool todo=true)
Signals that another round of fixed-point iteration is required, either as part of.
Definition phase.h:48
Phase(World &world, std::string name)
Definition phase.h:31
virtual void run()
Entry point and generates some debug output; invokes Phase::start.
Definition phase.cpp:13
bool todo() const
Definition phase.h:40
virtual void start()=0
Actual entry.
virtual bool analyze()
Runs the optional pre-analysis on RWPhase::old_world(), typically to a fixed point,...
Definition phase.cpp:84
World & new_world()
Create new Defs into this.
Definition phase.h:195
virtual void rewrite_annex(flags_t, const Def *)
Definition phase.cpp:94
void start() override
Actual entry.
Definition phase.cpp:65
World & old_world()
Get old Defs from here.
Definition phase.h:194
virtual void rewrite_external(Def *)
Definition phase.cpp:96
const Def * rewrite(const Def *) final
Definition phase.cpp:148
const ReplMan & man() const
Definition phase.h:264
void start() final
Actual entry.
Definition phase.cpp:140
ReplManPhase(World &world, std::unique_ptr< ReplMan > &&man)
Definition phase.h:254
void apply(const App *) final
Invoked if your Stage has additional args.
Definition phase.cpp:126
const auto & repls() const
Definition phase.h:226
ReplMan(World &world, flags_t annex)
Definition phase.h:218
void add(std::unique_ptr< Repl > &&repl)
Definition phase.h:225
void apply(Repls &&)
Definition phase.cpp:105
Simple Stage that searches for a pattern and replaces it.
Definition phase.h:208
Repl(World &world, flags_t annex)
Definition phase.h:210
friend void swap(Rewriter &rw1, Rewriter &rw2) noexcept
Definition rewrite.h:97
virtual void push()
Definition rewrite.h:53
virtual const Def * map(const Def *old_def, const Def *new_def)
Definition rewrite.h:60
std::deque< Def2Def > old2news_
Definition rewrite.h:108
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:27
Common base for Phase and Pass.
Definition pass.h:26
World & world()
Definition pass.h:64
std::string name_
Definition pass.h:76
static auto create(const Flags2Stages &stages, const Def *def)
Definition pass.h:40
std::string_view name() const
Definition pass.h:67
Driver & driver()
Definition pass.h:65
flags_t annex() const
Definition pass.h:68
World & verify()
Verifies that all externals() and annexes() are Def::is_closed(), if MIM_ENABLE_CHECKS.
Definition world.cpp:721
void debug_dump()
Dump in Debug build if World::log::level is Log::Level::Debug.
Definition dump.cpp:555
const Def * register_annex(flags_t f, const Def *)
Definition world.cpp:93
#define ILOG(...)
Definition log.h:91
#define VLOG(...)
Definition log.h:92
Definition ast.h:14
u64 flags_t
Definition types.h:46
std::deque< std::unique_ptr< Pass > > Passes
Definition pass.h:16
std::deque< std::unique_ptr< Repl > > Repls
Definition phase.h:21
std::deque< std::unique_ptr< Phase > > Phases
Definition phase.h:22