ProfileVerifierPass.cpp revision 31dcbc3b4a1dea7351af5e8c08285c91049ab2c3
1//===- ProfileVerifierPass.cpp - LLVM Pass to estimate profile info -------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements a pass that checks profiling information for
11// plausibility.
12//
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"
21#include <set>
22using namespace llvm;
23
24static cl::opt<bool,true>
25ProfileVerifierDisableAssertions("profile-verifier-noassert",
26     cl::desc("Disable assertions"));
27
28namespace {
29  class VISIBILITY_HIDDEN ProfileVerifierPass : public FunctionPass {
30
31    struct DetailedBlockInfo {
32      const BasicBlock *BB;
33      double            BBWeight;
34      double            inWeight;
35      int               inCount;
36      double            outWeight;
37      int               outCount;
38    };
39
40    ProfileInfo *PI;
41    std::set<const BasicBlock*> BBisVisited;
42    bool DisableAssertions;
43
44    // When debugging is enabled, the verifier prints a whole slew of debug
45    // information, otherwise its just the assert. These are all the helper
46    // functions.
47    bool PrintedDebugTree;
48    std::set<const BasicBlock*> BBisPrinted;
49    void debugEntry(DetailedBlockInfo*);
50    void printDebugInfo(const BasicBlock *BB);
51
52  public:
53    static char ID; // Class identification, replacement for typeinfo
54
55    explicit ProfileVerifierPass (bool da = false) : FunctionPass(&ID),
56                                                     DisableAssertions(da) {
57    }
58
59    void getAnalysisUsage(AnalysisUsage &AU) const {
60      AU.setPreservesAll();
61      AU.addRequired<ProfileInfo>();
62    }
63
64    const char *getPassName() const {
65      return "Profiling information verifier";
66    }
67
68    /// run - Verify the profile information.
69    bool runOnFunction(Function &F);
70    void recurseBasicBlock(const BasicBlock *BB);
71
72    double ReadOrAssert(ProfileInfo::Edge);
73    void   CheckValue(bool, const char*, DetailedBlockInfo*);
74  };
75}  // End of anonymous namespace
76
77char ProfileVerifierPass::ID = 0;
78static RegisterPass<ProfileVerifierPass>
79X("profile-verifier", "Verify profiling information", false, true);
80
81namespace llvm {
82  FunctionPass *createProfileVerifierPass() {
83    return new ProfileVerifierPass(ProfileVerifierDisableAssertions);
84  }
85}
86
87void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
88
89  if (BBisPrinted.find(BB) != BBisPrinted.end()) return;
90
91  double BBWeight = PI->getExecutionCount(BB);
92  if (BBWeight == ProfileInfo::MissingValue) { BBWeight = 0; }
93  double inWeight = 0;
94  int inCount = 0;
95  std::set<const BasicBlock*> ProcessedPreds;
96  for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
97        bbi != bbe; ++bbi ) {
98    if (ProcessedPreds.insert(*bbi).second) {
99      double EdgeWeight = PI->getEdgeWeight(PI->getEdge(*bbi,BB));
100      if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
101      errs()<<"calculated in-edge ("<<(*bbi)->getNameStr()<<","<<BB->getNameStr()
102            <<"): "<<EdgeWeight<<"\n";
103      inWeight += EdgeWeight;
104      inCount++;
105    }
106  }
107  double outWeight = 0;
108  int outCount = 0;
109  std::set<const BasicBlock*> ProcessedSuccs;
110  for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
111        bbi != bbe; ++bbi ) {
112    if (ProcessedSuccs.insert(*bbi).second) {
113      double EdgeWeight = PI->getEdgeWeight(PI->getEdge(BB,*bbi));
114      if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
115      errs()<<"calculated out-edge ("<<BB->getNameStr()<<","<<(*bbi)->getNameStr()
116            <<"): "<<EdgeWeight<<"\n";
117      outWeight += EdgeWeight;
118      outCount++;
119    }
120  }
121  errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
122        <<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
123        <<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n";
124
125  // mark as visited and recurse into subnodes
126  BBisPrinted.insert(BB);
127  for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
128        bbi != bbe; ++bbi ) {
129    printDebugInfo(*bbi);
130  }
131}
132
133void ProfileVerifierPass::debugEntry (DetailedBlockInfo *DI) {
134  errs() << "TROUBLE: Block " << DI->BB->getNameStr() << " in "
135         << DI->BB->getParent()->getNameStr()  << ":";
136  errs() << "BBWeight="  << DI->BBWeight   << ",";
137  errs() << "inWeight="  << DI->inWeight   << ",";
138  errs() << "inCount="   << DI->inCount    << ",";
139  errs() << "outWeight=" << DI->outWeight  << ",";
140  errs() << "outCount="  << DI->outCount   << ",";
141  if (!PrintedDebugTree) {
142    PrintedDebugTree = true;
143    printDebugInfo(&(DI->BB->getParent()->getEntryBlock()));
144  }
145}
146
147// compare with relative error
148static bool Equals(double A, double B) {
149  double maxRelativeError = 0.0000001;
150  if (A == B)
151    return true;
152  double relativeError;
153  if (fabs(B) > fabs(A))
154    relativeError = fabs((A - B) / B);
155  else
156    relativeError = fabs((A - B) / A);
157  if (relativeError <= maxRelativeError) return true;
158  return false;
159}
160
161double ProfileVerifierPass::ReadOrAssert(ProfileInfo::Edge E) {
162  const char *Message = "ASSERT:Edge has missing value";
163  double EdgeWeight = PI->getEdgeWeight(E);
164  if (EdgeWeight == ProfileInfo::MissingValue) {
165    if (DisableAssertions) {
166      errs() << Message << "\n";
167      return 0;
168    } else {
169      assert(0 && Message);
170      return 0;
171    }
172  } else {
173    return EdgeWeight;
174  }
175}
176
177void ProfileVerifierPass::CheckValue(bool Error, const char *Message, DetailedBlockInfo *DI) {
178  if (Error) {
179    DEBUG(debugEntry(DI));
180    if (DisableAssertions) {
181      errs() << Message << "\n";
182    } else {
183      assert(0 && Message);
184    }
185  }
186  return;
187}
188
189void ProfileVerifierPass::recurseBasicBlock(const BasicBlock *BB) {
190
191  if (BBisVisited.find(BB) != BBisVisited.end()) return;
192
193  DetailedBlockInfo DI;
194  DI.BB = BB;
195  DI.outCount = DI.inCount = DI.inWeight = DI.outWeight = 0;
196  std::set<const BasicBlock*> ProcessedPreds;
197  for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
198        bbi != bbe; ++bbi ) {
199    if (ProcessedPreds.insert(*bbi).second) {
200      DI.inWeight += ReadOrAssert(PI->getEdge(*bbi,BB));
201      DI.inCount++;
202    }
203  }
204
205  std::set<const BasicBlock*> ProcessedSuccs;
206  for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
207        bbi != bbe; ++bbi ) {
208    if (ProcessedSuccs.insert(*bbi).second) {
209      DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi));
210      DI.outCount++;
211    }
212  }
213
214  DI.BBWeight = PI->getExecutionCount(BB);
215  CheckValue(DI.BBWeight == ProfileInfo::MissingValue, "ASSERT:BasicBlock has missing value", &DI);
216
217  if (DI.inCount > 0) {
218    CheckValue(!Equals(DI.inWeight,DI.BBWeight), "ASSERT:inWeight and BBWeight do not match", &DI);
219  }
220  if (DI.outCount > 0) {
221    CheckValue(!Equals(DI.outWeight,DI.BBWeight), "ASSERT:outWeight and BBWeight do not match", &DI);
222  }
223
224  // mark as visited and recurse into subnodes
225  BBisVisited.insert(BB);
226  for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
227        bbi != bbe; ++bbi ) {
228    recurseBasicBlock(*bbi);
229  }
230}
231
232bool ProfileVerifierPass::runOnFunction(Function &F) {
233  PI = &getAnalysis<ProfileInfo>();
234
235  if (PI->getExecutionCount(&F) == ProfileInfo::MissingValue) {
236    DEBUG(errs()<<"Function "<<F.getNameStr()<<" has no profile\n");
237    return false;
238  }
239
240  PrintedDebugTree = false;
241  BBisVisited.clear();
242
243  const BasicBlock *entry = &F.getEntryBlock();
244  recurseBasicBlock(entry);
245
246  if (!DisableAssertions)
247    assert((PI->getExecutionCount(&F)==PI->getExecutionCount(entry)) &&
248           "Function count and entry block count do not match");
249  return false;
250}
251