Support for reading program counts in llvm-cov.

llvm-cov will now be able to read program counts from the GCDA file and
output it in the same format as gcov. The program summary tag was
identified from gcov-io.h as "\0\0\0\a3".

There is currently a bug in GCOVProfiling.cpp which does not generate
the
run- or program-counting IR, so this change was tested manually by
modifying the GCDA file and comparing the gcov and llvm-cov outputs.

llvm-svn: 193389
This commit is contained in:
Yuchen Wu 2013-10-25 02:22:21 +00:00
parent b093885696
commit 14ae8e6195
2 changed files with 34 additions and 13 deletions

View File

@ -126,6 +126,19 @@ public:
return true; return true;
} }
/// readProgramTag - If cursor points to a program summary tag then increment
/// the cursor and return true otherwise return false.
bool readProgramTag() {
StringRef Tag = Buffer->getBuffer().slice(Cursor, Cursor+4);
if (Tag.empty() ||
Tag[0] != '\0' || Tag[1] != '\0' ||
Tag[2] != '\0' || Tag[3] != '\xa3') {
return false;
}
Cursor += 4;
return true;
}
uint32_t readInt() { uint32_t readInt() {
uint32_t Result; uint32_t Result;
StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4); StringRef Str = Buffer->getBuffer().slice(Cursor, Cursor+4);
@ -159,13 +172,14 @@ private:
/// (.gcno and .gcda). /// (.gcno and .gcda).
class GCOVFile { class GCOVFile {
public: public:
GCOVFile() {} GCOVFile() : Functions(), ProgramCount(0) {}
~GCOVFile(); ~GCOVFile();
bool read(GCOVBuffer &Buffer); bool read(GCOVBuffer &Buffer);
void dump(); void dump();
void collectLineCounts(FileInfo &FI); void collectLineCounts(FileInfo &FI);
private: private:
SmallVector<GCOVFunction *, 16> Functions; SmallVector<GCOVFunction *, 16> Functions;
uint32_t ProgramCount;
}; };
/// GCOVFunction - Collects function information. /// GCOVFunction - Collects function information.
@ -220,9 +234,11 @@ public:
void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) { void addLineCount(StringRef Filename, uint32_t Line, uint64_t Count) {
LineInfo[Filename][Line-1] += Count; LineInfo[Filename][Line-1] += Count;
} }
void setProgramCount(uint32_t PC) { ProgramCount = PC; }
void print(StringRef gcnoFile, StringRef gcdaFile); void print(StringRef gcnoFile, StringRef gcdaFile);
private: private:
StringMap<LineCounts> LineInfo; StringMap<LineCounts> LineInfo;
uint32_t ProgramCount;
}; };
} }

View File

@ -44,21 +44,24 @@ bool GCOVFile::read(GCOVBuffer &Buffer) {
if (Format == GCOV::InvalidGCOV) if (Format == GCOV::InvalidGCOV)
return false; return false;
unsigned i = 0; if (isGCNOFile(Format)) {
while (1) { while (true) {
GCOVFunction *GFun = NULL; GCOVFunction *GFun = new GCOVFunction();
if (isGCDAFile(Format)) { if (!GFun->read(Buffer, Format))
// Use existing function while reading .gcda file. break;
assert(i < Functions.size() && ".gcda data does not match .gcno data");
GFun = Functions[i];
} else if (isGCNOFile(Format)) {
GFun = new GCOVFunction();
Functions.push_back(GFun); Functions.push_back(GFun);
} }
if (!GFun || !GFun->read(Buffer, Format))
break;
++i;
} }
else if (isGCDAFile(Format)) {
for (size_t i = 0, e = Functions.size(); i < e; ++i) {
bool ReadGCDA = Functions[i]->read(Buffer, Format);
(void)ReadGCDA;
assert(ReadGCDA && ".gcda data does not match .gcno data");
}
while (Buffer.readProgramTag())
++ProgramCount;
}
return true; return true;
} }
@ -75,6 +78,7 @@ void GCOVFile::collectLineCounts(FileInfo &FI) {
for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(), for (SmallVectorImpl<GCOVFunction *>::iterator I = Functions.begin(),
E = Functions.end(); I != E; ++I) E = Functions.end(); I != E; ++I)
(*I)->collectLineCounts(FI); (*I)->collectLineCounts(FI);
FI.setProgramCount(ProgramCount);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -252,6 +256,7 @@ void FileInfo::print(StringRef gcnoFile, StringRef gcdaFile) {
outs() << " -: 0:Source:" << Filename << "\n"; outs() << " -: 0:Source:" << Filename << "\n";
outs() << " -: 0:Graph:" << gcnoFile << "\n"; outs() << " -: 0:Graph:" << gcnoFile << "\n";
outs() << " -: 0:Data:" << gcdaFile << "\n"; outs() << " -: 0:Data:" << gcdaFile << "\n";
outs() << " -: 0:Programs:" << ProgramCount << "\n";
LineCounts &L = LineInfo[Filename]; LineCounts &L = LineInfo[Filename];
OwningPtr<MemoryBuffer> Buff; OwningPtr<MemoryBuffer> Buff;
if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) { if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {