mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-27 14:34:58 +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>
|
#include <set>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
static bool DisableAssertions = false;
|
|
||||||
static cl::opt<bool,true>
|
static cl::opt<bool,true>
|
||||||
ProfileVerifierDisableAssertions("profile-verifier-noassert",
|
ProfileVerifierDisableAssertions("profile-verifier-noassert",
|
||||||
cl::location(DisableAssertions), cl::desc("Disable assertions"));
|
cl::desc("Disable assertions"));
|
||||||
bool PrintedDebugTree = false;
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class VISIBILITY_HIDDEN ProfileVerifierPass : public FunctionPass {
|
class VISIBILITY_HIDDEN ProfileVerifierPass : public FunctionPass {
|
||||||
|
|
||||||
|
struct DetailedBlockInfo {
|
||||||
|
const BasicBlock *BB;
|
||||||
|
double BBWeight;
|
||||||
|
double inWeight;
|
||||||
|
int inCount;
|
||||||
|
double outWeight;
|
||||||
|
int outCount;
|
||||||
|
};
|
||||||
|
|
||||||
ProfileInfo *PI;
|
ProfileInfo *PI;
|
||||||
std::set<const BasicBlock*> BBisVisited;
|
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;
|
std::set<const BasicBlock*> BBisPrinted;
|
||||||
void debugEntry(const BasicBlock* BB, double w, double inw, int inc,
|
void debugEntry(DetailedBlockInfo*);
|
||||||
double outw, int outc, double d);
|
|
||||||
void printDebugInfo(const BasicBlock *BB);
|
void printDebugInfo(const BasicBlock *BB);
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
static char ID; // Class identification, replacement for typeinfo
|
static char ID; // Class identification, replacement for typeinfo
|
||||||
|
|
||||||
explicit ProfileVerifierPass () : FunctionPass(&ID) {
|
explicit ProfileVerifierPass (bool da = false) : FunctionPass(&ID),
|
||||||
DisableAssertions = ProfileVerifierDisableAssertions;
|
DisableAssertions(da) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void getAnalysisUsage(AnalysisUsage &AU) const {
|
void getAnalysisUsage(AnalysisUsage &AU) const {
|
||||||
@ -56,6 +68,9 @@ namespace {
|
|||||||
/// run - Verify the profile information.
|
/// run - Verify the profile information.
|
||||||
bool runOnFunction(Function &F);
|
bool runOnFunction(Function &F);
|
||||||
void recurseBasicBlock(const BasicBlock *BB);
|
void recurseBasicBlock(const BasicBlock *BB);
|
||||||
|
|
||||||
|
double ReadOrAssert(ProfileInfo::Edge);
|
||||||
|
void CheckValue(bool, const char*, DetailedBlockInfo*);
|
||||||
};
|
};
|
||||||
} // End of anonymous namespace
|
} // End of anonymous namespace
|
||||||
|
|
||||||
@ -65,11 +80,10 @@ X("profile-verifier", "Verify profiling information", false, true);
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
FunctionPass *createProfileVerifierPass() {
|
FunctionPass *createProfileVerifierPass() {
|
||||||
return new ProfileVerifierPass();
|
return new ProfileVerifierPass(ProfileVerifierDisableAssertions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
|
void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
|
||||||
|
|
||||||
if (BBisPrinted.find(BB) != BBisPrinted.end()) return;
|
if (BBisPrinted.find(BB) != BBisPrinted.end()) return;
|
||||||
@ -84,8 +98,8 @@ void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
|
|||||||
if (ProcessedPreds.insert(*bbi).second) {
|
if (ProcessedPreds.insert(*bbi).second) {
|
||||||
double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB));
|
double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB));
|
||||||
if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
|
if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
|
||||||
DEBUG(errs()<<"calculated in-edge ("<<(*bbi)->getNameStr()<<","<<BB->getNameStr()
|
errs()<<"calculated in-edge ("<<(*bbi)->getNameStr()<<","<<BB->getNameStr()
|
||||||
<<"): "<<EdgeWeight<<"\n");
|
<<"): "<<EdgeWeight<<"\n";
|
||||||
inWeight += EdgeWeight;
|
inWeight += EdgeWeight;
|
||||||
inCount++;
|
inCount++;
|
||||||
}
|
}
|
||||||
@ -98,15 +112,15 @@ void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
|
|||||||
if (ProcessedSuccs.insert(*bbi).second) {
|
if (ProcessedSuccs.insert(*bbi).second) {
|
||||||
double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi));
|
double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi));
|
||||||
if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
|
if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
|
||||||
DEBUG(errs()<<"calculated out-edge ("<<BB->getNameStr()<<","<<(*bbi)->getNameStr()
|
errs()<<"calculated out-edge ("<<BB->getNameStr()<<","<<(*bbi)->getNameStr()
|
||||||
<<"): "<<EdgeWeight<<"\n");
|
<<"): "<<EdgeWeight<<"\n";
|
||||||
outWeight += EdgeWeight;
|
outWeight += EdgeWeight;
|
||||||
outCount++;
|
outCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG(errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
|
errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
|
||||||
<<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
|
<<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
|
||||||
<<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n");
|
<<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n";
|
||||||
|
|
||||||
// mark as visited and recurse into subnodes
|
// mark as visited and recurse into subnodes
|
||||||
BBisPrinted.insert(BB);
|
BBisPrinted.insert(BB);
|
||||||
@ -116,22 +130,22 @@ void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileVerifierPass::debugEntry (const BasicBlock* BB, double w,
|
void ProfileVerifierPass::debugEntry (DetailedBlockInfo *DI) {
|
||||||
double inw, int inc, double outw, int
|
errs() << "TROUBLE: Block " << DI->BB->getNameStr() << " in "
|
||||||
outc, double d) {
|
<< DI->BB->getParent()->getNameStr() << ":";
|
||||||
DEBUG(errs()<<"TROUBLE: Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
|
errs() << "BBWeight=" << DI->BBWeight << ",";
|
||||||
<<",BBWeight="<<w<<",inWeight="<<inw<<",inCount="<<inc<<",outWeight="
|
errs() << "inWeight=" << DI->inWeight << ",";
|
||||||
<<outw<<",outCount"<<outc<<"\n");
|
errs() << "inCount=" << DI->inCount << ",";
|
||||||
DEBUG(errs()<<"DELTA:"<<d<<"\n");
|
errs() << "outWeight=" << DI->outWeight << ",";
|
||||||
|
errs() << "outCount=" << DI->outCount << ",";
|
||||||
if (!PrintedDebugTree) {
|
if (!PrintedDebugTree) {
|
||||||
PrintedDebugTree = true;
|
PrintedDebugTree = true;
|
||||||
printDebugInfo(&(BB->getParent()->getEntryBlock()));
|
printDebugInfo(&(DI->BB->getParent()->getEntryBlock()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// compare with relative error
|
// compare with relative error
|
||||||
static bool dcmp(double A, double B) {
|
static bool Equals(double A, double B) {
|
||||||
double maxRelativeError = 0.0000001;
|
double maxRelativeError = 0.0000001;
|
||||||
if (A == B)
|
if (A == B)
|
||||||
return true;
|
return true;
|
||||||
@ -144,59 +158,66 @@ static bool dcmp(double A, double B) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK(C,M) \
|
double ProfileVerifierPass::ReadOrAssert(ProfileInfo::Edge E) {
|
||||||
if (C) { \
|
const char *Message = "ASSERT:Edge has missing value";
|
||||||
if (DisableAssertions) { errs()<<(M)<<"\n"; } else { assert((!(C)) && (M)); } \
|
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) \
|
void ProfileVerifierPass::CheckValue(bool Error, const char *Message, DetailedBlockInfo *DI) {
|
||||||
if (C) { \
|
if (Error) {
|
||||||
DEBUG(debugEntry(BB, BBWeight, inWeight, inCount, \
|
DEBUG(debugEntry(DI));
|
||||||
outWeight, outCount, (D))); \
|
if (DisableAssertions) {
|
||||||
if (DisableAssertions) { errs()<<(M)<<"\n"; } else { assert((!(C)) && (M)); } \
|
errs() << Message << "\n";
|
||||||
|
} else {
|
||||||
|
assert(0 && Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileVerifierPass::recurseBasicBlock(const BasicBlock *BB) {
|
void ProfileVerifierPass::recurseBasicBlock(const BasicBlock *BB) {
|
||||||
|
|
||||||
if (BBisVisited.find(BB) != BBisVisited.end()) return;
|
if (BBisVisited.find(BB) != BBisVisited.end()) return;
|
||||||
|
|
||||||
double inWeight = 0;
|
DetailedBlockInfo DI;
|
||||||
int inCount = 0;
|
DI.BB = BB;
|
||||||
|
DI.outCount = DI.inCount = DI.inWeight = DI.outWeight = 0;
|
||||||
std::set<const BasicBlock*> ProcessedPreds;
|
std::set<const BasicBlock*> ProcessedPreds;
|
||||||
for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
|
for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
|
||||||
bbi != bbe; ++bbi ) {
|
bbi != bbe; ++bbi ) {
|
||||||
if (ProcessedPreds.insert(*bbi).second) {
|
if (ProcessedPreds.insert(*bbi).second) {
|
||||||
double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB));
|
DI.inWeight += ReadOrAssert(PI->getEdge(*bbi,BB));
|
||||||
CHECK(EdgeWeight == ProfileInfo::MissingValue,
|
DI.inCount++;
|
||||||
"ASSERT:Edge has missing value");
|
|
||||||
inWeight += EdgeWeight; inCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double outWeight = 0;
|
|
||||||
int outCount = 0;
|
|
||||||
std::set<const BasicBlock*> ProcessedSuccs;
|
std::set<const BasicBlock*> ProcessedSuccs;
|
||||||
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
|
for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
|
||||||
bbi != bbe; ++bbi ) {
|
bbi != bbe; ++bbi ) {
|
||||||
if (ProcessedSuccs.insert(*bbi).second) {
|
if (ProcessedSuccs.insert(*bbi).second) {
|
||||||
double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi));
|
DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi));
|
||||||
CHECK(EdgeWeight == ProfileInfo::MissingValue,
|
DI.outCount++;
|
||||||
"ASSERT:Edge has missing value");
|
|
||||||
outWeight += EdgeWeight; outCount++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double BBWeight = PI->getExecutionCount(BB);
|
DI.BBWeight = PI->getExecutionCount(BB);
|
||||||
CHECKDEBUG(BBWeight == ProfileInfo::MissingValue,
|
CheckValue(DI.BBWeight == ProfileInfo::MissingValue, "ASSERT:BasicBlock has missing value", &DI);
|
||||||
"ASSERT:BasicBlock has missing value",-1);
|
|
||||||
|
|
||||||
if (inCount > 0) {
|
if (DI.inCount > 0) {
|
||||||
CHECKDEBUG(!dcmp(inWeight,BBWeight),
|
CheckValue(!Equals(DI.inWeight,DI.BBWeight), "ASSERT:inWeight and BBWeight do not match", &DI);
|
||||||
"ASSERT:inWeight and BBWeight do not match",inWeight-BBWeight);
|
|
||||||
}
|
}
|
||||||
if (outCount > 0) {
|
if (DI.outCount > 0) {
|
||||||
CHECKDEBUG(!dcmp(outWeight,BBWeight),
|
CheckValue(!Equals(DI.outWeight,DI.BBWeight), "ASSERT:outWeight and BBWeight do not match", &DI);
|
||||||
"ASSERT:outWeight and BBWeight do not match",outWeight-BBWeight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mark as visited and recurse into subnodes
|
// mark as visited and recurse into subnodes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user