llvm-cov: Added -b option for branch probabilities.
[oota-llvm.git] / lib / IR / GCOV.cpp
1 //===- GCOV.cpp - LLVM coverage tool --------------------------------------===//
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 // GCOV implements the interface to read and write coverage files that use
11 // 'gcov' format.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Support/Debug.h"
16 #include "llvm/Support/GCOV.h"
17 #include "llvm/ADT/OwningPtr.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/Support/Format.h"
20 #include "llvm/Support/MemoryObject.h"
21 #include "llvm/Support/system_error.h"
22 #include <algorithm>
23 using namespace llvm;
24
25 //===----------------------------------------------------------------------===//
26 // GCOVFile implementation.
27
28 /// ~GCOVFile - Delete GCOVFile and its content.
29 GCOVFile::~GCOVFile() {
30   DeleteContainerPointers(Functions);
31 }
32
33 /// readGCNO - Read GCNO buffer.
34 bool GCOVFile::readGCNO(GCOVBuffer &Buffer) {
35   if (!Buffer.readGCNOFormat()) return false;
36   if (!Buffer.readGCOVVersion(Version)) return false;
37
38   if (!Buffer.readInt(Checksum)) return false;
39   while (true) {
40     if (!Buffer.readFunctionTag()) break;
41     GCOVFunction *GFun = new GCOVFunction(*this);
42     if (!GFun->readGCNO(Buffer, Version))
43       return false;
44     Functions.push_back(GFun);
45   }
46
47   GCNOInitialized = true;
48   return true;
49 }
50
51 /// readGCDA - Read GCDA buffer. It is required that readGCDA() can only be
52 /// called after readGCNO().
53 bool GCOVFile::readGCDA(GCOVBuffer &Buffer) {
54   assert(GCNOInitialized && "readGCDA() can only be called after readGCNO()");
55   if (!Buffer.readGCDAFormat()) return false;
56   GCOV::GCOVVersion GCDAVersion;
57   if (!Buffer.readGCOVVersion(GCDAVersion)) return false;
58   if (Version != GCDAVersion) {
59     errs() << "GCOV versions do not match.\n";
60     return false;
61   }
62
63   uint32_t GCDAChecksum;
64   if (!Buffer.readInt(GCDAChecksum)) return false;
65   if (Checksum != GCDAChecksum) {
66     errs() << "File checksums do not match: " << Checksum << " != "
67            << GCDAChecksum << ".\n";
68     return false;
69   }
70   for (size_t i = 0, e = Functions.size(); i < e; ++i) {
71     if (!Buffer.readFunctionTag()) {
72       errs() << "Unexpected number of functions.\n";
73       return false;
74     }
75     if (!Functions[i]->readGCDA(Buffer, Version))
76       return false;
77   }
78   if (Buffer.readObjectTag()) {
79     uint32_t Length;
80     uint32_t Dummy;
81     if (!Buffer.readInt(Length)) return false;
82     if (!Buffer.readInt(Dummy)) return false; // checksum
83     if (!Buffer.readInt(Dummy)) return false; // num
84     if (!Buffer.readInt(RunCount)) return false;;
85     Buffer.advanceCursor(Length-3);
86   }
87   while (Buffer.readProgramTag()) {
88     uint32_t Length;
89     if (!Buffer.readInt(Length)) return false;
90     Buffer.advanceCursor(Length);
91     ++ProgramCount;
92   }
93
94   return true;
95 }
96
97 /// dump - Dump GCOVFile content to dbgs() for debugging purposes.
98 void GCOVFile::dump() const {
99   for (SmallVectorImpl<GCOVFunction *>::const_iterator I = Functions.begin(),
100          E = Functions.end(); I != E; ++I)
101     (*I)->dump();
102 }
103
104 /// collectLineCounts - Collect line counts. This must be used after
105 /// reading .gcno and .gcda files.
106 void GCOVFile::collectLineCounts(FileInfo &FI) {
107   for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(),
108          E = Functions.end(); I != E; ++I)
109     (*I)->collectLineCounts(FI);
110   FI.setRunCount(RunCount);
111   FI.setProgramCount(ProgramCount);
112 }
113
114 //===----------------------------------------------------------------------===//
115 // GCOVFunction implementation.
116
117 /// ~GCOVFunction - Delete GCOVFunction and its content.
118 GCOVFunction::~GCOVFunction() {
119   DeleteContainerPointers(Blocks);
120   DeleteContainerPointers(Edges);
121 }
122
123 /// readGCNO - Read a function from the GCNO buffer. Return false if an error
124 /// occurs.
125 bool GCOVFunction::readGCNO(GCOVBuffer &Buff, GCOV::GCOVVersion Version) {
126   uint32_t Dummy;
127   if (!Buff.readInt(Dummy)) return false; // Function header length
128   if (!Buff.readInt(Ident)) return false;
129   if (!Buff.readInt(Checksum)) return false;
130   if (Version != GCOV::V402) {
131     uint32_t CfgChecksum;
132     if (!Buff.readInt(CfgChecksum)) return false;
133     if (Parent.getChecksum() != CfgChecksum) {
134       errs() << "File checksums do not match: " << Parent.getChecksum()
135              << " != " << CfgChecksum << " in (" << Name << ").\n";
136       return false;
137     }
138   }
139   if (!Buff.readString(Name)) return false;
140   if (!Buff.readString(Filename)) return false;
141   if (!Buff.readInt(LineNumber)) return false;
142
143   // read blocks.
144   if (!Buff.readBlockTag()) {
145     errs() << "Block tag not found.\n";
146     return false;
147   }
148   uint32_t BlockCount;
149   if (!Buff.readInt(BlockCount)) return false;
150   for (uint32_t i = 0, e = BlockCount; i != e; ++i) {
151     if (!Buff.readInt(Dummy)) return false; // Block flags;
152     Blocks.push_back(new GCOVBlock(*this, i));
153   }
154
155   // read edges.
156   while (Buff.readEdgeTag()) {
157     uint32_t EdgeCount;
158     if (!Buff.readInt(EdgeCount)) return false;
159     EdgeCount = (EdgeCount - 1) / 2;
160     uint32_t BlockNo;
161     if (!Buff.readInt(BlockNo)) return false;
162     if (BlockNo >= BlockCount) {
163       errs() << "Unexpected block number: " << BlockNo << " (in " << Name
164              << ").\n";
165       return false;
166     }
167     for (uint32_t i = 0, e = EdgeCount; i != e; ++i) {
168       uint32_t Dst;
169       if (!Buff.readInt(Dst)) return false;
170       GCOVEdge *Edge = new GCOVEdge(Blocks[BlockNo], Blocks[Dst]);
171       Edges.push_back(Edge);
172       Blocks[BlockNo]->addDstEdge(Edge);
173       Blocks[Dst]->addSrcEdge(Edge);
174       if (!Buff.readInt(Dummy)) return false; // Edge flag
175     }
176   }
177
178   // read line table.
179   while (Buff.readLineTag()) {
180     uint32_t LineTableLength;
181     if (!Buff.readInt(LineTableLength)) return false;
182     uint32_t EndPos = Buff.getCursor() + LineTableLength*4;
183     uint32_t BlockNo;
184     if (!Buff.readInt(BlockNo)) return false;
185     if (BlockNo >= BlockCount) {
186       errs() << "Unexpected block number: " << BlockNo << " (in " << Name
187              << ").\n";
188       return false;
189     }
190     GCOVBlock *Block = Blocks[BlockNo];
191     if (!Buff.readInt(Dummy)) return false; // flag
192     while (Buff.getCursor() != (EndPos - 4)) {
193       StringRef F;
194       if (!Buff.readString(F)) return false;
195       if (Filename != F) {
196         errs() << "Multiple sources for a single basic block: " << Filename
197                << " != " << F << " (in " << Name << ").\n";
198         return false;
199       }
200       if (Buff.getCursor() == (EndPos - 4)) break;
201       while (true) {
202         uint32_t Line;
203         if (!Buff.readInt(Line)) return false;
204         if (!Line) break;
205         Block->addLine(Line);
206       }
207     }
208     if (!Buff.readInt(Dummy)) return false; // flag
209   }
210   return true;
211 }
212
213 /// readGCDA - Read a function from the GCDA buffer. Return false if an error
214 /// occurs.
215 bool GCOVFunction::readGCDA(GCOVBuffer &Buff, GCOV::GCOVVersion Version) {
216   uint32_t Dummy;
217   if (!Buff.readInt(Dummy)) return false; // Function header length
218
219   uint32_t GCDAIdent;
220   if (!Buff.readInt(GCDAIdent)) return false;
221   if (Ident != GCDAIdent) {
222     errs() << "Function identifiers do not match: " << Ident << " != "
223            << GCDAIdent << " (in " << Name << ").\n";
224     return false;
225   }
226
227   uint32_t GCDAChecksum;
228   if (!Buff.readInt(GCDAChecksum)) return false;
229   if (Checksum != GCDAChecksum) {
230     errs() << "Function checksums do not match: " << Checksum << " != "
231            << GCDAChecksum << " (in " << Name << ").\n";
232     return false;
233   }
234
235   uint32_t CfgChecksum;
236   if (Version != GCOV::V402) {
237     if (!Buff.readInt(CfgChecksum)) return false;
238     if (Parent.getChecksum() != CfgChecksum) {
239       errs() << "File checksums do not match: " << Parent.getChecksum()
240              << " != " << CfgChecksum << " (in " << Name << ").\n";
241       return false;
242     }
243   }
244
245   StringRef GCDAName;
246   if (!Buff.readString(GCDAName)) return false;
247   if (Name != GCDAName) {
248     errs() << "Function names do not match: " << Name << " != " << GCDAName
249            << ".\n";
250     return false;
251   }
252
253   if (!Buff.readArcTag()) {
254     errs() << "Arc tag not found (in " << Name << ").\n";
255     return false;
256   }
257
258   uint32_t Count;
259   if (!Buff.readInt(Count)) return false;
260   Count /= 2;
261
262   // This for loop adds the counts for each block. A second nested loop is
263   // required to combine the edge counts that are contained in the GCDA file.
264   for (uint32_t BlockNo = 0; Count > 0; ++BlockNo) {
265     // The last block is always reserved for exit block
266     if (BlockNo >= Blocks.size()-1) {
267       errs() << "Unexpected number of edges (in " << Name << ").\n";
268       return false;
269     }
270     GCOVBlock &Block = *Blocks[BlockNo];
271     for (size_t EdgeNo = 0, End = Block.getNumDstEdges(); EdgeNo < End;
272            ++EdgeNo) {
273       if (Count == 0) {
274         errs() << "Unexpected number of edges (in " << Name << ").\n";
275         return false;
276       }
277       uint64_t ArcCount;
278       if (!Buff.readInt64(ArcCount)) return false;
279       Block.addCount(EdgeNo, ArcCount);
280       --Count;
281     }
282     Block.sortDstEdges();
283   }
284   return true;
285 }
286
287 /// getEntryCount - Get the number of times the function was called by
288 /// retrieving the entry block's count.
289 uint64_t GCOVFunction::getEntryCount() const {
290   return Blocks.front()->getCount();
291 }
292
293 /// getExitCount - Get the number of times the function returned by retrieving
294 /// the exit block's count.
295 uint64_t GCOVFunction::getExitCount() const {
296   return Blocks.back()->getCount();
297 }
298
299 /// dump - Dump GCOVFunction content to dbgs() for debugging purposes.
300 void GCOVFunction::dump() const {
301   dbgs() <<  "===== " << Name << " @ " << Filename << ":" << LineNumber << "\n";
302   for (SmallVectorImpl<GCOVBlock *>::const_iterator I = Blocks.begin(),
303          E = Blocks.end(); I != E; ++I)
304     (*I)->dump();
305 }
306
307 /// collectLineCounts - Collect line counts. This must be used after
308 /// reading .gcno and .gcda files.
309 void GCOVFunction::collectLineCounts(FileInfo &FI) {
310   for (SmallVectorImpl<GCOVBlock *>::iterator I = Blocks.begin(),
311          E = Blocks.end(); I != E; ++I)
312     (*I)->collectLineCounts(FI);
313   FI.addFunctionLine(Filename, LineNumber, this);
314 }
315
316 //===----------------------------------------------------------------------===//
317 // GCOVBlock implementation.
318
319 /// ~GCOVBlock - Delete GCOVBlock and its content.
320 GCOVBlock::~GCOVBlock() {
321   SrcEdges.clear();
322   DstEdges.clear();
323   Lines.clear();
324 }
325
326 /// addCount - Add to block counter while storing the edge count. If the
327 /// destination has no outgoing edges, also update that block's count too.
328 void GCOVBlock::addCount(size_t DstEdgeNo, uint64_t N) {
329   assert(DstEdgeNo < DstEdges.size()); // up to caller to ensure EdgeNo is valid
330   DstEdges[DstEdgeNo]->Count = N;
331   Counter += N;
332   if (!DstEdges[DstEdgeNo]->Dst->getNumDstEdges())
333     DstEdges[DstEdgeNo]->Dst->Counter += N;
334 }
335
336 /// sortDstEdges - Sort destination edges by block number, nop if already
337 /// sorted. This is required for printing branch info in the correct order.
338 void GCOVBlock::sortDstEdges() {
339   if (!DstEdgesAreSorted) {
340     SortDstEdgesFunctor SortEdges;
341     std::stable_sort(DstEdges.begin(), DstEdges.end(), SortEdges);
342   }
343 }
344
345 /// collectLineCounts - Collect line counts. This must be used after
346 /// reading .gcno and .gcda files.
347 void GCOVBlock::collectLineCounts(FileInfo &FI) {
348   for (SmallVectorImpl<uint32_t>::iterator I = Lines.begin(),
349          E = Lines.end(); I != E; ++I)
350     FI.addBlockLine(Parent.getFilename(), *I, this);
351 }
352
353 /// dump - Dump GCOVBlock content to dbgs() for debugging purposes.
354 void GCOVBlock::dump() const {
355   dbgs() << "Block : " << Number << " Counter : " << Counter << "\n";
356   if (!SrcEdges.empty()) {
357     dbgs() << "\tSource Edges : ";
358     for (EdgeIterator I = SrcEdges.begin(), E = SrcEdges.end(); I != E; ++I) {
359       const GCOVEdge *Edge = *I;
360       dbgs() << Edge->Src->Number << " (" << Edge->Count << "), ";
361     }
362     dbgs() << "\n";
363   }
364   if (!DstEdges.empty()) {
365     dbgs() << "\tDestination Edges : ";
366     for (EdgeIterator I = DstEdges.begin(), E = DstEdges.end(); I != E; ++I) {
367       const GCOVEdge *Edge = *I;
368       dbgs() << Edge->Dst->Number << " (" << Edge->Count << "), ";
369     }
370     dbgs() << "\n";
371   }
372   if (!Lines.empty()) {
373     dbgs() << "\tLines : ";
374     for (SmallVectorImpl<uint32_t>::const_iterator I = Lines.begin(),
375            E = Lines.end(); I != E; ++I)
376       dbgs() << (*I) << ",";
377     dbgs() << "\n";
378   }
379 }
380
381 //===----------------------------------------------------------------------===//
382 // FileInfo implementation.
383
384 // Safe integer division, returns 0 if numerator is 0.
385 static uint32_t safeDiv(uint64_t Numerator, uint64_t Divisor) {
386   if (!Numerator)
387     return 0;
388   return Numerator/Divisor;
389 }
390
391 // This custom division function mimics gcov's branch ouputs:
392 //   - Round to closest whole number
393 //   - Only output 0% or 100% if it's exactly that value
394 static uint32_t branchDiv(uint64_t Numerator, uint64_t Divisor) {
395   if (!Numerator)
396     return 0;
397   if (Numerator == Divisor)
398     return 100;
399
400   uint8_t Res = (Numerator*100+Divisor/2) / Divisor;
401   if (Res == 0)
402     return 1;
403   if (Res == 100)
404     return 99;
405   return Res;
406 }
407
408 /// print -  Print source files with collected line count information.
409 void FileInfo::print(StringRef GCNOFile, StringRef GCDAFile) const {
410   for (StringMap<LineData>::const_iterator I = LineInfo.begin(),
411          E = LineInfo.end(); I != E; ++I) {
412     StringRef Filename = I->first();
413     OwningPtr<MemoryBuffer> Buff;
414     if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
415       errs() << Filename << ": " << ec.message() << "\n";
416       return;
417     }
418     StringRef AllLines = Buff->getBuffer();
419
420     std::string CovFilename = Filename.str() + ".gcov";
421     std::string ErrorInfo;
422     raw_fd_ostream OS(CovFilename.c_str(), ErrorInfo);
423     if (!ErrorInfo.empty())
424       errs() << ErrorInfo << "\n";
425
426     OS << "        -:    0:Source:" << Filename << "\n";
427     OS << "        -:    0:Graph:" << GCNOFile << "\n";
428     OS << "        -:    0:Data:" << GCDAFile << "\n";
429     OS << "        -:    0:Runs:" << RunCount << "\n";
430     OS << "        -:    0:Programs:" << ProgramCount << "\n";
431
432     const LineData &Line = I->second;
433     for (uint32_t LineIndex = 0; !AllLines.empty(); ++LineIndex) {
434       if (Options.BranchProb) {
435         FunctionLines::const_iterator FuncsIt = Line.Functions.find(LineIndex);
436         if (FuncsIt != Line.Functions.end())
437           printFunctionSummary(OS, FuncsIt->second);
438       }
439
440       BlockLines::const_iterator BlocksIt = Line.Blocks.find(LineIndex);
441       if (BlocksIt == Line.Blocks.end()) {
442         // No basic blocks are on this line. Not an executable line of code.
443         OS << "        -:";
444         std::pair<StringRef, StringRef> P = AllLines.split('\n');
445         OS << format("%5u:", LineIndex+1) << P.first << "\n";
446         AllLines = P.second;
447       } else {
448         const BlockVector &Blocks = BlocksIt->second;
449
450         // Add up the block counts to form line counts.
451         uint64_t LineCount = 0;
452         for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
453                I != E; ++I) {
454           const GCOVBlock *Block = *I;
455           if (Options.AllBlocks) {
456             // Only take the highest block count for that line.
457             uint64_t BlockCount = Block->getCount();
458             LineCount = LineCount > BlockCount ? LineCount : BlockCount;
459           } else {
460             // Sum up all of the block counts.
461             LineCount += Block->getCount();
462           }
463         }
464         if (LineCount == 0)
465           OS << "    #####:";
466         else
467           OS << format("%9" PRIu64 ":", LineCount);
468
469         std::pair<StringRef, StringRef> P = AllLines.split('\n');
470         OS << format("%5u:", LineIndex+1) << P.first << "\n";
471         AllLines = P.second;
472
473         uint32_t BlockNo = 0;
474         uint32_t EdgeNo = 0;
475         for (BlockVector::const_iterator I = Blocks.begin(), E = Blocks.end();
476                I != E; ++I) {
477           const GCOVBlock *Block = *I;
478
479           // Only print block and branch information at the end of the block.
480           if (Block->getLastLine() != LineIndex+1)
481             continue;
482           if (Options.AllBlocks)
483             printBlockInfo(OS, *Block, LineIndex, BlockNo);
484           if (Options.BranchProb)
485             printBranchInfo(OS, *Block, LineIndex, EdgeNo);
486         }
487       }
488     }
489   }
490 }
491
492 /// printFunctionSummary - Print function and block summary.
493 void FileInfo::printFunctionSummary(raw_fd_ostream &OS,
494                                     const FunctionVector &Funcs) const {
495   for (FunctionVector::const_iterator I = Funcs.begin(), E = Funcs.end();
496          I != E; ++I) {
497     const GCOVFunction *Func = *I;
498     uint64_t EntryCount = Func->getEntryCount();
499     uint32_t BlocksExecuted = 0;
500     for (GCOVFunction::BlockIterator I = Func->block_begin(),
501            E = Func->block_end(); I != E; ++I) {
502       const GCOVBlock *Block = *I;
503       if (Block->getNumDstEdges() && Block->getCount())
504           ++BlocksExecuted;
505     }
506
507     OS << "function " << Func->getName() << " called " << EntryCount
508        << " returned " << safeDiv(Func->getExitCount()*100, EntryCount)
509        << "% blocks executed "
510        << safeDiv(BlocksExecuted*100, Func->getNumBlocks()-1) << "%\n";
511   }
512 }
513
514 /// printBlockInfo - Output counts for each block.
515 void FileInfo::printBlockInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
516                               uint32_t LineIndex, uint32_t &BlockNo) const {
517   if (Block.getCount() == 0)
518     OS << "    $$$$$:";
519   else
520     OS << format("%9" PRIu64 ":", Block.getCount());
521   OS << format("%5u-block %2u\n", LineIndex+1, BlockNo++);
522 }
523
524 /// printBranchInfo - Print branch probabilities for blocks that have
525 /// conditional branches.
526 void FileInfo::printBranchInfo(raw_fd_ostream &OS, const GCOVBlock &Block,
527                                uint32_t LineIndex, uint32_t &EdgeNo) const {
528   if (Block.getNumDstEdges() < 2)
529     return;
530
531   SmallVector<uint64_t, 16> BranchCounts;
532   uint64_t TotalCounts = 0;
533   for (GCOVBlock::EdgeIterator I = Block.dst_begin(), E = Block.dst_end();
534          I != E; ++I) {
535     const GCOVEdge *Edge = *I;
536     BranchCounts.push_back(Edge->Count);
537     TotalCounts += Edge->Count;
538   }
539
540   for (SmallVectorImpl<uint64_t>::const_iterator I = BranchCounts.begin(),
541          E = BranchCounts.end(); I != E; ++I) {
542     if (TotalCounts)
543       OS << format("branch %2u taken %u%%\n", EdgeNo++,
544                    branchDiv(*I, TotalCounts));
545     else
546       OS << format("branch %2u never executed\n", EdgeNo++);
547   }
548 }