GCOVProfiling.cpp revision c7a884040e4ec7795515978a94803894ad08c4ca
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() 46bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky : ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false), 47bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky UseExtraChecksum(false) { 48a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 49a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky } 50bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format = false, 51bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool useExtraChecksum = false) 52f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData), 53bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Use402Format(use402Format), UseExtraChecksum(useExtraChecksum) { 54a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?"); 55b1928704201034c785a26296a49f69355eb56a05Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 56b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 57b1928704201034c785a26296a49f69355eb56a05Nick Lewycky virtual const char *getPassName() const { 58b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return "GCOV Profiler"; 59b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 60b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 61b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 62269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky bool runOnModule(Module &M); 63269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 64b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Create the GCNO files for the Module based on DebugInfo. 65f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel void emitGCNO(); 66b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 670c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // Modify the program to track transitions along edges and call into the 680c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // profiling runtime to emit .gcda files when run. 69f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool emitProfileArcs(); 700c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 71b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Get pointers to the functions in the runtime library. 72b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getStartFileFunc(); 73c7a884040e4ec7795515978a94803894ad08c4caBill Wendling void incrementIndirectCounter(IRBuilder<> &Builder, BasicBlock *Exit, 74c7a884040e4ec7795515978a94803894ad08c4caBill Wendling GlobalVariable *EdgeState, 75c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Value *CounterPtrArray); 76b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitFunctionFunc(); 77b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitArcsFunc(); 78b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEndFileFunc(); 79b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Create or retrieve an i32 state value that is used to represent the 811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // pred block number for certain non-trivial edges. 821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *getEdgeStateValue(); 831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Produce a table of pointers to counters, by predecessor and successor 851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // block number. 861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *buildEdgeLookupTable(Function *F, 871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counter, 881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs); 901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 91b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Add the function to write out all our counters to the global destructor 92b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // list. 93f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel void insertCounterWriteout(SmallVector<std::pair<GlobalVariable *, 945409a188328d9de3755febc23558d4fc1797d04eNick Lewycky MDNode *>, 8> &); 95b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 96269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky std::string mangleName(DICompileUnit CU, std::string NewStem); 97269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 98a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitNotes; 99a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitData; 100f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling bool Use402Format; 101bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool UseExtraChecksum; 102a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky 1031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Module *M; 104b1928704201034c785a26296a49f69355eb56a05Nick Lewycky LLVMContext *Ctx; 105b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 106b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 107b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 108b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0; 109b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", 110b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "Insert instrumentation for GCOV profiling", false, false) 111b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 112f5c95b889f270f170ff4f6a24b082be5bb68296eBill WendlingModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData, 1137c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky bool Use402Format, 1147c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky bool UseExtraChecksum) { 1157c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky return new GCOVProfiler(EmitNotes, EmitData, Use402Format, UseExtraChecksum); 116a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky} 117b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 118b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 119b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVRecord { 120b1928704201034c785a26296a49f69355eb56a05Nick Lewycky protected: 1211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *LinesTag; 1221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *FunctionTag; 1231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *BlockTag; 1241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *EdgeTag; 125b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 126b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GCOVRecord() {} 127b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeBytes(const char *Bytes, int Size) { 1291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky os->write(Bytes, Size); 130b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 131b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void write(uint32_t i) { 1331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(reinterpret_cast<char*>(&i), 4); 134b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 135b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 136b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Returns the length measured in 4-byte blocks that will be used to 137b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // represent this string in a GCOV file 1381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned lengthOfGCOVString(StringRef s) { 139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 14017df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // padding out to the next 4-byte word. The length is measured in 4-byte 14117df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // words including padding, not bytes of actual string. 142d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky return (s.size() / 4) + 1; 143b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 144b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeGCOVString(StringRef s) { 1461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = lengthOfGCOVString(s); 1471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 1481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(s.data(), s.size()); 149b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 150b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Write 1 to 4 bytes of NUL padding. 1517a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) > 0); 1527a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) <= 4); 1537a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 154b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 155b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 156b1928704201034c785a26296a49f69355eb56a05Nick Lewycky raw_ostream *os; 157b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 1581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::LinesTag = "\0\0\x45\x01"; 1591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::FunctionTag = "\0\0\0\1"; 1601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::BlockTag = "\0\0\x41\x01"; 1611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::EdgeTag = "\0\0\x43\x01"; 162b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 163b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction; 164b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock; 165b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Constructed only by requesting it from a GCOVBlock, this object stores a 16716c19a155c65fd41865562fe4e678ef32728510bDevang Patel // list of line numbers and a single filename, representing lines that belong 16816c19a155c65fd41865562fe4e678ef32728510bDevang Patel // to the block. 169b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVLines : public GCOVRecord { 170b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 1711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addLine(uint32_t Line) { 1721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Lines.push_back(Line); 173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 174b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t length() { 176bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Here 2 = 1 for string length + 1 for '0' id#. 17716c19a155c65fd41865562fe4e678ef32728510bDevang Patel return lengthOfGCOVString(Filename) + 2 + Lines.size(); 178b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 179b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 18016c19a155c65fd41865562fe4e678ef32728510bDevang Patel void writeOut() { 18116c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(0); 18216c19a155c65fd41865562fe4e678ef32728510bDevang Patel writeGCOVString(Filename); 18316c19a155c65fd41865562fe4e678ef32728510bDevang Patel for (int i = 0, e = Lines.size(); i != e; ++i) 18416c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(Lines[i]); 18516c19a155c65fd41865562fe4e678ef32728510bDevang Patel } 186b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 18716c19a155c65fd41865562fe4e678ef32728510bDevang Patel GCOVLines(StringRef F, raw_ostream *os) 18816c19a155c65fd41865562fe4e678ef32728510bDevang Patel : Filename(F) { 189b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 190b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 191b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 192680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel private: 19316c19a155c65fd41865562fe4e678ef32728510bDevang Patel StringRef Filename; 1941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<uint32_t, 32> Lines; 195b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 196b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 197b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Represent a basic block in GCOV. Each block has a unique number in the 198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // function, number of lines belonging to each block, and a set of edges to 199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // other blocks. 200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock : public GCOVRecord { 201b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 20268155d31cd0175be89e26ee68387cb411fca537bDevang Patel GCOVLines &getFile(StringRef Filename) { 2031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVLines *&Lines = LinesByFile[Filename]; 2041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!Lines) { 20516c19a155c65fd41865562fe4e678ef32728510bDevang Patel Lines = new GCOVLines(Filename, os); 206b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Lines; 208b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addEdge(GCOVBlock &Successor) { 2111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky OutEdges.push_back(&Successor); 212b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 213b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 2151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = 3; 2161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 2171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = LinesByFile.end(); I != E; ++I) { 21816c19a155c65fd41865562fe4e678ef32728510bDevang Patel Len += I->second->length(); 219b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 220b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(LinesTag, 4); 2221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 2231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Number); 2241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 22516c19a155c65fd41865562fe4e678ef32728510bDevang Patel E = LinesByFile.end(); I != E; ++I) 22616c19a155c65fd41865562fe4e678ef32728510bDevang Patel I->second->writeOut(); 2271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 2281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 229b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 230b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 231b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVBlock() { 2321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(LinesByFile); 233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 234b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 235b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky friend class GCOVFunction; 237b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock(uint32_t Number, raw_ostream *os) 2391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky : Number(Number) { 240b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 241b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 242b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Number; 2441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky StringMap<GCOVLines *> LinesByFile; 2451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<GCOVBlock *, 4> OutEdges; 246b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 247b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 248b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A function has a unique identifier, a checksum (we leave as zero) and a 249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // set of blocks and a map of edges between blocks. This is the only GCOV 250b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // object users can construct, the blocks and lines will be rooted here. 251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction : public GCOVRecord { 252b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 253bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVFunction(DISubprogram SP, raw_ostream *os, 254bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool Use402Format, bool UseExtraChecksum) { 255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 257b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Function *F = SP.getFunction(); 258bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << "Function: " << F->getName() << "\n"); 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; 268bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (UseExtraChecksum) 269bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky ++BlockLen; 2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(BlockLen); 2711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP); 2721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Ident); 273bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // lineno checksum 274bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (UseExtraChecksum) 275bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // cfg checksum 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 } 301bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Blocks.size() << " blocks.\n"); 302b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 303b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit edges between blocks. 3041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &Block = *I->second; 3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (Block.OutEdges.empty()) continue; 3081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 3091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(EdgeTag, 4); 3101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges.size() * 2 + 1); 3111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.Number); 3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) { 313bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number 314bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky << "\n"); 3151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges[i]->Number); 3161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // no flags 317b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 318b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 319b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 320b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit lines for each block. 3211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky I->second->writeOut(); 324b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 325b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 326b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 327b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 3281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DenseMap<BasicBlock *, GCOVBlock *> Blocks; 3291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock *ReturnBlock; 330b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 331b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 332b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 333269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewyckystd::string GCOVProfiler::mangleName(DICompileUnit CU, std::string NewStem) { 334269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 335269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 336269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *N = GCov->getOperand(i); 337269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (N->getNumOperands() != 2) continue; 338fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 339269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); 340fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (!GCovFile || !CompileUnit) continue; 341fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (CompileUnit == CU) { 342fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky SmallString<128> Filename = GCovFile->getString(); 343fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky sys::path::replace_extension(Filename, NewStem); 344fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky return Filename.str(); 345fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky } 346269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 347269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 348fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky 349fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky SmallString<128> Filename = CU.getFilename(); 350fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky sys::path::replace_extension(Filename, NewStem); 351fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky return sys::path::filename(Filename.str()); 352269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky} 353269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 3540c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) { 3551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky this->M = &M; 3560c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky Ctx = &M.getContext(); 3570c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 358f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitNotes) emitGCNO(); 359f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitData) return emitProfileArcs(); 360a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky return false; 3610c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky} 3620c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 363f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid GCOVProfiler::emitGCNO() { 364f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 365bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!CU_Nodes) return; 366bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 367bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 368bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Each compile unit gets its own .gcno file. This means that whether we run 369bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // this pass over the original .o's as they're produced, or run it after 370bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // LTO, we'll generate the same .gcno files. 371bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 372bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DICompileUnit CU(CU_Nodes->getOperand(i)); 373bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky std::string ErrorInfo; 374bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo, 375bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream::F_Binary); 376bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!Use402Format) 377bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("oncg*404MVLL", 12); 378bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky else 379bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("oncg*204MVLL", 12); 380bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 381bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DIArray SPs = CU.getSubprograms(); 382bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 383bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DISubprogram SP(SPs.getElement(i)); 384bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!SP.Verify()) continue; 385bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 386bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Function *F = SP.getFunction(); 387bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!F) continue; 388bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVFunction Func(SP, &out, Use402Format, UseExtraChecksum); 389bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 390bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 391bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVBlock &Block = Func.getBlock(BB); 392bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky TerminatorInst *TI = BB->getTerminator(); 393bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (int successors = TI->getNumSuccessors()) { 394bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (int i = 0; i != successors; ++i) { 395bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 396f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 397bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } else if (isa<ReturnInst>(TI)) { 398bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getReturnBlock()); 399bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 400bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 401bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky uint32_t Line = 0; 402bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); 403bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky I != IE; ++I) { 404bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky const DebugLoc &Loc = I->getDebugLoc(); 405bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Loc.isUnknown()) continue; 406bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Line == Loc.getLine()) continue; 407bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Line = Loc.getLine(); 408bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue; 409bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 410bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVLines &Lines = Block.getFile(SP.getFilename()); 411bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Lines.addLine(Loc.getLine()); 412b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 413b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 414bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Func.writeOut(); 415b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 416bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("\0\0\0\0\0\0\0\0", 8); // EOF 417bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.close(); 418b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 419b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 420b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 421f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() { 422f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 423f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!CU_Nodes) return false; 424f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 425f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool Result = false; 426f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 427f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DICompileUnit CU(CU_Nodes->getOperand(i)); 428f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DIArray SPs = CU.getSubprograms(); 429f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; 430f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 431f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(SPs.getElement(i)); 432f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!SP.Verify()) continue; 433f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Function *F = SP.getFunction(); 434f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!F) continue; 435f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!Result) Result = true; 436f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edges = 0; 437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 438f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 439f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (isa<ReturnInst>(TI)) 440f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ++Edges; 441f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel else 442f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edges += TI->getNumSuccessors(); 443f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 444f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 445f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ArrayType *CounterTy = 4461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ArrayType::get(Type::getInt64Ty(*Ctx), Edges); 447f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *Counters = 4481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable(*M, CounterTy, false, 449b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GlobalValue::InternalLinkage, 4501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant::getNullValue(CounterTy), 451b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "__llvm_gcov_ctr", 0, false, 0); 452f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP)); 453f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 454f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgePreds; 455f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgeSuccs; 456f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 457f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edge = 0; 458f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 459f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 460f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 461f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors) { 462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(TI); 463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors == 1) { 465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge); 467f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Count = Builder.CreateAdd(Count, 469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt64Ty(*Ctx),1)); 470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Sel = Builder.CreateSelect( 473b1928704201034c785a26296a49f69355eb56a05Nick Lewycky BI->getCondition(), 4741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt64Ty(*Ctx), Edge), 4751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1)); 476f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<Value *, 2> Idx; 477f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx))); 478f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Idx.push_back(Sel); 479f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx); 480f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Count = Builder.CreateAdd(Count, 482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt64Ty(*Ctx),1)); 483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else { 485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgePreds.insert(BB); 486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0; i != Successors; ++i) 487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgeSuccs.insert(TI->getSuccessor(i)); 488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge += Successors; 490b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 491b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 492f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 493f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!ComplexEdgePreds.empty()) { 494f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeTable = 4951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky buildEdgeLookupTable(F, Counters, 4961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ComplexEdgePreds, ComplexEdgeSuccs); 497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeState = getEdgeStateValue(); 498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 499f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Type *Int32Ty = Type::getInt32Ty(*Ctx); 500f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) { 501f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator()); 502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState); 503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) { 505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // call runtime to perform increment 506c7a884040e4ec7795515978a94803894ad08c4caBill Wendling BasicBlock *BB = ComplexEdgeSuccs[i+1]; 507c7a884040e4ec7795515978a94803894ad08c4caBill Wendling BasicBlock::iterator InsertPt = BB->getFirstInsertionPt(); 508c7a884040e4ec7795515978a94803894ad08c4caBill Wendling BasicBlock *Split = BB->splitBasicBlock(InsertPt); 509c7a884040e4ec7795515978a94803894ad08c4caBill Wendling InsertPt = BB->getFirstInsertionPt(); 510f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(InsertPt); 511f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *CounterPtrArray = 5121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0, 5131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky i * ComplexEdgePreds.size()); 514c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 515c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // Build code to increment the counter. 516c7a884040e4ec7795515978a94803894ad08c4caBill Wendling incrementIndirectCounter(Builder, Split, EdgeState, CounterPtrArray); 517f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 518b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 519b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 520f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel insertCounterWriteout(CountersBySP); 521b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 522f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return Result; 523b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 524b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 5251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it 5261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update. 5271790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable( 5281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Function *F, 5291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counters, 5301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 5311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs) { 5321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // TODO: support invoke, threads. We rely on the fact that nothing can modify 5331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // the whole-Module pred edge# between the time we set it and the time we next 5341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // read it. Threads and invoke make this untrue. 5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]]. 537db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); 538db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner ArrayType *EdgeTableTy = ArrayType::get( 5391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Int64PtrTy, Succs.size() * Preds.size()); 5401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant **EdgeTable = new Constant*[Succs.size() * Preds.size()]; 5421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant *NullValue = Constant::getNullValue(Int64PtrTy); 5431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, ie = Succs.size() * Preds.size(); i != ie; ++i) 5441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[i] = NullValue; 5451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned Edge = 0; 5471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 5481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky TerminatorInst *TI = BB->getTerminator(); 5491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 5507a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) { 5511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0; i != Successors; ++i) { 5521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky BasicBlock *Succ = TI->getSuccessor(i); 5531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> builder(Succ); 5541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0, 5551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge + i); 5561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) + 5571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky (Preds.idFor(BB)-1)] = cast<Constant>(Counter); 5581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge += Successors; 5611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 563267010864e139781ef5949939e081c41f954de0aJay Foad ArrayRef<Constant*> V(&EdgeTable[0], Succs.size() * Preds.size()); 5641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *EdgeTableGV = 5651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable( 5661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *M, EdgeTableTy, true, GlobalValue::InternalLinkage, 567267010864e139781ef5949939e081c41f954de0aJay Foad ConstantArray::get(EdgeTableTy, V), 5681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcda_edge_table"); 5691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTableGV->setUnnamedAddr(true); 5701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return EdgeTableGV; 5711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 573b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() { 574db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 5755fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type::getInt8PtrTy(*Ctx), false); 5761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_start_file", FTy); 5771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 579c7a884040e4ec7795515978a94803894ad08c4caBill Wendling/// incrementIndirectCounter - Emit code that increments the indirect 580c7a884040e4ec7795515978a94803894ad08c4caBill Wendling/// counter. The code is meant to copy the llvm_gcda_increment_indirect_counter 581c7a884040e4ec7795515978a94803894ad08c4caBill Wendling/// function, but because it's inlined into the function, we don't have to worry 582c7a884040e4ec7795515978a94803894ad08c4caBill Wendling/// about the runtime library possibly writing into a protected area. 583c7a884040e4ec7795515978a94803894ad08c4caBill Wendlingvoid GCOVProfiler::incrementIndirectCounter(IRBuilder<> &Builder, 584c7a884040e4ec7795515978a94803894ad08c4caBill Wendling BasicBlock *Exit, 585c7a884040e4ec7795515978a94803894ad08c4caBill Wendling GlobalVariable *EdgeState, 586c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Value *CounterPtrArray) { 587c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Type *Int64Ty = Type::getInt64Ty(*Ctx); 588c7a884040e4ec7795515978a94803894ad08c4caBill Wendling ConstantInt *NegOne = ConstantInt::get(Type::getInt32Ty(*Ctx), 0xffffffff); 589c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 590c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // Create exiting blocks. 591c7a884040e4ec7795515978a94803894ad08c4caBill Wendling BasicBlock *InsBB = Builder.GetInsertBlock(); 592c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Function *Fn = InsBB->getParent(); 593c7a884040e4ec7795515978a94803894ad08c4caBill Wendling BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn, Exit); 594c7a884040e4ec7795515978a94803894ad08c4caBill Wendling BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn, Exit); 595c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 596c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // uint32_t pred = *EdgeState; 597c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // if (pred == 0xffffffff) return; 598c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Value *Pred = Builder.CreateLoad(EdgeState, "predecessor"); 599c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Value *Cond = Builder.CreateICmpEQ(Pred, NegOne); 600c7a884040e4ec7795515978a94803894ad08c4caBill Wendling InsBB->getTerminator()->eraseFromParent(); 601c7a884040e4ec7795515978a94803894ad08c4caBill Wendling BranchInst::Create(Exit, PredNotNegOne, Cond, InsBB); 602c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 603c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Builder.SetInsertPoint(PredNotNegOne); 604c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 605c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // uint64_t *counter = CounterPtrArray[pred]; 606c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // if (!counter) return; 607c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Value *ZExtPred = Builder.CreateZExt(Pred, Int64Ty); 608c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Value *GEP = Builder.CreateGEP(CounterPtrArray, ZExtPred); 609c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Value *Counter = Builder.CreateLoad(GEP, "counter"); 610c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Cond = Builder.CreateICmpEQ(Counter, 611c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Constant::getNullValue(Type::getInt64PtrTy(*Ctx, 0))); 612c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Builder.CreateCondBr(Cond, Exit, CounterEnd); 613c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 614c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Builder.SetInsertPoint(CounterEnd); 615c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 616c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // ++*counter; 617c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter), 618c7a884040e4ec7795515978a94803894ad08c4caBill Wendling ConstantInt::get(Int64Ty, 1)); 619c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Builder.CreateStore(Add, Counter); 620c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Builder.CreateBr(Exit); 621c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 622c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // Clear the predecessor number 623c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Builder.SetInsertPoint(Exit->getFirstInsertionPt()); 624c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Builder.CreateStore(NegOne, EdgeState); 625b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 626b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 627b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() { 6285fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[2] = { 6295409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt32Ty(*Ctx), // uint32_t ident 6305409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt8PtrTy(*Ctx), // const char *function_name 6315409a188328d9de3755febc23558d4fc1797d04eNick Lewycky }; 632c7a884040e4ec7795515978a94803894ad08c4caBill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 6331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 634b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 635b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 636b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() { 6375fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[] = { 638b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt32Ty(*Ctx), // uint32_t num_counters 639b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt64PtrTy(*Ctx), // uint64_t *counters 640b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 641db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 642b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Args, false); 6431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 644b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 645b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 646b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() { 647db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 649b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 650b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6511790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() { 6521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 6531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!GV) { 6541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 6551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalValue::InternalLinkage, 6561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt32Ty(*Ctx), 6571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 0xffffffff), 6581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcov_global_state_pred"); 6591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV->setUnnamedAddr(true); 6601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GV; 6621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 663b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckyvoid GCOVProfiler::insertCounterWriteout( 6655409a188328d9de3755febc23558d4fc1797d04eNick Lewycky SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> &CountersBySP) { 666db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *WriteoutFTy = 667b1928704201034c785a26296a49f69355eb56a05Nick Lewycky FunctionType::get(Type::getVoidTy(*Ctx), false); 668b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Function *WriteoutF = Function::Create(WriteoutFTy, 669b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GlobalValue::InternalLinkage, 6701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcov_writeout", M); 671b1928704201034c785a26296a49f69355eb56a05Nick Lewycky WriteoutF->setUnnamedAddr(true); 672b1928704201034c785a26296a49f69355eb56a05Nick Lewycky BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF); 6731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> Builder(BB); 674b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 675b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *StartFile = getStartFileFunc(); 676b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitFunction = getEmitFunctionFunc(); 677b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitArcs = getEmitArcsFunc(); 678b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EndFile = getEndFileFunc(); 679b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 680f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 681f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (CU_Nodes) { 682f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 683f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DICompileUnit compile_unit(CU_Nodes->getOperand(i)); 684f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel std::string FilenameGcda = mangleName(compile_unit, "gcda"); 685f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(StartFile, 686f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateGlobalStringPtr(FilenameGcda)); 687f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (SmallVector<std::pair<GlobalVariable *, MDNode *>, 8>::iterator 6885409a188328d9de3755febc23558d4fc1797d04eNick Lewycky I = CountersBySP.begin(), E = CountersBySP.end(); 689f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel I != E; ++I) { 690f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(I->second); 691f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel intptr_t ident = reinterpret_cast<intptr_t>(I->second); 692f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitFunction, 693f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt32Ty(*Ctx), ident), 694f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateGlobalStringPtr(SP.getName())); 695f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 696f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *GV = I->first; 697f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Arcs = 698b1928704201034c785a26296a49f69355eb56a05Nick Lewycky cast<ArrayType>(GV->getType()->getElementType())->getNumElements(); 699f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitArcs, 700f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs), 701f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateConstGEP2_64(GV, 0, 0)); 702f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 703f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(EndFile); 704b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 705b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 7061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateRetVoid(); 707b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 7081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky InsertProfilingShutdownCall(WriteoutF, M); 709b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 710