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 * RWPhase
21 */
22
24 for (bool todo = true; todo;) {
25 todo = false;
26 todo |= analyze();
27 }
28
29 for (const auto& [f, def] : old_world().flags2annex())
30 rewrite_annex(f, def);
31
32 bootstrapping_ = false;
33
34 for (auto mut : old_world().copy_externals())
36
37 swap(old_world(), new_world());
38}
39
41
43 auto new_mut = rewrite(old_mut)->as_mut();
44 if (old_mut->is_external()) new_mut->make_external();
45}
46
47/*
48 * ReplMan
49 */
50
52 for (auto&& repl : repls)
53 if (auto&& man = repl->isa<ReplMan>())
54 apply(std::move(man->repls_));
55 else
56 add(std::move(repl));
57}
58
59void ReplMan::apply(const App* app) {
60 auto repls = Repls();
61 for (auto arg : app->args())
62 if (auto stage = Stage::create(driver().stages(), arg))
63 repls.emplace_back(std::unique_ptr<Repl>(static_cast<Repl*>(stage.release())));
64
65 apply(std::move(repls));
66}
67
68/*
69 * ReplManPhase
70 */
71
72void ReplManPhase::apply(const App* app) {
73 man_ = std::make_unique<ReplMan>(old_world(), annex());
74 auto repls = Repls();
75 for (auto arg : app->args())
76 if (auto stage = Phase::create(driver().stages(), arg))
77 repls.emplace_back(std::unique_ptr<Repl>(static_cast<Repl*>(stage.release())));
78 man_->apply(std::move(repls));
79}
80
82 auto& rmp = static_cast<ReplManPhase&>(stage);
83 swap(man_, rmp.man_);
84}
85
87 old_world().verify().ILOG("🔥 run");
88 for (auto&& repl : man().repls())
89 ILOG(" 🔹 `{}`", repl->name());
92}
93
94const Def* ReplManPhase::rewrite(const Def* def) {
95 for (bool todo = true; todo;) {
96 todo = false;
97 for (auto&& repl : man().repls())
98 if (auto subst = repl->replace(def)) todo = true, def = subst;
99 }
100
101 return Rewriter::rewrite(def);
102}
103
104/*
105 * PhaseMan
106 */
107
108void PhaseMan::apply(bool fp, Phases&& phases) {
109 fixed_point_ = fp;
110 phases_ = std::move(phases);
111 name_ += fixed_point_ ? " tt" : " ff";
112}
113
114void PhaseMan::apply(const App* app) {
115 auto [fp, args] = app->uncurry_args<2>();
116
117 auto phases = Phases();
118 for (auto arg : args->projs())
119 if (auto stage = create(driver().stages(), arg)) {
120 // clang-format off
121 if (auto pm = stage->isa<PassManPhase>(); pm && pm-> man().empty()) continue;
122 if (auto rp = stage->isa<ReplMan >(); rp && rp->repls().empty()) continue;
123 // clang-format on
124 phases.emplace_back(std::unique_ptr<Phase>(static_cast<Phase*>(stage.release())));
125 }
126
127 apply(Lit::as<bool>(fp), std::move(phases));
128}
129
130void PhaseMan::apply(Stage& stage) {
131 auto& man = static_cast<PhaseMan&>(stage);
132 apply(man.fixed_point(), std::move(man.phases_));
133}
134
136 int iter = 0;
137 for (bool todo = true; todo; ++iter) {
138 todo = false;
139
140 if (fixed_point()) VLOG("🔄 fixed-point iteration: {}", iter);
141
142 for (auto& phase : phases()) {
143 phase->run();
144 todo |= phase->todo();
145 }
146
147 todo &= fixed_point();
148
149 if (todo) {
150 for (auto& old_phase : phases()) {
151 auto new_phase = std::unique_ptr<Phase>(static_cast<Phase*>(old_phase->recreate().release()));
152 swap(new_phase, old_phase);
153 }
154 }
155
156 todo_ |= todo;
157 }
158}
159
160/*
161 * PassManPhase
162 */
163
164void PassManPhase::apply(const App* app) {
165 man_ = std::make_unique<PassMan>(world(), annex());
166 auto passes = Passes();
167 for (auto arg : app->args())
168 if (auto stage = Phase::create(driver().stages(), arg))
169 passes.emplace_back(std::unique_ptr<Pass>(static_cast<Pass*>(stage.release())));
170
171 man_->apply(std::move(passes));
172}
173
175 auto& pmp = static_cast<PassManPhase&>(stage);
176 swap(man_, pmp.man_);
177}
178
179} // namespace mim
static auto uncurry_args(const Def *def)
Definition lam.h:330
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:491
bool is_external() const noexcept
Definition def.h:464
static T as(const Def *def)
Definition def.h:816
Wraps a PassMan pipeline as a Phase.
Definition phase.h:187
PassManPhase(World &world, std::unique_ptr< PassMan > &&man)
Definition phase.h:191
void apply(const App *) final
Invoked if your Stage has additional args.
Definition phase.cpp:164
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:215
bool fixed_point() const
Definition phase.h:225
auto & phases()
Definition phase.h:226
void start() final
Actual entry.
Definition phase.cpp:135
void apply(bool, Phases &&)
Definition phase.cpp:108
bool todo_
Set to true to indicate that you want to rerun all Phasees in current your 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.
World & new_world()
Create new Defs into this.
Definition phase.h:100
virtual void rewrite_annex(flags_t, const Def *)
Definition phase.cpp:40
void start() override
Actual entry.
Definition phase.cpp:23
virtual bool analyze()
You can do an optional fixed-point loop on the RWPhase::old_world before rewriting.
Definition phase.h:83
World & old_world()
Get old Defs from here.
Definition phase.h:99
virtual void rewrite_external(Def *)
Definition phase.cpp:42
const Def * rewrite(const Def *) final
Definition phase.cpp:94
const ReplMan & man() const
Definition phase.h:168
void start() final
Actual entry.
Definition phase.cpp:86
ReplManPhase(World &world, std::unique_ptr< ReplMan > &&man)
Definition phase.h:158
void apply(const App *) final
Invoked if your Stage has additional args.
Definition phase.cpp:72
const auto & repls() const
Definition phase.h:130
ReplMan(World &world, flags_t annex)
Definition phase.h:122
void add(std::unique_ptr< Repl > &&repl)
Definition phase.h:129
void apply(Repls &&)
Definition phase.cpp:51
Simple Stage that searches for a pattern and replaces it.
Definition phase.h:112
Repl(World &world, flags_t annex)
Definition phase.h:114
virtual const Def * rewrite(const Def *)
Definition rewrite.cpp:14
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:702
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:78
#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