mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-16 00:16:50 +00:00
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:
parent
ed1ac4ae8e
commit
e8d372e48d
@ -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()
|
||||
<<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
|
||||
<<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n");
|
||||
errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
|
||||
<<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
|
||||
<<",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
|
||||
|
Loading…
Reference in New Issue
Block a user