#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 in_active_vars; std::vector out_active_vars; std::vector use_vars; std::vector def_vars; }; class CFGType { public: std::vector> nodes; CFGNodeType *entry; std::unordered_map block_to_node; std::unordered_map label_to_block; }; 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);