Switch from a version 4.2/4.4 switch to a four-byte version string to be put

into the actual gcov file.

Instead of using the bottom 4 bytes as the function identifier, use a counter.
This makes the identifier numbers stable across multiple runs.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176616 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nick Lewycky
2013-03-07 08:28:49 +00:00
parent 4d895455fe
commit d9686a98b8
2 changed files with 27 additions and 24 deletions

View File

@@ -31,8 +31,9 @@ ModulePass *createOptimalEdgeProfilerPass();
ModulePass *createPathProfilerPass(); ModulePass *createPathProfilerPass();
// Insert GCOV profiling instrumentation // Insert GCOV profiling instrumentation
static const char DefaultGCovVersion[4] = {'*', '2', '0', '4'};
ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true, ModulePass *createGCOVProfilerPass(bool EmitNotes = true, bool EmitData = true,
bool Use402Format = false, const char (&Version)[4] =DefaultGCovVersion,
bool UseExtraChecksum = false, bool UseExtraChecksum = false,
bool NoRedZone = false, bool NoRedZone = false,
bool NoFunctionNamesInData = false); bool NoFunctionNamesInData = false);

View File

@@ -44,17 +44,19 @@ namespace {
public: public:
static char ID; static char ID;
GCOVProfiler() GCOVProfiler()
: ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false), : ModulePass(ID), EmitNotes(true), EmitData(true),
UseExtraChecksum(false), NoRedZone(false), UseExtraChecksum(false), NoRedZone(false),
NoFunctionNamesInData(false) { NoFunctionNamesInData(false) {
memcpy(Version, DefaultGCovVersion, 4);
initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
} }
GCOVProfiler(bool EmitNotes, bool EmitData, bool Use402Format, GCOVProfiler(bool EmitNotes, bool EmitData, const char (&Version)[4],
bool UseExtraChecksum, bool NoRedZone, bool UseExtraChecksum, bool NoRedZone,
bool NoFunctionNamesInData) bool NoFunctionNamesInData)
: ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData), : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData),
Use402Format(Use402Format), UseExtraChecksum(UseExtraChecksum), UseExtraChecksum(UseExtraChecksum), NoRedZone(NoRedZone),
NoRedZone(NoRedZone), NoFunctionNamesInData(NoFunctionNamesInData) { NoFunctionNamesInData(NoFunctionNamesInData) {
memcpy(this->Version, Version, 4);
assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?"); assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?");
initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
} }
@@ -99,7 +101,7 @@ namespace {
bool EmitNotes; bool EmitNotes;
bool EmitData; bool EmitData;
bool Use402Format; char Version[4];
bool UseExtraChecksum; bool UseExtraChecksum;
bool NoRedZone; bool NoRedZone;
bool NoFunctionNamesInData; bool NoFunctionNamesInData;
@@ -114,11 +116,11 @@ INITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
"Insert instrumentation for GCOV profiling", false, false) "Insert instrumentation for GCOV profiling", false, false)
ModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData, ModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData,
bool Use402Format, const char (&Version)[4],
bool UseExtraChecksum, bool UseExtraChecksum,
bool NoRedZone, bool NoRedZone,
bool NoFunctionNamesInData) { bool NoFunctionNamesInData) {
return new GCOVProfiler(EmitNotes, EmitData, Use402Format, UseExtraChecksum, return new GCOVProfiler(EmitNotes, EmitData, Version, UseExtraChecksum,
NoRedZone, NoFunctionNamesInData); NoRedZone, NoFunctionNamesInData);
} }
@@ -257,8 +259,8 @@ namespace {
// object users can construct, the blocks and lines will be rooted here. // object users can construct, the blocks and lines will be rooted here.
class GCOVFunction : public GCOVRecord { class GCOVFunction : public GCOVRecord {
public: public:
GCOVFunction(DISubprogram SP, raw_ostream *os, GCOVFunction(DISubprogram SP, raw_ostream *os, uint32_t Ident,
bool Use402Format, bool UseExtraChecksum) { bool UseExtraChecksum) {
this->os = os; this->os = os;
Function *F = SP.getFunction(); Function *F = SP.getFunction();
@@ -275,7 +277,6 @@ namespace {
if (UseExtraChecksum) if (UseExtraChecksum)
++BlockLen; ++BlockLen;
write(BlockLen); write(BlockLen);
uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP);
write(Ident); write(Ident);
write(0); // lineno checksum write(0); // lineno checksum
if (UseExtraChecksum) if (UseExtraChecksum)
@@ -380,10 +381,9 @@ void GCOVProfiler::emitGCNO() {
std::string ErrorInfo; std::string ErrorInfo;
raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo, raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo,
raw_fd_ostream::F_Binary); raw_fd_ostream::F_Binary);
if (!Use402Format) out.write("oncg", 4);
out.write("oncg*404MVLL", 12); out.write(Version, 4);
else out.write("MVLL", 4);
out.write("oncg*204MVLL", 12);
DIArray SPs = CU.getSubprograms(); DIArray SPs = CU.getSubprograms();
for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
@@ -392,7 +392,7 @@ void GCOVProfiler::emitGCNO() {
Function *F = SP.getFunction(); Function *F = SP.getFunction();
if (!F) continue; if (!F) continue;
GCOVFunction Func(SP, &out, Use402Format, UseExtraChecksum); GCOVFunction Func(SP, &out, i, UseExtraChecksum);
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
GCOVBlock &Block = Func.getBlock(BB); GCOVBlock &Block = Func.getBlock(BB);
@@ -581,8 +581,11 @@ GlobalVariable *GCOVProfiler::buildEdgeLookupTable(
} }
Constant *GCOVProfiler::getStartFileFunc() { Constant *GCOVProfiler::getStartFileFunc() {
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Type *Args[] = {
Type::getInt8PtrTy(*Ctx), false); Type::getInt8PtrTy(*Ctx), // const char *orig_filename
Type::getInt8PtrTy(*Ctx), // const char version[4]
};
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
return M->getOrInsertFunction("llvm_gcda_start_file", FTy); return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
} }
@@ -611,8 +614,7 @@ Constant *GCOVProfiler::getEmitArcsFunc() {
Type::getInt32Ty(*Ctx), // uint32_t num_counters Type::getInt32Ty(*Ctx), // uint32_t num_counters
Type::getInt64PtrTy(*Ctx), // uint64_t *counters Type::getInt64PtrTy(*Ctx), // uint64_t *counters
}; };
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
Args, false);
return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
} }
@@ -659,15 +661,15 @@ void GCOVProfiler::insertCounterWriteout(
for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
DICompileUnit CU(CU_Nodes->getOperand(i)); DICompileUnit CU(CU_Nodes->getOperand(i));
std::string FilenameGcda = mangleName(CU, "gcda"); std::string FilenameGcda = mangleName(CU, "gcda");
Builder.CreateCall(StartFile, Builder.CreateCall2(StartFile,
Builder.CreateGlobalStringPtr(FilenameGcda)); Builder.CreateGlobalStringPtr(FilenameGcda),
Builder.CreateGlobalStringPtr(Version));
for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator
I = CountersBySP.begin(), E = CountersBySP.end(); I = CountersBySP.begin(), E = CountersBySP.end();
I != E; ++I) { I != E; ++I) {
DISubprogram SP(I->second); DISubprogram SP(I->second);
intptr_t ident = reinterpret_cast<intptr_t>(I->second);
Builder.CreateCall2(EmitFunction, Builder.CreateCall2(EmitFunction,
Builder.getInt32(ident), Builder.getInt32(i),
NoFunctionNamesInData ? NoFunctionNamesInData ?
Constant::getNullValue(Builder.getInt8PtrTy()) : Constant::getNullValue(Builder.getInt8PtrTy()) :
Builder.CreateGlobalStringPtr(SP.getName())); Builder.CreateGlobalStringPtr(SP.getName()));