diff --git a/include/llvm/Support/GCOV.h b/include/llvm/Support/GCOV.h index d8836e06708..ccc7c6e0122 100644 --- a/include/llvm/Support/GCOV.h +++ b/include/llvm/Support/GCOV.h @@ -126,6 +126,19 @@ public: return true; } + /// readObjectTag - If cursor points to an object summary tag then increment + /// the cursor and return true otherwise return false. + bool readObjectTag() { + StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4); + if (Tag.empty() || + Tag[0] != '\0' || Tag[1] != '\0' || + Tag[2] != '\0' || Tag[3] != '\xa1') { + return false; + } + Cursor += 4; + return true; + } + /// readProgramTag - If cursor points to a program summary tag then increment /// the cursor and return true otherwise return false. bool readProgramTag() { @@ -163,6 +176,7 @@ public: } uint64_t getCursor() const { return Cursor; } + void advanceCursor(uint32_t n) { Cursor += n*4; } private: MemoryBuffer *Buffer; uint64_t Cursor; @@ -172,13 +186,14 @@ private: /// (.gcno and .gcda). class GCOVFile { public: - GCOVFile() : Functions(), ProgramCount(0) {} + GCOVFile() : Functions(), RunCount(0), ProgramCount(0) {} ~GCOVFile(); bool read(GCOVBuffer &Buffer); void dump(); void collectLineCounts(FileInfo &FI); private: SmallVector Functions; + uint32_t RunCount; uint32_t ProgramCount; }; @@ -234,10 +249,12 @@ public: void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) { LineInfo[Filename][Line-1] += Count; } - void setProgramCount(uint32_t PC) { ProgramCount = PC; } + void setRunCount(uint32_t Runs) { RunCount = Runs; } + void setProgramCount(uint32_t Programs) { ProgramCount = Programs; } void print(raw_fd_ostream &OS, StringRef gcnoFile, StringRef gcdaFile); private: StringMap LineInfo; + uint32_t RunCount; uint32_t ProgramCount; }; diff --git a/lib/IR/GCOV.cpp b/lib/IR/GCOV.cpp index 794ead9e71f..a33da2a5525 100644 --- a/lib/IR/GCOV.cpp +++ b/lib/IR/GCOV.cpp @@ -59,8 +59,18 @@ bool GCOVFile::read(GCOVBuffer &Buffer) { (void)ReadGCDA; assert(ReadGCDA && ".gcda data does not match .gcno data"); } - while (Buffer.readProgramTag()) + if (Buffer.readObjectTag()) { + uint32_t Length = Buffer.readInt(); + Buffer.readInt(); // checksum + Buffer.readInt(); // num + RunCount = Buffer.readInt(); + Buffer.advanceCursor(Length-3); + } + while (Buffer.readProgramTag()) { + uint32_t Length = Buffer.readInt(); + Buffer.advanceCursor(Length); ++ProgramCount; + } } return true; @@ -79,6 +89,7 @@ void GCOVFile::collectLineCounts(FileInfo &FI) { for (SmallVectorImpl::iterator I = Functions.begin(), E = Functions.end(); I != E; ++I) (*I)->collectLineCounts(FI); + FI.setRunCount(RunCount); FI.setProgramCount(ProgramCount); } @@ -258,6 +269,7 @@ void FileInfo::print(raw_fd_ostream &OS, StringRef gcnoFile, OS << " -: 0:Source:" << Filename << "\n"; OS << " -: 0:Graph:" << gcnoFile << "\n"; OS << " -: 0:Data:" << gcdaFile << "\n"; + OS << " -: 0:Runs:" << RunCount << "\n"; OS << " -: 0:Programs:" << ProgramCount << "\n"; LineCounts &L = LineInfo[Filename]; OwningPtr Buff;