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