52#define DEBUG_TYPE "insert-gcov-profiling"
68 cl::desc(
"Make counter updates atomic"));
73 return (s.
size() / 4) + 2;
97 : GCOVProfiler(
GCOVOptions::getDefault(), *
vfs::getRealFileSystem()) {}
101 runOnModule(
Module &M, function_ref<BlockFrequencyInfo *(Function &
F)> GetBFI,
102 function_ref<BranchProbabilityInfo *(Function &
F)> GetBPI,
103 std::function<
const TargetLibraryInfo &(Function &
F)> GetTLI);
105 void write(uint32_t i) {
110 void writeString(StringRef s) {
113 os->write_zeros(4 - s.
size() % 4);
115 void writeBytes(
const char *Bytes,
int Size) { os->write(Bytes,
Size); }
116 vfs::FileSystem &getVirtualFileSystem()
const {
return VFS; }
121 emitProfileNotes(NamedMDNode *CUNode,
bool HasExecOrFork,
122 function_ref<BlockFrequencyInfo *(Function &
F)> GetBFI,
123 function_ref<BranchProbabilityInfo *(Function &
F)> GetBPI,
124 function_ref<
const TargetLibraryInfo &(Function &
F)> GetTLI);
126 Function *createInternalFunction(FunctionType *FTy, StringRef Name,
127 StringRef MangledType =
"");
129 void emitGlobalConstructor(
130 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
131 void emitModuleInitFunctionPtrs(
132 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
134 bool isFunctionInstrumented(
const Function &
F);
135 std::vector<Regex> createRegexesFromString(StringRef RegexesStr);
136 static bool doesFilenameMatchARegex(StringRef Filename,
137 std::vector<Regex> &Regexes);
140 FunctionCallee getStartFileFunc(
const TargetLibraryInfo *TLI);
141 FunctionCallee getEmitFunctionFunc(
const TargetLibraryInfo *TLI);
142 FunctionCallee getEmitArcsFunc(
const TargetLibraryInfo *TLI);
143 FunctionCallee getSummaryInfoFunc();
144 FunctionCallee getEndFileFunc();
149 insertCounterWriteout(
ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
152 bool AddFlushBeforeForkAndExec();
154 enum class GCovFileType { GCNO, GCDA };
155 std::string mangleName(
const DICompileUnit *CU, GCovFileType FileType);
166 std::function<
const TargetLibraryInfo &(
Function &
F)> GetTLI;
167 LLVMContext *Ctx =
nullptr;
169 std::vector<Regex> FilterRe;
170 std::vector<Regex> ExcludeRe;
171 DenseSet<const BasicBlock *> ExecBlocks;
172 StringMap<bool> InstrumentedFiles;
173 vfs::FileSystem &VFS;
181 BBInfo(
unsigned Index) : Group(this),
Index(
Index) {}
182 std::string infoString()
const {
183 return (Twine(
"Index=") + Twine(Index)).str();
194 uint32_t SrcNumber, DstNumber;
196 bool Removed =
false;
197 bool IsCritical =
false;
199 Edge(
const BasicBlock *Src,
const BasicBlock *Dest, uint64_t W = 1)
200 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
203 std::string infoString()
const {
204 return (Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
205 (IsCritical ?
"c" :
" ") +
" W=" + Twine(Weight))
212 if (!SP->getLinkageName().empty())
213 return SP->getLinkageName();
214 return SP->getName();
237 GCOVRecord(GCOVProfiler *
P) :
P(
P) {}
239 void write(uint32_t i) {
P->write(i); }
240 void writeString(StringRef s) {
P->writeString(s); }
241 void writeBytes(
const char *Bytes,
int Size) {
P->writeBytes(Bytes,
Size); }
250 class GCOVLines :
public GCOVRecord {
254 void addLine(uint32_t Line) {
255 assert(Line != 0 &&
"Line zero is not a valid real line number.");
256 Lines.push_back(Line);
259 uint32_t length()
const {
265 writeString(Filename);
266 for (uint32_t L : Lines)
270 GCOVLines(GCOVProfiler *
P, StringRef
F)
284 GCOVLines &getFile(StringRef Filename) {
285 if (
Lines.empty() ||
Lines.back().getFilename() != Filename)
286 Lines.emplace_back(
P, Filename);
291 OutEdges.emplace_back(&
Successor, Flags);
297 for (
auto &L : Lines)
304 for (
auto &L : Lines)
322 friend class GCOVFunction;
335 GCOVFunction(GCOVProfiler *
P, Function *
F,
const DISubprogram *SP,
336 unsigned EndLine, uint32_t Ident,
int Version)
337 : GCOVRecord(
P),
SP(
SP), EndLine(EndLine), Ident(Ident),
341 for (BasicBlock &BB : *
F)
342 Blocks.insert(std::make_pair(&BB, GCOVBlock(
P, i++)));
344 std::string FunctionNameAndLine;
345 raw_string_ostream FNLOS(FunctionNameAndLine);
347 FuncChecksum =
hash_value(FunctionNameAndLine);
350 GCOVBlock &getBlock(
const BasicBlock *BB) {
351 return Blocks.find(
const_cast<BasicBlock *
>(BB))->second;
354 GCOVBlock &getEntryBlock() {
return EntryBlock; }
355 GCOVBlock &getReturnBlock() {
359 uint32_t getFuncChecksum()
const {
363 void writeOut(uint32_t CfgChecksum) {
376 writeString(Filename);
387 write(Blocks.size() + 2);
391 const uint32_t Outgoing = EntryBlock.OutEdges.size();
394 write(Outgoing * 2 + 1);
395 write(EntryBlock.Number);
396 for (
const auto &
E : EntryBlock.OutEdges) {
401 for (
auto &It : Blocks) {
402 const GCOVBlock &
Block = It.second;
403 if (
Block.OutEdges.empty())
continue;
408 for (
const auto &
E :
Block.OutEdges) {
415 for (
auto &It : Blocks)
416 It.second.writeOut();
420 const DISubprogram *
SP;
423 uint32_t FuncChecksum;
425 MapVector<BasicBlock *, GCOVBlock> Blocks;
426 GCOVBlock EntryBlock;
427 GCOVBlock ReturnBlock;
433std::vector<Regex> GCOVProfiler::createRegexesFromString(
StringRef RegexesStr) {
434 std::vector<Regex> Regexes;
435 while (!RegexesStr.
empty()) {
436 std::pair<StringRef, StringRef> HeadTail = RegexesStr.
split(
';');
437 if (!HeadTail.first.empty()) {
438 Regex Re(HeadTail.first);
440 if (!Re.isValid(Err)) {
441 Ctx->emitError(
Twine(
"Regex ") + HeadTail.first +
442 " is not valid: " + Err);
444 Regexes.emplace_back(std::move(Re));
446 RegexesStr = HeadTail.second;
451bool GCOVProfiler::doesFilenameMatchARegex(
StringRef Filename,
452 std::vector<Regex> &Regexes) {
453 for (
Regex &Re : Regexes)
454 if (Re.match(Filename))
459bool GCOVProfiler::isFunctionInstrumented(
const Function &
F) {
460 if (FilterRe.empty() && ExcludeRe.empty()) {
464 auto It = InstrumentedFiles.find(Filename);
465 if (It != InstrumentedFiles.end()) {
475 if (VFS.getRealPath(Filename, RealPath)) {
479 RealFilename = RealPath;
482 bool ShouldInstrument;
483 if (FilterRe.empty()) {
484 ShouldInstrument = !doesFilenameMatchARegex(RealFilename, ExcludeRe);
485 }
else if (ExcludeRe.empty()) {
486 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe);
488 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe) &&
489 !doesFilenameMatchARegex(RealFilename, ExcludeRe);
491 InstrumentedFiles[
Filename] = ShouldInstrument;
492 return ShouldInstrument;
496 GCovFileType OutputType) {
497 bool Notes = OutputType == GCovFileType::GCNO;
499 if (
NamedMDNode *GCov =
M->getNamedMetadata(
"llvm.gcov")) {
500 for (
int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
502 bool ThreeElement =
N->getNumOperands() == 3;
503 if (!ThreeElement &&
N->getNumOperands() != 2)
513 if (!NotesFile || !DataFile)
515 return std::string(Notes ? NotesFile->
getString()
525 return std::string(Filename);
534 return std::string(FName);
537 return std::string(CurPath);
540bool GCOVProfiler::runOnModule(
545 this->GetTLI = std::move(GetTLI);
546 Ctx = &
M.getContext();
548 NamedMDNode *CUNode =
M.getNamedMetadata(
"llvm.dbg.cu");
552 bool HasExecOrFork = AddFlushBeforeForkAndExec();
554 FilterRe = createRegexesFromString(
Options.Filter);
555 ExcludeRe = createRegexesFromString(
Options.Exclude);
556 emitProfileNotes(CUNode, HasExecOrFork, GetBFI, GetBPI, this->GetTLI);
563 GCOVProfiler Profiler(GCOVOpts, *VFS);
577 if (!Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI))
587 for (
const auto &BB :
F) {
588 for (
const auto &
I : BB) {
594 if (
Loc.getLine() == 0)
continue;
595 EndLine = std::max(EndLine,
Loc.getLine());
604 if (!
F.hasPersonalityFn())
return false;
610bool GCOVProfiler::AddFlushBeforeForkAndExec() {
614 for (
auto &
F :
M->functions()) {
615 TLI = TLI ==
nullptr ? &GetTLI(
F) : TLI;
618 if (
Function *Callee = CI->getCalledFunction()) {
621 if (LF == LibFunc_fork) {
625 }
else if (LF == LibFunc_execl || LF == LibFunc_execle ||
626 LF == LibFunc_execlp || LF == LibFunc_execv ||
627 LF == LibFunc_execvp || LF == LibFunc_execve ||
628 LF == LibFunc_execvpe || LF == LibFunc_execvP) {
637 for (
auto *
F : Forks) {
647 F->setCalledFunction(GCOVFork);
664 for (
auto *
E : Execs) {
673 M->getOrInsertFunction(
"llvm_writeout_files", FTy);
674 Builder.CreateCall(WriteoutF);
677 Builder.SetInsertPoint(&*NextInst);
680 FunctionCallee ResetF =
M->getOrInsertFunction(
"llvm_reset_counters", FTy);
681 Builder.CreateCall(ResetF)->setDebugLoc(
Loc);
682 ExecBlocks.insert(Parent);
687 return !Forks.
empty() || !Execs.empty();
692 if (
E.InMST ||
E.Removed)
698 if (SrcBB ==
nullptr)
700 if (DestBB ==
nullptr)
715 return CanInstrument(SrcBB);
717 return CanInstrument(DestBB);
727 MST.
addEdge(SrcBB, InstrBB, 0);
728 MST.
addEdge(InstrBB, DestBB, 0).InMST =
true;
731 return CanInstrument(InstrBB);
738 GCOVBlock &Src =
E.SrcBB ? GF.getBlock(
E.SrcBB) : GF.getEntryBlock();
739 GCOVBlock &Dst =
E.DestBB ? GF.getBlock(
E.DestBB) : GF.getReturnBlock();
740 dbgs() <<
" Edge " <<
ID++ <<
": " << Src.Number <<
"->" << Dst.Number
741 <<
E.infoString() <<
"\n";
746bool GCOVProfiler::emitProfileNotes(
752 uint8_t c3 =
Options.Version[0];
753 uint8_t c2 =
Options.Version[1];
754 uint8_t c1 =
Options.Version[2];
755 Version = c3 >=
'A' ? (c3 -
'A') * 100 + (c2 -
'0') * 10 + c1 -
'0'
756 : (c3 -
'0') * 10 + c1 -
'0';
761 memcpy(
Options.Version,
"B11*", 4);
764 bool EmitGCDA =
Options.EmitData;
776 std::vector<uint8_t> EdgeDestinations;
781 unsigned FunctionIdent = 0;
782 for (
auto &
F :
M->functions()) {
790 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
792 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
797 uint32_t
Line =
SP->getLine();
813 auto &
E = *MST.allEdges()[
I];
822 Funcs.push_back(std::make_unique<GCOVFunction>(
this, &
F, SP, EndLine,
829 return E->Removed || (!E->InMST && !E->Place);
831 const size_t Measured =
832 std::stable_partition(
833 MST.allEdges().begin(), MST.allEdges().end(),
834 [](std::unique_ptr<Edge> &
E) { return E->Place; }) -
835 MST.allEdges().begin();
837 Edge &
E = *MST.allEdges()[
I];
839 E.SrcBB ?
Func.getBlock(
E.SrcBB) :
Func.getEntryBlock();
841 E.DestBB ?
Func.getBlock(
E.DestBB) :
Func.getReturnBlock();
842 E.SrcNumber = Src.Number;
843 E.DstNumber = Dst.Number;
846 MST.allEdges().begin(), MST.allEdges().begin() + Measured,
847 [](
const std::unique_ptr<Edge> &L,
const std::unique_ptr<Edge> &R) {
848 return L->SrcNumber != R->SrcNumber ? L->SrcNumber < R->SrcNumber
849 : L->DstNumber < R->DstNumber;
854 E.SrcBB ?
Func.getBlock(
E.SrcBB) :
Func.getEntryBlock();
856 E.DestBB ?
Func.getBlock(
E.DestBB) :
Func.getReturnBlock();
861 if (!
SP->isArtificial())
862 Func.getBlock(&EntryBlock).getFile(Filename).addLine(Line);
866 for (
auto &GB :
Func.Blocks) {
868 auto &
Block = GB.second;
869 for (
auto Succ :
Block.OutEdges) {
870 uint32_t Idx = Succ.first->Number;
871 do EdgeDestinations.push_back(Idx & 255);
872 while ((Idx >>= 8) > 0);
875 for (
const auto &
I : BB) {
881 if (
Loc.getLine() == 0 ||
Loc.isImplicitCode())
884 if (Line ==
Loc.getLine())
continue;
903 Counters->setSection(
"__llvm_gcov_ctr_section");
907 const Edge &
E = *MST.allEdges()[
I];
908 IRBuilder<> Builder(
E.Place,
E.Place->getFirstInsertionPt());
909 Value *
V = Builder.CreateConstInBoundsGEP2_64(
920 Builder.CreateLoad(Builder.getInt64Ty(), V,
"gcov_ctr");
922 Value *NewCount = Builder.CreateAdd(OldCount, Builder.getInt64(1));
923 Inst = Builder.CreateStore(NewCount, V);
932 JC.
update(EdgeDestinations);
933 uint32_t Stamp = JC.
getCRC();
942 Twine(
"failed to open coverage notes file for writing: ") +
948 out.write(
"gcno", 4);
951 out.write(
"oncg", 4);
959 for (
auto &Func : Funcs)
960 Func->writeOut(Stamp);
970 emitModuleInitFunctionPtrs(CountersBySP);
972 emitGlobalConstructor(CountersBySP);
985 F->addFnAttr(Attribute::NoUnwind);
987 F->addFnAttr(Attribute::NoRedZone);
988 if (!MangledType.
empty())
993void GCOVProfiler::emitGlobalConstructor(
994 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
995 Function *WriteoutF = insertCounterWriteout(CountersBySP);
996 Function *ResetF = insertReset(CountersBySP);
1002 Function *
F = createInternalFunction(FTy,
"__llvm_gcov_init",
"_ZTSFvvE");
1003 F->addFnAttr(Attribute::NoInline);
1014 FunctionCallee GCOVInit =
M->getOrInsertFunction(
"llvm_gcov_init", FTy);
1015 Builder.CreateCall(GCOVInit, {WriteoutF, ResetF});
1016 Builder.CreateRetVoid();
1021void GCOVProfiler::emitModuleInitFunctionPtrs(
1022 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
1023 Function *WriteoutF = insertCounterWriteout(CountersBySP);
1024 Function *ResetF = insertReset(CountersBySP);
1030 auto &Ctx =
M->getContext();
1032 Type *InitFuncDataTy[] = {
1033#define COVINIT_FUNC(Type, LLVMType, Name, Init) LLVMType,
1040#define COVINIT_FUNC(Type, LLVMType, Name, Init) Init,
1046 "__llvm_covinit_functions");
1050 IPSK_covinit,
M->getTargetTriple().getObjectFormat()));
1052 CovInitGV->setConstant(
true);
1062 return M->getOrInsertFunction(
"llvm_gcda_start_file", FTy,
1073 return M->getOrInsertFunction(
"llvm_gcda_emit_function", FTy,
1083 return M->getOrInsertFunction(
"llvm_gcda_emit_arcs", FTy,
1089 return M->getOrInsertFunction(
"llvm_gcda_summary_info", FTy);
1094 return M->getOrInsertFunction(
"llvm_gcda_end_file", FTy);
1097Function *GCOVProfiler::insertCounterWriteout(
1098 ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
1100 Function *WriteoutF =
M->getFunction(
"__llvm_gcov_writeout");
1103 createInternalFunction(WriteoutFTy,
"__llvm_gcov_writeout",
"_ZTSFvvE");
1104 WriteoutF->
addFnAttr(Attribute::NoInline);
1109 auto *TLI = &GetTLI(*WriteoutF);
1117 NamedMDNode *CUNodes =
M->getNamedMetadata(
"llvm.dbg.cu");
1119 Builder.CreateRetVoid();
1126 {Builder.getPtrTy(), Builder.getInt32Ty(), Builder.getInt32Ty()},
1127 "start_file_args_ty");
1129 {Builder.getInt32Ty(), Builder.getInt32Ty(), Builder.getInt32Ty()},
1130 "emit_function_args_ty");
1131 auto *PtrTy = Builder.getPtrTy();
1135 {StartFileCallArgsTy, Builder.
getInt32Ty(), PtrTy, PtrTy},
"file_info");
1137 Constant *Zero32 = Builder.getInt32(0);
1139 Constant *TwoZero32s[] = {Zero32, Zero32};
1149 std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA);
1152 StartFileCallArgsTy,
1153 {Builder.CreateGlobalString(FilenameGcda),
1155 Builder.getInt32(CfgChecksum)});
1160 uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[
j]->getFuncChecksum();
1162 EmitFunctionCallArgsTy,
1163 {Builder.getInt32(j),
1164 Builder.getInt32(FuncChecksum),
1165 Builder.getInt32(CfgChecksum)}));
1175 int CountersSize = CountersBySP.
size();
1176 assert(CountersSize == (
int)EmitFunctionCallArgsArray.size() &&
1177 "Mismatched array size!");
1178 assert(CountersSize == (
int)EmitArcsCallArgsArray.
size() &&
1179 "Mismatched array size!");
1180 auto *EmitFunctionCallArgsArrayTy =
1183 *M, EmitFunctionCallArgsArrayTy,
true,
1186 EmitFunctionCallArgsArray),
1187 Twine(
"__llvm_internal_gcov_emit_function_args.") +
Twine(i));
1188 auto *EmitArcsCallArgsArrayTy =
1190 EmitFunctionCallArgsArrayGV->setUnnamedAddr(
1193 *M, EmitArcsCallArgsArrayTy,
true,
1196 Twine(
"__llvm_internal_gcov_emit_arcs_args.") +
Twine(i));
1201 {StartFileCallArgs, Builder.getInt32(CountersSize),
1203 EmitFunctionCallArgsArrayGV,
1206 EmitArcsCallArgsArrayTy, EmitArcsCallArgsArrayGV, TwoZero32s)}));
1210 if (FileInfos.
empty()) {
1211 Builder.CreateRetVoid();
1220 if ((int64_t)FileInfos.
size() > (int64_t)INT_MAX)
1221 FileInfos.
resize(INT_MAX);
1229 "__llvm_internal_gcov_emit_file_info");
1233 auto *FileLoopHeader =
1235 auto *CounterLoopHeader =
1241 Builder.CreateBr(FileLoopHeader);
1244 Builder.SetInsertPoint(FileLoopHeader);
1245 PHINode *
IV = Builder.CreatePHI(Builder.getInt32Ty(), 2,
1247 IV->addIncoming(Builder.getInt32(0), BB);
1248 auto *FileInfoPtr = Builder.CreateInBoundsGEP(
1249 FileInfoArrayTy, FileInfoArrayGV, {Builder.getInt32(0),
IV});
1250 auto *StartFileCallArgsPtr =
1251 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0,
"start_file_args");
1252 auto *StartFileCall = Builder.CreateCall(
1255 Builder.CreateStructGEP(StartFileCallArgsTy,
1256 StartFileCallArgsPtr, 0),
1259 Builder.CreateStructGEP(StartFileCallArgsTy,
1260 StartFileCallArgsPtr, 1),
1263 Builder.CreateStructGEP(StartFileCallArgsTy,
1264 StartFileCallArgsPtr, 2),
1266 if (
auto AK = TLI->getExtAttrForI32Param(
false))
1267 StartFileCall->addParamAttr(2, AK);
1269 FileInfoTy->getElementType(1),
1270 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1),
"num_ctrs");
1271 auto *EmitFunctionCallArgsArray =
1272 Builder.CreateLoad(FileInfoTy->getElementType(2),
1273 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2),
1274 "emit_function_args");
1275 auto *EmitArcsCallArgsArray = Builder.CreateLoad(
1276 FileInfoTy->getElementType(3),
1277 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3),
"emit_arcs_args");
1278 auto *EnterCounterLoopCond =
1279 Builder.CreateICmpSLT(Builder.getInt32(0),
NumCounters);
1280 Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch);
1282 Builder.SetInsertPoint(CounterLoopHeader);
1283 auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), 2,
1285 JV->addIncoming(Builder.getInt32(0), FileLoopHeader);
1286 auto *EmitFunctionCallArgsPtr = Builder.CreateInBoundsGEP(
1287 EmitFunctionCallArgsTy, EmitFunctionCallArgsArray, JV);
1288 auto *EmitFunctionCall = Builder.CreateCall(
1290 {Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(0),
1291 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1292 EmitFunctionCallArgsPtr, 0),
1294 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(1),
1295 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1296 EmitFunctionCallArgsPtr, 1),
1298 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
1299 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1300 EmitFunctionCallArgsPtr, 2),
1302 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
1303 EmitFunctionCall->addParamAttr(0, AK);
1304 EmitFunctionCall->addParamAttr(1, AK);
1305 EmitFunctionCall->addParamAttr(2, AK);
1307 auto *EmitArcsCallArgsPtr =
1308 Builder.CreateInBoundsGEP(EmitArcsCallArgsTy, EmitArcsCallArgsArray, JV);
1309 auto *EmitArcsCall = Builder.CreateCall(
1311 {Builder.CreateLoad(
1313 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0),
1317 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 1),
1319 if (
auto AK = TLI->getExtAttrForI32Param(
false))
1320 EmitArcsCall->addParamAttr(0, AK);
1321 auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1));
1322 auto *CounterLoopCond = Builder.CreateICmpSLT(NextJV,
NumCounters);
1323 Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch);
1324 JV->addIncoming(NextJV, CounterLoopHeader);
1326 Builder.SetInsertPoint(FileLoopLatch);
1327 Builder.CreateCall(SummaryInfo, {});
1328 Builder.CreateCall(EndFile, {});
1329 auto *NextIV = Builder.CreateAdd(
IV, Builder.getInt32(1),
"next_file_idx");
1330 auto *FileLoopCond =
1331 Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.
size()));
1332 Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB);
1333 IV->addIncoming(NextIV, FileLoopLatch);
1335 Builder.SetInsertPoint(ExitBB);
1336 Builder.CreateRetVoid();
1341Function *GCOVProfiler::insertReset(
1342 ArrayRef<std::pair<GlobalVariable *, MDNode *>> CountersBySP) {
1344 Function *ResetF =
M->getFunction(
"__llvm_gcov_reset");
1346 ResetF = createInternalFunction(FTy,
"__llvm_gcov_reset",
"_ZTSFvvE");
1354 for (
const auto &
I : CountersBySP) {
1358 GVTy->getNumElements() *
1359 GVTy->getElementType()->getScalarSizeInBits() / 8,
1365 Builder.CreateRetVoid();
1368 Builder.CreateRet(ConstantInt::get(RetTy, 0));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
Expand Atomic instructions
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides the interface for the GCOV style profiler pass.
static unsigned wordsOfString(StringRef s)
static bool functionHasLines(const Function &F, unsigned &EndLine)
static bool isUsingScopeBasedEH(Function &F)
static void dumpEdges(CFGMST< Edge, BBInfo > &MST, GCOVFunction &GF)
static BasicBlock * getInstrBB(CFGMST< Edge, BBInfo > &MST, Edge &E, const DenseSet< const BasicBlock * > &ExecBlocks)
static cl::opt< std::string > DefaultGCOVVersion("default-gcov-version", cl::init("0000"), cl::Hidden, cl::ValueRequired)
static SmallString< 128 > getFilename(const DIScope *SP, vfs::FileSystem &VFS)
Extract a filename for a DIScope.
static StringRef getFunctionName(const DISubprogram *SP)
static cl::opt< bool > AtomicCounter("gcov-atomic-counter", cl::Hidden, cl::desc("Make counter updates atomic"))
Module.h This file contains the declarations for the Module class.
#define INSTR_PROF_DATA_ALIGNMENT
static void addEdge(SmallVectorImpl< LazyCallGraph::Edge > &Edges, DenseMap< LazyCallGraph::Node *, int > &EdgeIndexMap, LazyCallGraph::Node &N, LazyCallGraph::Edge::Kind EK)
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
FunctionAnalysisManager FAM
std::pair< BasicBlock *, BasicBlock * > Edge
Provides some synthesis utilities to produce sequences of values.
Defines the virtual file system interface vfs::FileSystem.
static const uint32_t IV[8]
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Class to represent array types.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM Basic Block Representation.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
const Function * getParent() const
Return the enclosing method, or null if none.
const Instruction & back() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
An union-find based Minimum Spanning Tree for CFG.
Edge & addEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W)
const std::vector< std::unique_ptr< Edge > > & allEdges() const
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static Constant * getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList)
Create an "inbounds" getelementptr.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
uint64_t getDWOId() const
Base class for scope-like contexts.
StringRef getFilename() const
Subprogram description. Uses SubclassData1.
Implements a dense probed hash-table based set.
Represents either an error or a value T.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
static Function * createWithDefaultAttr(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Creates a function with some attributes recorded in llvm.module.flags and the LLVMContext applied.
Type * getReturnType() const
Returns the type of the ret val.
GCOVBlock - Collects block information.
GCOVFunction - Collects function information.
GCOVFunction(GCOVFile &file)
LLVM_ABI StringRef getFilename() const
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
@ DefaultVisibility
The GV is visible.
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ InternalLinkage
Rename collisions when linking (static functions).
Type * getValueType() const
MaybeAlign getAlign() const
Returns the alignment of the given variable.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
LLVM_ABI void setNoSanitizeMetadata()
Sets the nosanitize metadata on this instruction.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI void update(ArrayRef< uint8_t > Data)
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
const MDOperand & getOperand(unsigned I) const
LLVM_ABI StringRef getString() const
A Module instance is used to store all the information related to an LLVM module.
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI unsigned getNumOperands() const
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Type * getElementType(unsigned N) const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
LLVM Value Representation.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
A raw_ostream that writes to a file descriptor.
The virtual file system interface.
virtual bool exists(const Twine &Path)
Check whether Path exists.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
initializer< Ty > init(const Ty &Val)
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
NodeAddr< FuncNode * > Func
void write32(void *P, uint32_t V, endianness E)
uint32_t read32be(const void *P)
LLVM_ABI void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
hash_code hash_value(const FixedPointSemantics &Val)
LLVM_ABI unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)
Search for the specified successor of basic block BB and return its position in the terminator instru...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
LLVM_ABI std::string getInstrProfSectionName(InstrProfSectKind IPSK, Triple::ObjectFormatType OF, bool AddSegmentInfo=true)
Return the name of the profile section corresponding to IPSK.
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
If this edge is a critical edge, insert a new node to split the critical edge.
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
LLVM_ABI void setKCFIType(Module &M, Function &F, StringRef MangledType)
Sets the KCFI type for the function.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
This struct is a compact representation of a valid (non-zero power of two) alignment.
static LLVM_ABI GCOVOptions getDefault()
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.