57 #define DEBUG_TYPE "insert-gcov-profiling" 73 cl::desc(
"Make counter updates atomic"));
78 return (s.
size() / 4) + 2;
101 GCOVProfiler() : GCOVProfiler(
GCOVOptions::getDefault()) {}
102 GCOVProfiler(
const GCOVOptions &Opts) : Options(Opts) {}
116 os->write_zeros(4 - s.
size() % 4);
118 void writeBytes(
const char *Bytes,
int Size) { os->write(Bytes,
Size); }
123 emitProfileNotes(
NamedMDNode *CUNode,
bool HasExecOrFork,
128 void emitGlobalConstructor(
131 bool isFunctionInstrumented(
const Function &
F);
132 std::vector<Regex> createRegexesFromString(
StringRef RegexesStr);
133 static bool doesFilenameMatchARegex(
StringRef Filename,
134 std::vector<Regex> &Regexes);
146 insertCounterWriteout(
ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
149 bool AddFlushBeforeForkAndExec();
151 enum class GCovFileType { GCNO, GCDA };
165 std::vector<Regex> FilterRe;
166 std::vector<Regex> ExcludeRe;
171 class GCOVProfilerLegacyPass :
public ModulePass {
174 GCOVProfilerLegacyPass()
175 : GCOVProfilerLegacyPass(
GCOVOptions::getDefault()) {}
180 StringRef getPassName()
const override {
return "GCOV Profiler"; }
182 bool runOnModule(
Module &M)
override {
184 return &this->getAnalysis<BlockFrequencyInfoWrapperPass>(
F).getBFI();
187 return &this->getAnalysis<BranchProbabilityInfoWrapperPass>(
F).getBPI();
190 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
F);
192 return Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI);
201 GCOVProfiler Profiler;
210 const std::string infoString()
const {
224 bool Removed =
false;
225 bool IsCritical =
false;
228 : SrcBB(Src), DestBB(Dest), Weight(
W) {}
231 const std::string infoString()
const {
232 return (
Twine(Removed ?
"-" :
" ") + (InMST ?
" " :
"*") +
233 (IsCritical ?
"c" :
" ") +
" W=" +
Twine(Weight))
241 GCOVProfilerLegacyPass,
"insert-gcov-profiling",
242 "Insert instrumentation for GCOV profiling",
false,
false)
251 return new GCOVProfilerLegacyPass(Options);
255 if (!SP->getLinkageName().empty())
256 return SP->getLinkageName();
280 GCOVRecord(GCOVProfiler *
P) :
P(
P) {}
283 void writeString(
StringRef s) {
P->writeString(s); }
284 void writeBytes(
const char *Bytes,
int Size) {
P->writeBytes(Bytes,
Size); }
293 class GCOVLines :
public GCOVRecord {
296 assert(Line != 0 &&
"Line zero is not a valid real line number.");
297 Lines.push_back(Line);
306 writeString(Filename);
307 for (
int i = 0,
e =
Lines.size(); i !=
e; ++i)
315 std::string Filename;
326 return LinesByFile.try_emplace(Filename,
P, Filename).first->second;
330 OutEdges.emplace_back(&
Successor, Flags);
336 for (
auto &
I : LinesByFile) {
337 Len +=
I.second.length();
349 for (
auto &
I : SortedLinesByFile)
350 I->getValue().writeOut();
359 assert(LinesByFile.empty());
382 : GCOVRecord(
P), SP(SP), EndLine(EndLine), Ident(Ident),
385 bool ExitBlockBeforeBody =
Version >= 48;
386 uint32_t i = ExitBlockBeforeBody ? 2 : 1;
388 Blocks.insert(std::make_pair(&BB,
GCOVBlock(
P, i++)));
389 if (!ExitBlockBeforeBody)
390 ReturnBlock.Number = i;
392 std::string FunctionNameAndLine;
396 FuncChecksum =
hash_value(FunctionNameAndLine);
400 return Blocks.find(const_cast<BasicBlock *>(BB))->second;
403 GCOVBlock &getEntryBlock() {
return EntryBlock; }
412 void writeOut(
uint32_t CfgChecksum) {
429 writeString(Filename);
430 write(SP->getLine());
432 write(SP->isArtificial());
433 writeString(Filename);
434 write(SP->getLine());
446 write(Blocks.size() + 2);
447 for (
int i = Blocks.size() + 2; i; --i)
451 write(Blocks.size() + 2);
456 const uint32_t Outgoing = EntryBlock.OutEdges.size();
459 write(Outgoing * 2 + 1);
460 write(EntryBlock.Number);
461 for (
const auto &
E : EntryBlock.OutEdges) {
466 for (
auto &It : Blocks) {
468 if (
Block.OutEdges.empty())
continue;
473 for (
const auto &
E :
Block.OutEdges) {
480 for (
auto &It : Blocks)
481 It.second.writeOut();
498 std::vector<Regex> GCOVProfiler::createRegexesFromString(
StringRef RegexesStr) {
499 std::vector<Regex> Regexes;
500 while (!RegexesStr.
empty()) {
501 std::pair<StringRef, StringRef> HeadTail = RegexesStr.
split(
';');
502 if (!HeadTail.first.empty()) {
503 Regex Re(HeadTail.first);
505 if (!Re.isValid(Err)) {
506 Ctx->emitError(
Twine(
"Regex ") + HeadTail.first +
507 " is not valid: " + Err);
511 RegexesStr = HeadTail.second;
516 bool GCOVProfiler::doesFilenameMatchARegex(
StringRef Filename,
517 std::vector<Regex> &Regexes) {
518 for (
Regex &Re : Regexes)
519 if (Re.match(Filename))
524 bool GCOVProfiler::isFunctionInstrumented(
const Function &
F) {
525 if (FilterRe.empty() && ExcludeRe.empty()) {
529 auto It = InstrumentedFiles.
find(Filename);
530 if (It != InstrumentedFiles.end()) {
542 RealFilename = Filename;
544 RealFilename = RealPath;
547 bool ShouldInstrument;
548 if (FilterRe.empty()) {
549 ShouldInstrument = !doesFilenameMatchARegex(RealFilename, ExcludeRe);
550 }
else if (ExcludeRe.empty()) {
551 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe);
553 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe) &&
554 !doesFilenameMatchARegex(RealFilename, ExcludeRe);
556 InstrumentedFiles[Filename] = ShouldInstrument;
557 return ShouldInstrument;
561 GCovFileType OutputType) {
562 bool Notes = OutputType == GCovFileType::GCNO;
564 if (
NamedMDNode *GCov =
M->getNamedMetadata(
"llvm.gcov")) {
565 for (
int i = 0,
e = GCov->getNumOperands(); i !=
e; ++i) {
566 MDNode *
N = GCov->getOperand(i);
567 bool ThreeElement =
N->getNumOperands() == 3;
568 if (!ThreeElement &&
N->getNumOperands() != 2)
570 if (dyn_cast<MDNode>(
N->getOperand(ThreeElement ? 2 : 1)) !=
CU)
576 MDString *NotesFile = dyn_cast<MDString>(
N->getOperand(0));
577 MDString *DataFile = dyn_cast<MDString>(
N->getOperand(1));
578 if (!NotesFile || !DataFile)
580 return std::string(Notes ? NotesFile->
getString()
581 : DataFile->getString());
584 MDString *GCovFile = dyn_cast<MDString>(
N->getOperand(0));
590 return std::string(Filename.
str());
599 return std::string(FName);
601 return std::string(CurPath.
str());
604 bool GCOVProfiler::runOnModule(
610 Ctx = &
M.getContext();
612 NamedMDNode *CUNode =
M.getNamedMetadata(
"llvm.dbg.cu");
613 if (!CUNode || (!Options.EmitNotes && !Options.EmitData))
616 bool HasExecOrFork = AddFlushBeforeForkAndExec();
618 FilterRe = createRegexesFromString(Options.Filter);
619 ExcludeRe = createRegexesFromString(Options.Exclude);
620 emitProfileNotes(CUNode, HasExecOrFork, GetBFI, GetBPI, this->GetTLI);
627 GCOVProfiler Profiler(GCOVOpts);
641 if (!Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI))
655 if (isa<DbgInfoIntrinsic>(&
I))
continue;
662 if (Loc.
getLine() == 0)
continue;
672 if (!
F.hasPersonalityFn())
return false;
678 bool GCOVProfiler::AddFlushBeforeForkAndExec() {
681 for (
auto &
F :
M->functions()) {
682 auto *TLI = &GetTLI(
F);
684 if (
CallInst *CI = dyn_cast<CallInst>(&
I)) {
685 if (
Function *Callee = CI->getCalledFunction()) {
687 if (TLI->getLibFunc(*Callee, LF)) {
688 if (LF == LibFunc_fork) {
692 }
else if (LF == LibFunc_execl || LF == LibFunc_execle ||
693 LF == LibFunc_execlp || LF == LibFunc_execv ||
694 LF == LibFunc_execvp || LF == LibFunc_execve ||
695 LF == LibFunc_execvpe || LF == LibFunc_execvP) {
704 for (
auto F : Forks) {
707 auto NextInst = ++
F->getIterator();
712 F->setCalledFunction(GCOVFork);
729 for (
auto E : Execs) {
732 auto NextInst = ++
E->getIterator();
738 M->getOrInsertFunction(
"llvm_writeout_files", FTy);
742 Builder.SetInsertPoint(&*NextInst);
745 FunctionCallee ResetF =
M->getOrInsertFunction(
"llvm_reset_counters", FTy);
746 Builder.CreateCall(ResetF)->setDebugLoc(Loc);
747 ExecBlocks.insert(Parent);
752 return !Forks.empty() || !Execs.empty();
757 if (
E.InMST ||
E.Removed)
760 BasicBlock *SrcBB = const_cast<BasicBlock *>(
E.SrcBB);
761 BasicBlock *DestBB = const_cast<BasicBlock *>(
E.DestBB);
763 if (SrcBB ==
nullptr)
765 if (DestBB ==
nullptr)
780 return CanInstrument(SrcBB);
782 return CanInstrument(DestBB);
792 MST.
addEdge(SrcBB, InstrBB, 0);
793 MST.
addEdge(InstrBB, DestBB, 0).InMST =
true;
796 return CanInstrument(InstrBB);
803 GCOVBlock &Src =
E.SrcBB ? GF.getBlock(
E.SrcBB) : GF.getEntryBlock();
804 GCOVBlock &Dst =
E.DestBB ? GF.getBlock(
E.DestBB) : GF.getReturnBlock();
805 dbgs() <<
" Edge " <<
ID++ <<
": " << Src.Number <<
"->" << Dst.Number
806 <<
E.infoString() <<
"\n";
811 bool GCOVProfiler::emitProfileNotes(
818 uint8_t c3 = Options.Version[0];
819 uint8_t c2 = Options.Version[1];
820 uint8_t c1 = Options.Version[2];
821 Version = c3 >=
'A' ? (c3 -
'A') * 100 + (c2 -
'0') * 10 + c1 -
'0' 822 : (c3 -
'0') * 10 + c1 -
'0';
825 bool EmitGCDA = Options.EmitData;
837 std::vector<uint8_t> EdgeDestinations;
842 unsigned FunctionIdent = 0;
843 for (
auto &
F :
M->functions()) {
867 for (
size_t I : llvm::seq<size_t>(0, MST.AllEdges.size())) {
868 auto &
E = *MST.AllEdges[
I];
877 Funcs.push_back(std::make_unique<GCOVFunction>(
this, &
F, SP, EndLine,
884 return E->Removed || (!E->InMST && !E->Place);
886 const size_t Measured =
887 std::stable_partition(
888 MST.AllEdges.begin(), MST.AllEdges.end(),
889 [](std::unique_ptr<Edge> &
E) {
return E->Place; }) -
890 MST.AllEdges.begin();
891 for (
size_t I : llvm::seq<size_t>(0, Measured)) {
892 Edge &
E = *MST.AllEdges[
I];
894 E.SrcBB ?
Func.getBlock(
E.SrcBB) :
Func.getEntryBlock();
896 E.DestBB ?
Func.getBlock(
E.DestBB) :
Func.getReturnBlock();
897 E.SrcNumber = Src.Number;
898 E.DstNumber = Dst.Number;
901 MST.AllEdges.begin(), MST.AllEdges.begin() + Measured,
902 [](
const std::unique_ptr<Edge> &L,
const std::unique_ptr<Edge> &
R) {
903 return L->SrcNumber !=
R->SrcNumber ? L->SrcNumber <
R->SrcNumber
904 : L->DstNumber <
R->DstNumber;
909 E.SrcBB ?
Func.getBlock(
E.SrcBB) :
Func.getEntryBlock();
911 E.DestBB ?
Func.getBlock(
E.DestBB) :
Func.getReturnBlock();
916 if (!SP->isArtificial())
917 Func.getBlock(&EntryBlock).getFile(Filename).addLine(Line);
921 for (
auto &GB :
Func.Blocks) {
923 auto &
Block = GB.second;
924 for (
auto Succ :
Block.OutEdges) {
926 do EdgeDestinations.push_back(Idx & 255);
927 while ((Idx >>= 8) > 0);
933 if (isa<DbgInfoIntrinsic>(&
I))
continue;
943 if (Line == Loc.
getLine())
continue;
961 for (
size_t I : llvm::seq<size_t>(0, Measured)) {
962 const Edge &
E = *MST.AllEdges[
I];
966 if (Options.Atomic) {
981 JC.
update(EdgeDestinations);
985 if (Options.EmitNotes) {
991 Twine(
"failed to open coverage notes file for writing: ") +
997 out.write(
"gcno", 4);
998 out.write(Options.Version, 4);
1000 out.write(
"oncg", 4);
1001 std::reverse_copy(Options.Version, Options.Version + 4, Tmp);
1010 for (
auto &Func : Funcs)
1011 Func->writeOut(Stamp);
1019 emitGlobalConstructor(CountersBySP);
1026 void GCOVProfiler::emitGlobalConstructor(
1027 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
1028 Function *WriteoutF = insertCounterWriteout(CountersBySP);
1029 Function *ResetF = insertReset(CountersBySP);
1036 "__llvm_gcov_init", M);
1039 F->addFnAttr(Attribute::NoInline);
1040 if (Options.NoRedZone)
1041 F->addFnAttr(Attribute::NoRedZone);
1052 FunctionCallee GCOVInit =
M->getOrInsertFunction(
"llvm_gcov_init", FTy);
1053 Builder.CreateCall(GCOVInit, {WriteoutF, ResetF});
1068 AL =
AL.addParamAttribute(*Ctx, 2, AK);
1082 AL =
AL.addParamAttribute(*Ctx, 0, AK);
1083 AL =
AL.addParamAttribute(*Ctx, 1, AK);
1084 AL =
AL.addParamAttribute(*Ctx, 2, AK);
1086 return M->getOrInsertFunction(
"llvm_gcda_emit_function", FTy);
1097 AL =
AL.addParamAttribute(*Ctx, 0, AK);
1098 return M->getOrInsertFunction(
"llvm_gcda_emit_arcs", FTy,
AL);
1103 return M->getOrInsertFunction(
"llvm_gcda_summary_info", FTy);
1108 return M->getOrInsertFunction(
"llvm_gcda_end_file", FTy);
1111 Function *GCOVProfiler::insertCounterWriteout(
1112 ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
1114 Function *WriteoutF =
M->getFunction(
"__llvm_gcov_writeout");
1117 "__llvm_gcov_writeout", M);
1119 WriteoutF->
addFnAttr(Attribute::NoInline);
1120 if (Options.NoRedZone)
1121 WriteoutF->
addFnAttr(Attribute::NoRedZone);
1126 auto *TLI = &GetTLI(*WriteoutF);
1134 NamedMDNode *CUNodes =
M->getNamedMetadata(
"llvm.dbg.cu");
1144 "start_file_args_ty");
1147 "emit_function_args_ty");
1150 "emit_arcs_args_ty");
1153 EmitFunctionCallArgsTy->getPointerTo(),
1154 EmitArcsCallArgsTy->getPointerTo()},
1159 Constant *TwoZero32s[] = {Zero32, Zero32};
1163 auto *
CU = cast<DICompileUnit>(CUNodes->
getOperand(i));
1169 std::string FilenameGcda = mangleName(
CU, GCovFileType::GCDA);
1172 StartFileCallArgsTy,
1173 {
Builder.CreateGlobalStringPtr(FilenameGcda),
1175 Builder.getInt32(CfgChecksum)});
1179 for (
int j : llvm::seq<int>(0, CountersBySP.
size())) {
1180 uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum();
1182 EmitFunctionCallArgsTy,
1184 Builder.getInt32(FuncChecksum),
1185 Builder.getInt32(CfgChecksum)}));
1188 unsigned Arcs = cast<ArrayType>(GV->
getValueType())->getNumElements();
1195 int CountersSize = CountersBySP.
size();
1196 assert(CountersSize == (
int)EmitFunctionCallArgsArray.size() &&
1197 "Mismatched array size!");
1198 assert(CountersSize == (
int)EmitArcsCallArgsArray.
size() &&
1199 "Mismatched array size!");
1200 auto *EmitFunctionCallArgsArrayTy =
1203 *M, EmitFunctionCallArgsArrayTy,
true,
1206 EmitFunctionCallArgsArray),
1207 Twine(
"__llvm_internal_gcov_emit_function_args.") +
Twine(i));
1208 auto *EmitArcsCallArgsArrayTy =
1210 EmitFunctionCallArgsArrayGV->setUnnamedAddr(
1213 *M, EmitArcsCallArgsArrayTy,
true,
1216 Twine(
"__llvm_internal_gcov_emit_arcs_args.") +
Twine(i));
1221 {StartFileCallArgs,
Builder.getInt32(CountersSize),
1223 EmitFunctionCallArgsArrayGV,
1226 EmitArcsCallArgsArrayTy, EmitArcsCallArgsArrayGV, TwoZero32s)}));
1230 if (FileInfos.
empty()) {
1240 if ((int64_t)FileInfos.
size() > (int64_t)INT_MAX)
1241 FileInfos.
resize(INT_MAX);
1249 "__llvm_internal_gcov_emit_file_info");
1253 auto *FileLoopHeader =
1255 auto *CounterLoopHeader =
1261 Builder.CreateBr(FileLoopHeader);
1264 Builder.SetInsertPoint(FileLoopHeader);
1268 auto *FileInfoPtr =
Builder.CreateInBoundsGEP(
1269 FileInfoArrayTy, FileInfoArrayGV, {
Builder.getInt32(0), IV});
1270 auto *StartFileCallArgsPtr =
1271 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0,
"start_file_args");
1272 auto *StartFileCall =
Builder.CreateCall(
1275 Builder.CreateStructGEP(StartFileCallArgsTy,
1276 StartFileCallArgsPtr, 0),
1279 Builder.CreateStructGEP(StartFileCallArgsTy,
1280 StartFileCallArgsPtr, 1),
1283 Builder.CreateStructGEP(StartFileCallArgsTy,
1284 StartFileCallArgsPtr, 2),
1287 StartFileCall->addParamAttr(2, AK);
1288 auto *NumCounters =
Builder.CreateLoad(
1289 FileInfoTy->getElementType(1),
1290 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1),
"num_ctrs");
1291 auto *EmitFunctionCallArgsArray =
1292 Builder.CreateLoad(FileInfoTy->getElementType(2),
1293 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2),
1294 "emit_function_args");
1295 auto *EmitArcsCallArgsArray =
Builder.CreateLoad(
1296 FileInfoTy->getElementType(3),
1297 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3),
"emit_arcs_args");
1298 auto *EnterCounterLoopCond =
1300 Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch);
1302 Builder.SetInsertPoint(CounterLoopHeader);
1305 JV->addIncoming(
Builder.getInt32(0), FileLoopHeader);
1306 auto *EmitFunctionCallArgsPtr =
Builder.CreateInBoundsGEP(
1307 EmitFunctionCallArgsTy, EmitFunctionCallArgsArray, JV);
1308 auto *EmitFunctionCall =
Builder.CreateCall(
1310 {
Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(0),
1311 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1312 EmitFunctionCallArgsPtr, 0),
1314 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(1),
1315 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1316 EmitFunctionCallArgsPtr, 1),
1318 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
1319 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1320 EmitFunctionCallArgsPtr, 2),
1323 EmitFunctionCall->addParamAttr(0, AK);
1324 EmitFunctionCall->addParamAttr(1, AK);
1325 EmitFunctionCall->addParamAttr(2, AK);
1327 auto *EmitArcsCallArgsPtr =
1328 Builder.CreateInBoundsGEP(EmitArcsCallArgsTy, EmitArcsCallArgsArray, JV);
1329 auto *EmitArcsCall =
Builder.CreateCall(
1332 EmitArcsCallArgsTy->getElementType(0),
1333 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0),
1336 EmitArcsCallArgsTy->getElementType(1),
1337 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 1),
1340 EmitArcsCall->addParamAttr(0, AK);
1342 auto *CounterLoopCond =
Builder.CreateICmpSLT(NextJV, NumCounters);
1343 Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch);
1344 JV->addIncoming(NextJV, CounterLoopHeader);
1346 Builder.SetInsertPoint(FileLoopLatch);
1347 Builder.CreateCall(SummaryInfo, {});
1348 Builder.CreateCall(EndFile, {});
1349 auto *NextIV =
Builder.CreateAdd(IV,
Builder.getInt32(1),
"next_file_idx");
1350 auto *FileLoopCond =
1352 Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB);
1355 Builder.SetInsertPoint(ExitBB);
1361 Function *GCOVProfiler::insertReset(
1362 ArrayRef<std::pair<GlobalVariable *, MDNode *>> CountersBySP) {
1364 Function *ResetF =
M->getFunction(
"__llvm_gcov_reset");
1367 "__llvm_gcov_reset", M);
1370 if (Options.NoRedZone)
1371 ResetF->
addFnAttr(Attribute::NoRedZone);
1377 for (
const auto &
I : CountersBySP) {
1380 Builder.CreateStore(Null, GV);
static BasicBlock * getInstrBB(CFGMST< Edge, BBInfo > &MST, Edge &E, const DenseSet< const BasicBlock * > &ExecBlocks)
This routine provides some synthesis utilities to produce sequences of values.
reference emplace_back(ArgTypes &&... Args)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
MDNode * getOperand(unsigned i) const
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
Type * getElementType(unsigned N) const
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
ModulePass * createGCOVProfilerPass(const GCOVOptions &Options=GCOVOptions::getDefault())
A Module instance is used to store all the information related to an LLVM module.
LLVM_NODISCARD bool empty() const
static GCOVOptions getDefault()
std::vector< std::unique_ptr< Edge > > AllEdges
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Implements a dense probed hash-table based set.
size_t find(char C, size_t From=0) const
find - Search for the first character C in the string.
void push_back(const T &Elt)
static SmallString< 128 > getFilename(const DISubprogram *SP)
Extract a filename for a DISubprogram.
This class represents a function call, abstracting a target machine's calling convention.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
An efficient, type-erasing, non-owning reference to a callable.
std::error_code current_path(SmallVectorImpl< char > &result)
Get the current path.
This class implements a map that also provides access to all stored values in a deterministic order.
static IntegerType * getInt64Ty(LLVMContext &C)
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...
StringRef getFilename() const
An union-find based Minimum Spanning Tree for CFG.
static PointerType * getInt64PtrTy(LLVMContext &C, unsigned AS=0)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Attribute::AttrKind getExtAttrForI32Param(bool Signed=true) const
Returns extension attribute kind to be used for i32 parameters corresponding to C-level int or unsign...
AnalysisUsage & addRequired()
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
uint32_t read32be(const void *P)
bool isImplicitCode() const
Check if the DebugLoc corresponds to an implicit code.
Class to represent struct types.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isIntegerTy() const
True if this is an instance of IntegerType.
void write32(void *P, uint32_t V, endianness E)
Legacy analysis pass which computes BlockFrequencyInfo.
unsigned getNumOperands() const
static bool isUsingScopeBasedEH(Function &F)
DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
StringRef getFilename() const
bool isScopedEHPersonality(EHPersonality Pers)
Returns true if this personality uses scope-style EH IR instructions: catchswitch,...
StringRef str() const
Explicit conversion to StringRef.
Analysis pass which computes BranchProbabilityInfo.
Class to represent function types.
This file provides the interface for the GCOV style profiler pass.
Class to represent array types.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
GCOVBlock - Collects block information.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM_NODISCARD size_t size() const
size - Get the string size.
hash_code hash_value(const APFloat &Arg)
See friend declarations above.
static void addEdge(SmallVectorImpl< LazyCallGraph::Edge > &Edges, DenseMap< LazyCallGraph::Node *, int > &EdgeIndexMap, LazyCallGraph::Node &N, LazyCallGraph::Edge::Kind EK)
Legacy analysis pass which computes BranchProbabilityInfo.
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
GCOVFunction(GCOVFile &file)
StringRef getString() const
bool isVoidTy() const
Return true if this is 'void'.
std::error_code real_path(const Twine &path, SmallVectorImpl< char > &output, bool expand_tilde=false)
Collapse all .
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
initializer< Ty > init(const Ty &Val)
Type * getReturnType() const
Returns the type of the ret val.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
static Constant * getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList)
Create an "inbounds" getelementptr.
A set of analyses that are preserved following a run of a transformation pass.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed.
This is an important class for using LLVM in a threaded context.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
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.
INITIALIZE_PASS_BEGIN(GCOVProfilerLegacyPass, "insert-gcov-profiling", "Insert instrumentation for GCOV profiling", false, false) INITIALIZE_PASS_END(GCOVProfilerLegacyPass
EHPersonality classifyEHPersonality(const Value *Pers)
See if the given exception handling personality function is one that we understand.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
const Instruction & back() const
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
void sort(IteratorTy Start, IteratorTy End)
static Constant * get(StructType *T, ArrayRef< Constant * > V)
static cl::opt< std::string > DefaultGCOVVersion("default-gcov-version", cl::init("408*"), cl::Hidden, cl::ValueRequired)
MDNode * getScope() const
static unsigned wordsOfString(StringRef s)
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
static void write(bool isBE, void *P, T V)
StringRef getDirectory() const
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static bool functionHasLines(const Function &F, unsigned &EndLine)
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Analysis pass which computes BlockFrequencyInfo.
FileType
Defines the file type this file represents.
Align max(MaybeAlign Lhs, Align Rhs)
StringRef getName() const
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
LLVM_NODISCARD std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
void initializeGCOVProfilerLegacyPassPass(PassRegistry &)
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static StringRef getFunctionName(const DISubprogram *SP)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
void update(ArrayRef< uint8_t > Data)
Analysis providing branch probability information.
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...
GCOVFunction - Collects function information.
A raw_ostream that writes to a file descriptor.
void setUnnamedAddr(UnnamedAddr Val)
Edge & addEdge(const BasicBlock *Src, const BasicBlock *Dest, uint64_t W)
static void dumpEdges(CFGMST< Edge, BBInfo > &MST, GCOVFunction &GF)
StringRef filename(StringRef path, Style style=Style::native)
Get filename.
static IntegerType * getInt32Ty(LLVMContext &C)
bool SplitIndirectBrCriticalEdges(Function &F, BranchProbabilityInfo *BPI=nullptr, BlockFrequencyInfo *BFI=nullptr)
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Type * getValueType() const
Rename collisions when linking (static functions).
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Analysis pass providing the TargetLibraryInfo.
LLVM_NODISCARD const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void stable_sort(R &&Range)
A raw_ostream that writes to an std::string.
static cl::opt< bool > AtomicCounter("gcov-atomic-counter", cl::Hidden, cl::desc("Make counter updates atomic"))
LLVM Value Representation.
static StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
This class implements an extremely fast bulk output stream that can only output to a stream.
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
print Print MemDeps of function
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
StringRef - Represent a constant reference to a string, i.e.
inst_range instructions(Function *F)
A container for analyses that lazily runs them and caches their results.
bool exists(const basic_file_status &status)
Does file exist?
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...