21using Repls = std::deque<std::unique_ptr<Repl>>;
22using Phases = std::deque<std::unique_ptr<Phase>>;
40 bool todo()
const {
return todo_; }
57 template<
class P,
class... Args>
58 static void run(Args&&... args) {
59 P p(std::forward<Args>(args)...);
126 : analysis_(analysis)
128 analysis->curr_mut_ = new_mut;
130 ~Enter() { analysis_->curr_mut_ = prev_mut_; }
139 void start()
override;
168 Def* curr_mut_ =
nullptr;
169 bool bootstrapping_ =
true;
212 if (
auto i = analysis_->lattice().find(old_def); i != analysis_->lattice().end())
return i->second;
247 void start()
override;
251 bool bootstrapping_ =
true;
273 void add(std::unique_ptr<Repl>&& repl) { repls_.emplace_back(std::move(repl)); }
274 const auto&
repls()
const {
return repls_; }
282#define MIM_CONCAT_INNER(a, b) a##b
283#define MIM_CONCAT(a, b) MIM_CONCAT_INNER(a, b)
285#define MIM_REPL(__stages, __annex, ...) MIM_REPL_IMPL(__stages, __annex, __LINE__, __VA_ARGS__)
288#define MIM_REPL_IMPL(__stages, __annex, __id, ...) \
289 struct MIM_CONCAT(Repl_, __id) : ::mim::Repl { \
290 MIM_CONCAT(Repl_, __id)(::mim::World & world, ::mim::flags_t annex) \
291 : Repl(world, annex) {} \
293 const ::mim::Def* replace(const ::mim::Def* def) final __VA_ARGS__ \
295 ::mim::Stage::hook<__annex, MIM_CONCAT(Repl_, __id)>(__stages)
342 void apply(
const App*)
final;
343 void apply(
Stage&)
final;
351 std::unique_ptr<PassMan> man_;
364 void apply(
bool,
Phases&&);
365 void apply(
const App*)
final;
366 void apply(
Stage&)
final;
373 const auto&
phases()
const {
return phases_; }
388template<class M =
Def>
408 M*
root()
const {
return root_; }
411 const bool elide_empty_;
412 const bool schedule_;
418template<
class M = Def>
Helps to keep track of curr_mut().
Enter(Analysis *analysis, Def *new_mut)
Traverses the current World using Rewriter infrastructure while staying in the same world.
void start() override
Actual entry.
void set(const Def *concr, const Def *abstr)
Records the abstract value abstr for concr in both lattice() (the analysis result) and map() (so the ...
Analysis(World &world, std::string name)
virtual void rewrite_annex(flags_t, Sym, const Def *)
Enter enter(Def *new_mut)
virtual void rewrite_external(Def *)
virtual Def * rewrite_deps(Def *)
Walks mut's dependencies under its curr_mut() scope.
virtual void reset()
Clears the rewriter map and resets Phase::todo() for the next fixed-point iteration.
const auto & lattice() const
bool is_bootstrapping() const
Analysis(World &world, flags_t annex)
Def * rewrite_mut(Def *) override
Default "visit a mutable" entry point: maps mut -> mut, seeds Lam binder vars to top (v -> v) in the ...
Cleanup(World &world, flags_t annex)
void start() override
Actual entry.
ClosedMutPhase(World &world, flags_t annex, bool elide_empty, bool schedule=false)
virtual void visit(M *)=0
ClosedMutPhase(World &world, std::string name, bool elide_empty, bool schedule=false)
virtual void visit(const Nest &)=0
const Nest & nest() const
NestPhase(World &world, std::string name, bool elide_empty, bool schedule=false)
NestPhase(World &world, flags_t annex, bool elide_empty, bool schedule=false)
Builds a nesting tree for all mutables/binders.
PassManPhase(World &world, flags_t annex)
PassManPhase(World &world, std::unique_ptr< PassMan > &&man)
void start() final
Actual entry.
const PassMan & man() const
An optimizer that combines several optimizations in an optimal way.
Organizes several Phases into a pipeline.
PhaseMan(World &world, flags_t annex)
const auto & phases() const
Unlike a Pass, a Phase performs one self-contained task and does not interleave with other phases.
void invalidate(bool todo=true)
Signals that another round of fixed-point iteration is required, either as part of.
Phase(World &world, std::string name)
static void run(Args &&... args)
Runs a single Phase.
Phase(World &world, flags_t annex)
virtual void run()
Entry point and generates some debug output; invokes Phase::start.
virtual void start()=0
Actual entry.
virtual bool analyze()
Runs the optional pre-analysis on RWPhase::old_world(), typically to a fixed point,...
World & new_world()
Create new Defs into this.
RWPhase(World &world, flags_t annex, Analysis *analysis=nullptr)
virtual void rewrite_annex(flags_t, Sym, const Def *)
bool is_bootstrapping() const
Returns whether we are currently bootstrapping (rewriting annexes).
RWPhase(World &world, std::string name, Analysis *analysis=nullptr)
void start() override
Actual entry.
const Def * lattice(const Def *old_def)
Returns the abstract value computed by the associated Analysis for the given old-world Def,...
World & world()=delete
Hides both and forbids direct access.
const Analysis * analysis() const
World & old_world()
Get old Defs from here.
virtual void rewrite_external(Def *)
const Def * rewrite(const Def *) final
ReplManPhase(World &world, flags_t annex)
const ReplMan & man() const
void start() final
Actual entry.
ReplManPhase(World &world, std::unique_ptr< ReplMan > &&man)
void apply(const App *) final
Invoked if your Stage has additional args.
void apply(Stage &stage) final
Dito, but invoked by Stage::recreate.
const auto & repls() const
const Def * replace(const Def *) final
ReplMan(World &world, flags_t annex)
void add(std::unique_ptr< Repl > &&repl)
Simple Stage that searches for a pattern and replaces it.
virtual const Def * replace(const Def *def)=0
Repl(World &world, flags_t annex)
virtual const Def * map(const Def *old_def, const Def *new_def)
Rewriter(std::unique_ptr< World > &&ptr)
Common base for Phase and Pass.
std::string_view name() const
Stage(World &world, std::string name)
The World represents the whole program and manages creation of MimIR nodes (Defs).
DefMap< const Def * > Def2Def
std::deque< std::unique_ptr< Repl > > Repls
std::deque< std::unique_ptr< Phase > > Phases