diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h --- a/llvm/include/llvm/Pass.h +++ b/llvm/include/llvm/Pass.h @@ -228,6 +228,16 @@ template AnalysisType &getAnalysisID(AnalysisID PI, Function &F, bool *Changed = nullptr); + +#ifdef EXPENSIVE_CHECKS + /// Hash a module in order to detect when a module (or more specific) pass has + /// modified it. + uint64_t structuralHash(Module &M) const; + + /// Hash a function in order to detect when a function (or more specific) pass + /// has modified it. + virtual uint64_t structuralHash(Function &F) const; +#endif }; //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp --- a/llvm/lib/Analysis/CallGraphSCCPass.cpp +++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp @@ -28,7 +28,6 @@ #include "llvm/IR/OptBisect.h" #include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/PrintPasses.h" -#include "llvm/IR/StructuralHash.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -470,7 +469,7 @@ initializeAnalysisImpl(P); #ifdef EXPENSIVE_CHECKS - uint64_t RefHash = StructuralHash(CG.getModule()); + uint64_t RefHash = P->structuralHash(CG.getModule()); #endif // Actually run this pass on the current SCC. @@ -480,7 +479,7 @@ Changed |= LocalChanged; #ifdef EXPENSIVE_CHECKS - if (!LocalChanged && (RefHash != StructuralHash(CG.getModule()))) { + if (!LocalChanged && (RefHash != P->structuralHash(CG.getModule()))) { llvm::errs() << "Pass modifies its input and doesn't report it: " << P->getPassName() << "\n"; llvm_unreachable("Pass modifies its input and doesn't report it"); diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -20,7 +20,6 @@ #include "llvm/IR/PassManager.h" #include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/PrintPasses.h" -#include "llvm/IR/StructuralHash.h" #include "llvm/InitializePasses.h" #include "llvm/Support/Debug.h" #include "llvm/Support/TimeProfiler.h" @@ -192,12 +191,12 @@ PassManagerPrettyStackEntry X(P, *CurrentLoop->getHeader()); TimeRegion PassTimer(getPassTimer(P)); #ifdef EXPENSIVE_CHECKS - uint64_t RefHash = StructuralHash(F); + uint64_t RefHash = P->structuralHash(F); #endif LocalChanged = P->runOnLoop(CurrentLoop, *this); #ifdef EXPENSIVE_CHECKS - if (!LocalChanged && (RefHash != StructuralHash(F))) { + if (!LocalChanged && (RefHash != P->structuralHash(F))) { llvm::errs() << "Pass modifies its input and doesn't report it: " << P->getPassName() << "\n"; llvm_unreachable("Pass modifies its input and doesn't report it"); diff --git a/llvm/lib/Analysis/RegionPass.cpp b/llvm/lib/Analysis/RegionPass.cpp --- a/llvm/lib/Analysis/RegionPass.cpp +++ b/llvm/lib/Analysis/RegionPass.cpp @@ -18,7 +18,6 @@ #include "llvm/IR/OptBisect.h" #include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/PrintPasses.h" -#include "llvm/IR/StructuralHash.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" @@ -95,12 +94,12 @@ TimeRegion PassTimer(getPassTimer(P)); #ifdef EXPENSIVE_CHECKS - uint64_t RefHash = StructuralHash(F); + uint64_t RefHash = P->structuralHash(F); #endif LocalChanged = P->runOnRegion(CurrentRegion, *this); #ifdef EXPENSIVE_CHECKS - if (!LocalChanged && (RefHash != StructuralHash(F))) { + if (!LocalChanged && (RefHash != P->structuralHash(F))) { llvm::errs() << "Pass modifies its input and doesn't report it: " << P->getPassName() << "\n"; llvm_unreachable("Pass modifies its input and doesn't report it"); diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/llvm/lib/IR/LegacyPassManager.cpp @@ -29,10 +29,6 @@ #include "llvm/Support/raw_ostream.h" #include -#ifdef EXPENSIVE_CHECKS -#include "llvm/IR/StructuralHash.h" -#endif - using namespace llvm; // See PassManagers.h for Pass Manager infrastructure overview. @@ -1429,12 +1425,12 @@ PassManagerPrettyStackEntry X(FP, F); TimeRegion PassTimer(getPassTimer(FP)); #ifdef EXPENSIVE_CHECKS - uint64_t RefHash = StructuralHash(F); + uint64_t RefHash = FP->structuralHash(F); #endif LocalChanged |= FP->runOnFunction(F); #if defined(EXPENSIVE_CHECKS) && !defined(NDEBUG) - if (!LocalChanged && (RefHash != StructuralHash(F))) { + if (!LocalChanged && (RefHash != FP->structuralHash(F))) { llvm::errs() << "Pass modifies its input and doesn't report it: " << FP->getPassName() << "\n"; llvm_unreachable("Pass modifies its input and doesn't report it"); @@ -1543,13 +1539,13 @@ TimeRegion PassTimer(getPassTimer(MP)); #ifdef EXPENSIVE_CHECKS - uint64_t RefHash = StructuralHash(M); + uint64_t RefHash = MP->structuralHash(M); #endif LocalChanged |= MP->runOnModule(M); #ifdef EXPENSIVE_CHECKS - assert((LocalChanged || (RefHash == StructuralHash(M))) && + assert((LocalChanged || (RefHash == MP->structuralHash(M))) && "Pass modifies its input and doesn't report it."); #endif diff --git a/llvm/lib/IR/Pass.cpp b/llvm/lib/IR/Pass.cpp --- a/llvm/lib/IR/Pass.cpp +++ b/llvm/lib/IR/Pass.cpp @@ -27,6 +27,10 @@ #include "llvm/Support/raw_ostream.h" #include +#ifdef EXPENSIVE_CHECKS +#include "llvm/IR/StructuralHash.h" +#endif + using namespace llvm; #define DEBUG_TYPE "ir" @@ -133,6 +137,12 @@ } #endif +#ifdef EXPENSIVE_CHECKS +uint64_t Pass::structuralHash(Module &M) const { return StructuralHash(M); } + +uint64_t Pass::structuralHash(Function &F) const { return StructuralHash(F); } +#endif + //===----------------------------------------------------------------------===// // ImmutablePass Implementation //