GCOVProfiling.cpp revision f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8
1b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===// 2b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// 3b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// The LLVM Compiler Infrastructure 4b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// 5b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// This file is distributed under the University of Illinois Open Source 6b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// License. See LICENSE.TXT for details. 7b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// 8b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===----------------------------------------------------------------------===// 9b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// 10b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// This pass implements GCOV-style profiling. When this pass is run it emits 11b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// "gcno" files next to the existing source, and instruments the code that runs 12b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// to records the edges between blocks that run and emit a complementary "gcda" 13b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// file on exit. 14b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// 15b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===----------------------------------------------------------------------===// 16b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 17b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#define DEBUG_TYPE "insert-gcov-profiling" 18b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 19b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "ProfilingUtils.h" 20b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Transforms/Instrumentation.h" 21b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Analysis/DebugInfo.h" 22b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Module.h" 23b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Pass.h" 24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Instructions.h" 25b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/raw_ostream.h" 26b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/Debug.h" 27b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/DebugLoc.h" 28b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/InstIterator.h" 29b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/IRBuilder.h" 30b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/PathV2.h" 31b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/DenseMap.h" 32b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/Statistic.h" 33b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/STLExtras.h" 34b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringExtras.h" 35b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringMap.h" 36b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/UniqueVector.h" 37b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <string> 38b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <utility> 39b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyusing namespace llvm; 40b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 41b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 42b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVProfiler : public ModulePass { 43b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 44b1928704201034c785a26296a49f69355eb56a05Nick Lewycky static char ID; 45a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky GCOVProfiler() 46f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling : ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false) { 47a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 48a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky } 49f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format = false) 50f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData), 51f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling Use402Format(use402Format) { 52a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?"); 53b1928704201034c785a26296a49f69355eb56a05Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 54b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 55b1928704201034c785a26296a49f69355eb56a05Nick Lewycky virtual const char *getPassName() const { 56b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return "GCOV Profiler"; 57b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 58b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 59b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 60269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky bool runOnModule(Module &M); 61269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 62b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Create the GCNO files for the Module based on DebugInfo. 63f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel void emitGCNO(); 64b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 650c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // Modify the program to track transitions along edges and call into the 660c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // profiling runtime to emit .gcda files when run. 67f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool emitProfileArcs(); 680c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 69b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Get pointers to the functions in the runtime library. 70b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getStartFileFunc(); 711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant *getIncrementIndirectCounterFunc(); 72b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitFunctionFunc(); 73b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitArcsFunc(); 74b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEndFileFunc(); 75b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Create or retrieve an i32 state value that is used to represent the 771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // pred block number for certain non-trivial edges. 781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *getEdgeStateValue(); 791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Produce a table of pointers to counters, by predecessor and successor 811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // block number. 821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *buildEdgeLookupTable(Function *F, 831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counter, 841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs); 861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 87b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Add the function to write out all our counters to the global destructor 88b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // list. 89f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel void insertCounterWriteout(SmallVector<std::pair<GlobalVariable *, 905409a188328d9de3755febc23558d4fc1797d04eNick Lewycky MDNode *>, 8> &); 91b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 92269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky std::string mangleName(DICompileUnit CU, std::string NewStem); 93269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 94a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitNotes; 95a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitData; 96f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling bool Use402Format; 97a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky 981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Module *M; 99b1928704201034c785a26296a49f69355eb56a05Nick Lewycky LLVMContext *Ctx; 100b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 101b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 102b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 103b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0; 104b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", 105b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "Insert instrumentation for GCOV profiling", false, false) 106b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 107f5c95b889f270f170ff4f6a24b082be5bb68296eBill WendlingModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData, 108f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling bool Use402Format) { 109f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling return new GCOVProfiler(EmitNotes, EmitData, Use402Format); 110a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky} 111b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckystatic DISubprogram findSubprogram(DIScope Scope) { 1131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky while (!Scope.isSubprogram()) { 1141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky assert(Scope.isLexicalBlock() && 115b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "Debug location not lexical block or subprogram"); 1161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Scope = DILexicalBlock(Scope).getContext(); 117b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 1181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return DISubprogram(Scope); 119b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 120b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 121b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 122b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVRecord { 123b1928704201034c785a26296a49f69355eb56a05Nick Lewycky protected: 1241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *LinesTag; 1251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *FunctionTag; 1261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *BlockTag; 1271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *EdgeTag; 128b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 129b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GCOVRecord() {} 130b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeBytes(const char *Bytes, int Size) { 1321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky os->write(Bytes, Size); 133b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 134b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void write(uint32_t i) { 1361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(reinterpret_cast<char*>(&i), 4); 137b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Returns the length measured in 4-byte blocks that will be used to 140b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // represent this string in a GCOV file 1411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned lengthOfGCOVString(StringRef s) { 142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 14317df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // padding out to the next 4-byte word. The length is measured in 4-byte 14417df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // words including padding, not bytes of actual string. 145d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky return (s.size() / 4) + 1; 146b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 147b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeGCOVString(StringRef s) { 1491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = lengthOfGCOVString(s); 1501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 1511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(s.data(), s.size()); 152b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 153b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Write 1 to 4 bytes of NUL padding. 1547a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) > 0); 1557a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) <= 4); 1567a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 157b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 158b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 159b1928704201034c785a26296a49f69355eb56a05Nick Lewycky raw_ostream *os; 160b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 1611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::LinesTag = "\0\0\x45\x01"; 1621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::FunctionTag = "\0\0\0\1"; 1631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::BlockTag = "\0\0\x41\x01"; 1641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::EdgeTag = "\0\0\x43\x01"; 165b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction; 167b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock; 168b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 169b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Constructed only by requesting it from a GCOVBlock, this object stores a 170b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // list of line numbers and a single filename, representing lines that belong 171b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // to the block. 172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVLines : public GCOVRecord { 173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addLine(uint32_t Line) { 1751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Lines.push_back(Line); 176b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 177b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t length() { 1791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return lengthOfGCOVString(Filename) + 2 + Lines.size(); 180b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 181b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 182b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 183b1928704201034c785a26296a49f69355eb56a05Nick Lewycky friend class GCOVBlock; 184b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVLines(std::string Filename, raw_ostream *os) 1861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky : Filename(Filename) { 187b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 188b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 189b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky std::string Filename; 1911790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<uint32_t, 32> Lines; 192b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 193b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 194b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Represent a basic block in GCOV. Each block has a unique number in the 195b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // function, number of lines belonging to each block, and a set of edges to 196b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // other blocks. 197b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock : public GCOVRecord { 198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 1991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVLines &getFile(std::string Filename) { 2001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVLines *&Lines = LinesByFile[Filename]; 2011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!Lines) { 2021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Lines = new GCOVLines(Filename, os); 203b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Lines; 205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 206b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addEdge(GCOVBlock &Successor) { 2081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky OutEdges.push_back(&Successor); 209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 210b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 2121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = 3; 2131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 2141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = LinesByFile.end(); I != E; ++I) { 2151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Len += I->second->length(); 216b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 217b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(LinesTag, 4); 2191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 2201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Number); 2211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 2221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = LinesByFile.end(); I != E; ++I) { 2231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 2241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(I->second->Filename); 2251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = I->second->Lines.size(); i != e; ++i) { 2261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(I->second->Lines[i]); 227b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 228b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 2301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 231b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVBlock() { 2341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(LinesByFile); 235b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 237b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 238b1928704201034c785a26296a49f69355eb56a05Nick Lewycky friend class GCOVFunction; 239b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock(uint32_t Number, raw_ostream *os) 2411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky : Number(Number) { 242b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 243b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Number; 2461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky StringMap<GCOVLines *> LinesByFile; 2471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<GCOVBlock *, 4> OutEdges; 248b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 250b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A function has a unique identifier, a checksum (we leave as zero) and a 251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // set of blocks and a map of edges between blocks. This is the only GCOV 252b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // object users can construct, the blocks and lines will be rooted here. 253b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction : public GCOVRecord { 254b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 255f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling GCOVFunction(DISubprogram SP, raw_ostream *os, bool Use402Format) { 256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 257b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 258b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Function *F = SP.getFunction(); 259b1928704201034c785a26296a49f69355eb56a05Nick Lewycky uint32_t i = 0; 260b1928704201034c785a26296a49f69355eb56a05Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 2611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Blocks[BB] = new GCOVBlock(i++, os); 262b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ReturnBlock = new GCOVBlock(i++, os); 2641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 2651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(FunctionTag, 4); 266f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) + 2671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1 + lengthOfGCOVString(SP.getFilename()) + 1; 268f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling if (!Use402Format) 269f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling ++BlockLen; // For second checksum. 2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(BlockLen); 2711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP); 2721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Ident); 2735409a188328d9de3755febc23558d4fc1797d04eNick Lewycky write(0); // checksum #1 274f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling if (!Use402Format) 275f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling write(0); // checksum #2 2761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getName()); 2771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getFilename()); 2781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(SP.getLineNumber()); 279b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 280b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 281b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVFunction() { 2821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(Blocks); 2831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky delete ReturnBlock; 284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 285b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getBlock(BasicBlock *BB) { 2871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Blocks[BB]; 288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 289b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getReturnBlock() { 2911790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *ReturnBlock; 292a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky } 293a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky 2941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 295b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit count of blocks. 2961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(BlockTag, 4); 2971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Blocks.size() + 1); 2981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Blocks.size() + 1; i != e; ++i) { 2991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // No flags on our blocks. 300b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 301b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 302b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit edges between blocks. 3031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &Block = *I->second; 3061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (Block.OutEdges.empty()) continue; 3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 3081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(EdgeTag, 4); 3091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges.size() * 2 + 1); 3101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.Number); 3111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) { 3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges[i]->Number); 3131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // no flags 314b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 315b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 316b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 317b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit lines for each block. 3181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky I->second->writeOut(); 321b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 322b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 323b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 324b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 3251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DenseMap<BasicBlock *, GCOVBlock *> Blocks; 3261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock *ReturnBlock; 327b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 328b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 329b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 330269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewyckystd::string GCOVProfiler::mangleName(DICompileUnit CU, std::string NewStem) { 331269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 332269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 333269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *N = GCov->getOperand(i); 334269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (N->getNumOperands() != 2) continue; 335fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 336269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); 337fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (!GCovFile || !CompileUnit) continue; 338fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (CompileUnit == CU) { 339fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky SmallString<128> Filename = GCovFile->getString(); 340fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky sys::path::replace_extension(Filename, NewStem); 341fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky return Filename.str(); 342fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky } 343269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 344269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 345fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky 346fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky SmallString<128> Filename = CU.getFilename(); 347fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky sys::path::replace_extension(Filename, NewStem); 348fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky return sys::path::filename(Filename.str()); 349269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky} 350269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 3510c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) { 3521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky this->M = &M; 3530c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky Ctx = &M.getContext(); 3540c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 355f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitNotes) emitGCNO(); 356f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitData) return emitProfileArcs(); 357a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky return false; 3580c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky} 3590c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 360f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid GCOVProfiler::emitGCNO() { 3611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DenseMap<const MDNode *, raw_fd_ostream *> GcnoFiles; 362f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 363f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (CU_Nodes) { 364f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 365f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // Each compile unit gets its own .gcno file. This means that whether we run 366f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // this pass over the original .o's as they're produced, or run it after 367f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // LTO, we'll generate the same .gcno files. 368f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 369f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DICompileUnit CU(CU_Nodes->getOperand(i)); 370f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel raw_fd_ostream *&out = GcnoFiles[CU]; 371f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel std::string ErrorInfo; 372f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel out = new raw_fd_ostream(mangleName(CU, "gcno").c_str(), ErrorInfo, 373f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel raw_fd_ostream::F_Binary); 374f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!Use402Format) 375f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel out->write("oncg*404MVLL", 12); 376f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel else 377f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel out->write("oncg*204MVLL", 12); 378f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 379f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DIArray SPs = CU.getSubprograms(); 380f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 381f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(SPs.getElement(i)); 382f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!SP.Verify()) continue; 383f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel raw_fd_ostream *&os = GcnoFiles[SP.getCompileUnit()]; 384f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 385f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Function *F = SP.getFunction(); 386f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!F) continue; 387f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GCOVFunction Func(SP, os, Use402Format); 388f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 389f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 390f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GCOVBlock &Block = Func.getBlock(BB); 391f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 392f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (int successors = TI->getNumSuccessors()) { 393f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0; i != successors; ++i) { 394f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 395f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 396f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else if (isa<ReturnInst>(TI)) { 397f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Block.addEdge(Func.getReturnBlock()); 398f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 399f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 400f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel uint32_t Line = 0; 401f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) { 402f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel const DebugLoc &Loc = I->getDebugLoc(); 403f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Loc.isUnknown()) continue; 404f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Line == Loc.getLine()) continue; 405f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Line = Loc.getLine(); 406f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (SP != findSubprogram(DIScope(Loc.getScope(*Ctx)))) continue; 407f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 408f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GCOVLines &Lines = Block.getFile(SP.getFilename()); 409f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Lines.addLine(Loc.getLine()); 410f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 411b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 412f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Func.writeOut(); 413b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 414b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 415b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 416b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 417b1928704201034c785a26296a49f69355eb56a05Nick Lewycky for (DenseMap<const MDNode *, raw_fd_ostream *>::iterator 4181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky I = GcnoFiles.begin(), E = GcnoFiles.end(); I != E; ++I) { 4191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky raw_fd_ostream *&out = I->second; 4201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky out->write("\0\0\0\0\0\0\0\0", 8); // EOF 4211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky out->close(); 4221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky delete out; 423b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 424b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 425b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 426f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() { 427f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 428f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!CU_Nodes) return false; 429f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 430f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool Result = false; 431f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 432f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DICompileUnit CU(CU_Nodes->getOperand(i)); 433f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DIArray SPs = CU.getSubprograms(); 434f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; 435f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 436f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(SPs.getElement(i)); 437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!SP.Verify()) continue; 438f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Function *F = SP.getFunction(); 439f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!F) continue; 440f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!Result) Result = true; 441f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edges = 0; 442f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 443f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 444f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (isa<ReturnInst>(TI)) 445f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ++Edges; 446f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel else 447f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edges += TI->getNumSuccessors(); 448f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 449f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 450f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ArrayType *CounterTy = 4511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ArrayType::get(Type::getInt64Ty(*Ctx), Edges); 452f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *Counters = 4531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable(*M, CounterTy, false, 454b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GlobalValue::InternalLinkage, 4551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant::getNullValue(CounterTy), 456b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "__llvm_gcov_ctr", 0, false, 0); 457f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP)); 458f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 459f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgePreds; 460f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgeSuccs; 461f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edge = 0; 463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors) { 467f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(TI); 468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors == 1) { 470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge); 472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 473f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Count = Builder.CreateAdd(Count, 474f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt64Ty(*Ctx),1)); 475f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 476f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 477f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Sel = Builder.CreateSelect( 478b1928704201034c785a26296a49f69355eb56a05Nick Lewycky BI->getCondition(), 4791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt64Ty(*Ctx), Edge), 4801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1)); 481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<Value *, 2> Idx; 482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx))); 483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Idx.push_back(Sel); 484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx); 485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Count = Builder.CreateAdd(Count, 487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt64Ty(*Ctx),1)); 488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else { 490f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgePreds.insert(BB); 491f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0; i != Successors; ++i) 492f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgeSuccs.insert(TI->getSuccessor(i)); 493f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 494f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge += Successors; 495b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 496b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!ComplexEdgePreds.empty()) { 499f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeTable = 5001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky buildEdgeLookupTable(F, Counters, 5011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ComplexEdgePreds, ComplexEdgeSuccs); 502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeState = getEdgeStateValue(); 503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Type *Int32Ty = Type::getInt32Ty(*Ctx); 505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) { 506f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator()); 507f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState); 508f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 509f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) { 510f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // call runtime to perform increment 511f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel BasicBlock::iterator InsertPt = 512f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgeSuccs[i+1]->getFirstInsertionPt(); 513f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(InsertPt); 514f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *CounterPtrArray = 5151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0, 5161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky i * ComplexEdgePreds.size()); 517f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(getIncrementIndirectCounterFunc(), 518f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel EdgeState, CounterPtrArray); 519f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // clear the predecessor number 520f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(ConstantInt::get(Int32Ty, 0xffffffff), EdgeState); 521f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 522b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 523b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 524f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel insertCounterWriteout(CountersBySP); 525b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 526f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return Result; 527b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 528b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 5291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it 5301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update. 5311790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable( 5321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Function *F, 5331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counters, 5341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs) { 5361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // TODO: support invoke, threads. We rely on the fact that nothing can modify 5371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // the whole-Module pred edge# between the time we set it and the time we next 5381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // read it. Threads and invoke make this untrue. 5391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]]. 541db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); 542db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner ArrayType *EdgeTableTy = ArrayType::get( 5431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Int64PtrTy, Succs.size() * Preds.size()); 5441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant **EdgeTable = new Constant*[Succs.size() * Preds.size()]; 5461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant *NullValue = Constant::getNullValue(Int64PtrTy); 5471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, ie = Succs.size() * Preds.size(); i != ie; ++i) 5481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[i] = NullValue; 5491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned Edge = 0; 5511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 5521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky TerminatorInst *TI = BB->getTerminator(); 5531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 5547a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) { 5551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0; i != Successors; ++i) { 5561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky BasicBlock *Succ = TI->getSuccessor(i); 5571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> builder(Succ); 5581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0, 5591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge + i); 5601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) + 5611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky (Preds.idFor(BB)-1)] = cast<Constant>(Counter); 5621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge += Successors; 5651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 567267010864e139781ef5949939e081c41f954de0aJay Foad ArrayRef<Constant*> V(&EdgeTable[0], Succs.size() * Preds.size()); 5681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *EdgeTableGV = 5691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable( 5701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *M, EdgeTableTy, true, GlobalValue::InternalLinkage, 571267010864e139781ef5949939e081c41f954de0aJay Foad ConstantArray::get(EdgeTableTy, V), 5721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcda_edge_table"); 5731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTableGV->setUnnamedAddr(true); 5741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return EdgeTableGV; 5751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 577b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() { 578db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 5795fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type::getInt8PtrTy(*Ctx), false); 5801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_start_file", FTy); 5811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5831790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyConstant *GCOVProfiler::getIncrementIndirectCounterFunc() { 5845fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[] = { 5851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Type::getInt32PtrTy(*Ctx), // uint32_t *predecessor 5861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Type::getInt64PtrTy(*Ctx)->getPointerTo(), // uint64_t **state_table_row 5871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky }; 588db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 5891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Args, false); 5901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_increment_indirect_counter", FTy); 591b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 592b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 593b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() { 5945fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[2] = { 5955409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt32Ty(*Ctx), // uint32_t ident 5965409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt8PtrTy(*Ctx), // const char *function_name 5975409a188328d9de3755febc23558d4fc1797d04eNick Lewycky }; 598db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 599b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Args, false); 6001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 601b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 602b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 603b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() { 6045fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[] = { 605b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt32Ty(*Ctx), // uint32_t num_counters 606b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt64PtrTy(*Ctx), // uint64_t *counters 607b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 608db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 609b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Args, false); 6101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 611b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 612b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 613b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() { 614db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 616b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 617b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6181790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() { 6191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 6201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!GV) { 6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 6221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalValue::InternalLinkage, 6231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt32Ty(*Ctx), 6241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 0xffffffff), 6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcov_global_state_pred"); 6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV->setUnnamedAddr(true); 6271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GV; 6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 630b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckyvoid GCOVProfiler::insertCounterWriteout( 6325409a188328d9de3755febc23558d4fc1797d04eNick Lewycky SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> &CountersBySP) { 633db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *WriteoutFTy = 634b1928704201034c785a26296a49f69355eb56a05Nick Lewycky FunctionType::get(Type::getVoidTy(*Ctx), false); 635b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Function *WriteoutF = Function::Create(WriteoutFTy, 636b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GlobalValue::InternalLinkage, 6371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcov_writeout", M); 638b1928704201034c785a26296a49f69355eb56a05Nick Lewycky WriteoutF->setUnnamedAddr(true); 639b1928704201034c785a26296a49f69355eb56a05Nick Lewycky BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF); 6401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> Builder(BB); 641b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 642b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *StartFile = getStartFileFunc(); 643b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitFunction = getEmitFunctionFunc(); 644b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitArcs = getEmitArcsFunc(); 645b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EndFile = getEndFileFunc(); 646b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 647f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 648f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (CU_Nodes) { 649f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 650f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DICompileUnit compile_unit(CU_Nodes->getOperand(i)); 651f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel std::string FilenameGcda = mangleName(compile_unit, "gcda"); 652f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(StartFile, 653f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateGlobalStringPtr(FilenameGcda)); 654f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (SmallVector<std::pair<GlobalVariable *, MDNode *>, 8>::iterator 6555409a188328d9de3755febc23558d4fc1797d04eNick Lewycky I = CountersBySP.begin(), E = CountersBySP.end(); 656f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel I != E; ++I) { 657f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(I->second); 658f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel intptr_t ident = reinterpret_cast<intptr_t>(I->second); 659f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitFunction, 660f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt32Ty(*Ctx), ident), 661f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateGlobalStringPtr(SP.getName())); 662f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 663f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *GV = I->first; 664f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Arcs = 665b1928704201034c785a26296a49f69355eb56a05Nick Lewycky cast<ArrayType>(GV->getType()->getElementType())->getNumElements(); 666f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitArcs, 667f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs), 668f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateConstGEP2_64(GV, 0, 0)); 669f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 670f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(EndFile); 671b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 672b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 6731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateRetVoid(); 674b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky InsertProfilingShutdownCall(WriteoutF, M); 676b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 677