1 //===- ProfileVerifierPass.cpp - LLVM Pass to estimate profile info -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements a pass that checks profiling information for
13 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "profile-verifier"
15 #include "llvm/Pass.h"
16 #include "llvm/Analysis/ProfileInfo.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/CFG.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include "llvm/Support/Debug.h"
24 static bool DisableAssertions = false;
25 static cl::opt<bool,true>
26 ProfileVerifierDisableAssertions("profile-verifier-noassert",
27 cl::location(DisableAssertions), cl::desc("Disable assertions"));
28 bool PrintedDebugTree = false;
31 class VISIBILITY_HIDDEN ProfileVerifierPass : public FunctionPass {
33 std::set<const BasicBlock*> BBisVisited;
35 std::set<const BasicBlock*> BBisPrinted;
36 void debugEntry(const BasicBlock* BB, double w, double inw, int inc,
37 double outw, int outc, double d);
38 void printDebugInfo(const BasicBlock *BB);
41 static char ID; // Class identification, replacement for typeinfo
43 explicit ProfileVerifierPass () : FunctionPass(&ID) {
44 DisableAssertions = ProfileVerifierDisableAssertions;
47 void getAnalysisUsage(AnalysisUsage &AU) const {
49 AU.addRequired<ProfileInfo>();
52 const char *getPassName() const {
53 return "Profiling information verifier";
56 /// run - Verify the profile information.
57 bool runOnFunction(Function &F);
58 void recurseBasicBlock(const BasicBlock *BB);
60 } // End of anonymous namespace
62 char ProfileVerifierPass::ID = 0;
63 static RegisterPass<ProfileVerifierPass>
64 X("profile-verifier", "Verify profiling information", false, true);
67 FunctionPass *createProfileVerifierPass() {
68 return new ProfileVerifierPass();
73 void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
75 if (BBisPrinted.find(BB) != BBisPrinted.end()) return;
77 double BBWeight = PI->getExecutionCount(BB);
78 if (BBWeight == ProfileInfo::MissingValue) { BBWeight = 0; }
81 std::set<const BasicBlock*> ProcessedPreds;
82 for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
84 if (ProcessedPreds.insert(*bbi).second) {
85 double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB));
86 if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
87 DEBUG(errs()<<"calculated in-edge ("<<(*bbi)->getNameStr()<<","<<BB->getNameStr()
88 <<"): "<<EdgeWeight<<"\n");
89 inWeight += EdgeWeight;
95 std::set<const BasicBlock*> ProcessedSuccs;
96 for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
98 if (ProcessedSuccs.insert(*bbi).second) {
99 double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi));
100 if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
101 DEBUG(errs()<<"calculated out-edge ("<<BB->getNameStr()<<","<<(*bbi)->getNameStr()
102 <<"): "<<EdgeWeight<<"\n");
103 outWeight += EdgeWeight;
107 DEBUG(errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
108 <<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
109 <<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n");
111 // mark as visited and recurse into subnodes
112 BBisPrinted.insert(BB);
113 for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
114 bbi != bbe; ++bbi ) {
115 printDebugInfo(*bbi);
119 void ProfileVerifierPass::debugEntry (const BasicBlock* BB, double w,
120 double inw, int inc, double outw, int
122 DEBUG(errs()<<"TROUBLE: Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
123 <<",BBWeight="<<w<<",inWeight="<<inw<<",inCount="<<inc<<",outWeight="
124 <<outw<<",outCount"<<outc<<"\n");
125 DEBUG(errs()<<"DELTA:"<<d<<"\n");
126 if (!PrintedDebugTree) {
127 PrintedDebugTree = true;
128 printDebugInfo(&(BB->getParent()->getEntryBlock()));
133 // compare with relative error
134 static bool dcmp(double A, double B) {
135 double maxRelativeError = 0.0000001;
138 double relativeError;
139 if (fabs(B) > fabs(A))
140 relativeError = fabs((A - B) / B);
142 relativeError = fabs((A - B) / A);
143 if (relativeError <= maxRelativeError) return true;
149 if (DisableAssertions) { errs()<<(M)<<"\n"; } else { assert((!(C)) && (M)); } \
152 #define CHECKDEBUG(C,M,D) \
154 DEBUG(debugEntry(BB, BBWeight, inWeight, inCount, \
155 outWeight, outCount, (D))); \
156 if (DisableAssertions) { errs()<<(M)<<"\n"; } else { assert((!(C)) && (M)); } \
159 void ProfileVerifierPass::recurseBasicBlock(const BasicBlock *BB) {
161 if (BBisVisited.find(BB) != BBisVisited.end()) return;
165 std::set<const BasicBlock*> ProcessedPreds;
166 for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
167 bbi != bbe; ++bbi ) {
168 if (ProcessedPreds.insert(*bbi).second) {
169 double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB));
170 CHECK(EdgeWeight == ProfileInfo::MissingValue,
171 "ASSERT:Edge has missing value");
172 inWeight += EdgeWeight; inCount++;
176 double outWeight = 0;
178 std::set<const BasicBlock*> ProcessedSuccs;
179 for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
180 bbi != bbe; ++bbi ) {
181 if (ProcessedSuccs.insert(*bbi).second) {
182 double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi));
183 CHECK(EdgeWeight == ProfileInfo::MissingValue,
184 "ASSERT:Edge has missing value");
185 outWeight += EdgeWeight; outCount++;
189 double BBWeight = PI->getExecutionCount(BB);
190 CHECKDEBUG(BBWeight == ProfileInfo::MissingValue,
191 "ASSERT:BasicBlock has missing value",-1);
194 CHECKDEBUG(!dcmp(inWeight,BBWeight),
195 "ASSERT:inWeight and BBWeight do not match",inWeight-BBWeight);
198 CHECKDEBUG(!dcmp(outWeight,BBWeight),
199 "ASSERT:outWeight and BBWeight do not match",outWeight-BBWeight);
202 // mark as visited and recurse into subnodes
203 BBisVisited.insert(BB);
204 for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
205 bbi != bbe; ++bbi ) {
206 recurseBasicBlock(*bbi);
210 bool ProfileVerifierPass::runOnFunction(Function &F) {
211 PI = &getAnalysis<ProfileInfo>();
213 if (PI->getExecutionCount(&F) == ProfileInfo::MissingValue) {
214 DEBUG(errs()<<"Function "<<F.getNameStr()<<" has no profile\n");
218 PrintedDebugTree = false;
221 const BasicBlock *entry = &F.getEntryBlock();
222 recurseBasicBlock(entry);
224 if (!DisableAssertions)
225 assert((PI->getExecutionCount(&F)==PI->getExecutionCount(entry)) &&
226 "Function count and entry block count do not match");