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
42/*
43 * RWPhase
44 */
45
47 for (bool todo = true; todo;) {
48 todo = false;
49 todo |= analyze();
50 }
51
52 for (const auto& [f, def] : old_world().flags2annex())
53 rewrite_annex(f, def);
54
55 bootstrapping_ = false;
56
57 for (auto mut : old_world().externals().muts())
59
61}
62
64 if (analysis_) {
65 analysis_->reset();
66 analysis_->run();
67 return analysis_->todo();
68 }
69
70 return false;
71}
72
74
76 auto new_mut = rewrite(old_mut)->as_mut();
77 if (old_mut->is_external()) new_mut->externalize();
78}
79
80/*
81 * ReplMan
82 */
83
85 for (auto&& repl : repls)
86 if (auto&& man = repl->isa<ReplMan>())
87 apply(std::move(man->repls_));
88 else
89 add(std::move(repl));
90}
91
92void ReplMan::apply(const App* app) {
93 auto repls = Repls();
94 for (auto arg : app->args())
95 if (auto stage = Stage::create(driver().stages(), arg))
96 repls.emplace_back(std::unique_ptr<Repl>(static_cast<Repl*>(stage.release())));
97
98 apply(std::move(repls));
99}
100
101/*
102 * ReplManPhase
103 */
104
105void ReplManPhase::apply(const App* app) {
106 man_ = std::make_unique<ReplMan>(old_world(), annex());
107 auto repls = Repls();
108 for (auto arg : app->args())
109 if (auto stage = Phase::create(driver().stages(), arg))
110 repls.emplace_back(std::unique_ptr<Repl>(static_cast<Repl*>(stage.release())));
111 man_->apply(std::move(repls));
112}
113
115 auto& rmp = static_cast<ReplManPhase&>(stage);
116 swap(man_, rmp.man_);
117}
118
120 old_world().verify().ILOG("🔥 run");
121 for (auto&& repl : man().repls())
122 ILOG(" 🔹 `{}`", repl->name());
125}
126
127const Def* ReplManPhase::rewrite(const Def* def) {
128 for (bool todo = true; todo;) {
129 todo = false;
130 for (auto&& repl : man().repls())
131 if (auto subst = repl->replace(def)) todo = true, def = subst;
132 }
133
134 return Rewriter::rewrite(def);
135}
136
137/*
138 * PhaseMan
139 */
140
141void PhaseMan::apply(bool fp, Phases&& phases) {
142 fixed_point_ = fp;
143 phases_ = std::move(phases);
144 name_ += fixed_point_ ? " tt" : " ff";
145}
146
147void PhaseMan::apply(const App* app) {
148 auto [fp, args] = app->uncurry_args<2>();
149
150 auto phases = Phases();
151 for (auto arg : args->projs())
152 if (auto stage = create(driver().stages(), arg)) {
153 // clang-format off
154 if (auto pm = stage->isa<PassManPhase>(); pm && pm-> man().empty()) continue;
155 if (auto rp = stage->isa<ReplMan >(); rp && rp->repls().empty()) continue;
156 // clang-format on
157 phases.emplace_back(std::unique_ptr<Phase>(static_cast<Phase*>(stage.release())));
158 }
159
160 apply(Lit::as<bool>(fp), std::move(phases));
161}
162
163void PhaseMan::apply(Stage& stage) {
164 auto& man = static_cast<PhaseMan&>(stage);
165 apply(man.fixed_point(), std::move(man.phases_));
166}
167
169 int iter = 0;
170 for (bool todo = true; todo; ++iter) {
171 todo = false;
172
173 if (fixed_point()) VLOG("🔄 fixed-point iteration: {}", iter);
174
175 for (auto& phase : phases()) {
176 phase->run();
177 todo |= phase->todo();
178 }
179
180 todo &= fixed_point();
181
182 if (todo) {
183 for (auto& old_phase : phases()) {
184 auto new_phase = std::unique_ptr<Phase>(static_cast<Phase*>(old_phase->recreate().release()));
185 swap(new_phase, old_phase);
186 }
187 }
188
189 todo_ |= todo;
190 }
191}
192
193/*
194 * PassManPhase
195 */
196
197void PassManPhase::apply(const App* app) {
198 man_ = std::make_unique<PassMan>(world(), annex());
199 auto passes = Passes();
200 for (auto arg : app->args())
201 if (auto stage = Phase::create(driver().stages(), arg))
202 passes.emplace_back(std::unique_ptr<Pass>(static_cast<Pass*>(stage.release())));
203
204 man_->apply(std::move(passes));
205}
206
208 auto& pmp = static_cast<PassManPhase&>(stage);
209 swap(man_, pmp.man_);
210}
211
212} // namespace mim
void start() override
Actual entry.
Definition phase.cpp:29
World & world()
Definition phase.h:90
virtual void rewrite_external(Def *)
Definition phase.cpp:40
virtual void reset()
Clears all members and sets todo() to false for next round in a fixed-point iteration.
Definition phase.cpp:23
virtual void rewrite_annex(flags_t, const Def *)
Definition phase.cpp:39
static auto uncurry_args(const Def *def)
Definition lam.h:329
Base class for all Defs.
Definition def.h:251
T * as_mut() const
Asserts that this is a mutable, casts constness away and performs a static_cast to T.
Definition def.h:495
bool is_external() const noexcept
Definition def.h:467
static T as(const Def *def)
Definition def.h:832
Wraps a PassMan pipeline as a Phase.
Definition phase.h:231
PassManPhase(World &world, std::unique_ptr< PassMan > &&man)
Definition phase.h:235
void apply(const App *) final
Invoked if your Stage has additional args.
Definition phase.cpp:197
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:259
bool fixed_point() const
Definition phase.h:269
auto & phases()
Definition phase.h:270
void start() final
Actual entry.
Definition phase.cpp:168
void apply(bool, Phases &&)
Definition phase.cpp:141
bool todo_
Set to true to indicate that you want to rerun all Phasees in your current fixed-point PhaseMan.
Definition phase.h:57
Phase(World &world, std::string name)
Definition phase.h:30
virtual void run()
Entry point and generates some debug output; invokes Phase::start.
Definition phase.cpp:13
bool todo() const
Definition phase.h:39
virtual void start()=0
Actual entry.
virtual bool analyze()
You can do an optional fixed-point loop on the RWPhase::old_world before rewriting.
Definition phase.cpp:63
World & new_world()
Create new Defs into this.
Definition phase.h:143
virtual void rewrite_annex(flags_t, const Def *)
Definition phase.cpp:73
void start() override
Actual entry.
Definition phase.cpp:46
World & old_world()
Get old Defs from here.
Definition phase.h:142
virtual void rewrite_external(Def *)
Definition phase.cpp:75
const Def * rewrite(const Def *) final
Definition phase.cpp:127
const ReplMan & man() const
Definition phase.h:212
void start() final
Actual entry.
Definition phase.cpp:119
ReplManPhase(World &world, std::unique_ptr< ReplMan > &&man)
Definition phase.h:202
void apply(const App *) final
Invoked if your Stage has additional args.
Definition phase.cpp:105
const auto & repls() const
Definition phase.h:174
ReplMan(World &world, flags_t annex)
Definition phase.h:166
void add(std::unique_ptr< Repl > &&repl)
Definition phase.h:173
void apply(Repls &&)
Definition phase.cpp:84
Simple Stage that searches for a pattern and replaces it.
Definition phase.h:156
Repl(World &world, flags_t annex)
Definition phase.h:158
friend void swap(Rewriter &rw1, Rewriter &rw2) noexcept
Definition rewrite.h:96
virtual void push()
Definition rewrite.h:52
std::deque< Def2Def > old2news_
Definition rewrite.h:107
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:709
void debug_dump()
Dump in Debug build if World::log::level is Log::Level::Debug.
Definition dump.cpp:493
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:45
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