Index: lib/Transforms/Instrumentation/GCOVProfiling.cpp =================================================================== --- lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -109,6 +109,8 @@ insertCounterWriteout(ArrayRef>); Function *insertFlush(ArrayRef>); + void AddFlushBeforeFork(); + enum class GCovFileType { GCNO, GCDA }; std::string mangleName(const DICompileUnit *CU, GCovFileType FileType); @@ -468,6 +470,8 @@ this->TLI = &TLI; Ctx = &M.getContext(); + AddFlushBeforeFork(); + if (Options.EmitNotes) emitProfileNotes(); if (Options.EmitData) return emitProfileArcs(); return false; @@ -524,6 +528,35 @@ return false; } +void GCOVProfiler::AddFlushBeforeFork() { + SmallVector Forks; + for (auto &F : M->functions()) { + for (auto &BB : F) { + for (auto &I : BB) { + if (CallInst *CI = dyn_cast(&I)) { + if (Function *Callee = CI->getCalledFunction()) { + if (Callee->getName() == "fork") { + FunctionType *FT = Callee->getFunctionType(); + if (FT->getReturnType()->isIntegerTy(32) && + FT->getNumParams() == 0) { + Forks.push_back(&I); + } + } + } + } + } + } + } + + for (auto I : Forks) { + IRBuilder<> Builder(I); + FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false); + Constant *GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy); + Builder.CreateCall(GCOVFlush); + I->getParent()->splitBasicBlock(I); + } +} + void GCOVProfiler::emitProfileNotes() { NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); if (!CU_Nodes) return;