35 template<
class P,
class... Args>
static void run(Args&&... args) {
36 P p(std::forward<Args>(args)...);
59 void start()
override;
68 void start()
override;
78 void start()
override;
85 template<
class... Args>
89 man_.template add<P>(std::forward<Args>(args)...);
90 name_ = std::string(man_.
passes().back()->name()) +
".pass_phase";
104 , man_(
std::move(man)) {}
106 void start()
override { man_->run(); }
109 std::unique_ptr<PassMan> man_;
118 void start()
override;
122 const auto&
phases()
const {
return phases_; }
127 template<
class P,
class... Args>
auto add(Args&&... args) {
128 if constexpr (std::is_base_of_v<Pass, P>) {
131 auto p = std::make_unique<P>(
world(), std::forward<Args&&>(args)...);
132 auto phase = p.get();
133 phases_.emplace_back(std::move(p));
134 if (phase->is_dirty()) phases_.emplace_back(std::make_unique<Cleanup>(
world()));
141 std::deque<std::unique_ptr<Phase>> phases_;
153 , elide_empty_(elide_empty) {}
155 void start()
override;
163 const Scope* scope_ =
nullptr;
174 , elide_empty_(elide_empty) {}
178 for (
const auto& [_, mut] :
world().externals()) queue.
push(mut);
180 while (!queue.
empty()) {
181 auto mut = queue.
pop();
182 if (
auto m = mut->isa<
M>(); m && m->is_closed() && (!elide_empty_ || m->is_set()))
visit(curr_mut_ = m);
Removes unreachable and dead code by rebuilding the whole World into a new one and swapping afterward...
void start() override
Actual entry.
Transitively visits all reachable closed mutables (Def::is_closed()) in World.
void start() override
Actual entry.
ClosedMutPhase(World &world, std::string_view name, bool elide_empty)
virtual void visit(M *)=0
Defs extended_ops() const
Like a RWPhase but starts with a fixed-point loop of FPPhase::analyze beforehand.
FPPhase(World &world, std::string_view name)
void start() override
Actual entry.
Wraps a PassMan pipeline as a Phase.
void start() override
Actual entry.
PassManPhase(World &world, std::unique_ptr< PassMan > &&man)
An optimizer that combines several optimizations in an optimal way.
void run()
Run all registered passes on the whole World.
const auto & passes() const
PassPhase(World &world, Args &&... args)
void start() override
Actual entry.
As opposed to a Pass, a Phase does one thing at a time and does not mix with other Phases.
static void run(Args &&... args)
Runs a single Phase.
Phase(World &world, std::string_view name, bool dirty)
virtual void run()
Entry point and generates some debug output; invokes Phase::start.
std::string_view name() const
virtual void start()=0
Actual entry.
Organizes several Phases as a pipeline.
auto add(Args &&... args)
Add a Phase.
void start() override
Actual entry.
const auto & phases() const
Visits the current Phase::world and constructs a new RWPhase::world along the way.
RWPhase(World &world, std::string_view name)
void start() override
Actual entry.
Recurseivly rewrites part of a program into the provided World.
Transitively visits all reachable Scopes in World that do not have free variables.
virtual void visit(const Scope &)=0
ScopePhase(World &world, std::string_view name, bool elide_empty)
const Scope & scope() const
void start() override
Actual entry.
A Scope represents a region of Defs that are live from the view of an entry's Var.
The World represents the whole program and manages creation of MimIR nodes (Defs).