1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[LCG] Clean up and make NDEBUG verify calls more rigorous with

make_scope_exit now that we have that utility.

This makes the code much more clear and readable by isolating the check.
It also makes it easy to go through and make sure all the interesting
update routines have a start and end verify so we don't slowly let the
graph drift into an invalid state.

llvm-svn: 280619
This commit is contained in:
Chandler Carruth 2016-09-04 08:34:31 +00:00
parent 2f848e0e0f
commit 6a72044ca6

View File

@ -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());