51#define DEBUG_TYPE "insert-gcov-profiling"
67 cl::desc(
"Make counter updates atomic"));
72 return (s.
size() / 4) + 2;
95 GCOVProfiler() : GCOVProfiler(
GCOVOptions::getDefault()) {}
98 runOnModule(
Module &M, function_ref<BlockFrequencyInfo *(Function &
F)> GetBFI,
99 function_ref<BranchProbabilityInfo *(Function &
F)> GetBPI,
100 std::function<
const TargetLibraryInfo &(Function &
F)> GetTLI);
102 void write(uint32_t i) {
107 void writeString(StringRef s) {
110 os->write_zeros(4 - s.
size() % 4);
112 void writeBytes(
const char *Bytes,
int Size) { os->write(Bytes,
Size); }
117 emitProfileNotes(NamedMDNode *CUNode,
bool HasExecOrFork,
118 function_ref<BlockFrequencyInfo *(Function &
F)> GetBFI,
119 function_ref<BranchProbabilityInfo *(Function &
F)> GetBPI,
120 function_ref<
const TargetLibraryInfo &(Function &
F)> GetTLI);
122 Function *createInternalFunction(FunctionType *FTy, StringRef Name,
123 StringRef MangledType =
"");
125 void emitGlobalConstructor(
126 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
127 void emitModuleInitFunctionPtrs(
128 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
130 bool isFunctionInstrumented(
const Function &
F);
131 std::vector<Regex> createRegexesFromString(StringRef RegexesStr);
132 static bool doesFilenameMatchARegex(StringRef Filename,
133 std::vector<Regex> &Regexes);
136 FunctionCallee getStartFileFunc(
const TargetLibraryInfo *TLI);
137 FunctionCallee getEmitFunctionFunc(
const TargetLibraryInfo *TLI);
138 FunctionCallee getEmitArcsFunc(
const TargetLibraryInfo *TLI);
139 FunctionCallee getSummaryInfoFunc();
140 FunctionCallee getEndFileFunc();
145 insertCounterWriteout(
ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
148 bool AddFlushBeforeForkAndExec();
150 enum class GCovFileType { GCNO, GCDA };
151 std::string mangleName(
const DICompileUnit *CU, GCovFileType FileType);
162 std::function<
const TargetLibraryInfo &(
Function &
F)> GetTLI;
163 LLVMContext *Ctx =
nullptr;
165 std::vector<Regex> FilterRe;
166 std::vector<Regex> ExcludeRe;
167 DenseSet<const BasicBlock *> ExecBlocks;
168 StringMap<bool> InstrumentedFiles;
176 BBInfo(
unsigned Index) : Group(this),
Index(
Index) {}
177 std::string infoString()
const {
178 return (Twine(
"Index=") + Twine(Index)).str();
189 uint32_t SrcNumber, DstNumber;
191 bool Removed =
false;
192 bool IsCritical =
false;
194 Edge(
const BasicBlock *Src,
const BasicBlock *Dest, uint64_t W = 1)
195 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
198 std::string infoString()
const {
199 return (Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
200 (IsCritical ?
"c" :
" ") +
" W=" + Twine(Weight))
207 if (!SP->getLinkageName().empty())
208 return SP->getLinkageName();
209 return SP->getName();
232 GCOVRecord(GCOVProfiler *
P) :
P(
P) {}
234 void write(uint32_t i) {
P->write(i); }
235 void writeString(StringRef s) {
P->writeString(s); }
236 void writeBytes(
const char *Bytes,
int Size) {
P->writeBytes(Bytes,
Size); }
245 class GCOVLines :
public GCOVRecord {
249 void addLine(uint32_t Line) {
250 assert(Line != 0 &&
"Line zero is not a valid real line number.");
251 Lines.push_back(Line);
254 uint32_t length()
const {
260 writeString(Filename);
261 for (uint32_t L : Lines)
265 GCOVLines(GCOVProfiler *
P, StringRef
F)
279 GCOVLines &getFile(StringRef Filename) {
280 if (
Lines.empty() ||
Lines.back().getFilename() != Filename)
281 Lines.emplace_back(
P, Filename);
286 OutEdges.emplace_back(&
Successor, Flags);
292 for (
auto &L : Lines)
299 for (
auto &L : Lines)
317 friend class GCOVFunction;
330 GCOVFunction(GCOVProfiler *
P, Function *
F,
const DISubprogram *SP,
331 unsigned EndLine, uint32_t Ident,
int Version)
332 : GCOVRecord(
P),
SP(
SP), EndLine(EndLine), Ident(Ident),
336 for (BasicBlock &BB : *
F)
337 Blocks.insert(std::make_pair(&BB, GCOVBlock(
P, i++)));
339 std::string FunctionNameAndLine;
340 raw_string_ostream FNLOS(FunctionNameAndLine);
342 FuncChecksum =
hash_value(FunctionNameAndLine);
345 GCOVBlock &getBlock(
const BasicBlock *BB) {
346 return Blocks.find(
const_cast<BasicBlock *
>(BB))->second;
349 GCOVBlock &getEntryBlock() {
return EntryBlock; }
350 GCOVBlock &getReturnBlock() {
354 uint32_t getFuncChecksum()
const {
358 void writeOut(uint32_t CfgChecksum) {
371 writeString(Filename);
382 write(Blocks.size() + 2);
386 const uint32_t Outgoing = EntryBlock.OutEdges.size();
389 write(Outgoing * 2 + 1);
390 write(EntryBlock.Number);
391 for (
const auto &
E : EntryBlock.OutEdges) {
396 for (
auto &It : Blocks) {
397 const GCOVBlock &
Block = It.second;
398 if (
Block.OutEdges.empty())
continue;
403 for (
const auto &
E :
Block.OutEdges) {
410 for (
auto &It : Blocks)
411 It.second.writeOut();
415 const DISubprogram *
SP;
418 uint32_t FuncChecksum;
420 MapVector<BasicBlock *, GCOVBlock> Blocks;
421 GCOVBlock EntryBlock;
422 GCOVBlock ReturnBlock;
428std::vector<Regex> GCOVProfiler::createRegexesFromString(
StringRef RegexesStr) {
429 std::vector<Regex> Regexes;
430 while (!RegexesStr.
empty()) {
431 std::pair<StringRef, StringRef> HeadTail = RegexesStr.
split(
';');
432 if (!HeadTail.first.empty()) {
433 Regex Re(HeadTail.first);
435 if (!Re.isValid(Err)) {
436 Ctx->emitError(
Twine(
"Regex ") + HeadTail.first +
437 " is not valid: " + Err);
439 Regexes.emplace_back(std::move(Re));
441 RegexesStr = HeadTail.second;
446bool GCOVProfiler::doesFilenameMatchARegex(
StringRef Filename,
447 std::vector<Regex> &Regexes) {
448 for (
Regex &Re : Regexes)
449 if (Re.match(Filename))
454bool GCOVProfiler::isFunctionInstrumented(
const Function &
F) {
455 if (FilterRe.empty() && ExcludeRe.empty()) {
459 auto It = InstrumentedFiles.find(Filename);
460 if (It != InstrumentedFiles.end()) {
474 RealFilename = RealPath;
477 bool ShouldInstrument;
478 if (FilterRe.empty()) {
479 ShouldInstrument = !doesFilenameMatchARegex(RealFilename, ExcludeRe);
480 }
else if (ExcludeRe.empty()) {
481 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe);
483 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe) &&
484 !doesFilenameMatchARegex(RealFilename, ExcludeRe);
486 InstrumentedFiles[
Filename] = ShouldInstrument;
487 return ShouldInstrument;
491 GCovFileType OutputType) {
492 bool Notes = OutputType == GCovFileType::GCNO;
494 if (
NamedMDNode *GCov =
M->getNamedMetadata(
"llvm.gcov")) {
495 for (
int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
497 bool ThreeElement =
N->getNumOperands() == 3;
498 if (!ThreeElement &&
N->getNumOperands() != 2)
508 if (!NotesFile || !DataFile)
510 return std::string(Notes ? NotesFile->
getString()
520 return std::string(Filename);
529 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);
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()) {
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];
902 IRBuilder<> Builder(
E.Place,
E.Place->getFirstInsertionPt());
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");
1131 Constant *Zero32 = Builder.getInt32(0);
1133 Constant *TwoZero32s[] = {Zero32, Zero32};
1143 std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA);
1146 StartFileCallArgsTy,
1147 {Builder.CreateGlobalString(FilenameGcda),
1149 Builder.getInt32(CfgChecksum)});
1154 uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[
j]->getFuncChecksum();
1156 EmitFunctionCallArgsTy,
1157 {Builder.getInt32(j),
1158 Builder.getInt32(FuncChecksum),
1159 Builder.getInt32(CfgChecksum)}));
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));
1195 {StartFileCallArgs, Builder.getInt32(CountersSize),
1197 EmitFunctionCallArgsArrayGV,
1200 EmitArcsCallArgsArrayTy, EmitArcsCallArgsArrayGV, TwoZero32s)}));
1204 if (FileInfos.
empty()) {
1205 Builder.CreateRetVoid();
1214 if ((int64_t)FileInfos.
size() > (int64_t)INT_MAX)
1215 FileInfos.
resize(INT_MAX);
1223 "__llvm_internal_gcov_emit_file_info");
1227 auto *FileLoopHeader =
1229 auto *CounterLoopHeader =
1235 Builder.CreateBr(FileLoopHeader);
1238 Builder.SetInsertPoint(FileLoopHeader);
1239 PHINode *
IV = Builder.CreatePHI(Builder.getInt32Ty(), 2,
1241 IV->addIncoming(Builder.getInt32(0), BB);
1242 auto *FileInfoPtr = Builder.CreateInBoundsGEP(
1243 FileInfoArrayTy, FileInfoArrayGV, {Builder.getInt32(0),
IV});
1244 auto *StartFileCallArgsPtr =
1245 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0,
"start_file_args");
1246 auto *StartFileCall = Builder.CreateCall(
1249 Builder.CreateStructGEP(StartFileCallArgsTy,
1250 StartFileCallArgsPtr, 0),
1253 Builder.CreateStructGEP(StartFileCallArgsTy,
1254 StartFileCallArgsPtr, 1),
1257 Builder.CreateStructGEP(StartFileCallArgsTy,
1258 StartFileCallArgsPtr, 2),
1260 if (
auto AK = TLI->getExtAttrForI32Param(
false))
1261 StartFileCall->addParamAttr(2, AK);
1263 FileInfoTy->getElementType(1),
1264 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1),
"num_ctrs");
1265 auto *EmitFunctionCallArgsArray =
1266 Builder.CreateLoad(FileInfoTy->getElementType(2),
1267 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2),
1268 "emit_function_args");
1269 auto *EmitArcsCallArgsArray = Builder.CreateLoad(
1270 FileInfoTy->getElementType(3),
1271 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3),
"emit_arcs_args");
1272 auto *EnterCounterLoopCond =
1273 Builder.CreateICmpSLT(Builder.getInt32(0),
NumCounters);
1274 Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch);
1276 Builder.SetInsertPoint(CounterLoopHeader);
1277 auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), 2,
1279 JV->addIncoming(Builder.getInt32(0), FileLoopHeader);
1280 auto *EmitFunctionCallArgsPtr = Builder.CreateInBoundsGEP(
1281 EmitFunctionCallArgsTy, EmitFunctionCallArgsArray, JV);
1282 auto *EmitFunctionCall = Builder.CreateCall(
1284 {Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(0),
1285 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1286 EmitFunctionCallArgsPtr, 0),
1288 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(1),
1289 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1290 EmitFunctionCallArgsPtr, 1),
1292 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
1293 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1294 EmitFunctionCallArgsPtr, 2),
1296 if (
auto AK = TLI->getExtAttrForI32Param(
false)) {
1297 EmitFunctionCall->addParamAttr(0, AK);
1298 EmitFunctionCall->addParamAttr(1, AK);
1299 EmitFunctionCall->addParamAttr(2, AK);
1301 auto *EmitArcsCallArgsPtr =
1302 Builder.CreateInBoundsGEP(EmitArcsCallArgsTy, EmitArcsCallArgsArray, JV);
1303 auto *EmitArcsCall = Builder.CreateCall(
1305 {Builder.CreateLoad(
1307 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0),
1311 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 1),
1313 if (
auto AK = TLI->getExtAttrForI32Param(
false))
1314 EmitArcsCall->addParamAttr(0, AK);
1315 auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1));
1316 auto *CounterLoopCond = Builder.CreateICmpSLT(NextJV,
NumCounters);
1317 Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch);
1318 JV->addIncoming(NextJV, CounterLoopHeader);
1320 Builder.SetInsertPoint(FileLoopLatch);
1321 Builder.CreateCall(SummaryInfo, {});
1322 Builder.CreateCall(EndFile, {});
1323 auto *NextIV = Builder.CreateAdd(
IV, Builder.getInt32(1),
"next_file_idx");
1324 auto *FileLoopCond =
1325 Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.
size()));
1326 Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB);
1327 IV->addIncoming(NextIV, FileLoopLatch);
1329 Builder.SetInsertPoint(ExitBB);
1330 Builder.CreateRetVoid();
1335Function *GCOVProfiler::insertReset(
1336 ArrayRef<std::pair<GlobalVariable *, MDNode *>> CountersBySP) {
1338 Function *ResetF =
M->getFunction(
"__llvm_gcov_reset");
1340 ResetF = createInternalFunction(FTy,
"__llvm_gcov_reset",
"_ZTSFvvE");
1348 for (
const auto &
I : CountersBySP) {
1352 GVTy->getNumElements() *
1353 GVTy->getElementType()->getScalarSizeInBits() / 8,
1359 Builder.CreateRetVoid();
1362 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 StringRef getFunctionName(const DISubprogram *SP)
static cl::opt< bool > AtomicCounter("gcov-atomic-counter", cl::Hidden, cl::desc("Make counter updates atomic"))
static SmallString< 128 > getFilename(const DIScope *SP)
Extract a filename for a DIScope.
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.
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.
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.
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 bool exists(const basic_file_status &status)
Does file exist?
LLVM_ABI std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
LLVM_ABI std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
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.