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
This commit is contained in:
Andreas Neustifter 2009-09-04 17:15:10 +00:00
parent ed1ac4ae8e
commit e8d372e48d

View File

@ -21,27 +21,39 @@
#include <set>
using namespace llvm;
static bool DisableAssertions = false;
static cl::opt<bool,true>
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<const BasicBlock*> 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<const BasicBlock*> 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()<<","<<BB->getNameStr()
<<"): "<<EdgeWeight<<"\n");
errs()<<"calculated in-edge ("<<(*bbi)->getNameStr()<<","<<BB->getNameStr()
<<"): "<<EdgeWeight<<"\n";
inWeight += EdgeWeight;
inCount++;
}
@ -98,15 +112,15 @@ void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
if (ProcessedSuccs.insert(*bbi).second) {
double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi));
if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
DEBUG(errs()<<"calculated out-edge ("<<BB->getNameStr()<<","<<(*bbi)->getNameStr()
<<"): "<<EdgeWeight<<"\n");
errs()<<"calculated out-edge ("<<BB->getNameStr()<<","<<(*bbi)->getNameStr()
<<"): "<<EdgeWeight<<"\n";
outWeight += EdgeWeight;
outCount++;
}
}
DEBUG(errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
<<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
<<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n");
<<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n";
// mark as visited and recurse into subnodes
BBisPrinted.insert(BB);
@ -116,22 +130,22 @@ void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
}
}
void ProfileVerifierPass::debugEntry (const BasicBlock* BB, double w,
double inw, int inc, double outw, int
outc, double d) {
DEBUG(errs()<<"TROUBLE: Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
<<",BBWeight="<<w<<",inWeight="<<inw<<",inCount="<<inc<<",outWeight="
<<outw<<",outCount"<<outc<<"\n");
DEBUG(errs()<<"DELTA:"<<d<<"\n");
void ProfileVerifierPass::debugEntry (DetailedBlockInfo *DI) {
errs() << "TROUBLE: Block " << DI->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<const BasicBlock*> 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<const BasicBlock*> 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