#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include #include #include #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/iterator_range.h" #include "revng/RestructureCFG/RegionCFGTreeBB.h" template class BasicBlockNode; /// The MetaRegion class, a wrapper for a set of nodes. template class MetaRegion { public: using BasicBlockNodeT = typename BasicBlockNode::BasicBlockNodeT; using BasicBlockNodeTSet = std::set; using BasicBlockNodeTVect = std::vector; using BasicBlockNodeTUPVect = std::vector>; using EdgeDescriptor = typename BasicBlockNode::EdgeDescriptor; using links_container = std::set; using links_iterator = typename links_container::iterator; using links_const_iterator = typename links_container::const_iterator; using links_range = llvm::iterator_range; using links_const_range = llvm::iterator_range; inline links_iterator begin() { return Nodes.begin(); } inline links_const_iterator cbegin() const { return Nodes.cbegin(); } inline links_iterator end() { return Nodes.end(); } inline links_const_iterator cend() const { return Nodes.cend(); } using BasicBlockNodeRPOT = llvm::ReversePostOrderTraversal; private: int Index; links_container Nodes; MetaRegion *ParentRegion = nullptr; bool IsSCS; public: MetaRegion(int Index, BasicBlockNodeTSet &Nodes, bool IsSCS = false) : Index(Index), Nodes(Nodes), ParentRegion(nullptr), IsSCS(IsSCS) {} int getIndex() const { return Index; } void replaceNodes(BasicBlockNodeTUPVect &NewNodes); void updateNodes(const BasicBlockNodeTSet &Removal, BasicBlockNodeT *Collapsed, BasicBlockNodeT *ExitDispatcher, const BasicBlockNodeTVect &DefaultEntrySet, const BasicBlockNodeTVect &DeduplicatedDummies); void setParent(MetaRegion *Parent) { ParentRegion = Parent; } MetaRegion *getParent() const { return ParentRegion; } std::set *> &getNodes() { return Nodes; } const std::set *> &getNodes() const { return Nodes; } size_t nodes_size() const { return Nodes.size(); } links_const_range nodes() const { return llvm::make_range(Nodes.begin(), Nodes.end()); } links_range nodes() { return llvm::make_range(Nodes.begin(), Nodes.end()); } std::set *> getSuccessors(); std::set getOutEdges(); std::set getInEdges(); bool intersectsWith(MetaRegion &Other) const; bool isSubSet(MetaRegion &Other) const; bool isSuperSet(MetaRegion &Other) const; bool nodesEquality(MetaRegion &Other) const; void mergeWith(MetaRegion &Other) { BasicBlockNodeTSet &OtherNodes = Other.getNodes(); Nodes.insert(OtherNodes.begin(), OtherNodes.end()); } bool isSCS() const { return IsSCS; } bool containsNode(BasicBlockNodeT *Node) const { return Nodes.contains(Node); } void insertNode(BasicBlockNodeT *NewNode) { Nodes.insert(NewNode); } void removeNode(BasicBlockNodeT *Node) { Nodes.erase(Node); } };