forked from OSchip/llvm-project
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:
parent
b093885696
commit
14ae8e6195
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in New Issue