GCOVProfiling.cpp 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  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. #include "llvm/ADT/DenseMap.h"
  16. #include "llvm/ADT/Hashing.h"
  17. #include "llvm/ADT/STLExtras.h"
  18. #include "llvm/ADT/Sequence.h"
  19. #include "llvm/ADT/Statistic.h"
  20. #include "llvm/ADT/StringExtras.h"
  21. #include "llvm/ADT/StringMap.h"
  22. #include "llvm/Analysis/EHPersonalities.h"
  23. #include "llvm/Analysis/TargetLibraryInfo.h"
  24. #include "llvm/IR/CFG.h"
  25. #include "llvm/IR/DebugInfo.h"
  26. #include "llvm/IR/DebugLoc.h"
  27. #include "llvm/IR/IRBuilder.h"
  28. #include "llvm/IR/InstIterator.h"
  29. #include "llvm/IR/Instructions.h"
  30. #include "llvm/IR/IntrinsicInst.h"
  31. #include "llvm/IR/Module.h"
  32. #include "llvm/Pass.h"
  33. #include "llvm/Support/CommandLine.h"
  34. #include "llvm/Support/Debug.h"
  35. #include "llvm/Support/FileSystem.h"
  36. #include "llvm/Support/Path.h"
  37. #include "llvm/Support/Regex.h"
  38. #include "llvm/Support/raw_ostream.h"
  39. #include "llvm/Transforms/Instrumentation.h"
  40. #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
  41. #include "llvm/Transforms/Utils/ModuleUtils.h"
  42. #include <algorithm>
  43. #include <memory>
  44. #include <string>
  45. #include <utility>
  46. using namespace llvm;
  47. #define DEBUG_TYPE "insert-gcov-profiling"
  48. static cl::opt<std::string>
  49. DefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden,
  50. cl::ValueRequired);
  51. static cl::opt<bool> DefaultExitBlockBeforeBody("gcov-exit-block-before-body",
  52. cl::init(false), cl::Hidden);
  53. GCOVOptions GCOVOptions::getDefault() {
  54. GCOVOptions Options;
  55. Options.EmitNotes = true;
  56. Options.EmitData = true;
  57. Options.UseCfgChecksum = false;
  58. Options.NoRedZone = false;
  59. Options.FunctionNamesInData = true;
  60. Options.ExitBlockBeforeBody = DefaultExitBlockBeforeBody;
  61. if (DefaultGCOVVersion.size() != 4) {
  62. llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") +
  63. DefaultGCOVVersion);
  64. }
  65. memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4);
  66. return Options;
  67. }
  68. namespace {
  69. class GCOVFunction;
  70. class GCOVProfiler {
  71. public:
  72. GCOVProfiler() : GCOVProfiler(GCOVOptions::getDefault()) {}
  73. GCOVProfiler(const GCOVOptions &Opts) : Options(Opts) {
  74. assert((Options.EmitNotes || Options.EmitData) &&
  75. "GCOVProfiler asked to do nothing?");
  76. ReversedVersion[0] = Options.Version[3];
  77. ReversedVersion[1] = Options.Version[2];
  78. ReversedVersion[2] = Options.Version[1];
  79. ReversedVersion[3] = Options.Version[0];
  80. ReversedVersion[4] = '\0';
  81. }
  82. bool runOnModule(Module &M, const TargetLibraryInfo &TLI);
  83. private:
  84. // Create the .gcno files for the Module based on DebugInfo.
  85. void emitProfileNotes();
  86. // Modify the program to track transitions along edges and call into the
  87. // profiling runtime to emit .gcda files when run.
  88. bool emitProfileArcs();
  89. bool isFunctionInstrumented(const Function &F);
  90. std::vector<Regex> createRegexesFromString(StringRef RegexesStr);
  91. static bool doesFilenameMatchARegex(StringRef Filename,
  92. std::vector<Regex> &Regexes);
  93. // Get pointers to the functions in the runtime library.
  94. FunctionCallee getStartFileFunc();
  95. FunctionCallee getEmitFunctionFunc();
  96. FunctionCallee getEmitArcsFunc();
  97. FunctionCallee getSummaryInfoFunc();
  98. FunctionCallee getEndFileFunc();
  99. // Add the function to write out all our counters to the global destructor
  100. // list.
  101. Function *
  102. insertCounterWriteout(ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
  103. Function *insertFlush(ArrayRef<std::pair<GlobalVariable *, MDNode *>>);
  104. void AddFlushBeforeForkAndExec();
  105. enum class GCovFileType { GCNO, GCDA };
  106. std::string mangleName(const DICompileUnit *CU, GCovFileType FileType);
  107. GCOVOptions Options;
  108. // Reversed, NUL-terminated copy of Options.Version.
  109. char ReversedVersion[5];
  110. // Checksum, produced by hash of EdgeDestinations
  111. SmallVector<uint32_t, 4> FileChecksums;
  112. Module *M;
  113. const TargetLibraryInfo *TLI;
  114. LLVMContext *Ctx;
  115. SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs;
  116. std::vector<Regex> FilterRe;
  117. std::vector<Regex> ExcludeRe;
  118. StringMap<bool> InstrumentedFiles;
  119. };
  120. class GCOVProfilerLegacyPass : public ModulePass {
  121. public:
  122. static char ID;
  123. GCOVProfilerLegacyPass()
  124. : GCOVProfilerLegacyPass(GCOVOptions::getDefault()) {}
  125. GCOVProfilerLegacyPass(const GCOVOptions &Opts)
  126. : ModulePass(ID), Profiler(Opts) {
  127. initializeGCOVProfilerLegacyPassPass(*PassRegistry::getPassRegistry());
  128. }
  129. StringRef getPassName() const override { return "GCOV Profiler"; }
  130. bool runOnModule(Module &M) override {
  131. auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
  132. return Profiler.runOnModule(M, TLI);
  133. }
  134. void getAnalysisUsage(AnalysisUsage &AU) const override {
  135. AU.addRequired<TargetLibraryInfoWrapperPass>();
  136. }
  137. private:
  138. GCOVProfiler Profiler;
  139. };
  140. }
  141. char GCOVProfilerLegacyPass::ID = 0;
  142. INITIALIZE_PASS_BEGIN(
  143. GCOVProfilerLegacyPass, "insert-gcov-profiling",
  144. "Insert instrumentation for GCOV profiling", false, false)
  145. INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
  146. INITIALIZE_PASS_END(
  147. GCOVProfilerLegacyPass, "insert-gcov-profiling",
  148. "Insert instrumentation for GCOV profiling", false, false)
  149. ModulePass *llvm::createGCOVProfilerPass(const GCOVOptions &Options) {
  150. return new GCOVProfilerLegacyPass(Options);
  151. }
  152. static StringRef getFunctionName(const DISubprogram *SP) {
  153. if (!SP->getLinkageName().empty())
  154. return SP->getLinkageName();
  155. return SP->getName();
  156. }
  157. /// Extract a filename for a DISubprogram.
  158. ///
  159. /// Prefer relative paths in the coverage notes. Clang also may split
  160. /// up absolute paths into a directory and filename component. When
  161. /// the relative path doesn't exist, reconstruct the absolute path.
  162. static SmallString<128> getFilename(const DISubprogram *SP) {
  163. SmallString<128> Path;
  164. StringRef RelPath = SP->getFilename();
  165. if (sys::fs::exists(RelPath))
  166. Path = RelPath;
  167. else
  168. sys::path::append(Path, SP->getDirectory(), SP->getFilename());
  169. return Path;
  170. }
  171. namespace {
  172. class GCOVRecord {
  173. protected:
  174. static const char *const LinesTag;
  175. static const char *const FunctionTag;
  176. static const char *const BlockTag;
  177. static const char *const EdgeTag;
  178. GCOVRecord() = default;
  179. void writeBytes(const char *Bytes, int Size) {
  180. os->write(Bytes, Size);
  181. }
  182. void write(uint32_t i) {
  183. writeBytes(reinterpret_cast<char*>(&i), 4);
  184. }
  185. // Returns the length measured in 4-byte blocks that will be used to
  186. // represent this string in a GCOV file
  187. static unsigned lengthOfGCOVString(StringRef s) {
  188. // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
  189. // padding out to the next 4-byte word. The length is measured in 4-byte
  190. // words including padding, not bytes of actual string.
  191. return (s.size() / 4) + 1;
  192. }
  193. void writeGCOVString(StringRef s) {
  194. uint32_t Len = lengthOfGCOVString(s);
  195. write(Len);
  196. writeBytes(s.data(), s.size());
  197. // Write 1 to 4 bytes of NUL padding.
  198. assert((unsigned)(4 - (s.size() % 4)) > 0);
  199. assert((unsigned)(4 - (s.size() % 4)) <= 4);
  200. writeBytes("\0\0\0\0", 4 - (s.size() % 4));
  201. }
  202. raw_ostream *os;
  203. };
  204. const char *const GCOVRecord::LinesTag = "\0\0\x45\x01";
  205. const char *const GCOVRecord::FunctionTag = "\0\0\0\1";
  206. const char *const GCOVRecord::BlockTag = "\0\0\x41\x01";
  207. const char *const GCOVRecord::EdgeTag = "\0\0\x43\x01";
  208. class GCOVFunction;
  209. class GCOVBlock;
  210. // Constructed only by requesting it from a GCOVBlock, this object stores a
  211. // list of line numbers and a single filename, representing lines that belong
  212. // to the block.
  213. class GCOVLines : public GCOVRecord {
  214. public:
  215. void addLine(uint32_t Line) {
  216. assert(Line != 0 && "Line zero is not a valid real line number.");
  217. Lines.push_back(Line);
  218. }
  219. uint32_t length() const {
  220. // Here 2 = 1 for string length + 1 for '0' id#.
  221. return lengthOfGCOVString(Filename) + 2 + Lines.size();
  222. }
  223. void writeOut() {
  224. write(0);
  225. writeGCOVString(Filename);
  226. for (int i = 0, e = Lines.size(); i != e; ++i)
  227. write(Lines[i]);
  228. }
  229. GCOVLines(StringRef F, raw_ostream *os)
  230. : Filename(F) {
  231. this->os = os;
  232. }
  233. private:
  234. std::string Filename;
  235. SmallVector<uint32_t, 32> Lines;
  236. };
  237. // Represent a basic block in GCOV. Each block has a unique number in the
  238. // function, number of lines belonging to each block, and a set of edges to
  239. // other blocks.
  240. class GCOVBlock : public GCOVRecord {
  241. public:
  242. GCOVLines &getFile(StringRef Filename) {
  243. return LinesByFile.try_emplace(Filename, Filename, os).first->second;
  244. }
  245. void addEdge(GCOVBlock &Successor) {
  246. OutEdges.push_back(&Successor);
  247. }
  248. void writeOut() {
  249. uint32_t Len = 3;
  250. SmallVector<StringMapEntry<GCOVLines> *, 32> SortedLinesByFile;
  251. for (auto &I : LinesByFile) {
  252. Len += I.second.length();
  253. SortedLinesByFile.push_back(&I);
  254. }
  255. writeBytes(LinesTag, 4);
  256. write(Len);
  257. write(Number);
  258. llvm::sort(SortedLinesByFile, [](StringMapEntry<GCOVLines> *LHS,
  259. StringMapEntry<GCOVLines> *RHS) {
  260. return LHS->getKey() < RHS->getKey();
  261. });
  262. for (auto &I : SortedLinesByFile)
  263. I->getValue().writeOut();
  264. write(0);
  265. write(0);
  266. }
  267. GCOVBlock(const GCOVBlock &RHS) : GCOVRecord(RHS), Number(RHS.Number) {
  268. // Only allow copy before edges and lines have been added. After that,
  269. // there are inter-block pointers (eg: edges) that won't take kindly to
  270. // blocks being copied or moved around.
  271. assert(LinesByFile.empty());
  272. assert(OutEdges.empty());
  273. }
  274. private:
  275. friend class GCOVFunction;
  276. GCOVBlock(uint32_t Number, raw_ostream *os)
  277. : Number(Number) {
  278. this->os = os;
  279. }
  280. uint32_t Number;
  281. StringMap<GCOVLines> LinesByFile;
  282. SmallVector<GCOVBlock *, 4> OutEdges;
  283. };
  284. // A function has a unique identifier, a checksum (we leave as zero) and a
  285. // set of blocks and a map of edges between blocks. This is the only GCOV
  286. // object users can construct, the blocks and lines will be rooted here.
  287. class GCOVFunction : public GCOVRecord {
  288. public:
  289. GCOVFunction(const DISubprogram *SP, Function *F, raw_ostream *os,
  290. uint32_t Ident, bool UseCfgChecksum, bool ExitBlockBeforeBody)
  291. : SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0),
  292. ReturnBlock(1, os) {
  293. this->os = os;
  294. LLVM_DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n");
  295. uint32_t i = 0;
  296. for (auto &BB : *F) {
  297. // Skip index 1 if it's assigned to the ReturnBlock.
  298. if (i == 1 && ExitBlockBeforeBody)
  299. ++i;
  300. Blocks.insert(std::make_pair(&BB, GCOVBlock(i++, os)));
  301. }
  302. if (!ExitBlockBeforeBody)
  303. ReturnBlock.Number = i;
  304. std::string FunctionNameAndLine;
  305. raw_string_ostream FNLOS(FunctionNameAndLine);
  306. FNLOS << getFunctionName(SP) << SP->getLine();
  307. FNLOS.flush();
  308. FuncChecksum = hash_value(FunctionNameAndLine);
  309. }
  310. GCOVBlock &getBlock(BasicBlock *BB) {
  311. return Blocks.find(BB)->second;
  312. }
  313. GCOVBlock &getReturnBlock() {
  314. return ReturnBlock;
  315. }
  316. std::string getEdgeDestinations() {
  317. std::string EdgeDestinations;
  318. raw_string_ostream EDOS(EdgeDestinations);
  319. Function *F = Blocks.begin()->first->getParent();
  320. for (BasicBlock &I : *F) {
  321. GCOVBlock &Block = getBlock(&I);
  322. for (int i = 0, e = Block.OutEdges.size(); i != e; ++i)
  323. EDOS << Block.OutEdges[i]->Number;
  324. }
  325. return EdgeDestinations;
  326. }
  327. uint32_t getFuncChecksum() {
  328. return FuncChecksum;
  329. }
  330. void setCfgChecksum(uint32_t Checksum) {
  331. CfgChecksum = Checksum;
  332. }
  333. void writeOut() {
  334. writeBytes(FunctionTag, 4);
  335. SmallString<128> Filename = getFilename(SP);
  336. uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(getFunctionName(SP)) +
  337. 1 + lengthOfGCOVString(Filename) + 1;
  338. if (UseCfgChecksum)
  339. ++BlockLen;
  340. write(BlockLen);
  341. write(Ident);
  342. write(FuncChecksum);
  343. if (UseCfgChecksum)
  344. write(CfgChecksum);
  345. writeGCOVString(getFunctionName(SP));
  346. writeGCOVString(Filename);
  347. write(SP->getLine());
  348. // Emit count of blocks.
  349. writeBytes(BlockTag, 4);
  350. write(Blocks.size() + 1);
  351. for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
  352. write(0); // No flags on our blocks.
  353. }
  354. LLVM_DEBUG(dbgs() << Blocks.size() << " blocks.\n");
  355. // Emit edges between blocks.
  356. if (Blocks.empty()) return;
  357. Function *F = Blocks.begin()->first->getParent();
  358. for (BasicBlock &I : *F) {
  359. GCOVBlock &Block = getBlock(&I);
  360. if (Block.OutEdges.empty()) continue;
  361. writeBytes(EdgeTag, 4);
  362. write(Block.OutEdges.size() * 2 + 1);
  363. write(Block.Number);
  364. for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
  365. LLVM_DEBUG(dbgs() << Block.Number << " -> "
  366. << Block.OutEdges[i]->Number << "\n");
  367. write(Block.OutEdges[i]->Number);
  368. write(0); // no flags
  369. }
  370. }
  371. // Emit lines for each block.
  372. for (BasicBlock &I : *F)
  373. getBlock(&I).writeOut();
  374. }
  375. private:
  376. const DISubprogram *SP;
  377. uint32_t Ident;
  378. uint32_t FuncChecksum;
  379. bool UseCfgChecksum;
  380. uint32_t CfgChecksum;
  381. DenseMap<BasicBlock *, GCOVBlock> Blocks;
  382. GCOVBlock ReturnBlock;
  383. };
  384. }
  385. // RegexesStr is a string containing differents regex separated by a semi-colon.
  386. // For example "foo\..*$;bar\..*$".
  387. std::vector<Regex> GCOVProfiler::createRegexesFromString(StringRef RegexesStr) {
  388. std::vector<Regex> Regexes;
  389. while (!RegexesStr.empty()) {
  390. std::pair<StringRef, StringRef> HeadTail = RegexesStr.split(';');
  391. if (!HeadTail.first.empty()) {
  392. Regex Re(HeadTail.first);
  393. std::string Err;
  394. if (!Re.isValid(Err)) {
  395. Ctx->emitError(Twine("Regex ") + HeadTail.first +
  396. " is not valid: " + Err);
  397. }
  398. Regexes.emplace_back(std::move(Re));
  399. }
  400. RegexesStr = HeadTail.second;
  401. }
  402. return Regexes;
  403. }
  404. bool GCOVProfiler::doesFilenameMatchARegex(StringRef Filename,
  405. std::vector<Regex> &Regexes) {
  406. for (Regex &Re : Regexes) {
  407. if (Re.match(Filename)) {
  408. return true;
  409. }
  410. }
  411. return false;
  412. }
  413. bool GCOVProfiler::isFunctionInstrumented(const Function &F) {
  414. if (FilterRe.empty() && ExcludeRe.empty()) {
  415. return true;
  416. }
  417. SmallString<128> Filename = getFilename(F.getSubprogram());
  418. auto It = InstrumentedFiles.find(Filename);
  419. if (It != InstrumentedFiles.end()) {
  420. return It->second;
  421. }
  422. SmallString<256> RealPath;
  423. StringRef RealFilename;
  424. // Path can be
  425. // /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/*.h so for
  426. // such a case we must get the real_path.
  427. if (sys::fs::real_path(Filename, RealPath)) {
  428. // real_path can fail with path like "foo.c".
  429. RealFilename = Filename;
  430. } else {
  431. RealFilename = RealPath;
  432. }
  433. bool ShouldInstrument;
  434. if (FilterRe.empty()) {
  435. ShouldInstrument = !doesFilenameMatchARegex(RealFilename, ExcludeRe);
  436. } else if (ExcludeRe.empty()) {
  437. ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe);
  438. } else {
  439. ShouldInstrument = doesFilenameMatchARegex(RealFilename, FilterRe) &&
  440. !doesFilenameMatchARegex(RealFilename, ExcludeRe);
  441. }
  442. InstrumentedFiles[Filename] = ShouldInstrument;
  443. return ShouldInstrument;
  444. }
  445. std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
  446. GCovFileType OutputType) {
  447. bool Notes = OutputType == GCovFileType::GCNO;
  448. if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
  449. for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
  450. MDNode *N = GCov->getOperand(i);
  451. bool ThreeElement = N->getNumOperands() == 3;
  452. if (!ThreeElement && N->getNumOperands() != 2)
  453. continue;
  454. if (dyn_cast<MDNode>(N->getOperand(ThreeElement ? 2 : 1)) != CU)
  455. continue;
  456. if (ThreeElement) {
  457. // These nodes have no mangling to apply, it's stored mangled in the
  458. // bitcode.
  459. MDString *NotesFile = dyn_cast<MDString>(N->getOperand(0));
  460. MDString *DataFile = dyn_cast<MDString>(N->getOperand(1));
  461. if (!NotesFile || !DataFile)
  462. continue;
  463. return Notes ? NotesFile->getString() : DataFile->getString();
  464. }
  465. MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
  466. if (!GCovFile)
  467. continue;
  468. SmallString<128> Filename = GCovFile->getString();
  469. sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda");
  470. return Filename.str();
  471. }
  472. }
  473. SmallString<128> Filename = CU->getFilename();
  474. sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda");
  475. StringRef FName = sys::path::filename(Filename);
  476. SmallString<128> CurPath;
  477. if (sys::fs::current_path(CurPath)) return FName;
  478. sys::path::append(CurPath, FName);
  479. return CurPath.str();
  480. }
  481. bool GCOVProfiler::runOnModule(Module &M, const TargetLibraryInfo &TLI) {
  482. this->M = &M;
  483. this->TLI = &TLI;
  484. Ctx = &M.getContext();
  485. AddFlushBeforeForkAndExec();
  486. FilterRe = createRegexesFromString(Options.Filter);
  487. ExcludeRe = createRegexesFromString(Options.Exclude);
  488. if (Options.EmitNotes) emitProfileNotes();
  489. if (Options.EmitData) return emitProfileArcs();
  490. return false;
  491. }
  492. PreservedAnalyses GCOVProfilerPass::run(Module &M,
  493. ModuleAnalysisManager &AM) {
  494. GCOVProfiler Profiler(GCOVOpts);
  495. auto &TLI = AM.getResult<TargetLibraryAnalysis>(M);
  496. if (!Profiler.runOnModule(M, TLI))
  497. return PreservedAnalyses::all();
  498. return PreservedAnalyses::none();
  499. }
  500. static bool functionHasLines(Function &F) {
  501. // Check whether this function actually has any source lines. Not only
  502. // do these waste space, they also can crash gcov.
  503. for (auto &BB : F) {
  504. for (auto &I : BB) {
  505. // Debug intrinsic locations correspond to the location of the
  506. // declaration, not necessarily any statements or expressions.
  507. if (isa<DbgInfoIntrinsic>(&I)) continue;
  508. const DebugLoc &Loc = I.getDebugLoc();
  509. if (!Loc)
  510. continue;
  511. // Artificial lines such as calls to the global constructors.
  512. if (Loc.getLine() == 0) continue;
  513. return true;
  514. }
  515. }
  516. return false;
  517. }
  518. static bool isUsingScopeBasedEH(Function &F) {
  519. if (!F.hasPersonalityFn()) return false;
  520. EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn());
  521. return isScopedEHPersonality(Personality);
  522. }
  523. static bool shouldKeepInEntry(BasicBlock::iterator It) {
  524. if (isa<AllocaInst>(*It)) return true;
  525. if (isa<DbgInfoIntrinsic>(*It)) return true;
  526. if (auto *II = dyn_cast<IntrinsicInst>(It)) {
  527. if (II->getIntrinsicID() == llvm::Intrinsic::localescape) return true;
  528. }
  529. return false;
  530. }
  531. void GCOVProfiler::AddFlushBeforeForkAndExec() {
  532. SmallVector<Instruction *, 2> ForkAndExecs;
  533. for (auto &F : M->functions()) {
  534. for (auto &I : instructions(F)) {
  535. if (CallInst *CI = dyn_cast<CallInst>(&I)) {
  536. if (Function *Callee = CI->getCalledFunction()) {
  537. LibFunc LF;
  538. if (TLI->getLibFunc(*Callee, LF) &&
  539. (LF == LibFunc_fork || LF == LibFunc_execl ||
  540. LF == LibFunc_execle || LF == LibFunc_execlp ||
  541. LF == LibFunc_execv || LF == LibFunc_execvp ||
  542. LF == LibFunc_execve || LF == LibFunc_execvpe ||
  543. LF == LibFunc_execvP)) {
  544. ForkAndExecs.push_back(&I);
  545. }
  546. }
  547. }
  548. }
  549. }
  550. // We need to split the block after the fork/exec call
  551. // because else the counters for the lines after will be
  552. // the same as before the call.
  553. for (auto I : ForkAndExecs) {
  554. IRBuilder<> Builder(I);
  555. FunctionType *FTy = FunctionType::get(Builder.getVoidTy(), {}, false);
  556. FunctionCallee GCOVFlush = M->getOrInsertFunction("__gcov_flush", FTy);
  557. Builder.CreateCall(GCOVFlush);
  558. I->getParent()->splitBasicBlock(I);
  559. }
  560. }
  561. void GCOVProfiler::emitProfileNotes() {
  562. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
  563. if (!CU_Nodes) return;
  564. for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
  565. // Each compile unit gets its own .gcno file. This means that whether we run
  566. // this pass over the original .o's as they're produced, or run it after
  567. // LTO, we'll generate the same .gcno files.
  568. auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
  569. // Skip module skeleton (and module) CUs.
  570. if (CU->getDWOId())
  571. continue;
  572. std::error_code EC;
  573. raw_fd_ostream out(mangleName(CU, GCovFileType::GCNO), EC,
  574. sys::fs::OF_None);
  575. if (EC) {
  576. Ctx->emitError(Twine("failed to open coverage notes file for writing: ") +
  577. EC.message());
  578. continue;
  579. }
  580. std::string EdgeDestinations;
  581. unsigned FunctionIdent = 0;
  582. for (auto &F : M->functions()) {
  583. DISubprogram *SP = F.getSubprogram();
  584. if (!SP) continue;
  585. if (!functionHasLines(F) || !isFunctionInstrumented(F))
  586. continue;
  587. // TODO: Functions using scope-based EH are currently not supported.
  588. if (isUsingScopeBasedEH(F)) continue;
  589. // gcov expects every function to start with an entry block that has a
  590. // single successor, so split the entry block to make sure of that.
  591. BasicBlock &EntryBlock = F.getEntryBlock();
  592. BasicBlock::iterator It = EntryBlock.begin();
  593. while (shouldKeepInEntry(It))
  594. ++It;
  595. EntryBlock.splitBasicBlock(It);
  596. Funcs.push_back(make_unique<GCOVFunction>(SP, &F, &out, FunctionIdent++,
  597. Options.UseCfgChecksum,
  598. Options.ExitBlockBeforeBody));
  599. GCOVFunction &Func = *Funcs.back();
  600. // Add the function line number to the lines of the entry block
  601. // to have a counter for the function definition.
  602. uint32_t Line = SP->getLine();
  603. auto Filename = getFilename(SP);
  604. Func.getBlock(&EntryBlock).getFile(Filename).addLine(Line);
  605. for (auto &BB : F) {
  606. GCOVBlock &Block = Func.getBlock(&BB);
  607. Instruction *TI = BB.getTerminator();
  608. if (int successors = TI->getNumSuccessors()) {
  609. for (int i = 0; i != successors; ++i) {
  610. Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
  611. }
  612. } else if (isa<ReturnInst>(TI)) {
  613. Block.addEdge(Func.getReturnBlock());
  614. }
  615. for (auto &I : BB) {
  616. // Debug intrinsic locations correspond to the location of the
  617. // declaration, not necessarily any statements or expressions.
  618. if (isa<DbgInfoIntrinsic>(&I)) continue;
  619. const DebugLoc &Loc = I.getDebugLoc();
  620. if (!Loc)
  621. continue;
  622. // Artificial lines such as calls to the global constructors.
  623. if (Loc.getLine() == 0 || Loc.isImplicitCode())
  624. continue;
  625. if (Line == Loc.getLine()) continue;
  626. Line = Loc.getLine();
  627. if (SP != getDISubprogram(Loc.getScope()))
  628. continue;
  629. GCOVLines &Lines = Block.getFile(Filename);
  630. Lines.addLine(Loc.getLine());
  631. }
  632. Line = 0;
  633. }
  634. EdgeDestinations += Func.getEdgeDestinations();
  635. }
  636. FileChecksums.push_back(hash_value(EdgeDestinations));
  637. out.write("oncg", 4);
  638. out.write(ReversedVersion, 4);
  639. out.write(reinterpret_cast<char*>(&FileChecksums.back()), 4);
  640. for (auto &Func : Funcs) {
  641. Func->setCfgChecksum(FileChecksums.back());
  642. Func->writeOut();
  643. }
  644. out.write("\0\0\0\0\0\0\0\0", 8); // EOF
  645. out.close();
  646. }
  647. }
  648. bool GCOVProfiler::emitProfileArcs() {
  649. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
  650. if (!CU_Nodes) return false;
  651. bool Result = false;
  652. for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
  653. SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
  654. for (auto &F : M->functions()) {
  655. DISubprogram *SP = F.getSubprogram();
  656. if (!SP) continue;
  657. if (!functionHasLines(F) || !isFunctionInstrumented(F))
  658. continue;
  659. // TODO: Functions using scope-based EH are currently not supported.
  660. if (isUsingScopeBasedEH(F)) continue;
  661. if (!Result) Result = true;
  662. DenseMap<std::pair<BasicBlock *, BasicBlock *>, unsigned> EdgeToCounter;
  663. unsigned Edges = 0;
  664. for (auto &BB : F) {
  665. Instruction *TI = BB.getTerminator();
  666. if (isa<ReturnInst>(TI)) {
  667. EdgeToCounter[{&BB, nullptr}] = Edges++;
  668. } else {
  669. for (BasicBlock *Succ : successors(TI)) {
  670. EdgeToCounter[{&BB, Succ}] = Edges++;
  671. }
  672. }
  673. }
  674. ArrayType *CounterTy =
  675. ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
  676. GlobalVariable *Counters =
  677. new GlobalVariable(*M, CounterTy, false,
  678. GlobalValue::InternalLinkage,
  679. Constant::getNullValue(CounterTy),
  680. "__llvm_gcov_ctr");
  681. CountersBySP.push_back(std::make_pair(Counters, SP));
  682. // If a BB has several predecessors, use a PHINode to select
  683. // the correct counter.
  684. for (auto &BB : F) {
  685. const unsigned EdgeCount =
  686. std::distance(pred_begin(&BB), pred_end(&BB));
  687. if (EdgeCount) {
  688. // The phi node must be at the begin of the BB.
  689. IRBuilder<> BuilderForPhi(&*BB.begin());
  690. Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
  691. PHINode *Phi = BuilderForPhi.CreatePHI(Int64PtrTy, EdgeCount);
  692. for (BasicBlock *Pred : predecessors(&BB)) {
  693. auto It = EdgeToCounter.find({Pred, &BB});
  694. assert(It != EdgeToCounter.end());
  695. const unsigned Edge = It->second;
  696. Value *EdgeCounter = BuilderForPhi.CreateConstInBoundsGEP2_64(
  697. Counters->getValueType(), Counters, 0, Edge);
  698. Phi->addIncoming(EdgeCounter, Pred);
  699. }
  700. // Skip phis, landingpads.
  701. IRBuilder<> Builder(&*BB.getFirstInsertionPt());
  702. Value *Count = Builder.CreateLoad(Builder.getInt64Ty(), Phi);
  703. Count = Builder.CreateAdd(Count, Builder.getInt64(1));
  704. Builder.CreateStore(Count, Phi);
  705. Instruction *TI = BB.getTerminator();
  706. if (isa<ReturnInst>(TI)) {
  707. auto It = EdgeToCounter.find({&BB, nullptr});
  708. assert(It != EdgeToCounter.end());
  709. const unsigned Edge = It->second;
  710. Value *Counter = Builder.CreateConstInBoundsGEP2_64(
  711. Counters->getValueType(), Counters, 0, Edge);
  712. Value *Count = Builder.CreateLoad(Builder.getInt64Ty(), Counter);
  713. Count = Builder.CreateAdd(Count, Builder.getInt64(1));
  714. Builder.CreateStore(Count, Counter);
  715. }
  716. }
  717. }
  718. }
  719. Function *WriteoutF = insertCounterWriteout(CountersBySP);
  720. Function *FlushF = insertFlush(CountersBySP);
  721. // Create a small bit of code that registers the "__llvm_gcov_writeout" to
  722. // be executed at exit and the "__llvm_gcov_flush" function to be executed
  723. // when "__gcov_flush" is called.
  724. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  725. Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
  726. "__llvm_gcov_init", M);
  727. F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
  728. F->setLinkage(GlobalValue::InternalLinkage);
  729. F->addFnAttr(Attribute::NoInline);
  730. if (Options.NoRedZone)
  731. F->addFnAttr(Attribute::NoRedZone);
  732. BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
  733. IRBuilder<> Builder(BB);
  734. FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  735. Type *Params[] = {
  736. PointerType::get(FTy, 0),
  737. PointerType::get(FTy, 0)
  738. };
  739. FTy = FunctionType::get(Builder.getVoidTy(), Params, false);
  740. // Initialize the environment and register the local writeout and flush
  741. // functions.
  742. FunctionCallee GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
  743. Builder.CreateCall(GCOVInit, {WriteoutF, FlushF});
  744. Builder.CreateRetVoid();
  745. appendToGlobalCtors(*M, F, 0);
  746. }
  747. return Result;
  748. }
  749. FunctionCallee GCOVProfiler::getStartFileFunc() {
  750. Type *Args[] = {
  751. Type::getInt8PtrTy(*Ctx), // const char *orig_filename
  752. Type::getInt8PtrTy(*Ctx), // const char version[4]
  753. Type::getInt32Ty(*Ctx), // uint32_t checksum
  754. };
  755. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
  756. AttributeList AL;
  757. if (auto AK = TLI->getExtAttrForI32Param(false))
  758. AL = AL.addParamAttribute(*Ctx, 2, AK);
  759. FunctionCallee Res = M->getOrInsertFunction("llvm_gcda_start_file", FTy, AL);
  760. return Res;
  761. }
  762. FunctionCallee GCOVProfiler::getEmitFunctionFunc() {
  763. Type *Args[] = {
  764. Type::getInt32Ty(*Ctx), // uint32_t ident
  765. Type::getInt8PtrTy(*Ctx), // const char *function_name
  766. Type::getInt32Ty(*Ctx), // uint32_t func_checksum
  767. Type::getInt8Ty(*Ctx), // uint8_t use_extra_checksum
  768. Type::getInt32Ty(*Ctx), // uint32_t cfg_checksum
  769. };
  770. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
  771. AttributeList AL;
  772. if (auto AK = TLI->getExtAttrForI32Param(false)) {
  773. AL = AL.addParamAttribute(*Ctx, 0, AK);
  774. AL = AL.addParamAttribute(*Ctx, 2, AK);
  775. AL = AL.addParamAttribute(*Ctx, 3, AK);
  776. AL = AL.addParamAttribute(*Ctx, 4, AK);
  777. }
  778. return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
  779. }
  780. FunctionCallee GCOVProfiler::getEmitArcsFunc() {
  781. Type *Args[] = {
  782. Type::getInt32Ty(*Ctx), // uint32_t num_counters
  783. Type::getInt64PtrTy(*Ctx), // uint64_t *counters
  784. };
  785. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
  786. AttributeList AL;
  787. if (auto AK = TLI->getExtAttrForI32Param(false))
  788. AL = AL.addParamAttribute(*Ctx, 0, AK);
  789. return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy, AL);
  790. }
  791. FunctionCallee GCOVProfiler::getSummaryInfoFunc() {
  792. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  793. return M->getOrInsertFunction("llvm_gcda_summary_info", FTy);
  794. }
  795. FunctionCallee GCOVProfiler::getEndFileFunc() {
  796. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  797. return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
  798. }
  799. Function *GCOVProfiler::insertCounterWriteout(
  800. ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
  801. FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  802. Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
  803. if (!WriteoutF)
  804. WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
  805. "__llvm_gcov_writeout", M);
  806. WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
  807. WriteoutF->addFnAttr(Attribute::NoInline);
  808. if (Options.NoRedZone)
  809. WriteoutF->addFnAttr(Attribute::NoRedZone);
  810. BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
  811. IRBuilder<> Builder(BB);
  812. FunctionCallee StartFile = getStartFileFunc();
  813. FunctionCallee EmitFunction = getEmitFunctionFunc();
  814. FunctionCallee EmitArcs = getEmitArcsFunc();
  815. FunctionCallee SummaryInfo = getSummaryInfoFunc();
  816. FunctionCallee EndFile = getEndFileFunc();
  817. NamedMDNode *CUNodes = M->getNamedMetadata("llvm.dbg.cu");
  818. if (!CUNodes) {
  819. Builder.CreateRetVoid();
  820. return WriteoutF;
  821. }
  822. // Collect the relevant data into a large constant data structure that we can
  823. // walk to write out everything.
  824. StructType *StartFileCallArgsTy = StructType::create(
  825. {Builder.getInt8PtrTy(), Builder.getInt8PtrTy(), Builder.getInt32Ty()});
  826. StructType *EmitFunctionCallArgsTy = StructType::create(
  827. {Builder.getInt32Ty(), Builder.getInt8PtrTy(), Builder.getInt32Ty(),
  828. Builder.getInt8Ty(), Builder.getInt32Ty()});
  829. StructType *EmitArcsCallArgsTy = StructType::create(
  830. {Builder.getInt32Ty(), Builder.getInt64Ty()->getPointerTo()});
  831. StructType *FileInfoTy =
  832. StructType::create({StartFileCallArgsTy, Builder.getInt32Ty(),
  833. EmitFunctionCallArgsTy->getPointerTo(),
  834. EmitArcsCallArgsTy->getPointerTo()});
  835. Constant *Zero32 = Builder.getInt32(0);
  836. // Build an explicit array of two zeros for use in ConstantExpr GEP building.
  837. Constant *TwoZero32s[] = {Zero32, Zero32};
  838. SmallVector<Constant *, 8> FileInfos;
  839. for (int i : llvm::seq<int>(0, CUNodes->getNumOperands())) {
  840. auto *CU = cast<DICompileUnit>(CUNodes->getOperand(i));
  841. // Skip module skeleton (and module) CUs.
  842. if (CU->getDWOId())
  843. continue;
  844. std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA);
  845. uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i];
  846. auto *StartFileCallArgs = ConstantStruct::get(
  847. StartFileCallArgsTy, {Builder.CreateGlobalStringPtr(FilenameGcda),
  848. Builder.CreateGlobalStringPtr(ReversedVersion),
  849. Builder.getInt32(CfgChecksum)});
  850. SmallVector<Constant *, 8> EmitFunctionCallArgsArray;
  851. SmallVector<Constant *, 8> EmitArcsCallArgsArray;
  852. for (int j : llvm::seq<int>(0, CountersBySP.size())) {
  853. auto *SP = cast_or_null<DISubprogram>(CountersBySP[j].second);
  854. uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum();
  855. EmitFunctionCallArgsArray.push_back(ConstantStruct::get(
  856. EmitFunctionCallArgsTy,
  857. {Builder.getInt32(j),
  858. Options.FunctionNamesInData
  859. ? Builder.CreateGlobalStringPtr(getFunctionName(SP))
  860. : Constant::getNullValue(Builder.getInt8PtrTy()),
  861. Builder.getInt32(FuncChecksum),
  862. Builder.getInt8(Options.UseCfgChecksum),
  863. Builder.getInt32(CfgChecksum)}));
  864. GlobalVariable *GV = CountersBySP[j].first;
  865. unsigned Arcs = cast<ArrayType>(GV->getValueType())->getNumElements();
  866. EmitArcsCallArgsArray.push_back(ConstantStruct::get(
  867. EmitArcsCallArgsTy,
  868. {Builder.getInt32(Arcs), ConstantExpr::getInBoundsGetElementPtr(
  869. GV->getValueType(), GV, TwoZero32s)}));
  870. }
  871. // Create global arrays for the two emit calls.
  872. int CountersSize = CountersBySP.size();
  873. assert(CountersSize == (int)EmitFunctionCallArgsArray.size() &&
  874. "Mismatched array size!");
  875. assert(CountersSize == (int)EmitArcsCallArgsArray.size() &&
  876. "Mismatched array size!");
  877. auto *EmitFunctionCallArgsArrayTy =
  878. ArrayType::get(EmitFunctionCallArgsTy, CountersSize);
  879. auto *EmitFunctionCallArgsArrayGV = new GlobalVariable(
  880. *M, EmitFunctionCallArgsArrayTy, /*isConstant*/ true,
  881. GlobalValue::InternalLinkage,
  882. ConstantArray::get(EmitFunctionCallArgsArrayTy,
  883. EmitFunctionCallArgsArray),
  884. Twine("__llvm_internal_gcov_emit_function_args.") + Twine(i));
  885. auto *EmitArcsCallArgsArrayTy =
  886. ArrayType::get(EmitArcsCallArgsTy, CountersSize);
  887. EmitFunctionCallArgsArrayGV->setUnnamedAddr(
  888. GlobalValue::UnnamedAddr::Global);
  889. auto *EmitArcsCallArgsArrayGV = new GlobalVariable(
  890. *M, EmitArcsCallArgsArrayTy, /*isConstant*/ true,
  891. GlobalValue::InternalLinkage,
  892. ConstantArray::get(EmitArcsCallArgsArrayTy, EmitArcsCallArgsArray),
  893. Twine("__llvm_internal_gcov_emit_arcs_args.") + Twine(i));
  894. EmitArcsCallArgsArrayGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
  895. FileInfos.push_back(ConstantStruct::get(
  896. FileInfoTy,
  897. {StartFileCallArgs, Builder.getInt32(CountersSize),
  898. ConstantExpr::getInBoundsGetElementPtr(EmitFunctionCallArgsArrayTy,
  899. EmitFunctionCallArgsArrayGV,
  900. TwoZero32s),
  901. ConstantExpr::getInBoundsGetElementPtr(
  902. EmitArcsCallArgsArrayTy, EmitArcsCallArgsArrayGV, TwoZero32s)}));
  903. }
  904. // If we didn't find anything to actually emit, bail on out.
  905. if (FileInfos.empty()) {
  906. Builder.CreateRetVoid();
  907. return WriteoutF;
  908. }
  909. // To simplify code, we cap the number of file infos we write out to fit
  910. // easily in a 32-bit signed integer. This gives consistent behavior between
  911. // 32-bit and 64-bit systems without requiring (potentially very slow) 64-bit
  912. // operations on 32-bit systems. It also seems unreasonable to try to handle
  913. // more than 2 billion files.
  914. if ((int64_t)FileInfos.size() > (int64_t)INT_MAX)
  915. FileInfos.resize(INT_MAX);
  916. // Create a global for the entire data structure so we can walk it more
  917. // easily.
  918. auto *FileInfoArrayTy = ArrayType::get(FileInfoTy, FileInfos.size());
  919. auto *FileInfoArrayGV = new GlobalVariable(
  920. *M, FileInfoArrayTy, /*isConstant*/ true, GlobalValue::InternalLinkage,
  921. ConstantArray::get(FileInfoArrayTy, FileInfos),
  922. "__llvm_internal_gcov_emit_file_info");
  923. FileInfoArrayGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
  924. // Create the CFG for walking this data structure.
  925. auto *FileLoopHeader =
  926. BasicBlock::Create(*Ctx, "file.loop.header", WriteoutF);
  927. auto *CounterLoopHeader =
  928. BasicBlock::Create(*Ctx, "counter.loop.header", WriteoutF);
  929. auto *FileLoopLatch = BasicBlock::Create(*Ctx, "file.loop.latch", WriteoutF);
  930. auto *ExitBB = BasicBlock::Create(*Ctx, "exit", WriteoutF);
  931. // We always have at least one file, so just branch to the header.
  932. Builder.CreateBr(FileLoopHeader);
  933. // The index into the files structure is our loop induction variable.
  934. Builder.SetInsertPoint(FileLoopHeader);
  935. PHINode *IV =
  936. Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2);
  937. IV->addIncoming(Builder.getInt32(0), BB);
  938. auto *FileInfoPtr = Builder.CreateInBoundsGEP(
  939. FileInfoArrayTy, FileInfoArrayGV, {Builder.getInt32(0), IV});
  940. auto *StartFileCallArgsPtr =
  941. Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 0);
  942. auto *StartFileCall = Builder.CreateCall(
  943. StartFile,
  944. {Builder.CreateLoad(StartFileCallArgsTy->getElementType(0),
  945. Builder.CreateStructGEP(StartFileCallArgsTy,
  946. StartFileCallArgsPtr, 0)),
  947. Builder.CreateLoad(StartFileCallArgsTy->getElementType(1),
  948. Builder.CreateStructGEP(StartFileCallArgsTy,
  949. StartFileCallArgsPtr, 1)),
  950. Builder.CreateLoad(StartFileCallArgsTy->getElementType(2),
  951. Builder.CreateStructGEP(StartFileCallArgsTy,
  952. StartFileCallArgsPtr, 2))});
  953. if (auto AK = TLI->getExtAttrForI32Param(false))
  954. StartFileCall->addParamAttr(2, AK);
  955. auto *NumCounters =
  956. Builder.CreateLoad(FileInfoTy->getElementType(1),
  957. Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 1));
  958. auto *EmitFunctionCallArgsArray =
  959. Builder.CreateLoad(FileInfoTy->getElementType(2),
  960. Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 2));
  961. auto *EmitArcsCallArgsArray =
  962. Builder.CreateLoad(FileInfoTy->getElementType(3),
  963. Builder.CreateStructGEP(FileInfoTy, FileInfoPtr, 3));
  964. auto *EnterCounterLoopCond =
  965. Builder.CreateICmpSLT(Builder.getInt32(0), NumCounters);
  966. Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch);
  967. Builder.SetInsertPoint(CounterLoopHeader);
  968. auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2);
  969. JV->addIncoming(Builder.getInt32(0), FileLoopHeader);
  970. auto *EmitFunctionCallArgsPtr = Builder.CreateInBoundsGEP(
  971. EmitFunctionCallArgsTy, EmitFunctionCallArgsArray, JV);
  972. auto *EmitFunctionCall = Builder.CreateCall(
  973. EmitFunction,
  974. {Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(0),
  975. Builder.CreateStructGEP(EmitFunctionCallArgsTy,
  976. EmitFunctionCallArgsPtr, 0)),
  977. Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(1),
  978. Builder.CreateStructGEP(EmitFunctionCallArgsTy,
  979. EmitFunctionCallArgsPtr, 1)),
  980. Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
  981. Builder.CreateStructGEP(EmitFunctionCallArgsTy,
  982. EmitFunctionCallArgsPtr, 2)),
  983. Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(3),
  984. Builder.CreateStructGEP(EmitFunctionCallArgsTy,
  985. EmitFunctionCallArgsPtr, 3)),
  986. Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(4),
  987. Builder.CreateStructGEP(EmitFunctionCallArgsTy,
  988. EmitFunctionCallArgsPtr,
  989. 4))});
  990. if (auto AK = TLI->getExtAttrForI32Param(false)) {
  991. EmitFunctionCall->addParamAttr(0, AK);
  992. EmitFunctionCall->addParamAttr(2, AK);
  993. EmitFunctionCall->addParamAttr(3, AK);
  994. EmitFunctionCall->addParamAttr(4, AK);
  995. }
  996. auto *EmitArcsCallArgsPtr =
  997. Builder.CreateInBoundsGEP(EmitArcsCallArgsTy, EmitArcsCallArgsArray, JV);
  998. auto *EmitArcsCall = Builder.CreateCall(
  999. EmitArcs,
  1000. {Builder.CreateLoad(
  1001. EmitArcsCallArgsTy->getElementType(0),
  1002. Builder.CreateStructGEP(EmitArcsCallArgsTy, EmitArcsCallArgsPtr, 0)),
  1003. Builder.CreateLoad(EmitArcsCallArgsTy->getElementType(1),
  1004. Builder.CreateStructGEP(EmitArcsCallArgsTy,
  1005. EmitArcsCallArgsPtr, 1))});
  1006. if (auto AK = TLI->getExtAttrForI32Param(false))
  1007. EmitArcsCall->addParamAttr(0, AK);
  1008. auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1));
  1009. auto *CounterLoopCond = Builder.CreateICmpSLT(NextJV, NumCounters);
  1010. Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch);
  1011. JV->addIncoming(NextJV, CounterLoopHeader);
  1012. Builder.SetInsertPoint(FileLoopLatch);
  1013. Builder.CreateCall(SummaryInfo, {});
  1014. Builder.CreateCall(EndFile, {});
  1015. auto *NextIV = Builder.CreateAdd(IV, Builder.getInt32(1));
  1016. auto *FileLoopCond =
  1017. Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.size()));
  1018. Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB);
  1019. IV->addIncoming(NextIV, FileLoopLatch);
  1020. Builder.SetInsertPoint(ExitBB);
  1021. Builder.CreateRetVoid();
  1022. return WriteoutF;
  1023. }
  1024. Function *GCOVProfiler::
  1025. insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
  1026. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  1027. Function *FlushF = M->getFunction("__llvm_gcov_flush");
  1028. if (!FlushF)
  1029. FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
  1030. "__llvm_gcov_flush", M);
  1031. else
  1032. FlushF->setLinkage(GlobalValue::InternalLinkage);
  1033. FlushF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global);
  1034. FlushF->addFnAttr(Attribute::NoInline);
  1035. if (Options.NoRedZone)
  1036. FlushF->addFnAttr(Attribute::NoRedZone);
  1037. BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
  1038. // Write out the current counters.
  1039. Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
  1040. assert(WriteoutF && "Need to create the writeout function first!");
  1041. IRBuilder<> Builder(Entry);
  1042. Builder.CreateCall(WriteoutF, {});
  1043. // Zero out the counters.
  1044. for (const auto &I : CountersBySP) {
  1045. GlobalVariable *GV = I.first;
  1046. Constant *Null = Constant::getNullValue(GV->getValueType());
  1047. Builder.CreateStore(Null, GV);
  1048. }
  1049. Type *RetTy = FlushF->getReturnType();
  1050. if (RetTy == Type::getVoidTy(*Ctx))
  1051. Builder.CreateRetVoid();
  1052. else if (RetTy->isIntegerTy())
  1053. // Used if __llvm_gcov_flush was implicitly declared.
  1054. Builder.CreateRet(ConstantInt::get(RetTy, 0));
  1055. else
  1056. report_fatal_error("invalid return type for __llvm_gcov_flush");
  1057. return FlushF;
  1058. }