blob: 5f362944dc3c234e10e1a0e319a71607b06c747d [file] [log] [blame]
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +00001//===- 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"
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +000015#include "llvm/Instructions.h"
16#include "llvm/Module.h"
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000017#include "llvm/Pass.h"
18#include "llvm/Analysis/ProfileInfo.h"
19#include "llvm/Support/CommandLine.h"
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +000020#include "llvm/Support/CallSite.h"
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000021#include "llvm/Support/CFG.h"
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +000022#include "llvm/Support/InstIterator.h"
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000023#include "llvm/Support/raw_ostream.h"
24#include "llvm/Support/Debug.h"
25#include <set>
26using namespace llvm;
27
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +000028static cl::opt<bool,false>
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000029ProfileVerifierDisableAssertions("profile-verifier-noassert",
Andreas Neustiftere8d372e2009-09-04 17:15:10 +000030 cl::desc("Disable assertions"));
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000031
32namespace {
Nick Lewycky6726b6d2009-10-25 06:33:48 +000033 class ProfileVerifierPass : public FunctionPass {
Andreas Neustiftere8d372e2009-09-04 17:15:10 +000034
35 struct DetailedBlockInfo {
36 const BasicBlock *BB;
37 double BBWeight;
38 double inWeight;
39 int inCount;
40 double outWeight;
41 int outCount;
42 };
43
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000044 ProfileInfo *PI;
45 std::set<const BasicBlock*> BBisVisited;
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +000046 std::set<const Function*> FisVisited;
Andreas Neustiftere8d372e2009-09-04 17:15:10 +000047 bool DisableAssertions;
48
49 // When debugging is enabled, the verifier prints a whole slew of debug
50 // information, otherwise its just the assert. These are all the helper
51 // functions.
52 bool PrintedDebugTree;
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000053 std::set<const BasicBlock*> BBisPrinted;
Andreas Neustiftere8d372e2009-09-04 17:15:10 +000054 void debugEntry(DetailedBlockInfo*);
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000055 void printDebugInfo(const BasicBlock *BB);
Andreas Neustiftere8d372e2009-09-04 17:15:10 +000056
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000057 public:
58 static char ID; // Class identification, replacement for typeinfo
59
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +000060 explicit ProfileVerifierPass () : FunctionPass(&ID) {
61 DisableAssertions = ProfileVerifierDisableAssertions;
62 }
63 explicit ProfileVerifierPass (bool da) : FunctionPass(&ID),
64 DisableAssertions(da) {
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000065 }
66
67 void getAnalysisUsage(AnalysisUsage &AU) const {
68 AU.setPreservesAll();
69 AU.addRequired<ProfileInfo>();
70 }
71
72 const char *getPassName() const {
73 return "Profiling information verifier";
74 }
75
76 /// run - Verify the profile information.
77 bool runOnFunction(Function &F);
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +000078 void recurseBasicBlock(const BasicBlock*);
Andreas Neustiftere8d372e2009-09-04 17:15:10 +000079
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +000080 bool exitReachable(const Function*);
Andreas Neustiftere8d372e2009-09-04 17:15:10 +000081 double ReadOrAssert(ProfileInfo::Edge);
82 void CheckValue(bool, const char*, DetailedBlockInfo*);
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000083 };
84} // End of anonymous namespace
85
86char ProfileVerifierPass::ID = 0;
87static RegisterPass<ProfileVerifierPass>
88X("profile-verifier", "Verify profiling information", false, true);
89
90namespace llvm {
91 FunctionPass *createProfileVerifierPass() {
Andreas Neustiftere8d372e2009-09-04 17:15:10 +000092 return new ProfileVerifierPass(ProfileVerifierDisableAssertions);
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000093 }
94}
95
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +000096void ProfileVerifierPass::printDebugInfo(const BasicBlock *BB) {
97
98 if (BBisPrinted.find(BB) != BBisPrinted.end()) return;
99
100 double BBWeight = PI->getExecutionCount(BB);
101 if (BBWeight == ProfileInfo::MissingValue) { BBWeight = 0; }
102 double inWeight = 0;
103 int inCount = 0;
104 std::set<const BasicBlock*> ProcessedPreds;
105 for ( pred_const_iterator bbi = pred_begin(BB), bbe = pred_end(BB);
106 bbi != bbe; ++bbi ) {
107 if (ProcessedPreds.insert(*bbi).second) {
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000108 ProfileInfo::Edge E = PI->getEdge(*bbi,BB);
109 double EdgeWeight = PI->getEdgeWeight(E);
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000110 if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000111 errs() << "calculated in-edge " << E << ": " << EdgeWeight << "\n";
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000112 inWeight += EdgeWeight;
113 inCount++;
114 }
115 }
116 double outWeight = 0;
117 int outCount = 0;
118 std::set<const BasicBlock*> ProcessedSuccs;
119 for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
120 bbi != bbe; ++bbi ) {
121 if (ProcessedSuccs.insert(*bbi).second) {
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000122 ProfileInfo::Edge E = PI->getEdge(BB,*bbi);
123 double EdgeWeight = PI->getEdgeWeight(E);
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000124 if (EdgeWeight == ProfileInfo::MissingValue) { EdgeWeight = 0; }
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000125 errs() << "calculated out-edge " << E << ": " << EdgeWeight << "\n";
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000126 outWeight += EdgeWeight;
127 outCount++;
128 }
129 }
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000130 errs()<<"Block "<<BB->getNameStr()<<" in "<<BB->getParent()->getNameStr()
131 <<",BBWeight="<<BBWeight<<",inWeight="<<inWeight<<",inCount="<<inCount
132 <<",outWeight="<<outWeight<<",outCount"<<outCount<<"\n";
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000133
134 // mark as visited and recurse into subnodes
135 BBisPrinted.insert(BB);
136 for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
137 bbi != bbe; ++bbi ) {
138 printDebugInfo(*bbi);
139 }
140}
141
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000142void ProfileVerifierPass::debugEntry (DetailedBlockInfo *DI) {
143 errs() << "TROUBLE: Block " << DI->BB->getNameStr() << " in "
144 << DI->BB->getParent()->getNameStr() << ":";
145 errs() << "BBWeight=" << DI->BBWeight << ",";
146 errs() << "inWeight=" << DI->inWeight << ",";
147 errs() << "inCount=" << DI->inCount << ",";
148 errs() << "outWeight=" << DI->outWeight << ",";
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000149 errs() << "outCount=" << DI->outCount << "\n";
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000150 if (!PrintedDebugTree) {
151 PrintedDebugTree = true;
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000152 printDebugInfo(&(DI->BB->getParent()->getEntryBlock()));
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000153 }
154}
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000155
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000156// This compares A and B but considering maybe small differences.
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000157static bool Equals(double A, double B) {
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000158 double maxRelativeError = 0.0000001;
159 if (A == B)
160 return true;
161 double relativeError;
162 if (fabs(B) > fabs(A))
163 relativeError = fabs((A - B) / B);
164 else
165 relativeError = fabs((A - B) / A);
166 if (relativeError <= maxRelativeError) return true;
167 return false;
168}
169
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000170// This checks if the function "exit" is reachable from an given function
171// via calls, this is necessary to check if a profile is valid despite the
172// counts not fitting exactly.
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000173bool ProfileVerifierPass::exitReachable(const Function *F) {
174 if (!F) return false;
175
176 if (FisVisited.count(F)) return false;
177
178 Function *Exit = F->getParent()->getFunction("exit");
179 if (Exit == F) {
180 return true;
181 }
182
183 FisVisited.insert(F);
184 bool exits = false;
185 for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
186 if (const CallInst *CI = dyn_cast<CallInst>(&*I)) {
187 exits |= exitReachable(CI->getCalledFunction());
188 if (exits) break;
189 }
190 }
191 return exits;
192}
193
194#define ASSERTMESSAGE(M) \
195 errs() << (M) << "\n"; \
196 if (!DisableAssertions) assert(0 && (M));
197
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000198double ProfileVerifierPass::ReadOrAssert(ProfileInfo::Edge E) {
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000199 double EdgeWeight = PI->getEdgeWeight(E);
200 if (EdgeWeight == ProfileInfo::MissingValue) {
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000201 errs() << "Edge " << E << " in Function "
Andreas Neustifterb1b4c012009-09-11 08:43:15 +0000202 << ProfileInfo::getFunction(E)->getNameStr() << ": ";
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000203 ASSERTMESSAGE("ASSERT:Edge has missing value");
204 return 0;
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000205 } else {
206 return EdgeWeight;
207 }
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000208}
209
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000210void ProfileVerifierPass::CheckValue(bool Error, const char *Message,
211 DetailedBlockInfo *DI) {
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000212 if (Error) {
213 DEBUG(debugEntry(DI));
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000214 errs() << "Block " << DI->BB->getNameStr() << " in Function "
215 << DI->BB->getParent()->getNameStr() << ": ";
216 ASSERTMESSAGE(Message);
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000217 }
218 return;
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000219}
220
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000221// This calculates the Information for a block and then recurses into the
222// successors.
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000223void ProfileVerifierPass::recurseBasicBlock(const BasicBlock *BB) {
224
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000225 // Break the recursion by remembering all visited blocks.
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000226 if (BBisVisited.find(BB) != BBisVisited.end()) return;
227
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000228 // Use a data structure to store all the information, this can then be handed
229 // to debug printers.
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000230 DetailedBlockInfo DI;
231 DI.BB = BB;
Edward O'Callaghan2afd0722009-11-02 02:55:39 +0000232 DI.outCount = DI.inCount = 0;
233 DI.inWeight = DI.outWeight = 0.0;
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000234
235 // Read predecessors.
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000236 std::set<const BasicBlock*> ProcessedPreds;
Andreas Neustifter0c0de662009-09-10 16:30:38 +0000237 pred_const_iterator bpi = pred_begin(BB), bpe = pred_end(BB);
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000238 // If there are none, check for (0,BB) edge.
Andreas Neustifter0c0de662009-09-10 16:30:38 +0000239 if (bpi == bpe) {
240 DI.inWeight += ReadOrAssert(PI->getEdge(0,BB));
241 DI.inCount++;
242 }
243 for (;bpi != bpe; ++bpi) {
244 if (ProcessedPreds.insert(*bpi).second) {
245 DI.inWeight += ReadOrAssert(PI->getEdge(*bpi,BB));
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000246 DI.inCount++;
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000247 }
248 }
249
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000250 // Read successors.
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000251 std::set<const BasicBlock*> ProcessedSuccs;
Andreas Neustifter0c0de662009-09-10 16:30:38 +0000252 succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000253 // If there is an (0,BB) edge, consider it too. (This is done not only when
254 // there are no successors, but every time; not every function contains
255 // return blocks with no successors (think loop latch as return block)).
256 double w = PI->getEdgeWeight(PI->getEdge(BB,0));
257 if (w != ProfileInfo::MissingValue) {
258 DI.outWeight += w;
259 DI.outCount++;
Andreas Neustifter0c0de662009-09-10 16:30:38 +0000260 }
261 for (;bbi != bbe; ++bbi) {
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000262 if (ProcessedSuccs.insert(*bbi).second) {
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000263 DI.outWeight += ReadOrAssert(PI->getEdge(BB,*bbi));
264 DI.outCount++;
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000265 }
266 }
267
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000268 // Read block weight.
Andreas Neustiftere8d372e2009-09-04 17:15:10 +0000269 DI.BBWeight = PI->getExecutionCount(BB);
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000270 CheckValue(DI.BBWeight == ProfileInfo::MissingValue,
271 "ASSERT:BasicBlock has missing value", &DI);
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000272
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000273 // Check if this block is a setjmp target.
274 bool isSetJmpTarget = false;
275 if (DI.outWeight > DI.inWeight) {
276 for (BasicBlock::const_iterator i = BB->begin(), ie = BB->end();
277 i != ie; ++i) {
278 if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
279 Function *F = CI->getCalledFunction();
280 if (F && (F->getNameStr() == "_setjmp")) {
281 isSetJmpTarget = true; break;
282 }
283 }
284 }
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000285 }
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000286 // Check if this block is eventually reaching exit.
287 bool isExitReachable = false;
288 if (DI.inWeight > DI.outWeight) {
289 for (BasicBlock::const_iterator i = BB->begin(), ie = BB->end();
290 i != ie; ++i) {
291 if (const CallInst *CI = dyn_cast<CallInst>(&*i)) {
292 FisVisited.clear();
293 isExitReachable |= exitReachable(CI->getCalledFunction());
294 if (isExitReachable) break;
295 }
296 }
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000297 }
298
Andreas Neustifter43b1b0e2009-09-09 13:01:03 +0000299 if (DI.inCount > 0 && DI.outCount == 0) {
300 // If this is a block with no successors.
301 if (!isSetJmpTarget) {
302 CheckValue(!Equals(DI.inWeight,DI.BBWeight),
303 "ASSERT:inWeight and BBWeight do not match", &DI);
304 }
305 } else if (DI.inCount == 0 && DI.outCount > 0) {
306 // If this is a block with no predecessors.
307 if (!isExitReachable)
308 CheckValue(!Equals(DI.BBWeight,DI.outWeight),
309 "ASSERT:BBWeight and outWeight do not match", &DI);
310 } else {
311 // If this block has successors and predecessors.
312 if (DI.inWeight > DI.outWeight && !isExitReachable)
313 CheckValue(!Equals(DI.inWeight,DI.outWeight),
314 "ASSERT:inWeight and outWeight do not match", &DI);
315 if (DI.inWeight < DI.outWeight && !isSetJmpTarget)
316 CheckValue(!Equals(DI.inWeight,DI.outWeight),
317 "ASSERT:inWeight and outWeight do not match", &DI);
318 }
319
320
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000321 // Mark this block as visited, rescurse into successors.
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000322 BBisVisited.insert(BB);
323 for ( succ_const_iterator bbi = succ_begin(BB), bbe = succ_end(BB);
324 bbi != bbe; ++bbi ) {
325 recurseBasicBlock(*bbi);
326 }
327}
328
329bool ProfileVerifierPass::runOnFunction(Function &F) {
330 PI = &getAnalysis<ProfileInfo>();
331
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000332 // Prepare global variables.
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000333 PrintedDebugTree = false;
334 BBisVisited.clear();
335
Andreas Neustifter8a58c182009-09-11 08:39:33 +0000336 // Fetch entry block and recurse into it.
Andreas Neustiftere7ddcfd2009-09-01 08:48:42 +0000337 const BasicBlock *entry = &F.getEntryBlock();
338 recurseBasicBlock(entry);
339
340 if (!DisableAssertions)
341 assert((PI->getExecutionCount(&F)==PI->getExecutionCount(entry)) &&
342 "Function count and entry block count do not match");
343 return false;
344}