diff --git a/include/revng-c/DataLayoutAnalysis/DLALayouts.h b/include/revng-c/DataLayoutAnalysis/DLALayouts.h index 7583e4624..9f1b89b41 100644 --- a/include/revng-c/DataLayoutAnalysis/DLALayouts.h +++ b/include/revng-c/DataLayoutAnalysis/DLALayouts.h @@ -294,6 +294,8 @@ public: void print(llvm::raw_ostream &Out) const; const llvm::Value &getValue() const { return *V; } + + bool isEmpty() const { return (V == nullptr); } }; // end class LayoutTypePtr using ValueLayoutMap = std::map; diff --git a/include/revng-c/DataLayoutAnalysis/DLATypeSystem.h b/include/revng-c/DataLayoutAnalysis/DLATypeSystem.h index 450439fde..8c49fcaea 100644 --- a/include/revng-c/DataLayoutAnalysis/DLATypeSystem.h +++ b/include/revng-c/DataLayoutAnalysis/DLATypeSystem.h @@ -119,7 +119,6 @@ struct LayoutTypeSystemNode { using NeighborsSet = std::set; NeighborsSet Successors{}; NeighborsSet Predecessors{}; - llvm::SmallSet AccessSizes{}; uint64_t Size{}; InterferingChildrenInfo InterferingInfo{ Unknown }; LayoutTypeSystemNode(uint64_t I) : ID(I) {} @@ -139,12 +138,6 @@ public: } }; -inline bool hasValidLayout(const LayoutTypeSystemNode *N) { - if (N == nullptr) - return false; - return not N->AccessSizes.empty(); -} - ///\brief This class handles equivalence classes between indexes of vectors class VectEqClasses : public llvm::IntEqClasses { private: @@ -195,11 +188,6 @@ struct TSDebugPrinter { const LayoutTypeSystemNode *N, llvm::raw_fd_ostream &File) const; - virtual void printAccessDetails(const LayoutTypeSystem &TS, - const LayoutTypeSystemNode *N, - const uint64_t AccessSize, - llvm::raw_fd_ostream &File) const {} - virtual ~TSDebugPrinter() {} }; diff --git a/lib/DataLayoutAnalysis/Backend/DLAMakeLayouts.cpp b/lib/DataLayoutAnalysis/Backend/DLAMakeLayouts.cpp index bc449ec44..5c46dc596 100644 --- a/lib/DataLayoutAnalysis/Backend/DLAMakeLayouts.cpp +++ b/lib/DataLayoutAnalysis/Backend/DLAMakeLayouts.cpp @@ -100,7 +100,6 @@ static Layout *getLayout(const LayoutTypeSystem &TS, revng_assert(*EqClassID < OrderedLayouts.size()); // Get the layout at that position Layout *L = OrderedLayouts[*EqClassID]; - revng_assert(L); return L; } @@ -112,9 +111,12 @@ static Layout *makeLayout(const LayoutTypeSystem &TS, case AllChildrenAreNonInterfering: { - auto NumAccesses = N->AccessSizes.size(); - uint64_t AccessSize = NumAccesses ? *N->AccessSizes.begin() : 0ULL; - revng_assert(NumAccesses == 0 or NumAccesses == 1); + // Create BaseLayout for leaf nodes + revng_assert(not isLeaf(N) or N->Size); + if (isLeaf(N)) { + Layout *AccessLayout = createLayout(Layouts, N->Size); + return AccessLayout; + } StructLayout::fields_container_t SFlds; @@ -184,10 +186,6 @@ static Layout *makeLayout(const LayoutTypeSystem &TS, case TypeLinkTag::LK_Inheritance: { revng_assert(not InheritsFromOther); - // We can't have accesses, if we have inheritance, otherwise we'd have - // that the inherited layout and the accesses do interfere with each - // other, and we should have created a union, not a struct. - revng_assert(not NumAccesses); InheritsFromOther = true; } break; @@ -197,9 +195,6 @@ static Layout *makeLayout(const LayoutTypeSystem &TS, if (OrdChild.Offset >= 0LL and OrdChild.Size > 0ULL) { Children.push_back(std::move(OrdChild)); - revng_assert(EdgeTag->getKind() != TypeLinkTag::LK_Instance - or not AccessSize - or static_cast(AccessSize) <= OrdChild.Offset); } } @@ -213,20 +208,14 @@ static Layout *makeLayout(const LayoutTypeSystem &TS, } } - // Create a BaseLayout as a first element of the struct - revng_assert(not NumAccesses or NumAccesses == 1ULL); - if (AccessSize) { - Layout *AccessLayout = createLayout(Layouts, AccessSize); - SFlds.push_back(AccessLayout); - } - // For each member of the struct + uint64_t CurSize = 0U; for (const auto &OrdChild : Children) { const auto &[StartByte, Size, Child] = OrdChild; revng_assert(StartByte >= 0LL and Size > 0ULL); uint64_t Start = static_cast(StartByte); - revng_assert(Start >= AccessSize); - auto PadSize = Start - AccessSize; // always >= 0; + revng_assert(Start >= CurSize); + auto PadSize = Start - CurSize; // always >= 0; revng_assert(PadSize >= 0); // If an unaccessed layout is known to exist, add it as padding @@ -234,7 +223,7 @@ static Layout *makeLayout(const LayoutTypeSystem &TS, Layout *Padding = createLayout(Layouts, PadSize); SFlds.push_back(Padding); } - AccessSize = Start + Size; + CurSize = Start + Size; Layout *ChildType = getLayout(TS, OrderedLayouts, Child); @@ -260,10 +249,7 @@ static Layout *makeLayout(const LayoutTypeSystem &TS, case AllChildrenAreInterfering: { UnionLayout::elements_container_t UFlds; - for (uint64_t AccessSize : N->AccessSizes) { - revng_log(Log, "Access: " << AccessSize); - UFlds.insert(createLayout(Layouts, AccessSize)); - } + revng_assert(not isLeaf(N)); // Look at all the instance-of edges and inheritance edges all together bool InheritsFromOther = false; @@ -348,7 +334,7 @@ LayoutPtrVector makeLayouts(const LayoutTypeSystem &TS, LayoutVector &Layouts) { for (const LTSN *N : post_order_ext(Root, Visited)) { // Leaves need to have ValidLayouts, otherwise they should have been // trimmed by PruneLayoutNodesWithoutLayout - revng_assert(not isLeaf(N) or hasValidLayout(N)); + revng_assert(not isLeaf(N) or N->Size); Layout *LN = makeLayout(TS, N, Layouts, OrderedLayouts); if (nullptr == LN) { revng_log(Log, "Node ID: " << N->ID << " Type: Empty"); @@ -381,8 +367,11 @@ ValueLayoutMap makeLayoutMap(const LayoutTypePtrVect &Values, for (size_t I = 0; I < Values.size(); I++) { // The layout of the I-th Value is stored at the EqClass(I) index auto LayoutIdx = EqClasses.getEqClassID(I); - if (LayoutIdx) - ValMap.insert(std::make_pair(Values[I], Layouts[*LayoutIdx])); + if (LayoutIdx and not Values[I].isEmpty()) { + auto NewPair = std::make_pair(Values[I], Layouts[*LayoutIdx]); + bool New = ValMap.insert(NewPair).second; + revng_assert(New); + } } return ValMap; diff --git a/lib/DataLayoutAnalysis/DLATypeSystem.cpp b/lib/DataLayoutAnalysis/DLATypeSystem.cpp index 611ed3d14..60504dd52 100644 --- a/lib/DataLayoutAnalysis/DLATypeSystem.cpp +++ b/lib/DataLayoutAnalysis/DLATypeSystem.cpp @@ -100,7 +100,6 @@ void LayoutTypeSystem::dumpDotOnFile(const char *FName) const { DotFile << "digraph LayoutTypeSystem {\n"; DotFile << " // List of nodes\n"; - unsigned AccessSizeID = 0; for (const LayoutTypeSystemNode *L : getLayoutsRange()) { DotFile << " node_" << L->ID << " [shape=rect,label=\"NODE ID: " << L->ID @@ -123,19 +122,6 @@ void LayoutTypeSystem::dumpDotOnFile(const char *FName) const { DebugPrinter->printNodeContent(*this, L, DotFile); DotFile << "\"];\n"; - - for (uint64_t AccessSize : L->AccessSizes) { - DotFile << " access_size_" << AccessSizeID - << " [label=\"Access Size: " << AccessSize; - - DebugPrinter->printAccessDetails(*this, L, AccessSize, DotFile); - - DotFile << "\"];\n"; - DotFile << " node_" << L->ID << " -> access_size_" << AccessSizeID - << ";\n"; - - ++AccessSizeID; - } } DotFile << " // List of edges\n"; @@ -285,9 +271,6 @@ void LayoutTypeSystem::mergeNodes(const LayoutTypeSystemNodePtrVec &ToMerge) { revng_assert(From != Into); revng_log(MergeLog, "Merging: " << From->ID << " Into: " << Into->ID); - Into->AccessSizes.insert(From->AccessSizes.begin(), - From->AccessSizes.end()); - EqClasses.join(IntoID, From->ID); fixPredSucc(From, Into); @@ -631,7 +614,7 @@ bool LayoutTypeSystem::verifyNoEquality() const { bool LayoutTypeSystem::verifyLeafs() const { for (const auto &Node : llvm::nodes(this)) { if (isLeaf(Node)) { - if (not hasValidLayout(Node)) { + if (Node->Size > 0) { if (VerifyDLALog.isEnabled()) revng_check(false); return false; @@ -691,8 +674,7 @@ std::optional VectEqClasses::getEqClassID(const unsigned ID) const { if (IsRemoved) return {}; - else - return EqID; + return EqID; } std::set VectEqClasses::getEqClass(const unsigned ElemID) const { diff --git a/lib/DataLayoutAnalysis/Frontend/DLACreateIntraProceduralTypes.cpp b/lib/DataLayoutAnalysis/Frontend/DLACreateIntraProceduralTypes.cpp index 33a12a5a5..73b300936 100644 --- a/lib/DataLayoutAnalysis/Frontend/DLACreateIntraProceduralTypes.cpp +++ b/lib/DataLayoutAnalysis/Frontend/DLACreateIntraProceduralTypes.cpp @@ -585,11 +585,11 @@ bool Builder::createIntraproceduralTypes(llvm::Module &M, OutFile = new raw_fd_ostream("DLA_pointer_accesses.csv", EC); revng_check(not EC, "Cannot open DLA_pointer_accesses.csv"); - (*OutFile) << "Value" - << ";" - << "Access Size" - << ";" - << "Accessed By" + (*OutFile) << "Value Node ID;" + << "Value;" + << "Access Node ID;" + << "Access Node Size;" + << "Accessed By;" << "\n"; } @@ -656,14 +656,28 @@ bool Builder::createIntraproceduralTypes(llvm::Module &M, continue; } + // Create Base node Changed |= ILA.createBaseAddrWithInstanceLink(*this, PointerVal, *B); - auto *AddrLayout = getLayoutType(PointerVal); + + // Create AccessSize node auto AccessSize = getLoadStoreSizeFromPtrOpUse(M, PtrUse); - AddrLayout->AccessSizes.insert(AccessSize); + auto *AccessSizeNode = TS.createArtificialLayoutType(); + AccessSizeNode->Size = AccessSize; + AccessSizeNode->InterferingInfo = AllChildrenAreNonInterfering; + + // Add link between base node and AccessSize node + revng_assert(PointerVal); + auto *AddrNode = getLayoutType(PointerVal); + revng_assert(AddrNode); + OffsetExpression OE{}; + OE.Offset = 0U; + TS.addInstanceLink(AddrNode, AccessSizeNode, std::move(OE)); if (AccessLog.isEnabled()) { revng_assert(OutFile); - (*OutFile) << *PointerVal << ";" << AccessSize << ";" << I << "\n"; + (*OutFile) << AddrNode->ID << ";" << *PointerVal << ";" + << AccessSizeNode->ID << ";" << AccessSizeNode->Size + << ";" << I << "\n"; } continue; diff --git a/lib/DataLayoutAnalysis/Frontend/DLATypeSystemBuilder.cpp b/lib/DataLayoutAnalysis/Frontend/DLATypeSystemBuilder.cpp index 96d21099a..34a5a4afa 100644 --- a/lib/DataLayoutAnalysis/Frontend/DLATypeSystemBuilder.cpp +++ b/lib/DataLayoutAnalysis/Frontend/DLATypeSystemBuilder.cpp @@ -3,9 +3,11 @@ // #include "llvm/IR/Argument.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Value.h" +#include "revng/Support/Assert.h" #include "revng/Support/IRHelpers.h" #include "../DLAHelpers.h" @@ -25,58 +27,28 @@ void LLVMTSDebugPrinter::printNodeContent(const LayoutTypeSystem &TS, revng_assert(not EqClasses.isRemoved(N->ID)); File << DoRet; - for (auto ID : EqClasses.getEqClass(N->ID)) { - if (ID < Values.size()) { - this->Values[ID].print(File); - File << DoRet; - } - } -} -void LLVMTSDebugPrinter::printAccessDetails(const LayoutTypeSystem &TS, - const LayoutTypeSystemNode *N, - const uint64_t AccessSize, - raw_fd_ostream &File) const { - auto EqClasses = TS.getEqClasses(); - revng_assert(not EqClasses.isRemoved(N->ID)); + auto HasAssociatedVal = [this](unsigned ID) { return (ID < Values.size()); }; - File << DoRet; - bool Found = false; + const auto &CollapsedNodes = EqClasses.getEqClass(N->ID); + File << "Collapsed Nodes:" << DoRet; - for (auto ID : EqClasses.getEqClass(N->ID)) { - // Ignore nodes that don't have an associated Value - if (ID >= Values.size()) - continue; + for (auto ID : CollapsedNodes) { + File << "{ ID: " << ID << ", "; + if (HasAssociatedVal(ID)) { + const LayoutTypePtr &Val = Values[ID]; + File << "Associated Value: "; - const llvm::Value &PtrV = this->Values[ID].getValue(); - - // Collect uses for which PtrV is a pointer operand - for (const Use &U : PtrV.uses()) { - const llvm::Value *PtrOp = nullptr; - const User *Usr = U.getUser(); - - if (auto *Load = dyn_cast(Usr)) - PtrOp = Load->getPointerOperand(); - else if (auto *Store = dyn_cast(Usr)) - PtrOp = Store->getPointerOperand(); + if (Val.isEmpty()) + File << "Empty (Access Node)"; else - continue; + Val.print(File); - if (&PtrV != PtrOp) - continue; - - unsigned InstrAccessSize = ::getLoadStoreSizeFromPtrOpUse(this->M, &U); - - if (AccessSize == InstrAccessSize) { - auto *I = cast(U.getUser()); - File << "\\\\n" - << "In : " << I->getFunction()->getName() << " : "; - File.write_escaped(dumpToString(I)); - Found = true; - } + } else { + File << " Artificial"; } + File << " }" << DoRet; } - revng_assert(Found or N->ID >= Values.size()); } void DLATypeSystemLLVMBuilder::assertGetLayoutTypePreConditions(const Value *V, @@ -368,13 +340,16 @@ DLATypeSystemLLVMBuilder::getOrCreateLayoutTypes(const Value &V) { } void DLATypeSystemLLVMBuilder::createValuesList() { - this->Values.resize(VisitedMap.size()); + // TODO: the fact that AccessNodes are now added by the frontend means that + // after initialization not all nodes in the graph correspond to a Value. + // Can we prevent this? + this->Values.resize(TS.getNID()); for (auto &MapIt : VisitedMap) { LayoutTypePtr Ptr = MapIt.first; unsigned NodeID = MapIt.second->ID; - revng_assert(NodeID < this->Values.size()); + revng_assert(NodeID < Values.size()); this->Values[NodeID] = Ptr; } } @@ -390,21 +365,31 @@ void DLATypeSystemLLVMBuilder::dumpValuesMapping(const llvm::StringRef Name) { OutFile << "ID; Value; EqClass\n"; for (auto *N : TS.getLayoutsRange()) { + // Print Node's ID OutFile << N->ID << ";"; + + // Check if it has an associated LayoutTypePtr if (N->ID < Values.size()) { auto &V = Values[N->ID]; - if (isa(V.getValue())) + + if (V.isEmpty()) + OutFile << "Empty (Access Node)"; + else if (isa(V.getValue())) V.getValue().printAsOperand(OutFile); else V.print(OutFile); } else { - OutFile << "Out of bounds"; + OutFile << "Out of bounds (No associated LayoutTypePtr)"; } + OutFile << ";"; + // Print ID of the node's equivalence class if (TS.getEqClasses().getNumClasses() == 0) { + // Uncompressed OutFile << TS.getEqClasses().findLeader(N->ID); } else { + // Compressed auto Class = TS.getEqClasses().getEqClassID(N->ID); if (Class) @@ -412,6 +397,7 @@ void DLATypeSystemLLVMBuilder::dumpValuesMapping(const llvm::StringRef Name) { else OutFile << "Removed"; } + OutFile << "\n"; } } @@ -425,4 +411,5 @@ void DLATypeSystemLLVMBuilder::buildFromLLVMModule(llvm::Module &M, createIntraproceduralTypes(M, MP); createValuesList(); + VisitedMap.clear(); } diff --git a/lib/DataLayoutAnalysis/Frontend/DLATypeSystemBuilder.h b/lib/DataLayoutAnalysis/Frontend/DLATypeSystemBuilder.h index b82e9ae05..828085e27 100644 --- a/lib/DataLayoutAnalysis/Frontend/DLATypeSystemBuilder.h +++ b/lib/DataLayoutAnalysis/Frontend/DLATypeSystemBuilder.h @@ -38,15 +38,6 @@ public: void printNodeContent(const LayoutTypeSystem &TS, const LayoutTypeSystemNode *N, llvm::raw_fd_ostream &DotFile) const override; - - ///\brief Print the instruction that originated a given \a AccessSize of \a N - /// - /// Information on the `load`/`store`s related to a given set of `Value`s is - /// reconstructed on-the-fly, therefore this function is expensive. - void printAccessDetails(const LayoutTypeSystem &TS, - const LayoutTypeSystemNode *N, - const uint64_t AccessSize, - llvm::raw_fd_ostream &DotFile) const override; }; ///\brief This class builds a DLA type system from an LLVM module diff --git a/lib/DataLayoutAnalysis/Middleend/DLAComputeNonInterferingComponents.cpp b/lib/DataLayoutAnalysis/Middleend/DLAComputeNonInterferingComponents.cpp index 7653b8d97..e3c1f744d 100644 --- a/lib/DataLayoutAnalysis/Middleend/DLAComputeNonInterferingComponents.cpp +++ b/lib/DataLayoutAnalysis/Middleend/DLAComputeNonInterferingComponents.cpp @@ -38,7 +38,7 @@ bool ComputeNonInterferingComponents::runOnTypeSystem(LayoutTypeSystem &TS) { continue; for (LTSN *N : llvm::post_order_ext(Root, Visited)) { - revng_assert(not isLeaf(N) or hasValidLayout(N)); + revng_assert(not isLeaf(N) or N->Size); revng_assert(N->Size); struct OrderedChild { @@ -116,15 +116,14 @@ bool ComputeNonInterferingComponents::runOnTypeSystem(LayoutTypeSystem &TS) { // constitute a single non-interfering component and we can leave them // alone. if (Children.empty()) { - N->InterferingInfo = AllChildrenAreInterfering; + N->InterferingInfo = AllChildrenAreNonInterfering; continue; } // If there is only one children and no accesses, we are sure that there's // nothing to do, because the only children cannot interfere with anything // else, and it is already a component on its own. - auto NumAccesses = N->AccessSizes.size(); - if (Children.size() == 1ULL and not NumAccesses) { + if (Children.size() == 1ULL) { N->InterferingInfo = AllChildrenAreNonInterfering; continue; } @@ -170,40 +169,8 @@ bool ComputeNonInterferingComponents::runOnTypeSystem(LayoutTypeSystem &TS) { }; OrderedChildIt ChildIt = Children.begin(); - { - auto FirstChildComp = MakeNewComponentFromChild(ChildIt); - - if (NumAccesses) { - int64_t AccessStartByte = 0LL; - auto MaxIt = std::max_element(N->AccessSizes.begin(), - N->AccessSizes.end()); - uint64_t AccEndByte = MaxIt != N->AccessSizes.end() ? *MaxIt : 0ULL; - - revng_assert(FirstChildComp.StartByte >= 0); - if (static_cast(FirstChildComp.StartByte) < AccEndByte) { - // Accesses interfere with the first component. - // Update the current component to reflect it. - FirstChildComp.StartByte = AccessStartByte; - FirstChildComp.EndByte = std::max(FirstChildComp.EndByte, - AccEndByte); - FirstChildComp.NumChildren += NumAccesses; - FirstChildComp.HasAccesses = true; - } else { - // Accesses are present, but they don't interfere with the node - // children, so we can create a separate non-interfering - // components just for them. - Components.push_back(Component{ - /* .StartChildIt */ ChildIt, - /* .EndChildIt */ ChildIt, - /* .StartByte */ AccessStartByte, - /* .EndByte */ AccEndByte, - /* .NumChildren */ NumAccesses, - /* .HasAccesses */ true, - }); - } - } - Components.push_back(std::move(FirstChildComp)); - } + auto FirstChildComp = MakeNewComponentFromChild(ChildIt); + Components.push_back(std::move(FirstChildComp)); OrderedChildIt ChildEnd = Children.end(); while (++ChildIt != ChildEnd) { @@ -223,7 +190,7 @@ bool ComputeNonInterferingComponents::runOnTypeSystem(LayoutTypeSystem &TS) { if (ChildBeginByte >= CurrComp.EndByte) { // The next candidate child falls entirely past the end of the // component that we've been accumulating until now. - // Create a new compoenent and push it into Components. + // Create a new component and push it into Components. Components.push_back(MakeNewComponentFromChild(ChildIt)); } else { // The next candidate child interferes with the current component, @@ -253,7 +220,6 @@ bool ComputeNonInterferingComponents::runOnTypeSystem(LayoutTypeSystem &TS) { // For each Component with more than one element we have to create a new // node in the type system, and push the edges from N to the elements of // the component down to the newly created node. - bool FoundAccesses = false; for (auto &C : llvm::make_filter_range(Components, HasManyElements)) { Changed = true; @@ -276,15 +242,6 @@ bool ComputeNonInterferingComponents::runOnTypeSystem(LayoutTypeSystem &TS) { for (auto &OrderedChild : OrderedChildRange) TS.moveEdges(N, New, OrderedChild.Child, -C.StartByte); - // If the component C includes the accesses we need to move the - // accessess down to New. - if (C.HasAccesses) { - revng_assert(not FoundAccesses); - FoundAccesses = true; - revng_assert(not C.StartByte); - New->AccessSizes = std::move(N->AccessSizes); - } - // Add a link between N and the New node representing the component. // The component is at offset C.StartByte inside N. // If this offset is zero we add an inheritance edge, otherwise an diff --git a/lib/DataLayoutAnalysis/Middleend/DLAComputeUpperMemberAccess.cpp b/lib/DataLayoutAnalysis/Middleend/DLAComputeUpperMemberAccess.cpp index a15d91b00..8aec3661e 100644 --- a/lib/DataLayoutAnalysis/Middleend/DLAComputeUpperMemberAccess.cpp +++ b/lib/DataLayoutAnalysis/Middleend/DLAComputeUpperMemberAccess.cpp @@ -8,8 +8,10 @@ #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Debug.h" #include "revng/ADT/FilteredGraphTraits.h" +#include "revng/Support/Assert.h" #include "revng/Support/Debug.h" #include "revng-c/DataLayoutAnalysis/DLATypeSystem.h" @@ -35,25 +37,19 @@ bool ComputeUpperMemberAccesses::runOnTypeSystem(LayoutTypeSystem &TS) { revng_assert(Root != nullptr); // Leaves need to have ValidLayouts, otherwise they should have been trimmed // by PruneLayoutNodesWithoutLayout - revng_assert(not isLeaf(Root) or hasValidLayout(Root)); + revng_assert(not isLeaf(Root) or Root->Size); if (not isRoot(Root)) continue; revng_assert(isInheritanceRoot(Root)); for (LTSN *N : post_order_ext(Root, Visited)) { - revng_assert(not isLeaf(N) or hasValidLayout(N)); - revng_assert(not N->Size); - auto FinalSize = N->Size; - auto MaxIt = std::max_element(N->AccessSizes.begin(), - N->AccessSizes.end()); - FinalSize = std::max(FinalSize, - MaxIt != N->AccessSizes.end() ? *MaxIt : 0UL); + revng_assert(not isLeaf(N) or N->Size); + uint64_t FinalSize = N->Size; // Look at all the instance-of edges and inheritance edges all together. bool HasBaseClass = false; for (auto &[Child, EdgeTag] : children_edges(N)) { - auto ChildSize = Child->Size; revng_assert(ChildSize > 0LL); @@ -111,6 +107,7 @@ bool ComputeUpperMemberAccesses::runOnTypeSystem(LayoutTypeSystem &TS) { } } N->Size = FinalSize; + revng_assert(FinalSize); Changed = true; } } diff --git a/lib/DataLayoutAnalysis/Middleend/DLAPruneLayoutNodesWithoutLayout.cpp b/lib/DataLayoutAnalysis/Middleend/DLAPruneLayoutNodesWithoutLayout.cpp index faa3e1766..9da97f191 100644 --- a/lib/DataLayoutAnalysis/Middleend/DLAPruneLayoutNodesWithoutLayout.cpp +++ b/lib/DataLayoutAnalysis/Middleend/DLAPruneLayoutNodesWithoutLayout.cpp @@ -41,8 +41,8 @@ bool PruneLayoutNodesWithoutLayout::runOnTypeSystem(LayoutTypeSystem &TS) { revng_log(Log, "## Visiting N: " << N->ID); revng_log(Log, "## Is Leaf: " << isLeaf(N)); - if (hasValidLayout(N)) { - revng_log(Log, "### hasValidLayout(N)!"); + if (N->Size > 0) { + revng_log(Log, "### has size " << N->Size << " !"); continue; }