LLVM 24.0.0git
GCOVProfiling.cpp
Go to the documentation of this file.
1//===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass implements GCOV-style profiling. When this pass is run it emits
10// "gcno" files next to the existing source, and instruments the code that runs
11// to records the edges between blocks that run and emit a complementary "gcda"
12// file on exit.
13//
14//===----------------------------------------------------------------------===//
15
17#include "llvm/ADT/Hashing.h"
18#include "llvm/ADT/MapVector.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/Sequence.h"
21#include "llvm/ADT/StringMap.h"
25#include "llvm/IR/DebugInfo.h"
26#include "llvm/IR/DebugLoc.h"
28#include "llvm/IR/IRBuilder.h"
31#include "llvm/IR/Module.h"
33#include "llvm/Support/CRC.h"
34#include "llvm/Support/Debug.h"
36#include "llvm/Support/Path.h"
37#include "llvm/Support/Regex.h"
44#include <algorithm>
45#include <memory>
46#include <string>
47#include <utility>
48
49using namespace llvm;
51
52#define DEBUG_TYPE "insert-gcov-profiling"
53
54enum : uint32_t {
56
57 GCOV_TAG_FUNCTION = 0x01000000,
58 GCOV_TAG_BLOCKS = 0x01410000,
59 GCOV_TAG_ARCS = 0x01430000,
60 GCOV_TAG_LINES = 0x01450000,
61};
62
63// Returns the number of words which will be used to represent this string.
64static unsigned wordsOfString(StringRef s) {
65 // Length + NUL-terminated string + 0~3 padding NULs.
66 return (s.size() / 4) + 2;
67}
68
69static GCOVOptions getDefaultOptions(const InstrumentationOptions &Opts) {
71 Options.EmitNotes = true;
72 Options.UseAbsolutePathsInNotes = false;
73 Options.EmitData = true;
74 Options.NoRedZone = false;
75 Options.Atomic = Opts.gcov_atomic_counter;
76
77 if (Opts.default_gcov_version.size() != 4) {
78 reportFatalUsageError(Twine("Invalid -default-gcov-version: ") +
79 Opts.default_gcov_version);
80 }
81 memcpy(Options.Version, Opts.default_gcov_version.data(), 4);
82 return Options;
83}
84
85namespace {
86class GCOVFunction;
87
88class GCOVProfiler {
89public:
90 GCOVProfiler(const GCOVOptions &Opts, vfs::FileSystem &VFS)
91 : Options(Opts), VFS(VFS) {}
92 bool
93 runOnModule(Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
94 function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
95 std::function<const TargetLibraryInfo &(Function &F)> GetTLI);
96
97 void write(uint32_t i) {
98 char Bytes[4];
99 endian::write32(Bytes, i, Endian);
100 os->write(Bytes, 4);
101 }
102 void writeString(StringRef s) {
103 write(wordsOfString(s) - 1);
104 os->write(s.data(), s.size());
105 os->write_zeros(4 - s.size() % 4);
106 }
107 void writeBytes(const char *Bytes, int Size) { os->write(Bytes, Size); }
108 SmallString<128> getFilename(const DIScope *SP);
109
110private:
111 // Create the .gcno files for the Module based on DebugInfo.
112 bool
113 emitProfileNotes(NamedMDNode *CUNode, bool HasExecOrFork,
114 function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
115 function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
116 function_ref<const TargetLibraryInfo &(Function &F)> GetTLI);
117
118 Function *createInternalFunction(FunctionType *FTy, StringRef Name,
119 StringRef MangledType = "");
120
121 void emitGlobalConstructor(
122 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
123 void emitModuleInitFunctionPtrs(
124 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP);
125
126 bool isFunctionInstrumented(const Function &F);
127 std::vector<Regex> createRegexesFromString(StringRef RegexesStr);
128 static bool doesFilenameMatchARegex(StringRef Filename,
129 std::vector<Regex> &Regexes);
130
131 // Get pointers to the functions in the runtime library.
132 FunctionCallee getStartFileFunc(const TargetLibraryInfo *TLI);
133 FunctionCallee getEmitFunctionFunc(const TargetLibraryInfo *TLI);
134 FunctionCallee getEmitArcsFunc(const TargetLibraryInfo *TLI);
135 FunctionCallee getSummaryInfoFunc();
136 FunctionCallee getEndFileFunc();
137
138 // Add the function to write out all our counters to the global destructor
139 // list.
140 Function *
141 insertCounterWriteout(ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
142 Function *insertReset(ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
143
144 bool AddFlushBeforeForkAndExec();
145
146 enum class GCovFileType { GCNO, GCDA };
147 std::string mangleName(const DICompileUnit *CU, GCovFileType FileType);
148
149 GCOVOptions Options;
150 llvm::endianness Endian;
151 raw_ostream *os;
152 int Version = 0;
153
154 // Checksum, produced by hash of EdgeDestinations
155 SmallVector<uint32_t, 4> FileChecksums;
156
157 Module *M = nullptr;
158 std::function<const TargetLibraryInfo &(Function &F)> GetTLI;
159 LLVMContext *Ctx = nullptr;
161 std::vector<Regex> FilterRe;
162 std::vector<Regex> ExcludeRe;
163 DenseSet<const BasicBlock *> ExecBlocks;
164 StringMap<bool> InstrumentedFiles;
165 vfs::FileSystem &VFS;
166};
167
168struct BBInfo {
169 BBInfo *Group;
170 uint32_t Index;
171 uint32_t Rank = 0;
172
173 BBInfo(unsigned Index) : Group(this), Index(Index) {}
174 std::string infoString() const {
175 return (Twine("Index=") + Twine(Index)).str();
176 }
177};
178
179struct Edge {
180 // This class implements the CFG edges. Note the CFG can be a multi-graph.
181 // So there might be multiple edges with same SrcBB and DestBB.
182 const BasicBlock *SrcBB;
183 const BasicBlock *DestBB;
184 uint64_t Weight;
185 BasicBlock *Place = nullptr;
186 uint32_t SrcNumber, DstNumber;
187 bool InMST = false;
188 bool Removed = false;
189 bool IsCritical = false;
190
191 Edge(const BasicBlock *Src, const BasicBlock *Dest, uint64_t W = 1)
192 : SrcBB(Src), DestBB(Dest), Weight(W) {}
193
194 // Return the information string of an edge.
195 std::string infoString() const {
196 return (Twine(Removed ? "-" : " ") + (InMST ? " " : "*") +
197 (IsCritical ? "c" : " ") + " W=" + Twine(Weight))
198 .str();
199 }
200};
201}
202
204 if (!SP->getLinkageName().empty())
205 return SP->getLinkageName();
206 return SP->getName();
207}
208
209/// Extract a filename for a DIScope.
210///
211/// Unless -fprofile-abs-path has been passed, prefer relative paths in the
212/// coverage notes. Clang also may split up absolute paths into a directory and
213/// filename component. When the relative path doesn't exist, reconstruct the
214/// absolute path.
215SmallString<128> GCOVProfiler::getFilename(const DIScope *SP) {
216 SmallString<128> Path;
217 StringRef RelPath = SP->getFilename();
218 if (VFS.exists(RelPath)) {
219 Path = RelPath;
220 if (Options.UseAbsolutePathsInNotes) {
221 VFS.makeAbsolute(Path);
222 sys::path::remove_dots(Path, true);
223 }
224 } else {
225 sys::path::append(Path, SP->getDirectory(), SP->getFilename());
226 }
227 return Path;
228}
229
230namespace {
231 class GCOVRecord {
232 protected:
233 GCOVProfiler *P;
234
235 GCOVRecord(GCOVProfiler *P) : P(P) {}
236
237 void write(uint32_t i) { P->write(i); }
238 void writeString(StringRef s) { P->writeString(s); }
239 void writeBytes(const char *Bytes, int Size) { P->writeBytes(Bytes, Size); }
240 };
241
242 class GCOVFunction;
243 class GCOVBlock;
244
245 // Constructed only by requesting it from a GCOVBlock, this object stores a
246 // list of line numbers and a single filename, representing lines that belong
247 // to the block.
248 class GCOVLines : public GCOVRecord {
249 public:
250 StringRef getFilename() { return Filename; }
251
252 void addLine(uint32_t Line) {
253 assert(Line != 0 && "Line zero is not a valid real line number.");
254 Lines.push_back(Line);
255 }
256
257 uint32_t length() const {
258 return 1 + wordsOfString(Filename) + Lines.size();
259 }
260
261 void writeOut() {
262 write(0);
264 for (uint32_t L : Lines)
265 write(L);
266 }
267
268 GCOVLines(GCOVProfiler *P, StringRef F)
269 : GCOVRecord(P), Filename(std::string(F)) {}
270
271 private:
272 std::string Filename;
273 SmallVector<uint32_t, 32> Lines;
274 };
275
276
277 // Represent a basic block in GCOV. Each block has a unique number in the
278 // function, number of lines belonging to each block, and a set of edges to
279 // other blocks.
280 class GCOVBlock : public GCOVRecord {
281 public:
282 GCOVLines &getFile(StringRef Filename) {
283 if (Lines.empty() || Lines.back().getFilename() != Filename)
284 Lines.emplace_back(P, Filename);
285 return Lines.back();
286 }
287
288 void addEdge(GCOVBlock &Successor, uint32_t Flags) {
289 OutEdges.emplace_back(&Successor, Flags);
290 }
291
292 void writeOut() {
293 uint32_t Len = 3;
294
295 for (auto &L : Lines)
296 Len += L.length();
297
299 write(Len);
300 write(Number);
301
302 for (auto &L : Lines)
303 L.writeOut();
304 write(0);
305 write(0);
306 }
307
308 GCOVBlock(const GCOVBlock &RHS) : GCOVRecord(RHS), Number(RHS.Number) {
309 // Only allow copy before edges and lines have been added. After that,
310 // there are inter-block pointers (eg: edges) that won't take kindly to
311 // blocks being copied or moved around.
312 assert(Lines.empty());
313 assert(OutEdges.empty());
314 }
315
316 uint32_t Number;
318
319 private:
320 friend class GCOVFunction;
321
322 GCOVBlock(GCOVProfiler *P, uint32_t Number)
323 : GCOVRecord(P), Number(Number) {}
324
326 };
327
328 // A function has a unique identifier, a checksum (we leave as zero) and a
329 // set of blocks and a map of edges between blocks. This is the only GCOV
330 // object users can construct, the blocks and lines will be rooted here.
331 class GCOVFunction : public GCOVRecord {
332 public:
333 GCOVFunction(GCOVProfiler *P, Function *F, const DISubprogram *SP,
334 unsigned EndLine, uint32_t Ident, int Version)
335 : GCOVRecord(P), SP(SP), EndLine(EndLine), Ident(Ident),
336 Version(Version), EntryBlock(P, 0), ReturnBlock(P, 1) {
337 LLVM_DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n");
338 uint32_t i = 2;
339 for (BasicBlock &BB : *F)
340 Blocks.insert(std::make_pair(&BB, GCOVBlock(P, i++)));
341
342 std::string FunctionNameAndLine;
343 raw_string_ostream FNLOS(FunctionNameAndLine);
344 FNLOS << getFunctionName(SP) << SP->getLine();
345 FuncChecksum = hash_value(FunctionNameAndLine);
346 }
347
348 GCOVBlock &getBlock(const BasicBlock *BB) {
349 return Blocks.find(const_cast<BasicBlock *>(BB))->second;
350 }
351
352 GCOVBlock &getEntryBlock() { return EntryBlock; }
353 GCOVBlock &getReturnBlock() {
354 return ReturnBlock;
355 }
356
357 uint32_t getFuncChecksum() const {
358 return FuncChecksum;
359 }
360
361 void writeOut(uint32_t CfgChecksum) {
363 SmallString<128> Filename = P->getFilename(SP);
364 uint32_t BlockLen = 3 + wordsOfString(getFunctionName(SP));
365 BlockLen += 1 + wordsOfString(Filename) + 4;
366
367 write(BlockLen);
368 write(Ident);
369 write(FuncChecksum);
370 write(CfgChecksum);
372
373 write(SP->isArtificial()); // artificial
375 write(SP->getLine()); // start_line
376 write(0); // start_column
377 // EndLine is the last line with !dbg. It is not the } line as in GCC,
378 // but good enough.
379 write(EndLine);
380 write(0); // end_column
381
382 // Emit count of blocks.
384 write(1);
385 write(Blocks.size() + 2);
386 LLVM_DEBUG(dbgs() << (Blocks.size() + 1) << " blocks\n");
387
388 // Emit edges between blocks.
389 const uint32_t Outgoing = EntryBlock.OutEdges.size();
390 if (Outgoing) {
392 write(Outgoing * 2 + 1);
393 write(EntryBlock.Number);
394 for (const auto &E : EntryBlock.OutEdges) {
395 write(E.first->Number);
396 write(E.second);
397 }
398 }
399 for (auto &It : Blocks) {
400 const GCOVBlock &Block = It.second;
401 if (Block.OutEdges.empty()) continue;
402
404 write(Block.OutEdges.size() * 2 + 1);
405 write(Block.Number);
406 for (const auto &E : Block.OutEdges) {
407 write(E.first->Number);
408 write(E.second);
409 }
410 }
411
412 // Emit lines for each block.
413 for (auto &It : Blocks)
414 It.second.writeOut();
415 }
416
417 public:
418 const DISubprogram *SP;
419 unsigned EndLine;
420 uint32_t Ident;
421 uint32_t FuncChecksum;
422 int Version;
423 MapVector<BasicBlock *, GCOVBlock> Blocks;
424 GCOVBlock EntryBlock;
425 GCOVBlock ReturnBlock;
426 };
427}
428
429// RegexesStr is a string containing differents regex separated by a semi-colon.
430// For example "foo\..*$;bar\..*$".
431std::vector<Regex> GCOVProfiler::createRegexesFromString(StringRef RegexesStr) {
432 std::vector<Regex> Regexes;
433 while (!RegexesStr.empty()) {
434 std::pair<StringRef, StringRef> HeadTail = RegexesStr.split(';');
435 if (!HeadTail.first.empty()) {
436 Regex Re(HeadTail.first);
437 std::string Err;
438 if (!Re.isValid(Err)) {
439 Ctx->emitError(Twine("Regex ") + HeadTail.first +
440 " is not valid: " + Err);
441 }
442 Regexes.emplace_back(std::move(Re));
443 }
444 RegexesStr = HeadTail.second;
445 }
446 return Regexes;
447}
448
449bool GCOVProfiler::doesFilenameMatchARegex(StringRef Filename,
450 std::vector<Regex> &Regexes) {
451 for (Regex &Re : Regexes)
452 if (Re.match(Filename))
453 return true;
454 return false;
455}
456
457bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
458 if (FilterRe.empty() && ExcludeRe.empty()) {
459 return true;
460 }
461 SmallString<128> Filename = getFilename(F.getSubprogram());
462 auto It = InstrumentedFiles.find(Filename);
463 if (It != InstrumentedFiles.end()) {
464 return It->second;
465 }
466
467 SmallString<256> RealPath;
468 StringRef RealFilename;
469
470 // Path can be
471 // /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/*.h so for
472 // such a case we must get the real_path.
473 if (VFS.getRealPath(Filename, RealPath)) {
474 // real_path can fail with path like "foo.c".
475 RealFilename = Filename;
476 } else {
477 RealFilename = RealPath;
478 }
479
480 bool ShouldInstrument;
481 if (FilterRe.empty()) {
482 ShouldInstrument = !doesFilenameMatchARegex(RealFilename, ExcludeRe);
483 } else if (ExcludeRe.empty()) {
484 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe);
485 } else {
486 ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe) &&
487 !doesFilenameMatchARegex(RealFilename, ExcludeRe);
488 }
489 InstrumentedFiles[Filename] = ShouldInstrument;
490 return ShouldInstrument;
491}
492
493std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
494 GCovFileType OutputType) {
495 bool Notes = OutputType == GCovFileType::GCNO;
496
497 if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
498 for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
499 MDNode *N = GCov->getOperand(i);
500 bool ThreeElement = N->getNumOperands() == 3;
501 if (!ThreeElement && N->getNumOperands() != 2)
502 continue;
503 if (dyn_cast<MDNode>(N->getOperand(ThreeElement ? 2 : 1)) != CU)
504 continue;
505
506 if (ThreeElement) {
507 // These nodes have no mangling to apply, it's stored mangled in the
508 // bitcode.
509 MDString *NotesFile = dyn_cast<MDString>(N->getOperand(0));
510 MDString *DataFile = dyn_cast<MDString>(N->getOperand(1));
511 if (!NotesFile || !DataFile)
512 continue;
513 return std::string(Notes ? NotesFile->getString()
514 : DataFile->getString());
515 }
516
517 MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
518 if (!GCovFile)
519 continue;
520
521 SmallString<128> Filename = GCovFile->getString();
522 sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda");
523 return std::string(Filename);
524 }
525 }
526
527 SmallString<128> Filename = CU->getFilename();
528 sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda");
529 StringRef FName = sys::path::filename(Filename);
530 ErrorOr<std::string> CWD = VFS.getCurrentWorkingDirectory();
531 if (!CWD)
532 return std::string(FName);
533 SmallString<128> CurPath{*CWD};
534 sys::path::append(CurPath, FName);
535 return std::string(CurPath);
536}
537
538bool GCOVProfiler::runOnModule(
539 Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
540 function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
541 std::function<const TargetLibraryInfo &(Function &F)> GetTLI) {
542 this->M = &M;
543 this->GetTLI = std::move(GetTLI);
544 Ctx = &M.getContext();
545
546 NamedMDNode *CUNode = M.getNamedMetadata("llvm.dbg.cu");
547 if (!CUNode || (!Options.EmitNotes && !Options.EmitData))
548 return false;
549
550 bool HasExecOrFork = AddFlushBeforeForkAndExec();
551
552 FilterRe = createRegexesFromString(Options.Filter);
553 ExcludeRe = createRegexesFromString(Options.Exclude);
554 emitProfileNotes(CUNode, HasExecOrFork, GetBFI, GetBPI, this->GetTLI);
555 return true;
556}
557
560
561 const InstrumentationOptions &Opts = getInstrumentationOptions(M);
562 GCOVProfiler Profiler(GCOVOpts ? *GCOVOpts : getDefaultOptions(Opts), *VFS);
565
566 auto GetBFI = [&FAM](Function &F) {
567 return &FAM.getResult<BlockFrequencyAnalysis>(F);
568 };
569 auto GetBPI = [&FAM](Function &F) {
570 return &FAM.getResult<BranchProbabilityAnalysis>(F);
571 };
572 auto GetTLI = [&FAM](Function &F) -> const TargetLibraryInfo & {
573 return FAM.getResult<TargetLibraryAnalysis>(F);
574 };
575
576 if (!Profiler.runOnModule(M, GetBFI, GetBPI, GetTLI))
577 return PreservedAnalyses::all();
578
580}
581
582static bool functionHasLines(const Function &F, unsigned &EndLine) {
583 // Check whether this function actually has any source lines. Not only
584 // do these waste space, they also can crash gcov.
585 EndLine = 0;
586 for (const auto &BB : F) {
587 for (const auto &I : BB) {
588 const DebugLoc &Loc = I.getDebugLoc();
589 if (!Loc)
590 continue;
591
592 // Artificial lines such as calls to the global constructors.
593 if (Loc.getLine() == 0) continue;
594 EndLine = std::max(EndLine, Loc.getLine());
595
596 return true;
597 }
598 }
599 return false;
600}
601
603 if (!F.hasPersonalityFn()) return false;
604
605 EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn());
606 return isScopedEHPersonality(Personality);
607}
608
609bool GCOVProfiler::AddFlushBeforeForkAndExec() {
610 const TargetLibraryInfo *TLI = nullptr;
613 for (auto &F : M->functions()) {
614 TLI = TLI == nullptr ? &GetTLI(F) : TLI;
615 for (auto &I : instructions(F)) {
616 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
617 if (Function *Callee = CI->getCalledFunction()) {
618 LibFunc LF = TLI->getLibFunc(*Callee);
619 if (LF != NotLibFunc) {
620 if (LF == LibFunc_fork) {
621#if !defined(_WIN32)
622 Forks.push_back(CI);
623#endif
624 } else if (LF == LibFunc_execl || LF == LibFunc_execle ||
625 LF == LibFunc_execlp || LF == LibFunc_execv ||
626 LF == LibFunc_execvp || LF == LibFunc_execve ||
627 LF == LibFunc_execvpe || LF == LibFunc_execvP) {
628 Execs.push_back(CI);
629 }
630 }
631 }
632 }
633 }
634 }
635
636 for (auto *F : Forks) {
637 IRBuilder<> Builder(F);
638 BasicBlock *Parent = F->getParent();
639 auto NextInst = ++F->getIterator();
640
641 // We've a fork so just reset the counters in the child process
642 FunctionType *FTy = FunctionType::get(Builder.getInt32Ty(), {}, false);
643 FunctionCallee GCOVFork = M->getOrInsertFunction(
644 "__gcov_fork", FTy,
645 TLI->getAttrList(Ctx, {}, /*Signed=*/true, /*Ret=*/true));
646 F->setCalledFunction(GCOVFork);
647
648 // We split just after the fork to have a counter for the lines after
649 // Anyway there's a bug:
650 // void foo() { fork(); }
651 // void bar() { foo(); blah(); }
652 // then "blah();" will be called 2 times but showed as 1
653 // because "blah()" belongs to the same block as "foo();"
654 Parent->splitBasicBlock(NextInst);
655
656 // back() is a br instruction with a debug location
657 // equals to the one from NextAfterFork
658 // So to avoid to have two debug locs on two blocks just change it
659 DebugLoc Loc = F->getDebugLoc();
660 Parent->back().setDebugLoc(Loc);
661 }
662
663 for (auto *E : Execs) {
664 IRBuilder<> Builder(E);
665 BasicBlock *Parent = E->getParent();
666 auto NextInst = ++E->getIterator();
667
668 // Since the process is replaced by a new one we need to write out gcdas
669 // No need to reset the counters since they'll be lost after the exec**
670 FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
671 FunctionCallee WriteoutF =
672 M->getOrInsertFunction("llvm_writeout_files", FTy);
673 Builder.CreateCall(WriteoutF);
674
675 DebugLoc Loc = E->getDebugLoc();
676 Builder.SetInsertPoint(&*NextInst);
677 // If the exec** fails we must reset the counters since they've been
678 // dumped
679 FunctionCallee ResetF = M->getOrInsertFunction("llvm_reset_counters", FTy);
680 Builder.CreateCall(ResetF)->setDebugLoc(Loc);
681 ExecBlocks.insert(Parent);
682 Parent->splitBasicBlock(NextInst);
683 Parent->back().setDebugLoc(Loc);
684 }
685
686 return !Forks.empty() || !Execs.empty();
687}
688
690 const DenseSet<const BasicBlock *> &ExecBlocks) {
691 if (E.InMST || E.Removed)
692 return nullptr;
693
694 BasicBlock *SrcBB = const_cast<BasicBlock *>(E.SrcBB);
695 BasicBlock *DestBB = const_cast<BasicBlock *>(E.DestBB);
696 // For a fake edge, instrument the real BB.
697 if (SrcBB == nullptr)
698 return DestBB;
699 if (DestBB == nullptr)
700 return SrcBB;
701
702 auto CanInstrument = [](BasicBlock *BB) -> BasicBlock * {
703 // There are basic blocks (such as catchswitch) cannot be instrumented.
704 // If the returned first insertion point is the end of BB, skip this BB.
705 if (BB->getFirstInsertionPt() == BB->end())
706 return nullptr;
707 return BB;
708 };
709
710 // Instrument the SrcBB if it has a single successor,
711 // otherwise, the DestBB if this is not a critical edge.
712 Instruction *TI = SrcBB->getTerminator();
713 if (TI->getNumSuccessors() <= 1 && !ExecBlocks.count(SrcBB))
714 return CanInstrument(SrcBB);
715 if (!E.IsCritical)
716 return CanInstrument(DestBB);
717
718 // Some IndirectBr critical edges cannot be split by the previous
719 // SplitIndirectBrCriticalEdges call. Bail out.
720 const unsigned SuccNum = GetSuccessorNumber(SrcBB, DestBB);
721 BasicBlock *InstrBB =
722 isa<IndirectBrInst>(TI) ? nullptr : SplitCriticalEdge(TI, SuccNum);
723 if (!InstrBB)
724 return nullptr;
725
726 MST.addEdge(SrcBB, InstrBB, 0);
727 MST.addEdge(InstrBB, DestBB, 0).InMST = true;
728 E.Removed = true;
729
730 return CanInstrument(InstrBB);
731}
732
733#ifndef NDEBUG
735 size_t ID = 0;
736 for (const auto &E : make_pointee_range(MST.allEdges())) {
737 GCOVBlock &Src = E.SrcBB ? GF.getBlock(E.SrcBB) : GF.getEntryBlock();
738 GCOVBlock &Dst = E.DestBB ? GF.getBlock(E.DestBB) : GF.getReturnBlock();
739 dbgs() << " Edge " << ID++ << ": " << Src.Number << "->" << Dst.Number
740 << E.infoString() << "\n";
741 }
742}
743#endif
744
745bool GCOVProfiler::emitProfileNotes(
746 NamedMDNode *CUNode, bool HasExecOrFork,
747 function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
748 function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
749 function_ref<const TargetLibraryInfo &(Function &F)> GetTLI) {
750 {
751 uint8_t c3 = Options.Version[0];
752 uint8_t c2 = Options.Version[1];
753 uint8_t c1 = Options.Version[2];
754 Version = c3 >= 'A' ? (c3 - 'A') * 100 + (c2 - '0') * 10 + c1 - '0'
755 : (c3 - '0') * 10 + c1 - '0';
756 }
757 // Emit .gcno files that are compatible with GCC 11.1.
758 if (Version < 111) {
759 Version = 111;
760 memcpy(Options.Version, "B11*", 4);
761 }
762
763 bool EmitGCDA = Options.EmitData;
764 for (unsigned i = 0, e = CUNode->getNumOperands(); i != e; ++i) {
765 // Each compile unit gets its own .gcno file. This means that whether we run
766 // this pass over the original .o's as they're produced, or run it after
767 // LTO, we'll generate the same .gcno files.
768
769 auto *CU = cast<DICompileUnit>(CUNode->getOperand(i));
770
771 // Skip module skeleton (and module) CUs.
772 if (CU->getDWOId())
773 continue;
774
775 std::vector<uint8_t> EdgeDestinations;
777
778 Endian = M->getDataLayout().isLittleEndian() ? llvm::endianness::little
780 unsigned FunctionIdent = 0;
781 for (auto &F : M->functions()) {
782 DISubprogram *SP = F.getSubprogram();
783 unsigned EndLine;
784 if (!SP) continue;
785 if (!functionHasLines(F, EndLine) || !isFunctionInstrumented(F))
786 continue;
787 // TODO: Functions using scope-based EH are currently not supported.
788 if (isUsingScopeBasedEH(F)) continue;
789 if (F.hasFnAttribute(llvm::Attribute::NoProfile))
790 continue;
791 if (F.hasFnAttribute(llvm::Attribute::SkipProfile))
792 continue;
793
794 // Add the function line number to the lines of the entry block
795 // to have a counter for the function definition.
796 uint32_t Line = SP->getLine();
797 auto Filename = getFilename(SP);
798
799 BranchProbabilityInfo *BPI = GetBPI(F);
800 BlockFrequencyInfo *BFI = GetBFI(F);
801
802 // Split indirectbr critical edges here before computing the MST rather
803 // than later in getInstrBB() to avoid invalidating it.
804 SplitIndirectBrCriticalEdges(F, /*IgnoreBlocksWithoutPHI=*/false, BPI,
805 BFI);
806
807 CFGMST<Edge, BBInfo> MST(F, /*InstrumentFuncEntry=*/false,
808 /*InstrumentLoopEntries=*/false, BPI, BFI);
809
810 // getInstrBB can split basic blocks and push elements to AllEdges.
811 for (size_t I : llvm::seq<size_t>(0, MST.numEdges())) {
812 auto &E = *MST.allEdges()[I];
813 // For now, disable spanning tree optimization when fork or exec* is
814 // used.
815 if (HasExecOrFork)
816 E.InMST = false;
817 E.Place = getInstrBB(MST, E, ExecBlocks);
818 }
819 // Basic blocks in F are finalized at this point.
820 BasicBlock &EntryBlock = F.getEntryBlock();
821 Funcs.push_back(std::make_unique<GCOVFunction>(this, &F, SP, EndLine,
822 FunctionIdent++, Version));
823 GCOVFunction &Func = *Funcs.back();
824
825 // Some non-tree edges are IndirectBr which cannot be split. Ignore them
826 // as well.
827 llvm::erase_if(MST.allEdges(), [](std::unique_ptr<Edge> &E) {
828 return E->Removed || (!E->InMST && !E->Place);
829 });
830 const size_t Measured =
831 std::stable_partition(
832 MST.allEdges().begin(), MST.allEdges().end(),
833 [](std::unique_ptr<Edge> &E) { return E->Place; }) -
834 MST.allEdges().begin();
835 for (size_t I : llvm::seq<size_t>(0, Measured)) {
836 Edge &E = *MST.allEdges()[I];
837 GCOVBlock &Src =
838 E.SrcBB ? Func.getBlock(E.SrcBB) : Func.getEntryBlock();
839 GCOVBlock &Dst =
840 E.DestBB ? Func.getBlock(E.DestBB) : Func.getReturnBlock();
841 E.SrcNumber = Src.Number;
842 E.DstNumber = Dst.Number;
843 }
844 std::stable_sort(
845 MST.allEdges().begin(), MST.allEdges().begin() + Measured,
846 [](const std::unique_ptr<Edge> &L, const std::unique_ptr<Edge> &R) {
847 return L->SrcNumber != R->SrcNumber ? L->SrcNumber < R->SrcNumber
848 : L->DstNumber < R->DstNumber;
849 });
850
851 for (const Edge &E : make_pointee_range(MST.allEdges())) {
852 GCOVBlock &Src =
853 E.SrcBB ? Func.getBlock(E.SrcBB) : Func.getEntryBlock();
854 GCOVBlock &Dst =
855 E.DestBB ? Func.getBlock(E.DestBB) : Func.getReturnBlock();
856 Src.addEdge(Dst, E.Place ? 0 : uint32_t(GCOV_ARC_ON_TREE));
857 }
858
859 // Artificial functions such as global initializers
860 if (!SP->isArtificial())
861 Func.getBlock(&EntryBlock).getFile(Filename).addLine(Line);
862
863 LLVM_DEBUG(dumpEdges(MST, Func));
864
865 for (auto &GB : Func.Blocks) {
866 const BasicBlock &BB = *GB.first;
867 auto &Block = GB.second;
868 for (auto Succ : Block.OutEdges) {
869 uint32_t Idx = Succ.first->Number;
870 do EdgeDestinations.push_back(Idx & 255);
871 while ((Idx >>= 8) > 0);
872 }
873
874 for (const auto &I : BB) {
875 const DebugLoc &Loc = I.getDebugLoc();
876 if (!Loc)
877 continue;
878
879 // Artificial lines such as calls to the global constructors.
880 if (Loc.getLine() == 0 || Loc.isImplicitCode())
881 continue;
882
883 if (Line == Loc.getLine()) continue;
884 Line = Loc.getLine();
885 MDNode *Scope = Loc.getScope();
886 if (SP != getDISubprogram(Scope))
887 continue;
888
889 GCOVLines &Lines = Block.getFile(getFilename(Loc->getScope()));
890 Lines.addLine(Loc.getLine());
891 }
892 Line = 0;
893 }
894 if (EmitGCDA) {
895 DISubprogram *SP = F.getSubprogram();
896 ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(*Ctx), Measured);
897 GlobalVariable *Counters = new GlobalVariable(
898 *M, CounterTy, false, GlobalValue::InternalLinkage,
899 Constant::getNullValue(CounterTy), "__llvm_gcov_ctr");
900 const llvm::Triple &Triple = M->getTargetTriple();
901 if (Triple.getObjectFormat() == llvm::Triple::XCOFF)
902 Counters->setSection("__llvm_gcov_ctr_section");
903 CountersBySP.emplace_back(Counters, SP);
904
905 for (size_t I : llvm::seq<size_t>(0, Measured)) {
906 const Edge &E = *MST.allEdges()[I];
907 IRBuilder<> Builder(E.Place->getFirstInsertionPt());
908 Value *V = Builder.CreateConstInBoundsGEP2_64(
909 Counters->getValueType(), Counters, 0, I);
910 // Disable sanitizers to decrease size bloat. We don't expect
911 // sanitizers to catch interesting issues.
912 Instruction *Inst;
913 if (Options.Atomic) {
914 Inst = Builder.CreateAtomicRMW(AtomicRMWInst::Add, V,
915 Builder.getInt64(1), MaybeAlign(),
916 AtomicOrdering::Monotonic);
917 } else {
918 LoadInst *OldCount =
919 Builder.CreateLoad(Builder.getInt64Ty(), V, "gcov_ctr");
920 OldCount->setNoSanitizeMetadata();
921 Value *NewCount = Builder.CreateAdd(OldCount, Builder.getInt64(1));
922 Inst = Builder.CreateStore(NewCount, V);
923 }
924 Inst->setNoSanitizeMetadata();
925 }
926 }
927 }
928
929 char Tmp[4];
930 JamCRC JC;
931 JC.update(EdgeDestinations);
932 uint32_t Stamp = JC.getCRC();
933 FileChecksums.push_back(Stamp);
934
935 if (Options.EmitNotes) {
936 std::error_code EC;
937 raw_fd_ostream out(mangleName(CU, GCovFileType::GCNO), EC,
939 if (EC) {
940 Ctx->emitError(
941 Twine("failed to open coverage notes file for writing: ") +
942 EC.message());
943 continue;
944 }
945 os = &out;
946 if (Endian == llvm::endianness::big) {
947 out.write("gcno", 4);
948 out.write(Options.Version, 4);
949 } else {
950 out.write("oncg", 4);
951 std::reverse_copy(Options.Version, Options.Version + 4, Tmp);
952 out.write(Tmp, 4);
953 }
954 write(Stamp);
955 writeString("."); // unuseful current_working_directory
956 write(0); // unuseful has_unexecuted_blocks
957
958 for (auto &Func : Funcs)
959 Func->writeOut(Stamp);
960
961 write(0);
962 write(0);
963 out.close();
964 }
965
966 if (EmitGCDA) {
967 const llvm::Triple &Triple = M->getTargetTriple();
968 if (Triple.getObjectFormat() == llvm::Triple::XCOFF)
969 emitModuleInitFunctionPtrs(CountersBySP);
970 else
971 emitGlobalConstructor(CountersBySP);
972 EmitGCDA = false;
973 }
974 }
975 return true;
976}
977
978Function *GCOVProfiler::createInternalFunction(FunctionType *FTy,
979 StringRef Name,
980 StringRef MangledType /*=""*/) {
982 FTy, GlobalValue::InternalLinkage, 0, Name, M);
983 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
984 F->addFnAttr(Attribute::NoUnwind);
985 if (Options.NoRedZone)
986 F->addFnAttr(Attribute::NoRedZone);
987 if (!MangledType.empty())
988 setKCFIType(*M, *F, MangledType);
989 return F;
990}
991
992void GCOVProfiler::emitGlobalConstructor(
993 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
994 Function *WriteoutF = insertCounterWriteout(CountersBySP);
995 Function *ResetF = insertReset(CountersBySP);
996
997 // Create a small bit of code that registers the "__llvm_gcov_writeout" to
998 // be executed at exit and the "__llvm_gcov_reset" function to be executed
999 // when "__gcov_flush" is called.
1000 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
1001 Function *F = createInternalFunction(FTy, "__llvm_gcov_init", "_ZTSFvvE");
1002 F->addFnAttr(Attribute::NoInline);
1003
1004 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
1005 IRBuilder<> Builder(BB);
1006
1007 FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
1008 auto *PFTy = PointerType::get(*Ctx, 0);
1009 FTy = FunctionType::get(Builder.getVoidTy(), {PFTy, PFTy}, false);
1010
1011 // Initialize the environment and register the local writeout, flush and
1012 // reset functions.
1013 FunctionCallee GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
1014 Builder.CreateCall(GCOVInit, {WriteoutF, ResetF});
1015 Builder.CreateRetVoid();
1016
1017 appendToGlobalCtors(*M, F, 0);
1018}
1019
1020void GCOVProfiler::emitModuleInitFunctionPtrs(
1021 SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) {
1022 Function *WriteoutF = insertCounterWriteout(CountersBySP);
1023 Function *ResetF = insertReset(CountersBySP);
1024
1025 // Instead of creating a function call and add it to the constructors list,
1026 // create a global variable in the __llvm_covinit section so the functions
1027 // can be registered by a constructor in the runtime.
1028
1029 auto &Ctx = M->getContext();
1030
1031 Type *InitFuncDataTy[] = {
1032#define COVINIT_FUNC(Type, LLVMType, Name, Init) LLVMType,
1034 };
1035
1036 auto STy = StructType::get(Ctx, ArrayRef(InitFuncDataTy));
1037
1038 Constant *InitFuncPtrs[] = {
1039#define COVINIT_FUNC(Type, LLVMType, Name, Init) Init,
1041 };
1042
1043 auto *CovInitGV =
1044 new GlobalVariable(*M, STy, false, GlobalValue::PrivateLinkage, nullptr,
1045 "__llvm_covinit_functions");
1046 CovInitGV->setInitializer(ConstantStruct::get(STy, InitFuncPtrs));
1047 CovInitGV->setVisibility(GlobalValue::VisibilityTypes::DefaultVisibility);
1048 CovInitGV->setSection(getInstrProfSectionName(
1049 IPSK_covinit, M->getTargetTriple().getObjectFormat()));
1050 CovInitGV->setAlignment(Align(INSTR_PROF_DATA_ALIGNMENT));
1051 CovInitGV->setConstant(true);
1052}
1053
1054FunctionCallee GCOVProfiler::getStartFileFunc(const TargetLibraryInfo *TLI) {
1055 Type *Args[] = {
1056 PointerType::getUnqual(*Ctx), // const char *orig_filename
1057 Type::getInt32Ty(*Ctx), // uint32_t version
1058 Type::getInt32Ty(*Ctx), // uint32_t checksum
1059 };
1060 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
1061 return M->getOrInsertFunction("llvm_gcda_start_file", FTy,
1062 TLI->getAttrList(Ctx, {1, 2}, /*Signed=*/false));
1063}
1064
1065FunctionCallee GCOVProfiler::getEmitFunctionFunc(const TargetLibraryInfo *TLI) {
1066 Type *Args[] = {
1067 Type::getInt32Ty(*Ctx), // uint32_t ident
1068 Type::getInt32Ty(*Ctx), // uint32_t func_checksum
1069 Type::getInt32Ty(*Ctx), // uint32_t cfg_checksum
1070 };
1071 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
1072 return M->getOrInsertFunction("llvm_gcda_emit_function", FTy,
1073 TLI->getAttrList(Ctx, {0, 1, 2}, /*Signed=*/false));
1074}
1075
1076FunctionCallee GCOVProfiler::getEmitArcsFunc(const TargetLibraryInfo *TLI) {
1077 Type *Args[] = {
1078 Type::getInt32Ty(*Ctx), // uint32_t num_counters
1079 PointerType::getUnqual(*Ctx), // uint64_t *counters
1080 };
1081 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
1082 return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy,
1083 TLI->getAttrList(Ctx, {0}, /*Signed=*/false));
1084}
1085
1086FunctionCallee GCOVProfiler::getSummaryInfoFunc() {
1087 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
1088 return M->getOrInsertFunction("llvm_gcda_summary_info", FTy);
1089}
1090
1091FunctionCallee GCOVProfiler::getEndFileFunc() {
1092 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
1093 return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
1094}
1095
1096Function *GCOVProfiler::insertCounterWriteout(
1097 ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
1098 FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
1099 Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
1100 if (!WriteoutF)
1101 WriteoutF =
1102 createInternalFunction(WriteoutFTy, "__llvm_gcov_writeout", "_ZTSFvvE");
1103 WriteoutF->addFnAttr(Attribute::NoInline);
1104
1105 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
1106 IRBuilder<> Builder(BB);
1107
1108 auto *TLI = &GetTLI(*WriteoutF);
1109
1110 FunctionCallee StartFile = getStartFileFunc(TLI);
1111 FunctionCallee EmitFunction = getEmitFunctionFunc(TLI);
1112 FunctionCallee EmitArcs = getEmitArcsFunc(TLI);
1113 FunctionCallee SummaryInfo = getSummaryInfoFunc();
1114 FunctionCallee EndFile = getEndFileFunc();
1115
1116 NamedMDNode *CUNodes = M->getNamedMetadata("llvm.dbg.cu");
1117 if (!CUNodes) {
1118 Builder.CreateRetVoid();
1119 return WriteoutF;
1120 }
1121
1122 // Collect the relevant data into a large constant data structure that we can
1123 // walk to write out everything.
1124 StructType *StartFileCallArgsTy = StructType::create(
1125 {Builder.getPtrTy(), Builder.getInt32Ty(), Builder.getInt32Ty()},
1126 "start_file_args_ty");
1127 StructType *EmitFunctionCallArgsTy = StructType::create(
1128 {Builder.getInt32Ty(), Builder.getInt32Ty(), Builder.getInt32Ty()},
1129 "emit_function_args_ty");
1130 auto *PtrTy = Builder.getPtrTy();
1131 StructType *EmitArcsCallArgsTy =
1132 StructType::create({Builder.getInt32Ty(), PtrTy}, "emit_arcs_args_ty");
1133 StructType *FileInfoTy = StructType::create(
1134 {StartFileCallArgsTy, Builder.getInt32Ty(), PtrTy, PtrTy}, "file_info");
1135
1137 for (int i : llvm::seq<int>(0, CUNodes->getNumOperands())) {
1138 auto *CU = cast<DICompileUnit>(CUNodes->getOperand(i));
1139
1140 // Skip module skeleton (and module) CUs.
1141 if (CU->getDWOId())
1142 continue;
1143
1144 std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA);
1145 uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i];
1146 auto *StartFileCallArgs = ConstantStruct::get(
1147 StartFileCallArgsTy,
1148 {Builder.CreateGlobalString(FilenameGcda),
1149 Builder.getInt32(endian::read32be(Options.Version)),
1150 Builder.getInt32(CfgChecksum)});
1151
1152 SmallVector<Constant *, 8> EmitFunctionCallArgsArray;
1153 SmallVector<Constant *, 8> EmitArcsCallArgsArray;
1154 for (int j : llvm::seq<int>(0, CountersBySP.size())) {
1155 uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum();
1156 EmitFunctionCallArgsArray.push_back(ConstantStruct::get(
1157 EmitFunctionCallArgsTy,
1158 {Builder.getInt32(j),
1159 Builder.getInt32(FuncChecksum),
1160 Builder.getInt32(CfgChecksum)}));
1161
1162 GlobalVariable *GV = CountersBySP[j].first;
1163 unsigned Arcs = cast<ArrayType>(GV->getValueType())->getNumElements();
1164 EmitArcsCallArgsArray.push_back(ConstantStruct::get(
1165 EmitArcsCallArgsTy, {Builder.getInt32(Arcs), GV}));
1166 }
1167 // Create global arrays for the two emit calls.
1168 int CountersSize = CountersBySP.size();
1169 assert(CountersSize == (int)EmitFunctionCallArgsArray.size() &&
1170 "Mismatched array size!");
1171 assert(CountersSize == (int)EmitArcsCallArgsArray.size() &&
1172 "Mismatched array size!");
1173 auto *EmitFunctionCallArgsArrayTy =
1174 ArrayType::get(EmitFunctionCallArgsTy, CountersSize);
1175 auto *EmitFunctionCallArgsArrayGV = new GlobalVariable(
1176 *M, EmitFunctionCallArgsArrayTy, /*isConstant*/ true,
1178 ConstantArray::get(EmitFunctionCallArgsArrayTy,
1179 EmitFunctionCallArgsArray),
1180 Twine("__llvm_internal_gcov_emit_function_args.") + Twine(i));
1181 auto *EmitArcsCallArgsArrayTy =
1182 ArrayType::get(EmitArcsCallArgsTy, CountersSize);
1183 EmitFunctionCallArgsArrayGV->setUnnamedAddr(
1184 GlobalValue::UnnamedAddr::Global);
1185 auto *EmitArcsCallArgsArrayGV = new GlobalVariable(
1186 *M, EmitArcsCallArgsArrayTy, /*isConstant*/ true,
1188 ConstantArray::get(EmitArcsCallArgsArrayTy, EmitArcsCallArgsArray),
1189 Twine("__llvm_internal_gcov_emit_arcs_args.") + Twine(i));
1190 EmitArcsCallArgsArrayGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
1191
1192 FileInfos.push_back(ConstantStruct::get(
1193 FileInfoTy, {StartFileCallArgs, Builder.getInt32(CountersSize),
1194 EmitFunctionCallArgsArrayGV, EmitArcsCallArgsArrayGV}));
1195 }
1196
1197 // If we didn't find anything to actually emit, bail on out.
1198 if (FileInfos.empty()) {
1199 Builder.CreateRetVoid();
1200 return WriteoutF;
1201 }
1202
1203 // To simplify code, we cap the number of file infos we write out to fit
1204 // easily in a 32-bit signed integer. This gives consistent behavior between
1205 // 32-bit and 64-bit systems without requiring (potentially very slow) 64-bit
1206 // operations on 32-bit systems. It also seems unreasonable to try to handle
1207 // more than 2 billion files.
1208 if ((int64_t)FileInfos.size() > (int64_t)INT_MAX)
1209 FileInfos.resize(INT_MAX);
1210
1211 // Create a global for the entire data structure so we can walk it more
1212 // easily.
1213 auto *FileInfoArrayTy = ArrayType::get(FileInfoTy, FileInfos.size());
1214 auto *FileInfoArrayGV = new GlobalVariable(
1215 *M, FileInfoArrayTy, /*isConstant*/ true, GlobalValue::InternalLinkage,
1216 ConstantArray::get(FileInfoArrayTy, FileInfos),
1217 "__llvm_internal_gcov_emit_file_info");
1218 FileInfoArrayGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
1219
1220 // Create the CFG for walking this data structure.
1221 auto *FileLoopHeader =
1222 BasicBlock::Create(*Ctx, "file.loop.header", WriteoutF);
1223 auto *CounterLoopHeader =
1224 BasicBlock::Create(*Ctx, "counter.loop.header", WriteoutF);
1225 auto *FileLoopLatch = BasicBlock::Create(*Ctx, "file.loop.latch", WriteoutF);
1226 auto *ExitBB = BasicBlock::Create(*Ctx, "exit", WriteoutF);
1227
1228 // We always have at least one file, so just branch to the header.
1229 Builder.CreateBr(FileLoopHeader);
1230
1231 // The index into the files structure is our loop induction variable.
1232 Builder.SetInsertPoint(FileLoopHeader);
1233 PHINode *IV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2,
1234 "file_idx");
1235 IV->addIncoming(Builder.getInt32(0), BB);
1236 auto *FileInfoPtr = Builder.CreateInBoundsGEP(
1237 FileInfoArrayTy, FileInfoArrayGV, {Builder.getInt32(0), IV});
1238 auto *StartFileCallArgsPtr =
1239 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0, "start_file_args");
1240 auto *StartFileCall = Builder.CreateCall(
1241 StartFile,
1242 {Builder.CreateLoad(StartFileCallArgsTy->getElementType(0),
1243 Builder.CreateStructGEP(StartFileCallArgsTy,
1244 StartFileCallArgsPtr, 0),
1245 "filename"),
1246 Builder.CreateLoad(StartFileCallArgsTy->getElementType(1),
1247 Builder.CreateStructGEP(StartFileCallArgsTy,
1248 StartFileCallArgsPtr, 1),
1249 "version"),
1250 Builder.CreateLoad(StartFileCallArgsTy->getElementType(2),
1251 Builder.CreateStructGEP(StartFileCallArgsTy,
1252 StartFileCallArgsPtr, 2),
1253 "stamp")});
1254 if (auto AK = TLI->getExtAttrForI32Param(false))
1255 StartFileCall->addParamAttr(2, AK);
1256 auto *NumCounters = Builder.CreateLoad(
1257 FileInfoTy->getElementType(1),
1258 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1), "num_ctrs");
1259 auto *EmitFunctionCallArgsArray =
1260 Builder.CreateLoad(FileInfoTy->getElementType(2),
1261 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2),
1262 "emit_function_args");
1263 auto *EmitArcsCallArgsArray = Builder.CreateLoad(
1264 FileInfoTy->getElementType(3),
1265 Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3), "emit_arcs_args");
1266 auto *EnterCounterLoopCond =
1267 Builder.CreateICmpSLT(Builder.getInt32(0), NumCounters);
1268 Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch);
1269
1270 Builder.SetInsertPoint(CounterLoopHeader);
1271 auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2,
1272 "ctr_idx");
1273 JV->addIncoming(Builder.getInt32(0), FileLoopHeader);
1274 auto *EmitFunctionCallArgsPtr = Builder.CreateInBoundsGEP(
1275 EmitFunctionCallArgsTy, EmitFunctionCallArgsArray, JV);
1276 auto *EmitFunctionCall = Builder.CreateCall(
1277 EmitFunction,
1278 {Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(0),
1279 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1280 EmitFunctionCallArgsPtr, 0),
1281 "ident"),
1282 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(1),
1283 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1284 EmitFunctionCallArgsPtr, 1),
1285 "func_checkssum"),
1286 Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
1287 Builder.CreateStructGEP(EmitFunctionCallArgsTy,
1288 EmitFunctionCallArgsPtr, 2),
1289 "cfg_checksum")});
1290 if (auto AK = TLI->getExtAttrForI32Param(false)) {
1291 EmitFunctionCall->addParamAttr(0, AK);
1292 EmitFunctionCall->addParamAttr(1, AK);
1293 EmitFunctionCall->addParamAttr(2, AK);
1294 }
1295 auto *EmitArcsCallArgsPtr =
1296 Builder.CreateInBoundsGEP(EmitArcsCallArgsTy, EmitArcsCallArgsArray, JV);
1297 auto *EmitArcsCall = Builder.CreateCall(
1298 EmitArcs,
1299 {Builder.CreateLoad(
1300 EmitArcsCallArgsTy->getElementType(0),
1301 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0),
1302 "num_counters"),
1303 Builder.CreateLoad(
1304 EmitArcsCallArgsTy->getElementType(1),
1305 Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 1),
1306 "counters")});
1307 if (auto AK = TLI->getExtAttrForI32Param(false))
1308 EmitArcsCall->addParamAttr(0, AK);
1309 auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1));
1310 auto *CounterLoopCond = Builder.CreateICmpSLT(NextJV, NumCounters);
1311 Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch);
1312 JV->addIncoming(NextJV, CounterLoopHeader);
1313
1314 Builder.SetInsertPoint(FileLoopLatch);
1315 Builder.CreateCall(SummaryInfo, {});
1316 Builder.CreateCall(EndFile, {});
1317 auto *NextIV = Builder.CreateAdd(IV, Builder.getInt32(1), "next_file_idx");
1318 auto *FileLoopCond =
1319 Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.size()));
1320 Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB);
1321 IV->addIncoming(NextIV, FileLoopLatch);
1322
1323 Builder.SetInsertPoint(ExitBB);
1324 Builder.CreateRetVoid();
1325
1326 return WriteoutF;
1327}
1328
1329Function *GCOVProfiler::insertReset(
1330 ArrayRef<std::pair<GlobalVariable *, MDNode *>> CountersBySP) {
1331 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
1332 Function *ResetF = M->getFunction("__llvm_gcov_reset");
1333 if (!ResetF)
1334 ResetF = createInternalFunction(FTy, "__llvm_gcov_reset", "_ZTSFvvE");
1335 ResetF->addFnAttr(Attribute::NoInline);
1336
1337 BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", ResetF);
1338 IRBuilder<> Builder(Entry);
1339 LLVMContext &C = Entry->getContext();
1340
1341 // Zero out the counters.
1342 for (const auto &I : CountersBySP) {
1343 GlobalVariable *GV = I.first;
1344 auto *GVTy = cast<ArrayType>(GV->getValueType());
1345 Builder.CreateMemSet(GV, Constant::getNullValue(Type::getInt8Ty(C)),
1346 GVTy->getNumElements() *
1347 GVTy->getElementType()->getScalarSizeInBits() / 8,
1348 GV->getAlign());
1349 }
1350
1351 Type *RetTy = ResetF->getReturnType();
1352 if (RetTy->isVoidTy())
1353 Builder.CreateRetVoid();
1354 else if (RetTy->isIntegerTy())
1355 // Used if __llvm_gcov_reset was implicitly declared.
1356 Builder.CreateRet(ConstantInt::get(RetTy, 0));
1357 else
1358 report_fatal_error("invalid return type for __llvm_gcov_reset");
1359
1360 return ResetF;
1361}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
uint64_t uint64_t
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 GCOVOptions getDefaultOptions(const InstrumentationOptions &Opts)
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 StringRef getFunctionName(const DISubprogram *SP)
@ GCOV_TAG_LINES
Definition GCOV.cpp:38
@ GCOV_ARC_ON_TREE
Definition GCOV.cpp:32
@ GCOV_TAG_ARCS
Definition GCOV.cpp:37
@ GCOV_TAG_FUNCTION
Definition GCOV.cpp:35
@ GCOV_TAG_BLOCKS
Definition GCOV.cpp:36
Module.h This file contains the declarations for the Module class.
#define INSTR_PROF_DATA_ALIGNMENT
static LVOptions Options
Definition LVOptions.cpp:25
static void addEdge(SmallVectorImpl< LazyCallGraph::Edge > &Edges, DenseMap< LazyCallGraph::Node *, int > &EdgeIndexMap, LazyCallGraph::Node &N, LazyCallGraph::Edge::Kind EK)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
static constexpr StringLiteral Filename
#define P(N)
FunctionAnalysisManager FAM
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
Provides some synthesis utilities to produce sequences of values.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Defines the virtual file system interface vfs::FileSystem.
Value * RHS
static const uint32_t IV[8]
Definition blake3_impl.h:83
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
@ Add
*p = old + v
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:453
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.
Definition BasicBlock.h:213
const Instruction & back() const
Definition BasicBlock.h:465
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Analysis pass which computes BlockFrequencyInfo.
Analysis pass which computes BranchProbabilityInfo.
An union-find based Minimum Spanning Tree for CFG.
Definition CFGMST.h:41
Edge & addEdge(BasicBlock *Src, BasicBlock *Dest, uint64_t W)
Definition CFGMST.h:329
const std::vector< std::unique_ptr< Edge > > & allEdges() const
Definition CFGMST.h:366
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
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.
A debug info location.
Definition DebugLoc.h:126
LLVM_ABI unsigned getLine() const
Definition DebugLoc.cpp:43
LLVM_ABI MDNode * getScope() const
Definition DebugLoc.cpp:53
LLVM_ABI bool isImplicitCode() const
Check if the DebugLoc corresponds to an implicit code.
Definition DebugLoc.cpp:83
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition Function.cpp:641
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.
Definition Function.cpp:372
Type * getReturnType() const
Returns the type of the ret val.
Definition Function.h:217
GCOVBlock - Collects block information.
Definition GCOV.h:283
GCOVFunction - Collects function information.
Definition GCOV.h:237
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
Type * getValueType() const
MaybeAlign getAlign() const
Returns the alignment of the given variable.
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.
uint32_t getCRC() const
Definition CRC.h:77
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Definition CRC.cpp:103
LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:615
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
LLVM_ABI MDNode * getOperand(unsigned i) const
LLVM_ABI unsigned getNumOperands() const
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
iterator end()
Definition StringMap.h:214
iterator find(StringRef Key)
Definition StringMap.h:227
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
Definition StringRef.h:138
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.
Definition Type.cpp:467
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Definition Type.cpp:662
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.
ObjectFormatType getObjectFormat() const
Get the object format for this triple.
Definition Triple.h:539
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:141
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition DenseSet.h:187
self_iterator getIterator()
Definition ilist_node.h:123
virtual llvm::ErrorOr< std::string > getCurrentWorkingDirectory() const =0
Get the working directory of this file system.
virtual bool exists(const Twine &Path)
Check whether Path exists.
virtual std::error_code makeAbsolute(SmallVectorImpl< char > &Path) const
Make Path an absolute path.
virtual std::error_code getRealPath(const Twine &Path, SmallVectorImpl< char > &Output)
Gets real path of Path e.g.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
constexpr MCPhysReg SP
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
void write32(void *P, uint32_t V, endianness E)
Definition Endian.h:435
uint32_t read32be(const void *P)
Definition Endian.h:421
LLVM_ABI void replace_extension(SmallVectorImpl< char > &path, const Twine &extension, Style style=Style::native)
Replace the file extension of path with extension.
Definition Path.cpp:491
LLVM_ABI bool remove_dots(SmallVectorImpl< char > &path, bool remove_dot_dot=false, Style style=Style::native)
Remove '.
Definition Path.cpp:779
LLVM_ABI StringRef filename(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get filename.
Definition Path.cpp:594
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:467
This is an optimization pass for GlobalISel generic memory operations.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
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...
Definition CFG.cpp:90
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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,...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
iterator_range< pointee_iterator< WrappedIteratorT > > make_pointee_range(RangeT &&Range)
Definition iterator.h:341
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
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...
Definition Casting.h:547
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.
Definition Casting.h:559
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2208
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
endianness
Definition bit.h:71
LLVM_ABI Error write(DWPWriter &Out, ArrayRef< std::string > Inputs, OnCuIndexOverflow OverflowOptValue, Dwarf64StrOffsetsPromotion StrOffsetsOptValue, raw_pwrite_stream *OS=nullptr)
Definition DWP.cpp:746
LLVM_ABI DISubprogram * getDISubprogram(const MDNode *Scope)
Find subprogram that is enclosing this scope.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
#define N