From e8d372e48d6aff0b79d1d5d707964d1a0b9e12aa Mon Sep 17 00:00:00 2001 From: Andreas Neustifter Date: Fri, 4 Sep 2009 17:15:10 +0000 Subject: Cleaned up ProfileVerifierPass. (See http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20090831/086219.html) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81007 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ProfileVerifierPass.cpp | 135 ++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 57 deletions(-) (limited to 'lib/Analysis') diff --git a/lib/Analysis/ProfileVerifierPass.cpp b/lib/Analysis/ProfileVerifierPass.cpp index d92ca65bae..e0ef6cee4f 100644 --- a/lib/Analysis/ProfileVerifierPass.cpp +++ b/lib/Analysis/ProfileVerifierPass.cpp @@ -21,27 +21,39 @@ #include using namespace llvm; -static bool DisableAssertions = false; static cl::opt ProfileVerifierDisableAssertions("profile-verifier-noassert", - cl::location(DisableAssertions), cl::desc("Disable assertions")); -bool PrintedDebugTree = false; + cl::desc("Disable assertions")); namespace { class VISIBILITY_HIDDEN ProfileVerifierPass : public FunctionPass { + + struct DetailedBlockInfo { + const BasicBlock *BB; + double BBWeight; + double inWeight; + int inCount; + double outWeight; + int outCount; + }; + ProfileInfo *PI; std::set BBisVisited; -#ifndef NDEBUG + bool DisableAssertions; + + // When debugging is enabled, the verifier prints a whole slew of debug + // information, otherwise its just the assert. These are all the helper + // functions. + bool PrintedDebugTree; std::set BBisPrinted; - void debugEntry(const BasicBlock* BB, double w, double inw, int inc, - double outw, int outc, double d); + void debugEntry(DetailedBlockInfo*); void printDebugInfo(const BasicBlock *BB); -#endif + public: static char ID; // Class identification, replacement for typeinfo - explicit ProfileVerifierPass () : FunctionPass(&ID) { - DisableAssertions = ProfileVerifierDisableAssertions; + explicit ProfileVerifierPass (bool da = false) : FunctionPass(&ID), + DisableAssertions(da) { } void getAnalysisUsage(AnalysisUsage &AU) const { @@ -56,6 +68,9 @@ namespace { /// run - Verify the profile information. bool runOnFunction(Function &F); void recurseBasicBlock(const BasicBlock *BB); + + double ReadOrAssert(ProfileInfo::Edge); + void CheckValue(bool, const char*, DetailedBlockInfo*); }; } // End of anonymous namespace @@ -65,11 +80,10 @@ X("profile-verifier", "Verify profiling information", false, true); namespace llvm { FunctionPass *createProfileVerifierPass() { - return new ProfileVerifierPass(); + return new ProfileVerifierPass(ProfileVerifierDisableAssertions); } } -#ifndef NDEBUG void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) { if (BBisPrinted.find(BB) != BBisPrinted.end()) return; @@ -84,8 +98,8 @@ void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) { if (ProcessedPreds.insert(*bbi).second) { double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB)); if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; } - DEBUG(errs()<<"calculated in-edge ("<<(*bbi)->getNameStr()<<","<getNameStr() - <<"): "<getNameStr()<<","<getNameStr() + <<"): "<getEdgeWeight(PI->getEdge(BB,*bbi)); if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; } - DEBUG(errs()<<"calculated out-edge ("<getNameStr()<<","<<(*bbi)->getNameStr() - <<"): "<getNameStr()<<","<<(*bbi)->getNameStr() + <<"): "<getNameStr()<<" in "<getParent()->getNameStr() - <<",BBWeight="<getNameStr()<<" in "<getParent()->getNameStr() + <<",BBWeight="<getNameStr()<<" in "<getParent()->getNameStr() - <<",BBWeight="<BB->getNameStr() << " in " + << DI->BB->getParent()->getNameStr() << ":"; + errs() << "BBWeight=" << DI->BBWeight << ","; + errs() << "inWeight=" << DI->inWeight << ","; + errs() << "inCount=" << DI->inCount << ","; + errs() << "outWeight=" << DI->outWeight << ","; + errs() << "outCount=" << DI->outCount << ","; if (!PrintedDebugTree) { PrintedDebugTree = true; - printDebugInfo(&(BB->getParent()->getEntryBlock())); + printDebugInfo(&(DI->BB->getParent()->getEntryBlock())); } } -#endif // compare with relative error -static bool dcmp(double A, double B) { +static bool Equals(double A, double B) { double maxRelativeError = 0.0000001; if (A == B) return true; @@ -144,59 +158,66 @@ static bool dcmp(double A, double B) { return false; } -#define CHECK(C,M) \ -if (C) { \ - if (DisableAssertions) { errs()<<(M)<<"\n"; } else { assert((!(C)) && (M)); } \ +double ProfileVerifierPass::ReadOrAssert(ProfileInfo::Edge E) { + const char *Message = "ASSERT:Edge has missing value"; + double EdgeWeight = PI->getEdgeWeight(E); + if (EdgeWeight == ProfileInfo::MissingValue) { + if (DisableAssertions) { + errs() << Message << "\n"; + return 0; + } else { + assert(0 && Message); + } + } else { + return EdgeWeight; + } } -#define CHECKDEBUG(C,M,D) \ -if (C) { \ - DEBUG(debugEntry(BB, BBWeight, inWeight, inCount, \ - outWeight, outCount, (D))); \ - if (DisableAssertions) { errs()<<(M)<<"\n"; } else { assert((!(C)) && (M)); } \ +void ProfileVerifierPass::CheckValue(bool Error, const char *Message, DetailedBlockInfo *DI) { + if (Error) { + DEBUG(debugEntry(DI)); + if (DisableAssertions) { + errs() << Message << "\n"; + } else { + assert(0 && Message); + } + } + return; } void ProfileVerifierPass::recurseBasicBlock(const BasicBlock *BB) { if (BBisVisited.find(BB) != BBisVisited.end()) return; - double inWeight = 0; - int inCount = 0; + DetailedBlockInfo DI; + DI.BB = BB; + DI.outCount = DI.inCount = DI.inWeight = DI.outWeight = 0; std::set ProcessedPreds; for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB); bbi != bbe; ++bbi ) { if (ProcessedPreds.insert(*bbi).second) { - double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB)); - CHECK(EdgeWeight == ProfileInfo::MissingValue, - "ASSERT:Edge has missing value"); - inWeight += EdgeWeight; inCount++; + DI.inWeight += ReadOrAssert(PI->getEdge(*bbi,BB)); + DI.inCount++; } } - double outWeight = 0; - int outCount = 0; std::set ProcessedSuccs; for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB); bbi != bbe; ++bbi ) { if (ProcessedSuccs.insert(*bbi).second) { - double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi)); - CHECK(EdgeWeight == ProfileInfo::MissingValue, - "ASSERT:Edge has missing value"); - outWeight += EdgeWeight; outCount++; + DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi)); + DI.outCount++; } } - double BBWeight = PI->getExecutionCount(BB); - CHECKDEBUG(BBWeight == ProfileInfo::MissingValue, - "ASSERT:BasicBlock has missing value",-1); + DI.BBWeight = PI->getExecutionCount(BB); + CheckValue(DI.BBWeight == ProfileInfo::MissingValue, "ASSERT:BasicBlock has missing value", &DI); - if (inCount > 0) { - CHECKDEBUG(!dcmp(inWeight,BBWeight), - "ASSERT:inWeight and BBWeight do not match",inWeight-BBWeight); + if (DI.inCount > 0) { + CheckValue(!Equals(DI.inWeight,DI.BBWeight), "ASSERT:inWeight and BBWeight do not match", &DI); } - if (outCount > 0) { - CHECKDEBUG(!dcmp(outWeight,BBWeight), - "ASSERT:outWeight and BBWeight do not match",outWeight-BBWeight); + if (DI.outCount > 0) { + CheckValue(!Equals(DI.outWeight,DI.BBWeight), "ASSERT:outWeight and BBWeight do not match", &DI); } // mark as visited and recurse into subnodes -- cgit v1.2.3