#pragma once #include "Dominators.hpp" #include "PassManager.hpp" #include #include #include #include class BasicBlock; class Dominators; class Function; class Module; using BBset = std::set; using BBvec = std::vector; class Loop { private: // attribute: // preheader, header, blocks, parent, sub_loops, latches BasicBlock *preheader_ = nullptr; BasicBlock *header_; std::shared_ptr parent_ = nullptr; BBvec blocks_; std::vector> sub_loops_; std::unordered_set latches_; public: Loop(BasicBlock *header) : header_(header) { blocks_.push_back(header); } ~Loop() = default; void add_block(BasicBlock *bb) { blocks_.push_back(bb); } BasicBlock *get_header() { return header_; } BasicBlock *get_preheader() { return preheader_; } std::shared_ptr get_parent() { return parent_; } void set_parent(std::shared_ptr parent) { parent_ = parent; } void set_preheader(BasicBlock *bb) { preheader_ = bb; } void add_sub_loop(std::shared_ptr loop) { sub_loops_.push_back(loop); } const BBvec& get_blocks() { return blocks_; } const std::vector>& get_sub_loops() { return sub_loops_; } const std::unordered_set& get_latches() { return latches_; } void add_latch(BasicBlock *bb) { latches_.insert(bb); } }; class LoopDetection : public Pass { private: Function *func_; std::unique_ptr dominators_; std::vector> loops_; // map from header to loop std::unordered_map> bb_to_loop_; void discover_loop_and_sub_loops(BasicBlock *bb, BBset &latches, std::shared_ptr loop); public: LoopDetection(Module *m) : Pass(m) {} ~LoopDetection() = default; void run() override; void run_on_func(Function *f); void print() ; std::vector> &get_loops() { return loops_; } };