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