#pragma once #include #include #include #include #include #include "IR/IR_basic.h" using CFGNodeCollection = std::list; class CFGNodeType { public: // successors, predecessors, corresponding_block is provided by BuildCFGForFunction std::vector successors, predecessors; BlockItem *corresponding_block; // the following fields are provided by user CFGNodeCollection dom; bool visited; CFGNodeType *idom; std::vector successors_in_dom_tree; CFGNodeCollection dom_frontier; std::vector block_in_active_vars; std::vector block_out_active_vars; std::vector block_use_vars; std::vector block_def_vars; std::unordered_map> action_use_vars; std::unordered_map> action_def_vars; std::unordered_map> action_in_active_vars; std::unordered_map> action_out_active_vars; }; class CFGType { public: std::vector> nodes; CFGNodeType *entry; std::unordered_map block_to_node; std::unordered_map label_to_block; std::vector id_to_var; std::unordered_map var_to_id; FunctionDefItem *corresponding_func; }; namespace opt { class MoveInstruct : public ActionItem { public: std::string src_full; std::string dest_full; LLVMType ty; MoveInstruct() = default; void RecursivePrint([[maybe_unused]] std::ostream &os) const { throw std::runtime_error("Move instruction is not an actual LLVM IR instruction"); } }; } // namespace opt template > Container GetCollectionsIntersection(const Container &a, const Container &b, Compare comp = Compare()) { Container result; auto ita = a.begin(); auto itb = b.begin(); while (ita != a.end() && itb != b.end()) { if (comp(*ita, *itb)) { ++ita; } else if (comp(*itb, *ita)) { ++itb; } else { result.push_back(*ita); ++ita; ++itb; } } return result; } template > Container GetCollectionsUnion(const Container &a, const Container &b, Compare comp = Compare()) { Container result; auto ita = a.begin(); auto itb = b.begin(); while (ita != a.end() && itb != b.end()) { if (comp(*ita, *itb)) { result.push_back(*ita); ++ita; } else if (comp(*itb, *ita)) { result.push_back(*itb); ++itb; } else { result.push_back(*ita); ++ita; ++itb; } } while (ita != a.end()) { result.push_back(*ita); ++ita; } while (itb != b.end()) { result.push_back(*itb); ++itb; } return result; } template > Container GetCollectionsDifference(const Container &a, const Container &b, Compare comp = Compare()) { Container result; auto ita = a.begin(); auto itb = b.begin(); while (ita != a.end() && itb != b.end()) { if (comp(*ita, *itb)) { result.push_back(*ita); ++ita; } else if (comp(*itb, *ita)) { ++itb; } else { ++ita; ++itb; } } while (ita != a.end()) { result.push_back(*ita); ++ita; } return result; } template > bool GetCollectionsIsSame(const Container &a, const Container &b, Compare comp = Compare()) { auto ita = a.begin(); auto itb = b.begin(); while (ita != a.end() && itb != b.end()) { if (comp(*ita, *itb) || comp(*itb, *ita)) { return false; } ++ita; ++itb; } return ita == a.end() && itb == b.end(); } CFGType BuildCFGForFunction(const std::shared_ptr &func);