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 int i = 0;
48 for (bool todo = true; todo;) {
49 VLOG("iteration: {}", i++);
50 todo = false;
51 todo |= analyze();
52 }
53
54 for (const auto& [f, def] : old_world().flags2annex())
55 rewrite_annex(f, def);
56
57 bootstrapping_ = false;
58
59 for (auto mut : old_world().externals().muts())
61
63}
64
66 if (analysis_) {
67 analysis_->reset();
68 analysis_->run();
69 return analysis_->todo();
70 }
71
72 return false;
73}
74
76
78 auto new_mut = rewrite(old_mut)->as_mut();
79 if (old_mut->is_external()) new_mut->externalize();
80}
81
82/*
83 * ReplMan
84 */
85
87 for (auto&& repl : repls)
88 if (auto&& man = repl->isa<ReplMan>())
89 apply(std::move(man->repls_));
90 else
91 add(std::move(repl));
92}
93
94void ReplMan::apply(const App* app) {
95 auto repls = Repls();
96 for (auto arg : app->args())
97 if (auto stage = Stage::create(driver().stages(), arg))
98 repls.emplace_back(std::unique_ptr<Repl>(static_cast<Repl*>(stage.release())));
99
100 apply(std::move(repls));
101}
102
103/*
104 * ReplManPhase
105 */
106
107void ReplManPhase::apply(const App* app) {
108 man_ = std::make_unique<ReplMan>(old_world(), annex());
109 auto repls = Repls();
110 for (auto arg : app->args())
111 if (auto stage = Phase::create(driver().stages(), arg))
112 repls.emplace_back(std::unique_ptr<Repl>(static_cast<Repl*>(stage.release())));
113 man_->apply(std::move(repls));
114}
115
117 auto& rmp = static_cast<ReplManPhase&>(stage);
118 swap(man_, rmp.man_);
119}
120
122 old_world().verify().ILOG("🔥 run");
123 for (auto&& repl : man().repls())
124 ILOG(" 🔹 `{}`", repl->name());
127}
128
129const Def* ReplManPhase::rewrite(const Def* def) {
130 for (bool todo = true; todo;) {
131 todo = false;
132 for (auto&& repl : man().repls())
133 if (auto subst = repl->replace(def)) todo = true, def = subst;
134 }
135
136 return Rewriter::rewrite(def);
137}
138
139/*
140 * PhaseMan
141 */
142
143void PhaseMan::apply(bool fp, Phases&& phases) {
144 fixed_point_ = fp;
145 phases_ = std::move(phases);
146 name_ += fixed_point_ ? " tt" : " ff";
147}
148
149void PhaseMan::apply(const App* app) {
150 auto [fp, args] = app->uncurry_args<2>();
151
152 auto phases = Phases();
153 for (auto arg : args->projs())
154 if (auto stage = create(driver().stages(), arg)) {
155 // clang-format off
156 if (auto pm = stage->isa<PassManPhase>(); pm && pm-> man().empty()) continue;
157 if (auto rp = stage->isa<ReplMan >(); rp && rp->repls().empty()) continue;
158 // clang-format on
159 phases.emplace_back(std::unique_ptr<Phase>(static_cast<Phase*>(stage.release())));
160 }
161
162 apply(Lit::as<bool>(fp), std::move(phases));
163}
164
165void PhaseMan::apply(Stage& stage) {
166 auto& man = static_cast<PhaseMan&>(stage);
167 apply(man.fixed_point(), std::move(man.phases_));
168}
169
171 int iter = 0;
172 for (bool todo = true; todo; ++iter) {
173 todo = false;
174
175 if (fixed_point()) VLOG("🔄 fixed-point iteration: {}", iter);
176
177 for (auto& phase : phases()) {
178 phase->run();
179 todo |= phase->todo();
180 }
181
182 todo &= fixed_point();
183
184 if (todo) {
185 for (auto& old_phase : phases()) {
186 auto new_phase = std::unique_ptr<Phase>(static_cast<Phase*>(old_phase->recreate().release()));
187 swap(new_phase, old_phase);
188 }
189 }
190
191 todo_ |= todo;
192 }
193}
194
195/*
196 * PassManPhase
197 */
198
199void PassManPhase::apply(const App* app) {
200 man_ = std::make_unique<PassMan>(world(), annex());
201 auto passes = Passes();
202 for (auto arg : app->args())
203 if (auto stage = Phase::create(driver().stages(), arg))
204 passes.emplace_back(std::unique_ptr<Pass>(static_cast<Pass*>(stage.release())));
205
206 man_->apply(std::move(passes));
207}
208
210 auto& pmp = static_cast<PassManPhase&>(stage);
211 swap(man_, pmp.man_);
212}
213
214} // 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:234
PassManPhase(World &world, std::unique_ptr< PassMan > &&man)
Definition phase.h:238
void apply(const App *) final
Invoked if your Stage has additional args.
Definition phase.cpp:199
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:262
bool fixed_point() const
Definition phase.h:272
auto & phases()
Definition phase.h:273
void start() final
Actual entry.
Definition phase.cpp:170
void apply(bool, Phases &&)
Definition phase.cpp:143
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:65
World & new_world()
Create new Defs into this.
Definition phase.h:146
virtual void rewrite_annex(flags_t, const Def *)
Definition phase.cpp:75
void start() override
Actual entry.
Definition phase.cpp:46
World & old_world()
Get old Defs from here.
Definition phase.h:145
virtual void rewrite_external(Def *)
Definition phase.cpp:77
const Def * rewrite(const Def *) final
Definition phase.cpp:129
const ReplMan & man() const
Definition phase.h:215
void start() final
Actual entry.
Definition phase.cpp:121
ReplManPhase(World &world, std::unique_ptr< ReplMan > &&man)
Definition phase.h:205
void apply(const App *) final
Invoked if your Stage has additional args.
Definition phase.cpp:107
const auto & repls() const
Definition phase.h:177
ReplMan(World &world, flags_t annex)
Definition phase.h:169
void add(std::unique_ptr< Repl > &&repl)
Definition phase.h:176
void apply(Repls &&)
Definition phase.cpp:86
Simple Stage that searches for a pattern and replaces it.
Definition phase.h:159
Repl(World &world, flags_t annex)
Definition phase.h:161
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: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