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 {
266 for (uint32_t L : Lines)
270 GCOVLines(GCOVProfiler *
P, StringRef
F)
284 GCOVLines &getFile(StringRef
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) {
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;
452 std::vector<Regex> &Regexes) {
453 for (
Regex &Re : Regexes)
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()
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");
1145 std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA);
1148 StartFileCallArgsTy,
1149 {Builder.CreateGlobalString(FilenameGcda),
1151 Builder.getInt32(CfgChecksum)});
1156 uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[
j]->getFuncChecksum();
1158 EmitFunctionCallArgsTy,
1159 {Builder.getInt32(j),
1160 Builder.getInt32(FuncChecksum),
1161 Builder.getInt32(CfgChecksum)}));
1166 EmitArcsCallArgsTy, {Builder.getInt32(Arcs), GV}));
1169 int CountersSize = CountersBySP.
size();
1170 assert(CountersSize == (
int)EmitFunctionCallArgsArray.size() &&
1171 "Mismatched array size!");
1172 assert(CountersSize == (
int)EmitArcsCallArgsArray.
size() &&
1173 "Mismatched array size!");
1174 auto *EmitFunctionCallArgsArrayTy =
1177 *M, EmitFunctionCallArgsArrayTy,
true,
1180 EmitFunctionCallArgsArray),
1181 Twine(
"__llvm_internal_gcov_emit_function_args.") +
Twine(i));
1182 auto *EmitArcsCallArgsArrayTy =
1184 EmitFunctionCallArgsArrayGV->setUnnamedAddr(
1187 *M, EmitArcsCallArgsArrayTy,
true,
1190 Twine(
"__llvm_internal_gcov_emit_arcs_args.") +
Twine(i));
1194 FileInfoTy, {StartFileCallArgs, Builder.getInt32(CountersSize),
1195 EmitFunctionCallArgsArrayGV, EmitArcsCallArgsArrayGV}));
1199 if (FileInfos.empty()) {
1200 Builder.CreateRetVoid();
1209 if ((int64_t)FileInfos.size() > (int64_t)INT_MAX)
1210 FileInfos.
resize(INT_MAX);
1214 auto *FileInfoArrayTy =
ArrayType::get(FileInfoTy, FileInfos.size());
1218 "__llvm_internal_gcov_emit_file_info");
1222 auto *FileLoopHeader =
1224 auto *CounterLoopHeader =
1230 Builder.CreateBr(FileLoopHeader);
1233 Builder.SetInsertPoint(FileLoopHeader);
1234 PHINode *
IV = Builder.CreatePHI(Builder.getInt32Ty(), 2,
1236 IV->addIncoming(Builder.getInt32(0), BB);
1237 auto *FileInfoPtr = Builder.CreateInBoundsGEP(
1238 FileInfoArrayTy, FileInfoArrayGV, {Builder.getInt32(0),
IV});
1239 auto *StartFileCallArgsPtr =
1240 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0,
"start_file_args");
1241 auto *StartFileCall = Builder.CreateCall(
1244 Builder.CreateStructGEP(StartFileCallArgsTy,
1245 StartFileCallArgsPtr, 0),
1248 Builder.CreateStructGEP(StartFileCallArgsTy,
1249 StartFileCallArgsPtr, 1),
1252 Builder.CreateStructGEP(StartFileCallArgsTy,
1253 StartFileCallArgsPtr, 2),
1255 if (
auto AK = TLI->getExtAttrForI32Param(
false))
1256 StartFileCall->addParamAttr(2, AK);
1258 FileInfoTy->getElementType(1),
1259 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1),
"num_ctrs");
1260 auto *EmitFunctionCallArgsArray =
1261 Builder.CreateLoad(FileInfoTy->getElementType(2),
1262 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2),
1263 "emit_function_args");
1264 auto *EmitArcsCallArgsArray = Builder.CreateLoad(
1265 FileInfoTy->getElementType(3),
1266 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3),
"emit_arcs_args");
1267 auto *EnterCounterLoopCond =
1268 Builder.CreateICmpSLT(Builder.getInt32(0),
NumCounters);
1269 Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch);
1271 Builder.SetInsertPoint(CounterLoopHeader);
1272 auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), 2,
1274 JV->addIncoming(Builder.getInt32(0), FileLoopHeader);
1275 auto *EmitFunctionCallArgsPtr = Builder.CreateInBoundsGEP(
1276 EmitFunctionCallArgsTy, EmitFunctionCallArgsArray, JV);
1277 auto *EmitFunctionCall = Builder.CreateCall(
1279 {Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(0),
1280 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1281 EmitFunctionCallArgsPtr, 0),
1283 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(1),
1284 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1285 EmitFunctionCallArgsPtr, 1),
1287 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
1288 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1289 EmitFunctionCallArgsPtr, 2),
1291 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
1292 EmitFunctionCall->addParamAttr(0, AK);
1293 EmitFunctionCall->addParamAttr(1, AK);
1294 EmitFunctionCall->addParamAttr(2, AK);
1296 auto *EmitArcsCallArgsPtr =
1297 Builder.CreateInBoundsGEP(EmitArcsCallArgsTy, EmitArcsCallArgsArray, JV);
1298 auto *EmitArcsCall = Builder.CreateCall(
1300 {Builder.CreateLoad(
1302 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0),
1306 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 1),
1308 if (
auto AK = TLI->getExtAttrForI32Param(
false))
1309 EmitArcsCall->addParamAttr(0, AK);
1310 auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1));
1311 auto *CounterLoopCond = Builder.CreateICmpSLT(NextJV,
NumCounters);
1312 Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch);
1313 JV->addIncoming(NextJV, CounterLoopHeader);
1315 Builder.SetInsertPoint(FileLoopLatch);
1316 Builder.CreateCall(SummaryInfo, {});
1317 Builder.CreateCall(EndFile, {});
1318 auto *NextIV = Builder.CreateAdd(
IV, Builder.getInt32(1),
"next_file_idx");
1319 auto *FileLoopCond =
1320 Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.size()));
1321 Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB);
1322 IV->addIncoming(NextIV, FileLoopLatch);
1324 Builder.SetInsertPoint(ExitBB);
1325 Builder.CreateRetVoid();
1330Function *GCOVProfiler::insertReset(
1331 ArrayRef<std::pair<GlobalVariable *, MDNode *>> CountersBySP) {
1333 Function *ResetF =
M->getFunction(
"__llvm_gcov_reset");
1335 ResetF = createInternalFunction(FTy,
"__llvm_gcov_reset",
"_ZTSFvvE");
1343 for (
const auto &
I : CountersBySP) {
1347 GVTy->getNumElements() *
1348 GVTy->getElementType()->getScalarSizeInBits() / 8,
1354 Builder.CreateRetVoid();
1357 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.
static constexpr StringLiteral Filename
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...
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
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.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
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 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.
LLVM_ABI bool SplitIndirectBrCriticalEdges(Function &F, bool IgnoreBlocksWithoutPHI, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr, DomTreeUpdater *DTU=nullptr)
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
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 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.
LLVM_ABI Error write(MCStreamer &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue)
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.