diff --git a/include/revng-c/DataLayoutAnalysis/DLATypeSystem.h b/include/revng-c/DataLayoutAnalysis/DLATypeSystem.h index 68ece2a03..1e0638c2d 100644 --- a/include/revng-c/DataLayoutAnalysis/DLATypeSystem.h +++ b/include/revng-c/DataLayoutAnalysis/DLATypeSystem.h @@ -324,6 +324,8 @@ public: bool verifyLeafs() const; // Checks that there are no equality edges. bool verifyNoEquality() const; + // Checks that there are no equality edges. + bool verifyInstanceAtOffset0DAG() const; // Checks that no union node has only one child bool verifyUnions() const; // Checks that no node conflicting edges. @@ -557,7 +559,7 @@ isInstanceEdge(const llvm::GraphTraits::EdgeRef &E) { } inline bool -isInstanceOff0Edge(llvm::GraphTraits::EdgeRef &E) { +isInstanceOff0(const llvm::GraphTraits::EdgeRef &E) { if (not isInstanceEdge(E)) return false; @@ -565,6 +567,11 @@ isInstanceOff0Edge(llvm::GraphTraits::EdgeRef &E) { return OE.Offset == 0 and OE.Strides.empty() and OE.TripCounts.empty(); } +inline bool +isInstanceOffNon0(const llvm::GraphTraits::EdgeRef &E) { + return isInstanceEdge(E) and not isInstanceOff0(E); +} + inline bool isPointerEdge(const llvm::GraphTraits::EdgeRef &E) { return hasLinkKind(E); diff --git a/lib/DataLayoutAnalysis/DLATypeSystem.cpp b/lib/DataLayoutAnalysis/DLATypeSystem.cpp index 190ebcaab..6abf8433b 100644 --- a/lib/DataLayoutAnalysis/DLATypeSystem.cpp +++ b/lib/DataLayoutAnalysis/DLATypeSystem.cpp @@ -615,6 +615,33 @@ bool LayoutTypeSystem::verifyNoEquality() const { return true; } +bool LayoutTypeSystem::verifyInstanceAtOffset0DAG() const { + if (not verifyConsistency()) + return false; + + std::set Visited; + for (const auto &Node : llvm::nodes(this)) { + revng_assert(Node != nullptr); + if (Visited.count(Node)) + continue; + + using GraphNodeT = const LayoutTypeSystemNode *; + using InstanceNodeT = EdgeFilteredGraph; + auto I = scc_begin(InstanceNodeT(Node)); + auto E = scc_end(InstanceNodeT(Node)); + for (; I != E; ++I) { + Visited.insert(I->begin(), I->end()); + if (I.hasCycle()) { + if (VerifyDLALog.isEnabled()) + revng_check(false); + return false; + } + } + } + + return true; +} + bool LayoutTypeSystem::verifyLeafs() const { for (const auto &Node : llvm::nodes(this)) { if (isLeaf(Node) and Node->Size == 0) { @@ -665,7 +692,7 @@ bool LayoutTypeSystem::verifyConflicts() const { for (auto &Succ : Node->Successors) { auto HasSameSuccAtOffset0 = [&Succ](const LinkT &L2) { - return isInstanceOff0Edge(L2) and (Succ.first == L2.first); + return isInstanceOff0(L2) and (Succ.first == L2.first); }; if (isInheritanceEdge(Succ) diff --git a/lib/DataLayoutAnalysis/Middleend/DLARemoveConflictingEdges.cpp b/lib/DataLayoutAnalysis/Middleend/DLARemoveConflictingEdges.cpp index 3a63dc058..07d9739e4 100644 --- a/lib/DataLayoutAnalysis/Middleend/DLARemoveConflictingEdges.cpp +++ b/lib/DataLayoutAnalysis/Middleend/DLARemoveConflictingEdges.cpp @@ -36,12 +36,12 @@ bool RemoveConflictingEdges::removeConflicts(LayoutTypeSystem &TS, auto It = Node->Successors.begin(); while (It != Node->Successors.end()) { auto &L = *It; - if (isInstanceOff0Edge(L) and InhNodes.contains(L.first)) { + if (isInstanceOff0(L) and InhNodes.contains(L.first)) { // Remove from successor's predecessors size_t NFound = std::erase_if(L.first->Predecessors, [Node](const Link &Pred) { return Pred.first->ID == Node->ID - and isInstanceOff0Edge(Pred); + and isInstanceOff0(Pred); }); revng_assert(NFound > 0);