52#define DEBUG_TYPE "insert-gcov-profiling"
66 return (s.
size() / 4) + 2;
74 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
75 Options.Atomic = Opts.gcov_atomic_counter;
77 if (Opts.default_gcov_version.size() != 4) {
79 Opts.default_gcov_version);
81 memcpy(
Options.Version, Opts.default_gcov_version.data(), 4);
91 : GCOVProfiler(
GCOVOptions::getDefault(), *
vfs::getRealFileSystem()) {}
95 runOnModule(
Module &M, function_ref<BlockFrequencyInfo *(
Function &
F)> GetBFI,
96 function_ref<BranchProbabilityInfo *(
Function &
F)> GetBPI,
97 std::function<
const TargetLibraryInfo &(
Function &
F)> GetTLI);
99 void write(uint32_t i) {
107 os->write_zeros(4 - s.
size() % 4);
109 void writeBytes(
const char *Bytes,
int Size) { os->write(Bytes,
Size); }
110 vfs::FileSystem &getVirtualFileSystem()
const {
return VFS; }
115 emitProfileNotes(NamedMDNode *CUNode,
bool HasExecOrFork,
116 function_ref<BlockFrequencyInfo *(
Function &
F)> GetBFI,
117 function_ref<BranchProbabilityInfo *(
Function &
F)> GetBPI,
118 function_ref<
const TargetLibraryInfo &(
Function &
F)> GetTLI);
120 Function *createInternalFunction(FunctionType *FTy, StringRef Name,
121 StringRef MangledType =
"");
123 void emitGlobalConstructor(
124 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
125 void emitModuleInitFunctionPtrs(
126 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
128 bool isFunctionInstrumented(
const Function &
F);
129 std::vector<Regex> createRegexesFromString(StringRef RegexesStr);
130 static bool doesFilenameMatchARegex(StringRef
Filename,
131 std::vector<Regex> &Regexes);
134 FunctionCallee getStartFileFunc(
const TargetLibraryInfo *TLI);
135 FunctionCallee getEmitFunctionFunc(
const TargetLibraryInfo *TLI);
136 FunctionCallee getEmitArcsFunc(
const TargetLibraryInfo *TLI);
137 FunctionCallee getSummaryInfoFunc();
138 FunctionCallee getEndFileFunc();
143 insertCounterWriteout(
ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
146 bool AddFlushBeforeForkAndExec();
148 enum class GCovFileType { GCNO, GCDA };
149 std::string mangleName(
const DICompileUnit *CU, GCovFileType FileType);
160 std::function<
const TargetLibraryInfo &(
Function &
F)> GetTLI;
161 LLVMContext *Ctx =
nullptr;
163 std::vector<Regex> FilterRe;
164 std::vector<Regex> ExcludeRe;
165 DenseSet<const BasicBlock *> ExecBlocks;
166 StringMap<bool> InstrumentedFiles;
167 vfs::FileSystem &VFS;
175 BBInfo(
unsigned Index) : Group(this),
Index(
Index) {}
176 std::string infoString()
const {
177 return (Twine(
"Index=") + Twine(Index)).str();
188 uint32_t SrcNumber, DstNumber;
190 bool Removed =
false;
191 bool IsCritical =
false;
193 Edge(
const BasicBlock *Src,
const BasicBlock *Dest,
uint64_t W = 1)
194 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
197 std::string infoString()
const {
198 return (Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
199 (IsCritical ?
"c" :
" ") +
" W=" + Twine(Weight))
206 if (!SP->getLinkageName().empty())
207 return SP->getLinkageName();
208 return SP->getName();
231 GCOVRecord(GCOVProfiler *
P) :
P(
P) {}
233 void write(uint32_t i) {
P->write(i); }
235 void writeBytes(
const char *Bytes,
int Size) {
P->writeBytes(Bytes,
Size); }
244 class GCOVLines :
public GCOVRecord {
248 void addLine(uint32_t Line) {
249 assert(Line != 0 &&
"Line zero is not a valid real line number.");
250 Lines.push_back(Line);
253 uint32_t length()
const {
260 for (uint32_t L : Lines)
264 GCOVLines(GCOVProfiler *
P, StringRef
F)
269 SmallVector<uint32_t, 32>
Lines;
278 GCOVLines &getFile(StringRef
Filename) {
285 OutEdges.emplace_back(&
Successor, Flags);
291 for (
auto &L : Lines)
298 for (
auto &L : Lines)
316 friend class GCOVFunction;
330 unsigned EndLine, uint32_t Ident,
int Version)
331 : GCOVRecord(
P),
SP(
SP), EndLine(EndLine), Ident(Ident),
335 for (BasicBlock &BB : *
F)
336 Blocks.insert(std::make_pair(&BB, GCOVBlock(
P, i++)));
338 std::string FunctionNameAndLine;
339 raw_string_ostream FNLOS(FunctionNameAndLine);
341 FuncChecksum =
hash_value(FunctionNameAndLine);
344 GCOVBlock &getBlock(
const BasicBlock *BB) {
345 return Blocks.find(
const_cast<BasicBlock *
>(BB))->second;
348 GCOVBlock &getEntryBlock() {
return EntryBlock; }
349 GCOVBlock &getReturnBlock() {
353 uint32_t getFuncChecksum()
const {
357 void writeOut(uint32_t CfgChecksum) {
381 write(Blocks.size() + 2);
385 const uint32_t Outgoing = EntryBlock.OutEdges.size();
388 write(Outgoing * 2 + 1);
389 write(EntryBlock.Number);
390 for (
const auto &
E : EntryBlock.OutEdges) {
395 for (
auto &It : Blocks) {
396 const GCOVBlock &
Block = It.second;
397 if (
Block.OutEdges.empty())
continue;
402 for (
const auto &
E :
Block.OutEdges) {
409 for (
auto &It : Blocks)
410 It.second.writeOut();
414 const DISubprogram *
SP;
417 uint32_t FuncChecksum;
419 MapVector<BasicBlock *, GCOVBlock> Blocks;
420 GCOVBlock EntryBlock;
421 GCOVBlock ReturnBlock;
427std::vector<Regex> GCOVProfiler::createRegexesFromString(
StringRef RegexesStr) {
428 std::vector<Regex> Regexes;
429 while (!RegexesStr.
empty()) {
430 std::pair<StringRef, StringRef> HeadTail = RegexesStr.
split(
';');
431 if (!HeadTail.first.empty()) {
432 Regex Re(HeadTail.first);
434 if (!Re.isValid(Err)) {
435 Ctx->emitError(
Twine(
"Regex ") + HeadTail.first +
436 " is not valid: " + Err);
438 Regexes.emplace_back(std::move(Re));
440 RegexesStr = HeadTail.second;
446 std::vector<Regex> &Regexes) {
447 for (
Regex &Re : Regexes)
453bool GCOVProfiler::isFunctionInstrumented(
const Function &
F) {
454 if (FilterRe.empty() && ExcludeRe.empty()) {
458 auto It = InstrumentedFiles.find(
Filename);
459 if (It != InstrumentedFiles.end()) {
469 if (VFS.getRealPath(
Filename, RealPath)) {
473 RealFilename = RealPath;
476 bool ShouldInstrument;
477 if (FilterRe.empty()) {
478 ShouldInstrument = !doesFilenameMatchARegex(RealFilename, ExcludeRe);
479 }
else if (ExcludeRe.empty()) {
480 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe);
482 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe) &&
483 !doesFilenameMatchARegex(RealFilename, ExcludeRe);
485 InstrumentedFiles[
Filename] = ShouldInstrument;
486 return ShouldInstrument;
490 GCovFileType OutputType) {
491 bool Notes = OutputType == GCovFileType::GCNO;
493 if (
NamedMDNode *GCov =
M->getNamedMetadata(
"llvm.gcov")) {
494 for (
int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
496 bool ThreeElement =
N->getNumOperands() == 3;
497 if (!ThreeElement &&
N->getNumOperands() != 2)
507 if (!NotesFile || !DataFile)
509 return std::string(Notes ? NotesFile->
getString()
528 return std::string(FName);
531 return std::string(CurPath);
534bool GCOVProfiler::runOnModule(
539 this->GetTLI = std::move(GetTLI);
540 Ctx = &
M.getContext();
542 NamedMDNode *CUNode =
M.getNamedMetadata(
"llvm.dbg.cu");
546 bool HasExecOrFork = AddFlushBeforeForkAndExec();
548 FilterRe = createRegexesFromString(
Options.Filter);
549 ExcludeRe = createRegexesFromString(
Options.Exclude);
550 emitProfileNotes(CUNode, HasExecOrFork, GetBFI, GetBPI, this->GetTLI);
557 GCOVProfiler Profiler(GCOVOpts, *VFS);
571 if (!Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI))
581 for (
const auto &BB :
F) {
582 for (
const auto &
I : BB) {
588 if (
Loc.getLine() == 0)
continue;
589 EndLine = std::max(EndLine,
Loc.getLine());
598 if (!
F.hasPersonalityFn())
return false;
604bool GCOVProfiler::AddFlushBeforeForkAndExec() {
608 for (
auto &
F :
M->functions()) {
609 TLI = TLI ==
nullptr ? &GetTLI(
F) : TLI;
612 if (
Function *Callee = CI->getCalledFunction()) {
614 if (LF != NotLibFunc) {
615 if (LF == LibFunc_fork) {
619 }
else if (LF == LibFunc_execl || LF == LibFunc_execle ||
620 LF == LibFunc_execlp || LF == LibFunc_execv ||
621 LF == LibFunc_execvp || LF == LibFunc_execve ||
622 LF == LibFunc_execvpe || LF == LibFunc_execvP) {
631 for (
auto *
F : Forks) {
641 F->setCalledFunction(GCOVFork);
658 for (
auto *
E : Execs) {
667 M->getOrInsertFunction(
"llvm_writeout_files", FTy);
668 Builder.CreateCall(WriteoutF);
671 Builder.SetInsertPoint(&*NextInst);
674 FunctionCallee ResetF =
M->getOrInsertFunction(
"llvm_reset_counters", FTy);
675 Builder.CreateCall(ResetF)->setDebugLoc(
Loc);
676 ExecBlocks.insert(Parent);
681 return !Forks.
empty() || !Execs.empty();
686 if (
E.InMST ||
E.Removed)
692 if (SrcBB ==
nullptr)
694 if (DestBB ==
nullptr)
709 return CanInstrument(SrcBB);
711 return CanInstrument(DestBB);
721 MST.
addEdge(SrcBB, InstrBB, 0);
722 MST.
addEdge(InstrBB, DestBB, 0).InMST =
true;
725 return CanInstrument(InstrBB);
732 GCOVBlock &Src =
E.SrcBB ? GF.getBlock(
E.SrcBB) : GF.getEntryBlock();
733 GCOVBlock &Dst =
E.DestBB ? GF.getBlock(
E.DestBB) : GF.getReturnBlock();
734 dbgs() <<
" Edge " << ID++ <<
": " << Src.Number <<
"->" << Dst.Number
735 <<
E.infoString() <<
"\n";
740bool GCOVProfiler::emitProfileNotes(
746 uint8_t c3 =
Options.Version[0];
747 uint8_t c2 =
Options.Version[1];
748 uint8_t c1 =
Options.Version[2];
749 Version = c3 >=
'A' ? (c3 -
'A') * 100 + (c2 -
'0') * 10 + c1 -
'0'
750 : (c3 -
'0') * 10 + c1 -
'0';
755 memcpy(
Options.Version,
"B11*", 4);
758 bool EmitGCDA =
Options.EmitData;
770 std::vector<uint8_t> EdgeDestinations;
775 unsigned FunctionIdent = 0;
776 for (
auto &
F :
M->functions()) {
784 if (
F.hasFnAttribute(llvm::Attribute::NoProfile))
786 if (
F.hasFnAttribute(llvm::Attribute::SkipProfile))
791 uint32_t
Line =
SP->getLine();
807 auto &
E = *MST.allEdges()[
I];
816 Funcs.push_back(std::make_unique<GCOVFunction>(
this, &
F, SP, EndLine,
823 return E->Removed || (!E->InMST && !E->Place);
825 const size_t Measured =
826 std::stable_partition(
827 MST.allEdges().begin(), MST.allEdges().end(),
828 [](std::unique_ptr<Edge> &
E) { return E->Place; }) -
829 MST.allEdges().begin();
831 Edge &
E = *MST.allEdges()[
I];
833 E.SrcBB ?
Func.getBlock(
E.SrcBB) :
Func.getEntryBlock();
835 E.DestBB ?
Func.getBlock(
E.DestBB) :
Func.getReturnBlock();
836 E.SrcNumber = Src.Number;
837 E.DstNumber = Dst.Number;
840 MST.allEdges().begin(), MST.allEdges().begin() + Measured,
841 [](
const std::unique_ptr<Edge> &L,
const std::unique_ptr<Edge> &R) {
842 return L->SrcNumber != R->SrcNumber ? L->SrcNumber < R->SrcNumber
843 : L->DstNumber < R->DstNumber;
848 E.SrcBB ?
Func.getBlock(
E.SrcBB) :
Func.getEntryBlock();
850 E.DestBB ?
Func.getBlock(
E.DestBB) :
Func.getReturnBlock();
855 if (!
SP->isArtificial())
856 Func.getBlock(&EntryBlock).getFile(
Filename).addLine(Line);
860 for (
auto &GB :
Func.Blocks) {
862 auto &
Block = GB.second;
863 for (
auto Succ :
Block.OutEdges) {
864 uint32_t
Idx = Succ.first->Number;
865 do EdgeDestinations.push_back(Idx & 255);
866 while ((Idx >>= 8) > 0);
869 for (
const auto &
I : BB) {
875 if (
Loc.getLine() == 0 ||
Loc.isImplicitCode())
878 if (Line ==
Loc.getLine())
continue;
897 Counters->setSection(
"__llvm_gcov_ctr_section");
901 const Edge &
E = *MST.allEdges()[
I];
903 Value *
V = Builder.CreateConstInBoundsGEP2_64(
914 Builder.CreateLoad(Builder.getInt64Ty(), V,
"gcov_ctr");
916 Value *NewCount = Builder.CreateAdd(OldCount, Builder.getInt64(1));
917 Inst = Builder.CreateStore(NewCount, V);
926 JC.
update(EdgeDestinations);
927 uint32_t Stamp = JC.
getCRC();
936 Twine(
"failed to open coverage notes file for writing: ") +
942 out.write(
"gcno", 4);
945 out.write(
"oncg", 4);
953 for (
auto &Func : Funcs)
954 Func->writeOut(Stamp);
964 emitModuleInitFunctionPtrs(CountersBySP);
966 emitGlobalConstructor(CountersBySP);
979 F->addFnAttr(Attribute::NoUnwind);
981 F->addFnAttr(Attribute::NoRedZone);
982 if (!MangledType.
empty())
987void GCOVProfiler::emitGlobalConstructor(
988 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
989 Function *WriteoutF = insertCounterWriteout(CountersBySP);
990 Function *ResetF = insertReset(CountersBySP);
996 Function *
F = createInternalFunction(FTy,
"__llvm_gcov_init",
"_ZTSFvvE");
997 F->addFnAttr(Attribute::NoInline);
1008 FunctionCallee GCOVInit =
M->getOrInsertFunction(
"llvm_gcov_init", FTy);
1009 Builder.CreateCall(GCOVInit, {WriteoutF, ResetF});
1010 Builder.CreateRetVoid();
1015void GCOVProfiler::emitModuleInitFunctionPtrs(
1016 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
1017 Function *WriteoutF = insertCounterWriteout(CountersBySP);
1018 Function *ResetF = insertReset(CountersBySP);
1024 auto &Ctx =
M->getContext();
1026 Type *InitFuncDataTy[] = {
1027#define COVINIT_FUNC(Type, LLVMType, Name, Init) LLVMType,
1034#define COVINIT_FUNC(Type, LLVMType, Name, Init) Init,
1040 "__llvm_covinit_functions");
1044 IPSK_covinit,
M->getTargetTriple().getObjectFormat()));
1046 CovInitGV->setConstant(
true);
1056 return M->getOrInsertFunction(
"llvm_gcda_start_file", FTy,
1067 return M->getOrInsertFunction(
"llvm_gcda_emit_function", FTy,
1077 return M->getOrInsertFunction(
"llvm_gcda_emit_arcs", FTy,
1083 return M->getOrInsertFunction(
"llvm_gcda_summary_info", FTy);
1088 return M->getOrInsertFunction(
"llvm_gcda_end_file", FTy);
1091Function *GCOVProfiler::insertCounterWriteout(
1092 ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
1094 Function *WriteoutF =
M->getFunction(
"__llvm_gcov_writeout");
1097 createInternalFunction(WriteoutFTy,
"__llvm_gcov_writeout",
"_ZTSFvvE");
1098 WriteoutF->
addFnAttr(Attribute::NoInline);
1103 auto *TLI = &GetTLI(*WriteoutF);
1111 NamedMDNode *CUNodes =
M->getNamedMetadata(
"llvm.dbg.cu");
1113 Builder.CreateRetVoid();
1120 {Builder.getPtrTy(), Builder.getInt32Ty(), Builder.getInt32Ty()},
1121 "start_file_args_ty");
1123 {Builder.getInt32Ty(), Builder.getInt32Ty(), Builder.getInt32Ty()},
1124 "emit_function_args_ty");
1125 auto *PtrTy = Builder.getPtrTy();
1129 {StartFileCallArgsTy, Builder.
getInt32Ty(), PtrTy, PtrTy},
"file_info");
1139 std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA);
1142 StartFileCallArgsTy,
1143 {Builder.CreateGlobalString(FilenameGcda),
1145 Builder.getInt32(CfgChecksum)});
1150 uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[
j]->getFuncChecksum();
1152 EmitFunctionCallArgsTy,
1153 {Builder.getInt32(j),
1154 Builder.getInt32(FuncChecksum),
1155 Builder.getInt32(CfgChecksum)}));
1160 EmitArcsCallArgsTy, {Builder.getInt32(Arcs), GV}));
1163 int CountersSize = CountersBySP.
size();
1164 assert(CountersSize == (
int)EmitFunctionCallArgsArray.size() &&
1165 "Mismatched array size!");
1166 assert(CountersSize == (
int)EmitArcsCallArgsArray.
size() &&
1167 "Mismatched array size!");
1168 auto *EmitFunctionCallArgsArrayTy =
1171 *M, EmitFunctionCallArgsArrayTy,
true,
1174 EmitFunctionCallArgsArray),
1175 Twine(
"__llvm_internal_gcov_emit_function_args.") +
Twine(i));
1176 auto *EmitArcsCallArgsArrayTy =
1178 EmitFunctionCallArgsArrayGV->setUnnamedAddr(
1181 *M, EmitArcsCallArgsArrayTy,
true,
1184 Twine(
"__llvm_internal_gcov_emit_arcs_args.") +
Twine(i));
1188 FileInfoTy, {StartFileCallArgs, Builder.getInt32(CountersSize),
1189 EmitFunctionCallArgsArrayGV, EmitArcsCallArgsArrayGV}));
1193 if (FileInfos.empty()) {
1194 Builder.CreateRetVoid();
1203 if ((int64_t)FileInfos.size() > (int64_t)INT_MAX)
1204 FileInfos.
resize(INT_MAX);
1208 auto *FileInfoArrayTy =
ArrayType::get(FileInfoTy, FileInfos.size());
1212 "__llvm_internal_gcov_emit_file_info");
1216 auto *FileLoopHeader =
1218 auto *CounterLoopHeader =
1224 Builder.CreateBr(FileLoopHeader);
1227 Builder.SetInsertPoint(FileLoopHeader);
1228 PHINode *
IV = Builder.CreatePHI(Builder.getInt32Ty(), 2,
1230 IV->addIncoming(Builder.getInt32(0), BB);
1231 auto *FileInfoPtr = Builder.CreateInBoundsGEP(
1232 FileInfoArrayTy, FileInfoArrayGV, {Builder.getInt32(0),
IV});
1233 auto *StartFileCallArgsPtr =
1234 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0,
"start_file_args");
1235 auto *StartFileCall = Builder.CreateCall(
1238 Builder.CreateStructGEP(StartFileCallArgsTy,
1239 StartFileCallArgsPtr, 0),
1242 Builder.CreateStructGEP(StartFileCallArgsTy,
1243 StartFileCallArgsPtr, 1),
1246 Builder.CreateStructGEP(StartFileCallArgsTy,
1247 StartFileCallArgsPtr, 2),
1249 if (
auto AK = TLI->getExtAttrForI32Param(
false))
1250 StartFileCall->addParamAttr(2, AK);
1251 auto *NumCounters = Builder.CreateLoad(
1252 FileInfoTy->getElementType(1),
1253 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1),
"num_ctrs");
1254 auto *EmitFunctionCallArgsArray =
1255 Builder.CreateLoad(FileInfoTy->getElementType(2),
1256 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2),
1257 "emit_function_args");
1258 auto *EmitArcsCallArgsArray = Builder.CreateLoad(
1259 FileInfoTy->getElementType(3),
1260 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3),
"emit_arcs_args");
1261 auto *EnterCounterLoopCond =
1262 Builder.CreateICmpSLT(Builder.getInt32(0), NumCounters);
1263 Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch);
1265 Builder.SetInsertPoint(CounterLoopHeader);
1266 auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), 2,
1268 JV->addIncoming(Builder.getInt32(0), FileLoopHeader);
1269 auto *EmitFunctionCallArgsPtr = Builder.CreateInBoundsGEP(
1270 EmitFunctionCallArgsTy, EmitFunctionCallArgsArray, JV);
1271 auto *EmitFunctionCall = Builder.CreateCall(
1273 {Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(0),
1274 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1275 EmitFunctionCallArgsPtr, 0),
1277 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(1),
1278 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1279 EmitFunctionCallArgsPtr, 1),
1281 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
1282 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1283 EmitFunctionCallArgsPtr, 2),
1285 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
1286 EmitFunctionCall->addParamAttr(0, AK);
1287 EmitFunctionCall->addParamAttr(1, AK);
1288 EmitFunctionCall->addParamAttr(2, AK);
1290 auto *EmitArcsCallArgsPtr =
1291 Builder.CreateInBoundsGEP(EmitArcsCallArgsTy, EmitArcsCallArgsArray, JV);
1292 auto *EmitArcsCall = Builder.CreateCall(
1294 {Builder.CreateLoad(
1296 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0),
1300 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 1),
1302 if (
auto AK = TLI->getExtAttrForI32Param(
false))
1303 EmitArcsCall->addParamAttr(0, AK);
1304 auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1));
1305 auto *CounterLoopCond = Builder.CreateICmpSLT(NextJV, NumCounters);
1306 Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch);
1307 JV->addIncoming(NextJV, CounterLoopHeader);
1309 Builder.SetInsertPoint(FileLoopLatch);
1310 Builder.CreateCall(SummaryInfo, {});
1311 Builder.CreateCall(EndFile, {});
1312 auto *NextIV = Builder.CreateAdd(
IV, Builder.getInt32(1),
"next_file_idx");
1313 auto *FileLoopCond =
1314 Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.size()));
1315 Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB);
1316 IV->addIncoming(NextIV, FileLoopLatch);
1318 Builder.SetInsertPoint(ExitBB);
1319 Builder.CreateRetVoid();
1324Function *GCOVProfiler::insertReset(
1325 ArrayRef<std::pair<GlobalVariable *, MDNode *>> CountersBySP) {
1327 Function *ResetF =
M->getFunction(
"__llvm_gcov_reset");
1329 ResetF = createInternalFunction(FTy,
"__llvm_gcov_reset",
"_ZTSFvvE");
1337 for (
const auto &
I : CountersBySP) {
1341 GVTy->getNumElements() *
1342 GVTy->getElementType()->getScalarSizeInBits() / 8,
1348 Builder.CreateRetVoid();
1351 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void writeString(raw_ostream &OS, StringRef S)
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 SmallString< 128 > getFilename(const DIScope *SP, vfs::FileSystem &VFS)
Extract a filename for a DIScope.
static StringRef getFunctionName(const DISubprogram *SP)
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.
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(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object 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.
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
Check if the string is empty.
constexpr size_t size() const
Get the string size.
constexpr const char * data() const
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
LibFunc getLibFunc(StringRef funcName) 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.
@ BasicBlock
Various leaf nodes.
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)
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.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI Error write(DWPWriter &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue, raw_pwrite_stream *OS=nullptr)
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.