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> P*
add(Args&&... args) {
127 auto key = std::type_index(
typeid(P));
128 if (
auto it = registry_.find(key); it != registry_.end())
return static_cast<P*
>(it->second);
129 auto p = std::make_unique<P>(*
this, std::forward<Args>(args)...);
131 fixed_point_ |= res->fixed_point();
132 passes_.emplace_back(std::move(p));
133 registry_.emplace(key, res);
138 template<
class P,
class... Args>
static void run(
World&
world, Args&&... args) {
140 man.
add<P>(std::forward<Args>(args)...);
150 State(
const State&) =
delete;
151 State(State&&) =
delete;
152 State& operator=(State) =
delete;
156 Def* curr_mut =
nullptr;
158 std::stack<Def*> stack;
159 MutMap<undo_t> mut2visit;
166 void pop_states(
undo_t undo);
167 State& curr_state() {
168 assert(!states_.empty());
169 return states_.back();
171 const State& curr_state()
const {
172 assert(!states_.empty());
173 return states_.back();
175 undo_t curr_undo()
const {
return states_.size() - 1; }
180 const Def* rewrite(
const Def*);
182 const Def* map(
const Def* old_def,
const Def* new_def) {
183 curr_state().old2new[old_def] = new_def;
184 curr_state().old2new.emplace(new_def, new_def);
188 std::optional<const Def*> lookup(
const Def* old_def) {
189 for (
auto& state : states_ | std::ranges::views::reverse)
190 if (
auto i = state.old2new.find(old_def); i != state.old2new.end())
return i->second;
197 undo_t analyze(
const Def*);
198 bool analyzed(
const Def* def) {
199 for (
auto& state : states_ | std::ranges::views::reverse)
200 if (state.analyzed.contains(def))
return true;
201 curr_state().analyzed.emplace(def);
207 std::deque<std::unique_ptr<Pass>> passes_;
208 absl::flat_hash_map<std::type_index, Pass*> registry_;
209 std::deque<State> states_;
210 Def* curr_mut_ =
nullptr;
211 bool fixed_point_ =
false;
214 template<
class P,
class M>
friend class FPPass;
226 if constexpr (std::is_same<M, Def>::value)
233 if constexpr (std::is_same<M, Def>::value)
258 assert(!
states().empty());
261 template<
size_t I>
auto&
data() {
return std::get<I>(
data()); }
263 template<
class K>
auto&
data(
const K& key) {
return data()[key]; }
265 template<
size_t I,
class K>
auto&
data(
const K& key) {
return data<I>()[key]; }
274 const auto& mut2visit =
Super::man().curr_state().mut2visit;
275 if (
auto i = mut2visit.find(mut); i != mut2visit.end())
return i->second;
281 for (
auto i =
states().size(); i-- != 0;)
290 void*
alloc()
override {
return new typename P::Data(); }
291 void*
copy(
const void* p)
override {
return new typename P::Data(*
static_cast<const typename P::Data*
>(p)); }
292 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, Defs ops, u32 index, u32 tag)
DefMap< const Def * > Def2Def
Vector< const Def * > DefVec
GIDSet< const Def * > DefSet
static constexpr undo_t No_Undo