mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-22 03:39:03 +00:00
Register the flush function for each compile unit.
For each compile unit, we want to register a function that will flush that compile unit. Otherwise, __gcov_flush() would only flush the counters within the current compile unit, and not any outside of it. PR15191 & <rdar://problem/13167507> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177340 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4a8dbb7da3
commit
d195eb6b83
@ -101,6 +101,7 @@ namespace {
|
|||||||
Constant *getIncrementIndirectCounterFunc();
|
Constant *getIncrementIndirectCounterFunc();
|
||||||
Constant *getEmitFunctionFunc();
|
Constant *getEmitFunctionFunc();
|
||||||
Constant *getEmitArcsFunc();
|
Constant *getEmitArcsFunc();
|
||||||
|
Constant *getDeleteFlushFunctionListFunc();
|
||||||
Constant *getEndFileFunc();
|
Constant *getEndFileFunc();
|
||||||
|
|
||||||
// Create or retrieve an i32 state value that is used to represent the
|
// Create or retrieve an i32 state value that is used to represent the
|
||||||
@ -116,9 +117,10 @@ namespace {
|
|||||||
|
|
||||||
// Add the function to write out all our counters to the global destructor
|
// Add the function to write out all our counters to the global destructor
|
||||||
// list.
|
// list.
|
||||||
void insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
|
Function *insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*,
|
||||||
|
MDNode*> >);
|
||||||
|
Function *insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
|
||||||
void insertIndirectCounterIncrement();
|
void insertIndirectCounterIncrement();
|
||||||
void insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
|
|
||||||
|
|
||||||
std::string mangleName(DICompileUnit CU, const char *NewStem);
|
std::string mangleName(DICompileUnit CU, const char *NewStem);
|
||||||
|
|
||||||
@ -538,8 +540,42 @@ bool GCOVProfiler::emitProfileArcs() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
insertCounterWriteout(CountersBySP);
|
Function *WriteoutF = insertCounterWriteout(CountersBySP);
|
||||||
insertFlush(CountersBySP);
|
Function *FlushF = insertFlush(CountersBySP);
|
||||||
|
|
||||||
|
// Create a small bit of code that registers the "__llvm_gcov_writeout" to
|
||||||
|
// be executed at exit and the "__llvm_gcov_flush" function to be executed
|
||||||
|
// when "__gcov_flush" is called.
|
||||||
|
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||||
|
Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
|
||||||
|
"__llvm_gcov_init", M);
|
||||||
|
F->setUnnamedAddr(true);
|
||||||
|
F->setLinkage(GlobalValue::InternalLinkage);
|
||||||
|
F->addFnAttr(Attribute::NoInline);
|
||||||
|
if (Options.NoRedZone)
|
||||||
|
F->addFnAttr(Attribute::NoRedZone);
|
||||||
|
|
||||||
|
BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
|
||||||
|
IRBuilder<> Builder(BB);
|
||||||
|
|
||||||
|
FTy = FunctionType::get(Builder.getInt32Ty(),
|
||||||
|
PointerType::get(FTy, 0), false);
|
||||||
|
Constant *AtExitFn = M->getOrInsertFunction("atexit", FTy);
|
||||||
|
Builder.CreateCall(AtExitFn, WriteoutF);
|
||||||
|
|
||||||
|
// Register the local flush function.
|
||||||
|
FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||||
|
FTy = FunctionType::get(Builder.getVoidTy(),
|
||||||
|
PointerType::get(FTy, 0), false);
|
||||||
|
Constant *RegFlush =
|
||||||
|
M->getOrInsertFunction("llvm_register_flush_function", FTy);
|
||||||
|
Builder.CreateCall(RegFlush, FlushF);
|
||||||
|
|
||||||
|
// Make sure that all the flush function list is deleted.
|
||||||
|
Builder.CreateCall(AtExitFn, getDeleteFlushFunctionListFunc());
|
||||||
|
Builder.CreateRetVoid();
|
||||||
|
|
||||||
|
appendToGlobalCtors(*M, F, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InsertIndCounterIncrCode)
|
if (InsertIndCounterIncrCode)
|
||||||
@ -635,6 +671,11 @@ Constant *GCOVProfiler::getEmitArcsFunc() {
|
|||||||
return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
|
return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Constant *GCOVProfiler::getDeleteFlushFunctionListFunc() {
|
||||||
|
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||||
|
return M->getOrInsertFunction("llvm_delete_flush_function_list", FTy);
|
||||||
|
}
|
||||||
|
|
||||||
Constant *GCOVProfiler::getEndFileFunc() {
|
Constant *GCOVProfiler::getEndFileFunc() {
|
||||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||||
return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
|
return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
|
||||||
@ -653,7 +694,7 @@ GlobalVariable *GCOVProfiler::getEdgeStateValue() {
|
|||||||
return GV;
|
return GV;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCOVProfiler::insertCounterWriteout(
|
Function *GCOVProfiler::insertCounterWriteout(
|
||||||
ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
|
ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
|
||||||
FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||||
Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
|
Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
|
||||||
@ -700,29 +741,9 @@ void GCOVProfiler::insertCounterWriteout(
|
|||||||
Builder.CreateCall(EndFile);
|
Builder.CreateCall(EndFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Builder.CreateRetVoid();
|
Builder.CreateRetVoid();
|
||||||
|
return WriteoutF;
|
||||||
// Create a small bit of code that registers the "__llvm_gcov_writeout"
|
|
||||||
// function to be executed at exit.
|
|
||||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
|
||||||
Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
|
|
||||||
"__llvm_gcov_init", M);
|
|
||||||
F->setUnnamedAddr(true);
|
|
||||||
F->setLinkage(GlobalValue::InternalLinkage);
|
|
||||||
F->addFnAttr(Attribute::NoInline);
|
|
||||||
if (Options.NoRedZone)
|
|
||||||
F->addFnAttr(Attribute::NoRedZone);
|
|
||||||
|
|
||||||
BB = BasicBlock::Create(*Ctx, "entry", F);
|
|
||||||
Builder.SetInsertPoint(BB);
|
|
||||||
|
|
||||||
FTy = FunctionType::get(Builder.getInt32Ty(),
|
|
||||||
PointerType::get(FTy, 0), false);
|
|
||||||
Constant *AtExitFn = M->getOrInsertFunction("atexit", FTy);
|
|
||||||
Builder.CreateCall(AtExitFn, WriteoutF);
|
|
||||||
Builder.CreateRetVoid();
|
|
||||||
|
|
||||||
appendToGlobalCtors(*M, F, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCOVProfiler::insertIndirectCounterIncrement() {
|
void GCOVProfiler::insertIndirectCounterIncrement() {
|
||||||
@ -776,13 +797,13 @@ void GCOVProfiler::insertIndirectCounterIncrement() {
|
|||||||
Builder.CreateRetVoid();
|
Builder.CreateRetVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GCOVProfiler::
|
Function *GCOVProfiler::
|
||||||
insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
|
insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
|
||||||
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
|
||||||
Function *FlushF = M->getFunction("__gcov_flush");
|
Function *FlushF = M->getFunction("__llvm_gcov_flush");
|
||||||
if (!FlushF)
|
if (!FlushF)
|
||||||
FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
|
FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
|
||||||
"__gcov_flush", M);
|
"__llvm_gcov_flush", M);
|
||||||
else
|
else
|
||||||
FlushF->setLinkage(GlobalValue::InternalLinkage);
|
FlushF->setLinkage(GlobalValue::InternalLinkage);
|
||||||
FlushF->setUnnamedAddr(true);
|
FlushF->setUnnamedAddr(true);
|
||||||
@ -812,8 +833,10 @@ insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
|
|||||||
if (RetTy == Type::getVoidTy(*Ctx))
|
if (RetTy == Type::getVoidTy(*Ctx))
|
||||||
Builder.CreateRetVoid();
|
Builder.CreateRetVoid();
|
||||||
else if (RetTy->isIntegerTy())
|
else if (RetTy->isIntegerTy())
|
||||||
// Used if __gcov_flush was implicitly declared.
|
// Used if __llvm_gcov_flush was implicitly declared.
|
||||||
Builder.CreateRet(ConstantInt::get(RetTy, 0));
|
Builder.CreateRet(ConstantInt::get(RetTy, 0));
|
||||||
else
|
else
|
||||||
report_fatal_error("invalid return type for __gcov_flush");
|
report_fatal_error("invalid return type for __llvm_gcov_flush");
|
||||||
|
|
||||||
|
return FlushF;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user