32 std::string_view
name()
const {
return name_; }
33 size_t index()
const {
return index_; }
92 virtual void*
alloc() {
return nullptr; }
93 virtual void*
copy(
const void*) {
return nullptr; }
115 const auto&
passes()
const {
return passes_; }
126 template<
class P,
class... Args>
128 auto key = std::type_index(
typeid(P));
129 if (
auto it = registry_.find(key); it != registry_.end())
return static_cast<P*
>(it->second);
130 auto p = std::make_unique<P>(*
this, std::forward<Args>(args)...);
132 fixed_point_ |= res->fixed_point();
133 passes_.emplace_back(std::move(p));
134 registry_.emplace(key, res);
139 template<
class P,
class... Args>
142 man.
add<P>(std::forward<Args>(args)...);
152 State(
const State&) =
delete;
153 State(State&&) =
delete;
154 State& operator=(State) =
delete;
158 Def* curr_mut =
nullptr;
160 std::stack<Def*> stack;
161 MutMap<undo_t> mut2visit;
168 void pop_states(
undo_t undo);
169 State& curr_state() {
170 assert(!states_.empty());
171 return states_.back();
173 const State& curr_state()
const {
174 assert(!states_.empty());
175 return states_.back();
177 undo_t curr_undo()
const {
return states_.size() - 1; }
182 const Def* rewrite(
const Def*);
184 const Def* map(
const Def* old_def,
const Def* new_def) {
185 curr_state().old2new[old_def] = new_def;
186 curr_state().old2new.emplace(new_def, new_def);
190 std::optional<const Def*> lookup(
const Def* old_def) {
191 for (
auto& state : states_ | std::ranges::views::reverse)
192 if (
auto i = state.old2new.find(old_def); i != state.old2new.end())
return i->second;
199 undo_t analyze(
const Def*);
200 bool analyzed(
const Def* def) {
201 for (
auto& state : states_ | std::ranges::views::reverse)
202 if (state.analyzed.contains(def))
return true;
203 curr_state().analyzed.emplace(def);
209 std::deque<std::unique_ptr<Pass>> passes_;
210 absl::flat_hash_map<std::type_index, Pass*> registry_;
211 std::deque<State> states_;
212 Def* curr_mut_ =
nullptr;
213 bool fixed_point_ =
false;
216 template<
class P,
class M>
223template<
class P,
class M = Def>
230 if constexpr (std::is_same<M, Def>::value)
237 if constexpr (std::is_same<M, Def>::value)
246template<
class P,
class M = Def>
263 assert(!
states().empty());
268 return std::get<I>(
data());
276 template<
size_t I,
class K>
288 const auto& mut2visit =
Super::man().curr_state().mut2visit;
289 if (
auto i = mut2visit.find(mut); i != mut2visit.end())
return i->second;
295 for (
auto i =
states().size(); i-- != 0;)
304 void*
alloc()
override {
return new typename P::Data(); }
305 void*
copy(
const void* p)
override {
return new typename P::Data(*
static_cast<const typename P::Data*
>(p)); }
306 void dealloc(
void* state)
override {
delete static_cast<typename P::Data*
>(state); }
void dealloc(void *state) override
Destructor.
undo_t undo_visit(Def *mut) const
Retrieves the point to backtrack to just before mut was seen the very first time.
auto & data(const K &key)
Use this for your convenience if P::Data is a map.
FPPass(PassMan &man, std::string_view name)
void * copy(const void *p) override
Copy constructor.
undo_t curr_undo() const
Current undo point.
const auto & states() const
bool fixed_point() const override
std::tuple<> Data
Default.
void * alloc() override
Default constructor.
auto & data(const K &key)
Use this for your convenience if P::Data<I> is a map.
undo_t undo_enter(Def *mut) const
Retrieves the point to backtrack to just before rewriting mut's body.
An optimizer that combines several optimizations in an optimal way.
void run()
Run all registered passes on the whole World.
static void run(World &world, Args &&... args)
Runs a single Pass.
const auto & passes() const
P * add(Args &&... args)
Add a pass to this PassMan.
virtual void enter()
Invoked just before Pass::rewriteing PassMan::curr_mut's body.
const Proxy * proxy(const Def *type, Defs ops, u32 tag=0)
virtual undo_t analyze(const Proxy *)
const PassMan & man() const
Pass(PassMan &, std::string_view name)
virtual void * alloc()
Default constructor.
virtual const Def * rewrite(const Var *var)
virtual void dealloc(void *)
Destructor.
virtual const Def * rewrite(const Proxy *proxy)
virtual undo_t analyze(const Var *)
virtual undo_t analyze(const Def *)
virtual void prepare()
Invoked once before entering the main rewrite loop.
virtual void * copy(const void *)
Copy constructor.
virtual bool fixed_point() const
virtual bool inspect() const =0
Should the PassMan even consider this pass?
virtual const Def * rewrite(const Def *def)
std::string_view name() const
const Proxy * isa_proxy(const Def *def, u32 tag=0)
Check whether given def is a Proxy whose Proxy::pass matches this Pass's IPass::index.
const Proxy * as_proxy(const Def *def, u32 tag=0)
RWPass(PassMan &man, std::string_view name)
bool inspect() const override
Should the PassMan even consider this pass?
The World represents the whole program and manages creation of MimIR nodes (Defs).
const Proxy * proxy(const Def *type, u32 index, u32 tag, Defs ops)
DefMap< const Def * > Def2Def
Vector< const Def * > DefVec
GIDSet< const Def * > DefSet
static constexpr undo_t No_Undo