GCOVProfiling.cpp revision ec3fc2eac0e9203dd1094b9ce458e8c1b42b832f
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" 210bcbd1df7a204e1e512f1a27066d725309de1b13Bill Wendling#include "llvm/DebugInfo.h" 2206cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/IRBuilder.h" 2306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Instructions.h" 24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Module.h" 25b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Pass.h" 26b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/DenseMap.h" 27b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/STLExtras.h" 2806cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/ADT/Statistic.h" 29b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringExtras.h" 30b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringMap.h" 31b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/UniqueVector.h" 3206cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/Debug.h" 3306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/DebugLoc.h" 3406cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/InstIterator.h" 3506cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/PathV2.h" 3606cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/raw_ostream.h" 3706cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Transforms/Utils/ModuleUtils.h" 38b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <string> 39b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <utility> 40b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyusing namespace llvm; 41b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 42b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 43b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVProfiler : public ModulePass { 44b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 45b1928704201034c785a26296a49f69355eb56a05Nick Lewycky static char ID; 46a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky GCOVProfiler() 47bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky : ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false), 48bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky UseExtraChecksum(false) { 49a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 50a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky } 51bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format = false, 52bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool useExtraChecksum = false) 53f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData), 54bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Use402Format(use402Format), UseExtraChecksum(useExtraChecksum) { 55a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?"); 56b1928704201034c785a26296a49f69355eb56a05Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 57b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 58b1928704201034c785a26296a49f69355eb56a05Nick Lewycky virtual const char *getPassName() const { 59b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return "GCOV Profiler"; 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(); 7377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Constant *getIncrementIndirectCounterFunc(); 74b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitFunctionFunc(); 75b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitArcsFunc(); 76b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEndFileFunc(); 77b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Create or retrieve an i32 state value that is used to represent the 791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // pred block number for certain non-trivial edges. 801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *getEdgeStateValue(); 811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Produce a table of pointers to counters, by predecessor and successor 831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // block number. 841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *buildEdgeLookupTable(Function *F, 851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counter, 861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs); 881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 89b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Add the function to write out all our counters to the global destructor 90b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // list. 9121b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling void insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*, MDNode*> >); 9277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling void insertIndirectCounterIncrement(); 93253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling void insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >); 94b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 9573996f44070df026e4d969b1b68461a70ebb3993Bill Wendling std::string mangleName(DICompileUnit CU, const char *NewStem); 96269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 97a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitNotes; 98a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitData; 99f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling bool Use402Format; 100bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool UseExtraChecksum; 101a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky 1021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Module *M; 103b1928704201034c785a26296a49f69355eb56a05Nick Lewycky LLVMContext *Ctx; 104b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 105b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 106b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 107b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0; 108b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", 109b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "Insert instrumentation for GCOV profiling", false, false) 110b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 111f5c95b889f270f170ff4f6a24b082be5bb68296eBill WendlingModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData, 1127c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky bool Use402Format, 1137c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky bool UseExtraChecksum) { 1147c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky return new GCOVProfiler(EmitNotes, EmitData, Use402Format, UseExtraChecksum); 115a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky} 116b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 117b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 118b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVRecord { 119b1928704201034c785a26296a49f69355eb56a05Nick Lewycky protected: 1201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *LinesTag; 1211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *FunctionTag; 1221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *BlockTag; 1231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *EdgeTag; 124b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 125b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GCOVRecord() {} 126b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeBytes(const char *Bytes, int Size) { 1281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky os->write(Bytes, Size); 129b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 130b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void write(uint32_t i) { 1321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(reinterpret_cast<char*>(&i), 4); 133b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 134b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 135b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Returns the length measured in 4-byte blocks that will be used to 136b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // represent this string in a GCOV file 1371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned lengthOfGCOVString(StringRef s) { 138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 13917df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // padding out to the next 4-byte word. The length is measured in 4-byte 14017df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // words including padding, not bytes of actual string. 141d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky return (s.size() / 4) + 1; 142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 143b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeGCOVString(StringRef s) { 1451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = lengthOfGCOVString(s); 1461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 1471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(s.data(), s.size()); 148b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 149b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Write 1 to 4 bytes of NUL padding. 1507a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) > 0); 1517a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) <= 4); 1527a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 153b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 154b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 155b1928704201034c785a26296a49f69355eb56a05Nick Lewycky raw_ostream *os; 156b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 1571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::LinesTag = "\0\0\x45\x01"; 1581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::FunctionTag = "\0\0\0\1"; 1591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::BlockTag = "\0\0\x41\x01"; 1601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::EdgeTag = "\0\0\x43\x01"; 161b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 162b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction; 163b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock; 164b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 165b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Constructed only by requesting it from a GCOVBlock, this object stores a 16616c19a155c65fd41865562fe4e678ef32728510bDevang Patel // list of line numbers and a single filename, representing lines that belong 16716c19a155c65fd41865562fe4e678ef32728510bDevang Patel // to the block. 168b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVLines : public GCOVRecord { 169b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 1701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addLine(uint32_t Line) { 1711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Lines.push_back(Line); 172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t length() { 175bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Here 2 = 1 for string length + 1 for '0' id#. 17616c19a155c65fd41865562fe4e678ef32728510bDevang Patel return lengthOfGCOVString(Filename) + 2 + Lines.size(); 177b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 178b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 17916c19a155c65fd41865562fe4e678ef32728510bDevang Patel void writeOut() { 18016c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(0); 18116c19a155c65fd41865562fe4e678ef32728510bDevang Patel writeGCOVString(Filename); 18216c19a155c65fd41865562fe4e678ef32728510bDevang Patel for (int i = 0, e = Lines.size(); i != e; ++i) 18316c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(Lines[i]); 18416c19a155c65fd41865562fe4e678ef32728510bDevang Patel } 185b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 18616c19a155c65fd41865562fe4e678ef32728510bDevang Patel GCOVLines(StringRef F, raw_ostream *os) 18716c19a155c65fd41865562fe4e678ef32728510bDevang Patel : Filename(F) { 188b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 189b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 190b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 191680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel private: 19216c19a155c65fd41865562fe4e678ef32728510bDevang Patel StringRef Filename; 1931790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<uint32_t, 32> Lines; 194b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 195b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 196b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Represent a basic block in GCOV. Each block has a unique number in the 197b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // function, number of lines belonging to each block, and a set of edges to 198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // other blocks. 199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock : public GCOVRecord { 200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 20168155d31cd0175be89e26ee68387cb411fca537bDevang Patel GCOVLines &getFile(StringRef Filename) { 2021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVLines *&Lines = LinesByFile[Filename]; 2031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!Lines) { 20416c19a155c65fd41865562fe4e678ef32728510bDevang Patel Lines = new GCOVLines(Filename, os); 205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Lines; 207b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 208b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addEdge(GCOVBlock &Successor) { 2101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky OutEdges.push_back(&Successor); 211b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 212b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 2141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = 3; 2151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 2161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = LinesByFile.end(); I != E; ++I) { 21716c19a155c65fd41865562fe4e678ef32728510bDevang Patel Len += I->second->length(); 218b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 219b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(LinesTag, 4); 2211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 2221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Number); 2231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 22416c19a155c65fd41865562fe4e678ef32728510bDevang Patel E = LinesByFile.end(); I != E; ++I) 22516c19a155c65fd41865562fe4e678ef32728510bDevang Patel I->second->writeOut(); 2261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 2271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 228b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 229b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 230b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVBlock() { 2311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(LinesByFile); 232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 234b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 235b1928704201034c785a26296a49f69355eb56a05Nick Lewycky friend class GCOVFunction; 236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock(uint32_t Number, raw_ostream *os) 2381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky : Number(Number) { 239b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 240b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 241b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Number; 2431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky StringMap<GCOVLines *> LinesByFile; 2441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<GCOVBlock *, 4> OutEdges; 245b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 246b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 247b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A function has a unique identifier, a checksum (we leave as zero) and a 248b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // set of blocks and a map of edges between blocks. This is the only GCOV 249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // object users can construct, the blocks and lines will be rooted here. 250b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction : public GCOVRecord { 251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 252bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVFunction(DISubprogram SP, raw_ostream *os, 253bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool Use402Format, bool UseExtraChecksum) { 254b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Function *F = SP.getFunction(); 257bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << "Function: " << F->getName() << "\n"); 258b1928704201034c785a26296a49f69355eb56a05Nick Lewycky uint32_t i = 0; 259b1928704201034c785a26296a49f69355eb56a05Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 2601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Blocks[BB] = new GCOVBlock(i++, os); 261b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ReturnBlock = new GCOVBlock(i++, os); 2631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 2641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(FunctionTag, 4); 265f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) + 2661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1 + lengthOfGCOVString(SP.getFilename()) + 1; 267bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (UseExtraChecksum) 268bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky ++BlockLen; 2691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(BlockLen); 2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP); 2711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Ident); 272bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // lineno checksum 273bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (UseExtraChecksum) 274bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // cfg checksum 2751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getName()); 2761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getFilename()); 2771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(SP.getLineNumber()); 278b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 279b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 280b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVFunction() { 2811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(Blocks); 2821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky delete ReturnBlock; 283b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getBlock(BasicBlock *BB) { 2861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Blocks[BB]; 287b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getReturnBlock() { 2901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *ReturnBlock; 291a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky } 292a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky 2931790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 294b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit count of blocks. 2951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(BlockTag, 4); 2961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Blocks.size() + 1); 2971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Blocks.size() + 1; i != e; ++i) { 2981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // No flags on our blocks. 299b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 300bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Blocks.size() << " blocks.\n"); 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) { 312bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number 313bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky << "\n"); 3141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges[i]->Number); 3151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // no flags 316b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 317b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 318b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 319b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit lines for each block. 3201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky I->second->writeOut(); 323b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 324b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 325b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 326b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 3271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DenseMap<BasicBlock *, GCOVBlock *> Blocks; 3281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock *ReturnBlock; 329b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 330b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 331b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 33273996f44070df026e4d969b1b68461a70ebb3993Bill Wendlingstd::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem) { 333269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 334269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 335269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *N = GCov->getOperand(i); 336269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (N->getNumOperands() != 2) continue; 337fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 338269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); 339fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (!GCovFile || !CompileUnit) continue; 340fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (CompileUnit == CU) { 3416e5190c193f6267893daf6943af88e95039e739cBill Wendling SmallString<128> Filename = GCovFile->getString(); 3426e5190c193f6267893daf6943af88e95039e739cBill Wendling sys::path::replace_extension(Filename, NewStem); 3436e5190c193f6267893daf6943af88e95039e739cBill Wendling return Filename.str(); 344fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky } 345269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 346269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 347fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky 3486e5190c193f6267893daf6943af88e95039e739cBill Wendling SmallString<128> Filename = CU.getFilename(); 349fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky sys::path::replace_extension(Filename, NewStem); 3506e5190c193f6267893daf6943af88e95039e739cBill Wendling return sys::path::filename(Filename.str()); 351269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky} 352269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 3530c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) { 3541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky this->M = &M; 3550c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky Ctx = &M.getContext(); 3560c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 357f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitNotes) emitGCNO(); 358f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitData) return emitProfileArcs(); 359a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky return false; 3600c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky} 3610c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 362f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid GCOVProfiler::emitGCNO() { 363f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 364bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!CU_Nodes) return; 365bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 366bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 367bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Each compile unit gets its own .gcno file. This means that whether we run 368bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // this pass over the original .o's as they're produced, or run it after 369bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // LTO, we'll generate the same .gcno files. 370bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 371bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DICompileUnit CU(CU_Nodes->getOperand(i)); 372bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky std::string ErrorInfo; 373bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo, 374bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream::F_Binary); 375bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!Use402Format) 376bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("oncg*404MVLL", 12); 377bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky else 378bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("oncg*204MVLL", 12); 379bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 380bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DIArray SPs = CU.getSubprograms(); 381bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 382bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DISubprogram SP(SPs.getElement(i)); 383bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!SP.Verify()) continue; 384bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 385bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Function *F = SP.getFunction(); 386bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!F) continue; 387bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVFunction Func(SP, &out, Use402Format, UseExtraChecksum); 388bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 389bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 390bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVBlock &Block = Func.getBlock(BB); 391bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky TerminatorInst *TI = BB->getTerminator(); 392bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (int successors = TI->getNumSuccessors()) { 393bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (int i = 0; i != successors; ++i) { 394bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 395f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 396bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } else if (isa<ReturnInst>(TI)) { 397bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getReturnBlock()); 398bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 399bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 400bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky uint32_t Line = 0; 401bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); 402bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky I != IE; ++I) { 403bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky const DebugLoc &Loc = I->getDebugLoc(); 404bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Loc.isUnknown()) continue; 405bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Line == Loc.getLine()) continue; 406bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Line = Loc.getLine(); 407bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue; 408bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 409bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVLines &Lines = Block.getFile(SP.getFilename()); 410bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Lines.addLine(Loc.getLine()); 411b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 412b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 413bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Func.writeOut(); 414b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 415bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("\0\0\0\0\0\0\0\0", 8); // EOF 416bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.close(); 417b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 418b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 419b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 420f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() { 421f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 422f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!CU_Nodes) return false; 423f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 424f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool Result = false; 42577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling bool InsertIndCounterIncrCode = 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), 451ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg "__llvm_gcov_ctr"); 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 50677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock::iterator InsertPt = 50777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling ComplexEdgeSuccs[i+1]->getFirstInsertionPt(); 508f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(InsertPt); 509f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *CounterPtrArray = 5101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0, 5111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky i * ComplexEdgePreds.size()); 512c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 513c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // Build code to increment the counter. 51477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling InsertIndCounterIncrCode = true; 51577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateCall2(getIncrementIndirectCounterFunc(), 51677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling EdgeState, CounterPtrArray); 517f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 518b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 519b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 5204a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 521f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel insertCounterWriteout(CountersBySP); 522253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling insertFlush(CountersBySP); 523b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 52477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 52577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (InsertIndCounterIncrCode) 52677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling insertIndirectCounterIncrement(); 52777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 528f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return Result; 529b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 530b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 5311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it 5321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update. 5331790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable( 5341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Function *F, 5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counters, 5361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 5371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs) { 5381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // TODO: support invoke, threads. We rely on the fact that nothing can modify 5391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // the whole-Module pred edge# between the time we set it and the time we next 5401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // read it. Threads and invoke make this untrue. 5411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]]. 543db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); 544db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner ArrayType *EdgeTableTy = ArrayType::get( 5451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Int64PtrTy, Succs.size() * Preds.size()); 5461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant **EdgeTable = new Constant*[Succs.size() * Preds.size()]; 5481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant *NullValue = Constant::getNullValue(Int64PtrTy); 5491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, ie = Succs.size() * Preds.size(); i != ie; ++i) 5501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[i] = NullValue; 5511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned Edge = 0; 5531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 5541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky TerminatorInst *TI = BB->getTerminator(); 5551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 5567a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) { 5571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0; i != Successors; ++i) { 5581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky BasicBlock *Succ = TI->getSuccessor(i); 5591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> builder(Succ); 5601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0, 5611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge + i); 5621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) + 5631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky (Preds.idFor(BB)-1)] = cast<Constant>(Counter); 5641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge += Successors; 5671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 569267010864e139781ef5949939e081c41f954de0aJay Foad ArrayRef<Constant*> V(&EdgeTable[0], Succs.size() * Preds.size()); 5701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *EdgeTableGV = 5711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable( 5721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *M, EdgeTableTy, true, GlobalValue::InternalLinkage, 573267010864e139781ef5949939e081c41f954de0aJay Foad ConstantArray::get(EdgeTableTy, V), 5741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcda_edge_table"); 5751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTableGV->setUnnamedAddr(true); 5761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return EdgeTableGV; 5771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 579b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() { 580db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 5815fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type::getInt8PtrTy(*Ctx), false); 5821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_start_file", FTy); 5831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 58577b19134104c3e96424dc010f2b69c3faf580e68Bill WendlingConstant *GCOVProfiler::getIncrementIndirectCounterFunc() { 58677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Int32Ty = Type::getInt32Ty(*Ctx); 587c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Type *Int64Ty = Type::getInt64Ty(*Ctx); 58877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Args[] = { 58977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Int32Ty->getPointerTo(), // uint32_t *predecessor 59077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters 59177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling }; 59277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 59377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy); 594b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 595b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 596b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() { 5975fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[2] = { 5985409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt32Ty(*Ctx), // uint32_t ident 5995409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt8PtrTy(*Ctx), // const char *function_name 6005409a188328d9de3755febc23558d4fc1797d04eNick Lewycky }; 601c7a884040e4ec7795515978a94803894ad08c4caBill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 6021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 603b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 604b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 605b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() { 6065fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[] = { 607b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt32Ty(*Ctx), // uint32_t num_counters 608b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt64PtrTy(*Ctx), // uint64_t *counters 609b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 610db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 611b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Args, false); 6121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 613b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 614b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 615b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() { 616db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 618b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 619b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6201790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() { 6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 6221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!GV) { 6231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 6241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalValue::InternalLinkage, 6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt32Ty(*Ctx), 6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 0xffffffff), 6271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcov_global_state_pred"); 6281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV->setUnnamedAddr(true); 6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GV; 6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 632b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckyvoid GCOVProfiler::insertCounterWriteout( 63421b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) { 635253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 636253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Function *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 637253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!WriteoutF) 638253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage, 639253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling "__llvm_gcov_writeout", M); 640b1928704201034c785a26296a49f69355eb56a05Nick Lewycky WriteoutF->setUnnamedAddr(true); 641253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 642253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF); 6431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> Builder(BB); 644b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 645b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *StartFile = getStartFileFunc(); 646b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitFunction = getEmitFunctionFunc(); 647b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitArcs = getEmitArcsFunc(); 648b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EndFile = getEndFileFunc(); 649b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 650f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 651f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (CU_Nodes) { 652f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 653032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling DICompileUnit CU(CU_Nodes->getOperand(i)); 654032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling std::string FilenameGcda = mangleName(CU, "gcda"); 655f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(StartFile, 656f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateGlobalStringPtr(FilenameGcda)); 65721b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator 6585409a188328d9de3755febc23558d4fc1797d04eNick Lewycky I = CountersBySP.begin(), E = CountersBySP.end(); 659f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel I != E; ++I) { 660f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(I->second); 661f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel intptr_t ident = reinterpret_cast<intptr_t>(I->second); 662f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitFunction, 663f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt32Ty(*Ctx), ident), 664f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateGlobalStringPtr(SP.getName())); 665f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 666f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *GV = I->first; 667f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Arcs = 668b1928704201034c785a26296a49f69355eb56a05Nick Lewycky cast<ArrayType>(GV->getType()->getElementType())->getNumElements(); 669f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitArcs, 670f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs), 671f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateConstGEP2_64(GV, 0, 0)); 672f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 673f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(EndFile); 674b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 675b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 6761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateRetVoid(); 677b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6784a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling // Create a small bit of code that registers the "__llvm_gcov_writeout" 6794a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling // function to be executed at exit. 6804a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6814a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, 6824a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling "__llvm_gcov_init", M); 6834a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling F->setUnnamedAddr(true); 6844a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling F->setLinkage(GlobalValue::InternalLinkage); 6854a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling F->addFnAttr(Attribute::NoInline); 6864a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 6874a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling BB = BasicBlock::Create(*Ctx, "entry", F); 6884a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.SetInsertPoint(BB); 6894a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 6904a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling FTy = FunctionType::get(Type::getInt32Ty(*Ctx), 6914a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling PointerType::get(FTy, 0), false); 692c1b6ea7b6ce3a738accbacddf52480bf94354d2fBill Wendling Constant *AtExitFn = M->getOrInsertFunction("atexit", FTy); 6934a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.CreateCall(AtExitFn, WriteoutF); 6944a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.CreateRetVoid(); 6954a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 6964a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling appendToGlobalCtors(*M, F, 0); 697b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 69877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 69977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendlingvoid GCOVProfiler::insertIndirectCounterIncrement() { 70077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Function *Fn = 70177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc()); 70277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->setUnnamedAddr(true); 70377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->setLinkage(GlobalValue::InternalLinkage); 70477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->addFnAttr(Attribute::NoInline); 70577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 70677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Int32Ty = Type::getInt32Ty(*Ctx); 70777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Int64Ty = Type::getInt64Ty(*Ctx); 70877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Constant *NegOne = ConstantInt::get(Int32Ty, 0xffffffff); 70977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 71077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // Create basic blocks for function. 71177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn); 71277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling IRBuilder<> Builder(BB); 71377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 71477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn); 71577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn); 71677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn); 71777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 71877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // uint32_t pred = *predecessor; 71977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // if (pred == 0xffffffff) return; 72077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Argument *Arg = Fn->arg_begin(); 72177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg->setName("predecessor"); 72277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Pred = Builder.CreateLoad(Arg, "pred"); 72377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Cond = Builder.CreateICmpEQ(Pred, NegOne); 72477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BranchInst::Create(Exit, PredNotNegOne, Cond, BB); 72577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 72677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(PredNotNegOne); 72777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 72877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // uint64_t *counter = counters[pred]; 72977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // if (!counter) return; 73077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *ZExtPred = Builder.CreateZExt(Pred, Int64Ty); 73177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg = llvm::next(Fn->arg_begin()); 73277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg->setName("counters"); 73377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *GEP = Builder.CreateGEP(Arg, ZExtPred); 73477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Counter = Builder.CreateLoad(GEP, "counter"); 73577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Cond = Builder.CreateICmpEQ(Counter, 73677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Constant::getNullValue(Int64Ty->getPointerTo())); 73777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateCondBr(Cond, Exit, CounterEnd); 73877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 73977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // ++*counter; 74077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(CounterEnd); 74177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter), 74277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling ConstantInt::get(Int64Ty, 1)); 74377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateStore(Add, Counter); 74477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateBr(Exit); 74577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 74677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // Fill in the exit block. 74777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(Exit); 74877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateRetVoid(); 74977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling} 750253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 751253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendlingvoid GCOVProfiler:: 752253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill WendlinginsertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) { 753253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 754253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Function *FlushF = M->getFunction("__llvm_gcov_flush"); 755253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!FlushF) 756253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF = Function::Create(FTy, GlobalValue::InternalLinkage, 757253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling "__llvm_gcov_flush", M); 758253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else 759253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF->setLinkage(GlobalValue::InternalLinkage); 760253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF->setUnnamedAddr(true); 761253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 762253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF); 763253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 764253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling // Write out the current counters. 765253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 766253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling assert(WriteoutF && "Need to create the writeout function first!"); 767253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 768253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling IRBuilder<> Builder(Entry); 769253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateCall(WriteoutF); 770253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 771032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling // Zero out the counters. 772032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator 773032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling I = CountersBySP.begin(), E = CountersBySP.end(); 774032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling I != E; ++I) { 775032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling GlobalVariable *GV = I->first; 776032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling Constant *Null = Constant::getNullValue(GV->getType()->getElementType()); 777ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling Builder.CreateStore(Null, GV); 778032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling } 779253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 780253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Type *RetTy = FlushF->getReturnType(); 781253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (RetTy == Type::getVoidTy(*Ctx)) 782253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateRetVoid(); 783253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else if (RetTy->isIntegerTy()) 784253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling // Used if __llvm_gcov_flush was implicitly declared. 785253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateRet(ConstantInt::get(RetTy, 0)); 786253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else 787253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling report_fatal_error("invalid return type for __llvm_gcov_flush"); 788253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling} 789