diff options
-rw-r--r-- | llvm/lib/Analysis/LazyCallGraph.cpp | 70 |
1 files changed, 38 insertions, 32 deletions
diff --git a/llvm/lib/Analysis/LazyCallGraph.cpp b/llvm/lib/Analysis/LazyCallGraph.cpp index 2e78fca3989..8ad34dc080b 100644 --- a/llvm/lib/Analysis/LazyCallGraph.cpp +++ b/llvm/lib/Analysis/LazyCallGraph.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/STLExtras.h" #include "llvm/IR/CallSite.h" #include "llvm/IR/InstVisitor.h" @@ -389,9 +390,15 @@ updatePostorderSequenceForEdgeInsertion( SmallVector<LazyCallGraph::SCC *, 1> LazyCallGraph::RefSCC::switchInternalEdgeToCall(Node &SourceN, Node &TargetN) { assert(!SourceN[TargetN].isCall() && "Must start with a ref edge!"); - SmallVector<SCC *, 1> DeletedSCCs; +#ifndef NDEBUG + // In a debug build, verify the RefSCC is valid to start with and when this + // routine finishes. + verify(); + auto VerifyOnExit = make_scope_exit([&]() { verify(); }); +#endif + SCC &SourceSCC = *G->lookupSCC(SourceN); SCC &TargetSCC = *G->lookupSCC(TargetN); @@ -399,10 +406,6 @@ LazyCallGraph::RefSCC::switchInternalEdgeToCall(Node &SourceN, Node &TargetN) { // we've just added more connectivity. if (&SourceSCC == &TargetSCC) { SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); -#ifndef NDEBUG - // Check that the RefSCC is still valid. - verify(); -#endif return DeletedSCCs; } @@ -416,10 +419,6 @@ LazyCallGraph::RefSCC::switchInternalEdgeToCall(Node &SourceN, Node &TargetN) { int TargetIdx = SCCIndices[&TargetSCC]; if (TargetIdx < SourceIdx) { SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); -#ifndef NDEBUG - // Check that the RefSCC is still valid. - verify(); -#endif return DeletedSCCs; } @@ -495,9 +494,6 @@ LazyCallGraph::RefSCC::switchInternalEdgeToCall(Node &SourceN, Node &TargetN) { if (MergeRange.begin() == MergeRange.end()) { // Now that the SCC structure is finalized, flip the kind to call. SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); -#ifndef NDEBUG - verify(); -#endif return DeletedSCCs; } @@ -534,10 +530,7 @@ LazyCallGraph::RefSCC::switchInternalEdgeToCall(Node &SourceN, Node &TargetN) { // Now that the SCC structure is finalized, flip the kind to call. SourceN.setEdgeKind(TargetN.getFunction(), Edge::Call); -#ifndef NDEBUG - // And we're done! Verify in debug builds that the RefSCC is coherent. - verify(); -#endif + // And we're done! return DeletedSCCs; } @@ -545,6 +538,13 @@ iterator_range<LazyCallGraph::RefSCC::iterator> LazyCallGraph::RefSCC::switchInternalEdgeToRef(Node &SourceN, Node &TargetN) { assert(SourceN[TargetN].isCall() && "Must start with a call edge!"); +#ifndef NDEBUG + // In a debug build, verify the RefSCC is valid to start with and when this + // routine finishes. + verify(); + auto VerifyOnExit = make_scope_exit([&]() { verify(); }); +#endif + SCC &SourceSCC = *G->lookupSCC(SourceN); SCC &TargetSCC = *G->lookupSCC(TargetN); @@ -558,13 +558,8 @@ LazyCallGraph::RefSCC::switchInternalEdgeToRef(Node &SourceN, Node &TargetN) { // If this call edge is just connecting two separate SCCs within this RefSCC, // there is nothing to do. - if (&SourceSCC != &TargetSCC) { -#ifndef NDEBUG - // Check that the RefSCC is still valid. - verify(); -#endif + if (&SourceSCC != &TargetSCC) return make_range(SCCs.end(), SCCs.end()); - } // Otherwise we are removing a call edge from a single SCC. This may break // the cycle. In order to compute the new set of SCCs, we need to do a small @@ -725,11 +720,6 @@ LazyCallGraph::RefSCC::switchInternalEdgeToRef(Node &SourceN, Node &TargetN) { for (int Idx = OldIdx, Size = SCCs.size(); Idx < Size; ++Idx) SCCIndices[SCCs[Idx]] = Idx; -#ifndef NDEBUG - // We're done. Check the validity on our way out. - verify(); -#endif - return make_range(SCCs.begin() + OldIdx, SCCs.begin() + OldIdx + NewSCCs.size()); } @@ -813,6 +803,13 @@ SmallVector<LazyCallGraph::RefSCC *, 1> LazyCallGraph::RefSCC::insertIncomingRefEdge(Node &SourceN, Node &TargetN) { assert(G->lookupRefSCC(TargetN) == this && "Target must be in this SCC."); +#ifndef NDEBUG + // In a debug build, verify the RefSCC is valid to start with and when this + // routine finishes. + verify(); + auto VerifyOnExit = make_scope_exit([&]() { verify(); }); +#endif + // We store the RefSCCs found to be connected in postorder so that we can use // that when merging. We also return this to the caller to allow them to // invalidate information pertaining to these RefSCCs. @@ -953,11 +950,6 @@ LazyCallGraph::RefSCC::insertIncomingRefEdge(Node &SourceN, Node &TargetN) { // connect the nodes to form the new edge. SourceN.insertEdgeInternal(TargetN, Edge::Ref); -#ifndef NDEBUG - // Check that the RefSCC is still valid. - verify(); -#endif - // We return the list of SCCs which were merged so that callers can // invalidate any data they have associated with those SCCs. Note that these // SCCs are no longer in an interesting state (they are totally empty) but @@ -975,6 +967,13 @@ void LazyCallGraph::RefSCC::removeOutgoingEdge(Node &SourceN, Node &TargetN) { assert(!is_contained(G->LeafRefSCCs, this) && "Cannot have a leaf RefSCC source."); +#ifndef NDEBUG + // In a debug build, verify the RefSCC is valid to start with and when this + // routine finishes. + verify(); + auto VerifyOnExit = make_scope_exit([&]() { verify(); }); +#endif + // First remove it from the node. SourceN.removeEdgeInternal(TargetN.getFunction()); @@ -1026,6 +1025,13 @@ LazyCallGraph::RefSCC::removeInternalRefEdge(Node &SourceN, Node &TargetN) { assert(!SourceN[TargetN].isCall() && "Cannot remove a call edge, it must first be made a ref edge"); +#ifndef NDEBUG + // In a debug build, verify the RefSCC is valid to start with and when this + // routine finishes. + verify(); + auto VerifyOnExit = make_scope_exit([&]() { verify(); }); +#endif + // First remove the actual edge. SourceN.removeEdgeInternal(TargetN.getFunction()); |