GCOVProfiling.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978
  1. //===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This pass implements GCOV-style profiling. When this pass is run it emits
  11. // "gcno" files next to the existing source, and instruments the code that runs
  12. // to records the edges between blocks that run and emit a complementary "gcda"
  13. // file on exit.
  14. //
  15. //===----------------------------------------------------------------------===//
  16. #include "llvm/Transforms/Instrumentation.h"
  17. #include "llvm/ADT/DenseMap.h"
  18. #include "llvm/ADT/Hashing.h"
  19. #include "llvm/ADT/STLExtras.h"
  20. #include "llvm/ADT/Statistic.h"
  21. #include "llvm/ADT/StringExtras.h"
  22. #include "llvm/ADT/StringMap.h"
  23. #include "llvm/ADT/UniqueVector.h"
  24. #include "llvm/IR/DebugInfo.h"
  25. #include "llvm/IR/DebugLoc.h"
  26. #include "llvm/IR/IRBuilder.h"
  27. #include "llvm/IR/InstIterator.h"
  28. #include "llvm/IR/Instructions.h"
  29. #include "llvm/IR/IntrinsicInst.h"
  30. #include "llvm/IR/Module.h"
  31. #include "llvm/Pass.h"
  32. #include "llvm/Support/CommandLine.h"
  33. #include "llvm/Support/Debug.h"
  34. #include "llvm/Support/FileSystem.h"
  35. #include "llvm/Support/Path.h"
  36. #include "llvm/Support/raw_ostream.h"
  37. #include "llvm/Transforms/Utils/ModuleUtils.h"
  38. #include <algorithm>
  39. #include <memory>
  40. #include <string>
  41. #include <utility>
  42. using namespace llvm;
  43. #define DEBUG_TYPE "insert-gcov-profiling"
  44. static cl::opt<std::string>
  45. DefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden,
  46. cl::ValueRequired);
  47. static cl::opt<bool> DefaultExitBlockBeforeBody("gcov-exit-block-before-body",
  48. cl::init(false), cl::Hidden);
  49. GCOVOptions GCOVOptions::getDefault() {
  50. GCOVOptions Options;
  51. Options.EmitNotes = true;
  52. Options.EmitData = true;
  53. Options.UseCfgChecksum = false;
  54. Options.NoRedZone = false;
  55. Options.FunctionNamesInData = true;
  56. Options.ExitBlockBeforeBody = DefaultExitBlockBeforeBody;
  57. if (DefaultGCOVVersion.size() != 4) {
  58. llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") +
  59. DefaultGCOVVersion);
  60. }
  61. memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4);
  62. return Options;
  63. }
  64. namespace {
  65. class GCOVFunction;
  66. class GCOVProfiler : public ModulePass {
  67. public:
  68. static char ID;
  69. GCOVProfiler() : GCOVProfiler(GCOVOptions::getDefault()) {}
  70. GCOVProfiler(const GCOVOptions &Opts) : ModulePass(ID), Options(Opts) {
  71. assert((Options.EmitNotes || Options.EmitData) &&
  72. "GCOVProfiler asked to do nothing?");
  73. ReversedVersion[0] = Options.Version[3];
  74. ReversedVersion[1] = Options.Version[2];
  75. ReversedVersion[2] = Options.Version[1];
  76. ReversedVersion[3] = Options.Version[0];
  77. ReversedVersion[4] = '\0';
  78. initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
  79. }
  80. const char *getPassName() const override {
  81. return "GCOV Profiler";
  82. }
  83. private:
  84. bool runOnModule(Module &M) override;
  85. // Create the .gcno files for the Module based on DebugInfo.
  86. void emitProfileNotes();
  87. // Modify the program to track transitions along edges and call into the
  88. // profiling runtime to emit .gcda files when run.
  89. bool emitProfileArcs();
  90. // Get pointers to the functions in the runtime library.
  91. Constant *getStartFileFunc();
  92. Constant *getIncrementIndirectCounterFunc();
  93. Constant *getEmitFunctionFunc();
  94. Constant *getEmitArcsFunc();
  95. Constant *getSummaryInfoFunc();
  96. Constant *getDeleteWriteoutFunctionListFunc();
  97. Constant *getDeleteFlushFunctionListFunc();
  98. Constant *getEndFileFunc();
  99. // Create or retrieve an i32 state value that is used to represent the
  100. // pred block number for certain non-trivial edges.
  101. GlobalVariable *getEdgeStateValue();
  102. // Produce a table of pointers to counters, by predecessor and successor
  103. // block number.
  104. GlobalVariable *buildEdgeLookupTable(Function *F,
  105. GlobalVariable *Counter,
  106. const UniqueVector<BasicBlock *>&Preds,
  107. const UniqueVector<BasicBlock*>&Succs);
  108. // Add the function to write out all our counters to the global destructor
  109. // list.
  110. Function *insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*,
  111. MDNode*> >);
  112. Function *insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
  113. void insertIndirectCounterIncrement();
  114. std::string mangleName(const DICompileUnit *CU, const char *NewStem);
  115. GCOVOptions Options;
  116. // Reversed, NUL-terminated copy of Options.Version.
  117. char ReversedVersion[5];
  118. // Checksum, produced by hash of EdgeDestinations
  119. SmallVector<uint32_t, 4> FileChecksums;
  120. Module *M;
  121. LLVMContext *Ctx;
  122. SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs;
  123. };
  124. }
  125. char GCOVProfiler::ID = 0;
  126. INITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
  127. "Insert instrumentation for GCOV profiling", false, false)
  128. ModulePass *llvm::createGCOVProfilerPass(const GCOVOptions &Options) {
  129. return new GCOVProfiler(Options);
  130. }
  131. static StringRef getFunctionName(const DISubprogram *SP) {
  132. if (!SP->getLinkageName().empty())
  133. return SP->getLinkageName();
  134. return SP->getName();
  135. }
  136. namespace {
  137. class GCOVRecord {
  138. protected:
  139. static const char *const LinesTag;
  140. static const char *const FunctionTag;
  141. static const char *const BlockTag;
  142. static const char *const EdgeTag;
  143. GCOVRecord() = default;
  144. void writeBytes(const char *Bytes, int Size) {
  145. os->write(Bytes, Size);
  146. }
  147. void write(uint32_t i) {
  148. writeBytes(reinterpret_cast<char*>(&i), 4);
  149. }
  150. // Returns the length measured in 4-byte blocks that will be used to
  151. // represent this string in a GCOV file
  152. static unsigned lengthOfGCOVString(StringRef s) {
  153. // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
  154. // padding out to the next 4-byte word. The length is measured in 4-byte
  155. // words including padding, not bytes of actual string.
  156. return (s.size() / 4) + 1;
  157. }
  158. void writeGCOVString(StringRef s) {
  159. uint32_t Len = lengthOfGCOVString(s);
  160. write(Len);
  161. writeBytes(s.data(), s.size());
  162. // Write 1 to 4 bytes of NUL padding.
  163. assert((unsigned)(4 - (s.size() % 4)) > 0);
  164. assert((unsigned)(4 - (s.size() % 4)) <= 4);
  165. writeBytes("\0\0\0\0", 4 - (s.size() % 4));
  166. }
  167. raw_ostream *os;
  168. };
  169. const char *const GCOVRecord::LinesTag = "\0\0\x45\x01";
  170. const char *const GCOVRecord::FunctionTag = "\0\0\0\1";
  171. const char *const GCOVRecord::BlockTag = "\0\0\x41\x01";
  172. const char *const GCOVRecord::EdgeTag = "\0\0\x43\x01";
  173. class GCOVFunction;
  174. class GCOVBlock;
  175. // Constructed only by requesting it from a GCOVBlock, this object stores a
  176. // list of line numbers and a single filename, representing lines that belong
  177. // to the block.
  178. class GCOVLines : public GCOVRecord {
  179. public:
  180. void addLine(uint32_t Line) {
  181. assert(Line != 0 && "Line zero is not a valid real line number.");
  182. Lines.push_back(Line);
  183. }
  184. uint32_t length() const {
  185. // Here 2 = 1 for string length + 1 for '0' id#.
  186. return lengthOfGCOVString(Filename) + 2 + Lines.size();
  187. }
  188. void writeOut() {
  189. write(0);
  190. writeGCOVString(Filename);
  191. for (int i = 0, e = Lines.size(); i != e; ++i)
  192. write(Lines[i]);
  193. }
  194. GCOVLines(StringRef F, raw_ostream *os)
  195. : Filename(F) {
  196. this->os = os;
  197. }
  198. private:
  199. StringRef Filename;
  200. SmallVector<uint32_t, 32> Lines;
  201. };
  202. // Represent a basic block in GCOV. Each block has a unique number in the
  203. // function, number of lines belonging to each block, and a set of edges to
  204. // other blocks.
  205. class GCOVBlock : public GCOVRecord {
  206. public:
  207. GCOVLines &getFile(StringRef Filename) {
  208. GCOVLines *&Lines = LinesByFile[Filename];
  209. if (!Lines) {
  210. Lines = new GCOVLines(Filename, os);
  211. }
  212. return *Lines;
  213. }
  214. void addEdge(GCOVBlock &Successor) {
  215. OutEdges.push_back(&Successor);
  216. }
  217. void writeOut() {
  218. uint32_t Len = 3;
  219. SmallVector<StringMapEntry<GCOVLines *> *, 32> SortedLinesByFile;
  220. for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
  221. E = LinesByFile.end(); I != E; ++I) {
  222. Len += I->second->length();
  223. SortedLinesByFile.push_back(&*I);
  224. }
  225. writeBytes(LinesTag, 4);
  226. write(Len);
  227. write(Number);
  228. std::sort(SortedLinesByFile.begin(), SortedLinesByFile.end(),
  229. [](StringMapEntry<GCOVLines *> *LHS,
  230. StringMapEntry<GCOVLines *> *RHS) {
  231. return LHS->getKey() < RHS->getKey();
  232. });
  233. for (SmallVectorImpl<StringMapEntry<GCOVLines *> *>::iterator
  234. I = SortedLinesByFile.begin(), E = SortedLinesByFile.end();
  235. I != E; ++I)
  236. (*I)->getValue()->writeOut();
  237. write(0);
  238. write(0);
  239. }
  240. ~GCOVBlock() {
  241. DeleteContainerSeconds(LinesByFile);
  242. }
  243. GCOVBlock(const GCOVBlock &RHS) : GCOVRecord(RHS), Number(RHS.Number) {
  244. // Only allow copy before edges and lines have been added. After that,
  245. // there are inter-block pointers (eg: edges) that won't take kindly to
  246. // blocks being copied or moved around.
  247. assert(LinesByFile.empty());
  248. assert(OutEdges.empty());
  249. }
  250. private:
  251. friend class GCOVFunction;
  252. GCOVBlock(uint32_t Number, raw_ostream *os)
  253. : Number(Number) {
  254. this->os = os;
  255. }
  256. uint32_t Number;
  257. StringMap<GCOVLines *> LinesByFile;
  258. SmallVector<GCOVBlock *, 4> OutEdges;
  259. };
  260. // A function has a unique identifier, a checksum (we leave as zero) and a
  261. // set of blocks and a map of edges between blocks. This is the only GCOV
  262. // object users can construct, the blocks and lines will be rooted here.
  263. class GCOVFunction : public GCOVRecord {
  264. public:
  265. GCOVFunction(const DISubprogram *SP, raw_ostream *os, uint32_t Ident,
  266. bool UseCfgChecksum, bool ExitBlockBeforeBody)
  267. : SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0),
  268. ReturnBlock(1, os) {
  269. this->os = os;
  270. Function *F = SP->getFunction();
  271. DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n");
  272. uint32_t i = 0;
  273. for (auto &BB : *F) {
  274. // Skip index 1 if it's assigned to the ReturnBlock.
  275. if (i == 1 && ExitBlockBeforeBody)
  276. ++i;
  277. Blocks.insert(std::make_pair(&BB, GCOVBlock(i++, os)));
  278. }
  279. if (!ExitBlockBeforeBody)
  280. ReturnBlock.Number = i;
  281. std::string FunctionNameAndLine;
  282. raw_string_ostream FNLOS(FunctionNameAndLine);
  283. FNLOS << getFunctionName(SP) << SP->getLine();
  284. FNLOS.flush();
  285. FuncChecksum = hash_value(FunctionNameAndLine);
  286. }
  287. GCOVBlock &getBlock(BasicBlock *BB) {
  288. return Blocks.find(BB)->second;
  289. }
  290. GCOVBlock &getReturnBlock() {
  291. return ReturnBlock;
  292. }
  293. std::string getEdgeDestinations() {
  294. std::string EdgeDestinations;
  295. raw_string_ostream EDOS(EdgeDestinations);
  296. Function *F = Blocks.begin()->first->getParent();
  297. for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
  298. GCOVBlock &Block = getBlock(I);
  299. for (int i = 0, e = Block.OutEdges.size(); i != e; ++i)
  300. EDOS << Block.OutEdges[i]->Number;
  301. }
  302. return EdgeDestinations;
  303. }
  304. uint32_t getFuncChecksum() {
  305. return FuncChecksum;
  306. }
  307. void setCfgChecksum(uint32_t Checksum) {
  308. CfgChecksum = Checksum;
  309. }
  310. void writeOut() {
  311. writeBytes(FunctionTag, 4);
  312. uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(getFunctionName(SP)) +
  313. 1 + lengthOfGCOVString(SP->getFilename()) + 1;
  314. if (UseCfgChecksum)
  315. ++BlockLen;
  316. write(BlockLen);
  317. write(Ident);
  318. write(FuncChecksum);
  319. if (UseCfgChecksum)
  320. write(CfgChecksum);
  321. writeGCOVString(getFunctionName(SP));
  322. writeGCOVString(SP->getFilename());
  323. write(SP->getLine());
  324. // Emit count of blocks.
  325. writeBytes(BlockTag, 4);
  326. write(Blocks.size() + 1);
  327. for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
  328. write(0); // No flags on our blocks.
  329. }
  330. DEBUG(dbgs() << Blocks.size() << " blocks.\n");
  331. // Emit edges between blocks.
  332. if (Blocks.empty()) return;
  333. Function *F = Blocks.begin()->first->getParent();
  334. for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
  335. GCOVBlock &Block = getBlock(I);
  336. if (Block.OutEdges.empty()) continue;
  337. writeBytes(EdgeTag, 4);
  338. write(Block.OutEdges.size() * 2 + 1);
  339. write(Block.Number);
  340. for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
  341. DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number
  342. << "\n");
  343. write(Block.OutEdges[i]->Number);
  344. write(0); // no flags
  345. }
  346. }
  347. // Emit lines for each block.
  348. for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
  349. getBlock(I).writeOut();
  350. }
  351. }
  352. private:
  353. const DISubprogram *SP;
  354. uint32_t Ident;
  355. uint32_t FuncChecksum;
  356. bool UseCfgChecksum;
  357. uint32_t CfgChecksum;
  358. DenseMap<BasicBlock *, GCOVBlock> Blocks;
  359. GCOVBlock ReturnBlock;
  360. };
  361. }
  362. std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
  363. const char *NewStem) {
  364. if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
  365. for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
  366. MDNode *N = GCov->getOperand(i);
  367. if (N->getNumOperands() != 2) continue;
  368. MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
  369. MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1));
  370. if (!GCovFile || !CompileUnit) continue;
  371. if (CompileUnit == CU) {
  372. SmallString<128> Filename = GCovFile->getString();
  373. sys::path::replace_extension(Filename, NewStem);
  374. return Filename.str();
  375. }
  376. }
  377. }
  378. SmallString<128> Filename = CU->getFilename();
  379. sys::path::replace_extension(Filename, NewStem);
  380. StringRef FName = sys::path::filename(Filename);
  381. SmallString<128> CurPath;
  382. if (sys::fs::current_path(CurPath)) return FName;
  383. sys::path::append(CurPath, FName);
  384. return CurPath.str();
  385. }
  386. bool GCOVProfiler::runOnModule(Module &M) {
  387. this->M = &M;
  388. Ctx = &M.getContext();
  389. if (Options.EmitNotes) emitProfileNotes();
  390. if (Options.EmitData) return emitProfileArcs();
  391. return false;
  392. }
  393. static bool functionHasLines(Function *F) {
  394. // Check whether this function actually has any source lines. Not only
  395. // do these waste space, they also can crash gcov.
  396. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
  397. for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
  398. I != IE; ++I) {
  399. // Debug intrinsic locations correspond to the location of the
  400. // declaration, not necessarily any statements or expressions.
  401. if (isa<DbgInfoIntrinsic>(I)) continue;
  402. const DebugLoc &Loc = I->getDebugLoc();
  403. if (!Loc)
  404. continue;
  405. // Artificial lines such as calls to the global constructors.
  406. if (Loc.getLine() == 0) continue;
  407. return true;
  408. }
  409. }
  410. return false;
  411. }
  412. void GCOVProfiler::emitProfileNotes() {
  413. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
  414. if (!CU_Nodes) return;
  415. for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
  416. // Each compile unit gets its own .gcno file. This means that whether we run
  417. // this pass over the original .o's as they're produced, or run it after
  418. // LTO, we'll generate the same .gcno files.
  419. auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
  420. std::error_code EC;
  421. raw_fd_ostream out(mangleName(CU, "gcno"), EC, sys::fs::F_None);
  422. std::string EdgeDestinations;
  423. unsigned FunctionIdent = 0;
  424. for (auto *SP : CU->getSubprograms()) {
  425. Function *F = SP->getFunction();
  426. if (!F) continue;
  427. if (!functionHasLines(F)) continue;
  428. // gcov expects every function to start with an entry block that has a
  429. // single successor, so split the entry block to make sure of that.
  430. BasicBlock &EntryBlock = F->getEntryBlock();
  431. BasicBlock::iterator It = EntryBlock.begin();
  432. while (isa<AllocaInst>(*It) || isa<DbgInfoIntrinsic>(*It))
  433. ++It;
  434. EntryBlock.splitBasicBlock(It);
  435. Funcs.push_back(make_unique<GCOVFunction>(SP, &out, FunctionIdent++,
  436. Options.UseCfgChecksum,
  437. Options.ExitBlockBeforeBody));
  438. GCOVFunction &Func = *Funcs.back();
  439. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
  440. GCOVBlock &Block = Func.getBlock(BB);
  441. TerminatorInst *TI = BB->getTerminator();
  442. if (int successors = TI->getNumSuccessors()) {
  443. for (int i = 0; i != successors; ++i) {
  444. Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
  445. }
  446. } else if (isa<ReturnInst>(TI)) {
  447. Block.addEdge(Func.getReturnBlock());
  448. }
  449. uint32_t Line = 0;
  450. for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
  451. I != IE; ++I) {
  452. // Debug intrinsic locations correspond to the location of the
  453. // declaration, not necessarily any statements or expressions.
  454. if (isa<DbgInfoIntrinsic>(I)) continue;
  455. const DebugLoc &Loc = I->getDebugLoc();
  456. if (!Loc)
  457. continue;
  458. // Artificial lines such as calls to the global constructors.
  459. if (Loc.getLine() == 0) continue;
  460. if (Line == Loc.getLine()) continue;
  461. Line = Loc.getLine();
  462. if (SP != getDISubprogram(Loc.getScope()))
  463. continue;
  464. GCOVLines &Lines = Block.getFile(SP->getFilename());
  465. Lines.addLine(Loc.getLine());
  466. }
  467. }
  468. EdgeDestinations += Func.getEdgeDestinations();
  469. }
  470. FileChecksums.push_back(hash_value(EdgeDestinations));
  471. out.write("oncg", 4);
  472. out.write(ReversedVersion, 4);
  473. out.write(reinterpret_cast<char*>(&FileChecksums.back()), 4);
  474. for (auto &Func : Funcs) {
  475. Func->setCfgChecksum(FileChecksums.back());
  476. Func->writeOut();
  477. }
  478. out.write("\0\0\0\0\0\0\0\0", 8); // EOF
  479. out.close();
  480. }
  481. }
  482. bool GCOVProfiler::emitProfileArcs() {
  483. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
  484. if (!CU_Nodes) return false;
  485. bool Result = false;
  486. bool InsertIndCounterIncrCode = false;
  487. for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
  488. auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
  489. SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
  490. for (auto *SP : CU->getSubprograms()) {
  491. Function *F = SP->getFunction();
  492. if (!F) continue;
  493. if (!functionHasLines(F)) continue;
  494. if (!Result) Result = true;
  495. unsigned Edges = 0;
  496. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
  497. TerminatorInst *TI = BB->getTerminator();
  498. if (isa<ReturnInst>(TI))
  499. ++Edges;
  500. else
  501. Edges += TI->getNumSuccessors();
  502. }
  503. ArrayType *CounterTy =
  504. ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
  505. GlobalVariable *Counters =
  506. new GlobalVariable(*M, CounterTy, false,
  507. GlobalValue::InternalLinkage,
  508. Constant::getNullValue(CounterTy),
  509. "__llvm_gcov_ctr");
  510. CountersBySP.push_back(std::make_pair(Counters, SP));
  511. UniqueVector<BasicBlock *> ComplexEdgePreds;
  512. UniqueVector<BasicBlock *> ComplexEdgeSuccs;
  513. unsigned Edge = 0;
  514. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
  515. TerminatorInst *TI = BB->getTerminator();
  516. int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
  517. if (Successors) {
  518. if (Successors == 1) {
  519. IRBuilder<> Builder(BB->getFirstInsertionPt());
  520. Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
  521. Edge);
  522. Value *Count = Builder.CreateLoad(Counter);
  523. Count = Builder.CreateAdd(Count, Builder.getInt64(1));
  524. Builder.CreateStore(Count, Counter);
  525. } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
  526. IRBuilder<> Builder(BI);
  527. Value *Sel = Builder.CreateSelect(BI->getCondition(),
  528. Builder.getInt64(Edge),
  529. Builder.getInt64(Edge + 1));
  530. SmallVector<Value *, 2> Idx;
  531. Idx.push_back(Builder.getInt64(0));
  532. Idx.push_back(Sel);
  533. Value *Counter = Builder.CreateInBoundsGEP(Counters->getValueType(),
  534. Counters, Idx);
  535. Value *Count = Builder.CreateLoad(Counter);
  536. Count = Builder.CreateAdd(Count, Builder.getInt64(1));
  537. Builder.CreateStore(Count, Counter);
  538. } else {
  539. ComplexEdgePreds.insert(BB);
  540. for (int i = 0; i != Successors; ++i)
  541. ComplexEdgeSuccs.insert(TI->getSuccessor(i));
  542. }
  543. Edge += Successors;
  544. }
  545. }
  546. if (!ComplexEdgePreds.empty()) {
  547. GlobalVariable *EdgeTable =
  548. buildEdgeLookupTable(F, Counters,
  549. ComplexEdgePreds, ComplexEdgeSuccs);
  550. GlobalVariable *EdgeState = getEdgeStateValue();
  551. for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
  552. IRBuilder<> Builder(ComplexEdgePreds[i + 1]->getFirstInsertionPt());
  553. Builder.CreateStore(Builder.getInt32(i), EdgeState);
  554. }
  555. for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
  556. // Call runtime to perform increment.
  557. IRBuilder<> Builder(ComplexEdgeSuccs[i+1]->getFirstInsertionPt());
  558. Value *CounterPtrArray =
  559. Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
  560. i * ComplexEdgePreds.size());
  561. // Build code to increment the counter.
  562. InsertIndCounterIncrCode = true;
  563. Builder.CreateCall(getIncrementIndirectCounterFunc(),
  564. {EdgeState, CounterPtrArray});
  565. }
  566. }
  567. }
  568. Function *WriteoutF = insertCounterWriteout(CountersBySP);
  569. Function *FlushF = insertFlush(CountersBySP);
  570. // Create a small bit of code that registers the "__llvm_gcov_writeout" to
  571. // be executed at exit and the "__llvm_gcov_flush" function to be executed
  572. // when "__gcov_flush" is called.
  573. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  574. Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
  575. "__llvm_gcov_init", M);
  576. F->setUnnamedAddr(true);
  577. F->setLinkage(GlobalValue::InternalLinkage);
  578. F->addFnAttr(Attribute::NoInline);
  579. if (Options.NoRedZone)
  580. F->addFnAttr(Attribute::NoRedZone);
  581. BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
  582. IRBuilder<> Builder(BB);
  583. FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  584. Type *Params[] = {
  585. PointerType::get(FTy, 0),
  586. PointerType::get(FTy, 0)
  587. };
  588. FTy = FunctionType::get(Builder.getVoidTy(), Params, false);
  589. // Initialize the environment and register the local writeout and flush
  590. // functions.
  591. Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
  592. Builder.CreateCall(GCOVInit, {WriteoutF, FlushF});
  593. Builder.CreateRetVoid();
  594. appendToGlobalCtors(*M, F, 0);
  595. }
  596. if (InsertIndCounterIncrCode)
  597. insertIndirectCounterIncrement();
  598. return Result;
  599. }
  600. // All edges with successors that aren't branches are "complex", because it
  601. // requires complex logic to pick which counter to update.
  602. GlobalVariable *GCOVProfiler::buildEdgeLookupTable(
  603. Function *F,
  604. GlobalVariable *Counters,
  605. const UniqueVector<BasicBlock *> &Preds,
  606. const UniqueVector<BasicBlock *> &Succs) {
  607. // TODO: support invoke, threads. We rely on the fact that nothing can modify
  608. // the whole-Module pred edge# between the time we set it and the time we next
  609. // read it. Threads and invoke make this untrue.
  610. // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]].
  611. size_t TableSize = Succs.size() * Preds.size();
  612. Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
  613. ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize);
  614. std::unique_ptr<Constant * []> EdgeTable(new Constant *[TableSize]);
  615. Constant *NullValue = Constant::getNullValue(Int64PtrTy);
  616. for (size_t i = 0; i != TableSize; ++i)
  617. EdgeTable[i] = NullValue;
  618. unsigned Edge = 0;
  619. for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
  620. TerminatorInst *TI = BB->getTerminator();
  621. int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
  622. if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) {
  623. for (int i = 0; i != Successors; ++i) {
  624. BasicBlock *Succ = TI->getSuccessor(i);
  625. IRBuilder<> Builder(Succ);
  626. Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
  627. Edge + i);
  628. EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) +
  629. (Preds.idFor(BB)-1)] = cast<Constant>(Counter);
  630. }
  631. }
  632. Edge += Successors;
  633. }
  634. GlobalVariable *EdgeTableGV =
  635. new GlobalVariable(
  636. *M, EdgeTableTy, true, GlobalValue::InternalLinkage,
  637. ConstantArray::get(EdgeTableTy,
  638. makeArrayRef(&EdgeTable[0],TableSize)),
  639. "__llvm_gcda_edge_table");
  640. EdgeTableGV->setUnnamedAddr(true);
  641. return EdgeTableGV;
  642. }
  643. Constant *GCOVProfiler::getStartFileFunc() {
  644. Type *Args[] = {
  645. Type::getInt8PtrTy(*Ctx), // const char *orig_filename
  646. Type::getInt8PtrTy(*Ctx), // const char version[4]
  647. Type::getInt32Ty(*Ctx), // uint32_t checksum
  648. };
  649. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
  650. return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
  651. }
  652. Constant *GCOVProfiler::getIncrementIndirectCounterFunc() {
  653. Type *Int32Ty = Type::getInt32Ty(*Ctx);
  654. Type *Int64Ty = Type::getInt64Ty(*Ctx);
  655. Type *Args[] = {
  656. Int32Ty->getPointerTo(), // uint32_t *predecessor
  657. Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters
  658. };
  659. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
  660. return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy);
  661. }
  662. Constant *GCOVProfiler::getEmitFunctionFunc() {
  663. Type *Args[] = {
  664. Type::getInt32Ty(*Ctx), // uint32_t ident
  665. Type::getInt8PtrTy(*Ctx), // const char *function_name
  666. Type::getInt32Ty(*Ctx), // uint32_t func_checksum
  667. Type::getInt8Ty(*Ctx), // uint8_t use_extra_checksum
  668. Type::getInt32Ty(*Ctx), // uint32_t cfg_checksum
  669. };
  670. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
  671. return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
  672. }
  673. Constant *GCOVProfiler::getEmitArcsFunc() {
  674. Type *Args[] = {
  675. Type::getInt32Ty(*Ctx), // uint32_t num_counters
  676. Type::getInt64PtrTy(*Ctx), // uint64_t *counters
  677. };
  678. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
  679. return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
  680. }
  681. Constant *GCOVProfiler::getSummaryInfoFunc() {
  682. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  683. return M->getOrInsertFunction("llvm_gcda_summary_info", FTy);
  684. }
  685. Constant *GCOVProfiler::getDeleteWriteoutFunctionListFunc() {
  686. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  687. return M->getOrInsertFunction("llvm_delete_writeout_function_list", FTy);
  688. }
  689. Constant *GCOVProfiler::getDeleteFlushFunctionListFunc() {
  690. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  691. return M->getOrInsertFunction("llvm_delete_flush_function_list", FTy);
  692. }
  693. Constant *GCOVProfiler::getEndFileFunc() {
  694. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  695. return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
  696. }
  697. GlobalVariable *GCOVProfiler::getEdgeStateValue() {
  698. GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred");
  699. if (!GV) {
  700. GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false,
  701. GlobalValue::InternalLinkage,
  702. ConstantInt::get(Type::getInt32Ty(*Ctx),
  703. 0xffffffff),
  704. "__llvm_gcov_global_state_pred");
  705. GV->setUnnamedAddr(true);
  706. }
  707. return GV;
  708. }
  709. Function *GCOVProfiler::insertCounterWriteout(
  710. ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
  711. FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  712. Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
  713. if (!WriteoutF)
  714. WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
  715. "__llvm_gcov_writeout", M);
  716. WriteoutF->setUnnamedAddr(true);
  717. WriteoutF->addFnAttr(Attribute::NoInline);
  718. if (Options.NoRedZone)
  719. WriteoutF->addFnAttr(Attribute::NoRedZone);
  720. BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
  721. IRBuilder<> Builder(BB);
  722. Constant *StartFile = getStartFileFunc();
  723. Constant *EmitFunction = getEmitFunctionFunc();
  724. Constant *EmitArcs = getEmitArcsFunc();
  725. Constant *SummaryInfo = getSummaryInfoFunc();
  726. Constant *EndFile = getEndFileFunc();
  727. NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
  728. if (CU_Nodes) {
  729. for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
  730. auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
  731. std::string FilenameGcda = mangleName(CU, "gcda");
  732. uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i];
  733. Builder.CreateCall(StartFile,
  734. {Builder.CreateGlobalStringPtr(FilenameGcda),
  735. Builder.CreateGlobalStringPtr(ReversedVersion),
  736. Builder.getInt32(CfgChecksum)});
  737. for (unsigned j = 0, e = CountersBySP.size(); j != e; ++j) {
  738. auto *SP = cast_or_null<DISubprogram>(CountersBySP[j].second);
  739. uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum();
  740. Builder.CreateCall(
  741. EmitFunction,
  742. {Builder.getInt32(j),
  743. Options.FunctionNamesInData
  744. ? Builder.CreateGlobalStringPtr(getFunctionName(SP))
  745. : Constant::getNullValue(Builder.getInt8PtrTy()),
  746. Builder.getInt32(FuncChecksum),
  747. Builder.getInt8(Options.UseCfgChecksum),
  748. Builder.getInt32(CfgChecksum)});
  749. GlobalVariable *GV = CountersBySP[j].first;
  750. unsigned Arcs =
  751. cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
  752. Builder.CreateCall(EmitArcs, {Builder.getInt32(Arcs),
  753. Builder.CreateConstGEP2_64(GV, 0, 0)});
  754. }
  755. Builder.CreateCall(SummaryInfo, {});
  756. Builder.CreateCall(EndFile, {});
  757. }
  758. }
  759. Builder.CreateRetVoid();
  760. return WriteoutF;
  761. }
  762. void GCOVProfiler::insertIndirectCounterIncrement() {
  763. Function *Fn =
  764. cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
  765. Fn->setUnnamedAddr(true);
  766. Fn->setLinkage(GlobalValue::InternalLinkage);
  767. Fn->addFnAttr(Attribute::NoInline);
  768. if (Options.NoRedZone)
  769. Fn->addFnAttr(Attribute::NoRedZone);
  770. // Create basic blocks for function.
  771. BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn);
  772. IRBuilder<> Builder(BB);
  773. BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn);
  774. BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn);
  775. BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn);
  776. // uint32_t pred = *predecessor;
  777. // if (pred == 0xffffffff) return;
  778. Argument *Arg = Fn->arg_begin();
  779. Arg->setName("predecessor");
  780. Value *Pred = Builder.CreateLoad(Arg, "pred");
  781. Value *Cond = Builder.CreateICmpEQ(Pred, Builder.getInt32(0xffffffff));
  782. BranchInst::Create(Exit, PredNotNegOne, Cond, BB);
  783. Builder.SetInsertPoint(PredNotNegOne);
  784. // uint64_t *counter = counters[pred];
  785. // if (!counter) return;
  786. Value *ZExtPred = Builder.CreateZExt(Pred, Builder.getInt64Ty());
  787. Arg = std::next(Fn->arg_begin());
  788. Arg->setName("counters");
  789. Value *GEP = Builder.CreateGEP(Type::getInt64PtrTy(*Ctx), Arg, ZExtPred);
  790. Value *Counter = Builder.CreateLoad(GEP, "counter");
  791. Cond = Builder.CreateICmpEQ(Counter,
  792. Constant::getNullValue(
  793. Builder.getInt64Ty()->getPointerTo()));
  794. Builder.CreateCondBr(Cond, Exit, CounterEnd);
  795. // ++*counter;
  796. Builder.SetInsertPoint(CounterEnd);
  797. Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter),
  798. Builder.getInt64(1));
  799. Builder.CreateStore(Add, Counter);
  800. Builder.CreateBr(Exit);
  801. // Fill in the exit block.
  802. Builder.SetInsertPoint(Exit);
  803. Builder.CreateRetVoid();
  804. }
  805. Function *GCOVProfiler::
  806. insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
  807. FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
  808. Function *FlushF = M->getFunction("__llvm_gcov_flush");
  809. if (!FlushF)
  810. FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
  811. "__llvm_gcov_flush", M);
  812. else
  813. FlushF->setLinkage(GlobalValue::InternalLinkage);
  814. FlushF->setUnnamedAddr(true);
  815. FlushF->addFnAttr(Attribute::NoInline);
  816. if (Options.NoRedZone)
  817. FlushF->addFnAttr(Attribute::NoRedZone);
  818. BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
  819. // Write out the current counters.
  820. Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout");
  821. assert(WriteoutF && "Need to create the writeout function first!");
  822. IRBuilder<> Builder(Entry);
  823. Builder.CreateCall(WriteoutF, {});
  824. // Zero out the counters.
  825. for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator
  826. I = CountersBySP.begin(), E = CountersBySP.end();
  827. I != E; ++I) {
  828. GlobalVariable *GV = I->first;
  829. Constant *Null = Constant::getNullValue(GV->getType()->getElementType());
  830. Builder.CreateStore(Null, GV);
  831. }
  832. Type *RetTy = FlushF->getReturnType();
  833. if (RetTy == Type::getVoidTy(*Ctx))
  834. Builder.CreateRetVoid();
  835. else if (RetTy->isIntegerTy())
  836. // Used if __llvm_gcov_flush was implicitly declared.
  837. Builder.CreateRet(ConstantInt::get(RetTy, 0));
  838. else
  839. report_fatal_error("invalid return type for __llvm_gcov_flush");
  840. return FlushF;
  841. }