Files
revng-revng/lib/RestructureCFGPass/MetaRegion.cpp
T
Andrea Gussoni ad31920b63 Fix for default SetNode membership.
When creating the collapsed node, remember to add in the substitution
phase of the old nodes of the regions (relative to the outer regions),
also any nodes added as default `SetNode`s for any entry dispatcher
inserted.
2019-04-11 16:35:10 +02:00

119 lines
3.3 KiB
C++

/// \file MetaRegion.h
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
// std includes
#include <memory>
#include <set>
#include <utility>
#include <vector>
// local libraries includes
#include "MetaRegion.h"
#include "revng-c/RestructureCFGPass/BasicBlockNode.h"
void MetaRegion::replaceNodes(std::vector<std::unique_ptr<BasicBlockNode>> &N) {
Nodes.erase(Nodes.begin(), Nodes.end());
for (std::unique_ptr<BasicBlockNode> &Node : N)
Nodes.insert(Node.get());
}
void MetaRegion::updateNodes(std::set<BasicBlockNode *> &Removal,
BasicBlockNode *Collapsed,
std::vector<BasicBlockNode *> &Dispatcher,
std::vector<BasicBlockNode *> &DefaultEntrySet) {
// Remove the old SCS nodes
bool NeedSubstitution = false;
for (BasicBlockNode *Node : Removal) {
if (Nodes.count(Node) != 0) {
Nodes.erase(Node);
NeedSubstitution = true;
}
}
// Add the collapsed node.
if (NeedSubstitution) {
Nodes.insert(Collapsed);
Nodes.insert(Dispatcher.begin(), Dispatcher.end());
Nodes.insert(DefaultEntrySet.begin(), DefaultEntrySet.end());
}
}
std::set<BasicBlockNode *> MetaRegion::getSuccessors() {
std::set<BasicBlockNode *> Successors;
for (BasicBlockNode *Node : nodes()) {
for (BasicBlockNode *Successor : Node->successors()) {
if (not containsNode(Successor)) {
Successors.insert(Successor);
}
}
}
return Successors;
}
std::set<MetaRegion::EdgeDescriptor> MetaRegion::getOutEdges() {
std::set<EdgeDescriptor> OutEdges;
for (BasicBlockNode *Node : nodes()) {
for (BasicBlockNode *Successor : Node->successors()) {
if (not containsNode(Successor)) {
OutEdges.insert(EdgeDescriptor(Node, Successor));
}
}
}
return OutEdges;
}
std::set<MetaRegion::EdgeDescriptor> MetaRegion::getInEdges() {
std::set<EdgeDescriptor> InEdges;
for (BasicBlockNode *Node : nodes()) {
for (BasicBlockNode *Predecessor : Node->predecessors()) {
if (not containsNode(Predecessor)) {
InEdges.insert(EdgeDescriptor(Predecessor, Node));
}
}
}
return InEdges;
}
bool MetaRegion::intersectsWith(MetaRegion &Other) const {
std::vector<BasicBlockNode *> Intersection;
std::set<BasicBlockNode *> &OtherNodes = Other.getNodes();
std::set_intersection(Nodes.begin(),
Nodes.end(),
OtherNodes.begin(),
OtherNodes.end(),
std::back_inserter(Intersection));
return (Intersection.size() != 0);
}
bool MetaRegion::isSubSet(MetaRegion &Other) const {
std::set<BasicBlockNode *> &OtherNodes = Other.getNodes();
return std::includes(OtherNodes.begin(),
OtherNodes.end(),
Nodes.begin(),
Nodes.end());
}
bool MetaRegion::isSuperSet(MetaRegion &Other) const {
std::set<BasicBlockNode *> &OtherNodes = Other.getNodes();
return std::includes(Nodes.begin(),
Nodes.end(),
OtherNodes.begin(),
OtherNodes.end());
}
bool MetaRegion::nodesEquality(MetaRegion &Other) const {
std::set<BasicBlockNode *> &OtherNodes = Other.getNodes();
return Nodes == OtherNodes;
}