llvm.org GIT mirror llvm / 253353c
Introduce the __llvm_gcov_flush function. This function writes out the current values of the counters and then resets them. This can be used similarly to the __gcov_flush function to sync the counters when need be. For instance, in a situation where the application doesn't exit. <rdar://problem/12185886> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163757 91177308-0d34-0410-b5e6-96231b3b80d8 Bill Wendling 7 years ago
1 changed file(s) with 56 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
3333 #include "llvm/Support/InstIterator.h"
3434 #include "llvm/Support/PathV2.h"
3535 #include "llvm/Support/raw_ostream.h"
36 #include "llvm/Target/TargetData.h"
3637 #include "llvm/Transforms/Utils/ModuleUtils.h"
3738 #include
3839 #include
8990 // list.
9091 void insertCounterWriteout(ArrayRef >);
9192 void insertIndirectCounterIncrement();
93 void insertFlush(ArrayRef >);
9294
9395 std::string mangleName(DICompileUnit CU, const char *NewStem);
9496
99101
100102 Module *M;
101103 LLVMContext *Ctx;
104 const TargetData *TD;
102105 };
103106 }
104107
350353
351354 bool GCOVProfiler::runOnModule(Module &M) {
352355 this->M = &M;
356 TD = getAnalysisIfAvailable();
353357 Ctx = &M.getContext();
354358
355359 if (EmitNotes) emitGCNO();
517521 }
518522
519523 insertCounterWriteout(CountersBySP);
524 insertFlush(CountersBySP);
520525 }
521526
522527 if (InsertIndCounterIncrCode)
629634
630635 void GCOVProfiler::insertCounterWriteout(
631636 ArrayRef > CountersBySP) {
632 FunctionType *WriteoutFTy =
633 FunctionType::get(Type::getVoidTy(*Ctx), false);
634 Function *WriteoutF = Function::Create(WriteoutFTy,
635 GlobalValue::InternalLinkage,
636 "__llvm_gcov_writeout", M);
637 FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
638 Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
639 if (!WriteoutF)
640 WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
641 "__llvm_gcov_writeout", M);
637642 WriteoutF->setUnnamedAddr(true);
638 BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF);
643
644 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
639645 IRBuilder<> Builder(BB);
640646
641647 Constant *StartFile = getStartFileFunc();
743749 Builder.SetInsertPoint(Exit);
744750 Builder.CreateRetVoid();
745751 }
752
753 void GCOVProfiler::
754 insertFlush(ArrayRef > CountersBySP) {
755 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
756 Function *FlushF = M->getFunction("__llvm_gcov_flush");
757 if (!FlushF)
758 FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
759 "__llvm_gcov_flush", M);
760 else
761 FlushF->setLinkage(GlobalValue::InternalLinkage);
762 FlushF->setUnnamedAddr(true);
763
764 Type *Int8Ty = Type::getInt8Ty(*Ctx);
765 Type *Int64Ty = Type::getInt64Ty(*Ctx);
766 BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
767
768 // Write out the current counters.
769 Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout");
770 assert(WriteoutF && "Need to create the writeout function first!");
771
772 IRBuilder<> Builder(Entry);
773 Builder.CreateCall(WriteoutF);
774
775 if (TD)
776 // Zero out the counters.
777 for (ArrayRef >::iterator
778 I = CountersBySP.begin(), E = CountersBySP.end();
779 I != E; ++I) {
780 GlobalVariable *GV = I->first;
781 uint64_t NumBytes = TD->getTypeAllocSize(GV->getType()->getElementType());
782 Builder.CreateMemSet(Builder.CreateConstGEP2_64(GV, 0, 0),
783 ConstantInt::get(Int8Ty, 0),
784 ConstantInt::get(Int64Ty, NumBytes), false);
785 }
786
787 Type *RetTy = FlushF->getReturnType();
788 if (RetTy == Type::getVoidTy(*Ctx))
789 Builder.CreateRetVoid();
790 else if (RetTy->isIntegerTy())
791 // Used if __llvm_gcov_flush was implicitly declared.
792 Builder.CreateRet(ConstantInt::get(RetTy, 0));
793 else
794 report_fatal_error("invalid return type for __llvm_gcov_flush");
795 }