mirror of
https://github.com/revng/revng
synced 2026-06-21 14:07:57 +00:00
DLA: Add DeduplicateUnionFields Step
Add a step that recognizes if two subtrees of a union node are topologically equivalent and merges them. This corresponds to removing duplicate fields in unions. This deduplication was prevously done while emitting layouts. A check is inserted into DLAMakeLayouts to assert that, after constructing unions, no union has only one child, which could be the case if we didn't deduplicate union fields in the graph.
This commit is contained in:
committed by
Pietro Fezzardi
parent
637bf70ff3
commit
43ae7a91cb
@@ -8,6 +8,7 @@
|
||||
#include "llvm/ADT/SCCIterator.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
@@ -24,6 +25,8 @@ using namespace llvm;
|
||||
|
||||
using NodeAllocatorT = SpecificBumpPtrAllocator<dla::LayoutTypeSystemNode>;
|
||||
|
||||
static Logger<> CollapsedNodePrinter("dla-print-collapsed-in-dot");
|
||||
|
||||
void *operator new(size_t, NodeAllocatorT &NodeAllocator) {
|
||||
return NodeAllocator.Allocate();
|
||||
}
|
||||
@@ -93,7 +96,8 @@ static_assert(sizeof(Instance) == (str_len(Instance) + 1));
|
||||
static_assert(sizeof(Unexpected) == (str_len(Unexpected) + 1));
|
||||
} // end unnamed namespace
|
||||
|
||||
void LayoutTypeSystem::dumpDotOnFile(const char *FName) const {
|
||||
void debug_function LayoutTypeSystem::dumpDotOnFile(const char *FName,
|
||||
bool ShowCollapsed) const {
|
||||
std::error_code EC;
|
||||
raw_fd_ostream DotFile(FName, EC);
|
||||
revng_check(not EC, "Could not open file for printing LayoutTypeSystem dot");
|
||||
@@ -121,7 +125,9 @@ void LayoutTypeSystem::dumpDotOnFile(const char *FName) const {
|
||||
revng_unreachable();
|
||||
}
|
||||
|
||||
DebugPrinter->printNodeContent(*this, L, DotFile);
|
||||
if (CollapsedNodePrinter.isEnabled() or ShowCollapsed)
|
||||
DebugPrinter->printNodeContent(*this, L, DotFile);
|
||||
|
||||
DotFile << "\"];\n";
|
||||
}
|
||||
|
||||
@@ -640,6 +646,20 @@ bool LayoutTypeSystem::verifyInheritanceTree() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LayoutTypeSystem::verifyUnions() const {
|
||||
using GraphNodeT = const LayoutTypeSystemNode *;
|
||||
for (GraphNodeT Node : llvm::nodes(this)) {
|
||||
if (Node->InterferingInfo == AllChildrenAreInterfering
|
||||
and Node->Successors.size() <= 1) {
|
||||
if (VerifyDLALog.isEnabled())
|
||||
revng_check(false);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LayoutTypeSystem::verifyConflicts() const {
|
||||
using GraphNodeT = const LayoutTypeSystemNode *;
|
||||
using LinkT = const LayoutTypeSystemNode::Link;
|
||||
@@ -647,12 +667,12 @@ bool LayoutTypeSystem::verifyConflicts() const {
|
||||
for (GraphNodeT Node : llvm::nodes(this)) {
|
||||
for (auto &Succ : Node->Successors) {
|
||||
|
||||
auto HasSameSucc = [&Succ](const LinkT &L2) {
|
||||
auto HasSameSuccAtOffset0 = [&Succ](const LinkT &L2) {
|
||||
return isInstanceOff0Edge(L2) and (Succ.first == L2.first);
|
||||
};
|
||||
|
||||
if (isInheritanceEdge(Succ)
|
||||
and llvm::any_of(Node->Successors, HasSameSucc)) {
|
||||
and llvm::any_of(Node->Successors, HasSameSuccAtOffset0)) {
|
||||
if (VerifyDLALog.isEnabled())
|
||||
revng_check(false);
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user