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