GCOVProfiling.cpp revision 034b94b17006f51722886b0f2283fb6fb19aca1f
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 "llvm/Transforms/Instrumentation.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "ProfilingUtils.h" 21b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/DenseMap.h" 22b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/STLExtras.h" 2306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/ADT/Statistic.h" 24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringExtras.h" 25b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringMap.h" 26b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/UniqueVector.h" 27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/DebugInfo.h" 28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/IRBuilder.h" 29d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Instructions.h" 30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Module.h" 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Pass.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), 4808e13e4488cde76fc51f942e773874627a88eeaeBill Wendling UseExtraChecksum(false), NoRedZone(false) { 49a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 50a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky } 51f209dea96a34f8c3c06e19710e9ff008d4f18c6cRafael Espindola GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format, 52f209dea96a34f8c3c06e19710e9ff008d4f18c6cRafael Espindola bool useExtraChecksum, bool NoRedZone_) 53f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData), 54f209dea96a34f8c3c06e19710e9ff008d4f18c6cRafael Espindola Use402Format(use402Format), UseExtraChecksum(useExtraChecksum), 55f209dea96a34f8c3c06e19710e9ff008d4f18c6cRafael Espindola NoRedZone(NoRedZone_) { 56a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?"); 57b1928704201034c785a26296a49f69355eb56a05Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 58b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 59b1928704201034c785a26296a49f69355eb56a05Nick Lewycky virtual const char *getPassName() const { 60b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return "GCOV Profiler"; 61b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 62b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 63269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky bool runOnModule(Module &M); 64269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 65b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Create the GCNO files for the Module based on DebugInfo. 66f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel void emitGCNO(); 67b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 680c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // Modify the program to track transitions along edges and call into the 690c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // profiling runtime to emit .gcda files when run. 70f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool emitProfileArcs(); 710c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 72b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Get pointers to the functions in the runtime library. 73b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getStartFileFunc(); 7477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Constant *getIncrementIndirectCounterFunc(); 75b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitFunctionFunc(); 76b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitArcsFunc(); 77b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEndFileFunc(); 78b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Create or retrieve an i32 state value that is used to represent the 801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // pred block number for certain non-trivial edges. 811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *getEdgeStateValue(); 821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Produce a table of pointers to counters, by predecessor and successor 841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // block number. 851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *buildEdgeLookupTable(Function *F, 861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counter, 871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs); 891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 90b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Add the function to write out all our counters to the global destructor 91b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // list. 9221b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling void insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*, MDNode*> >); 9377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling void insertIndirectCounterIncrement(); 94253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling void insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >); 95b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 9673996f44070df026e4d969b1b68461a70ebb3993Bill Wendling std::string mangleName(DICompileUnit CU, const char *NewStem); 97269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 98a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitNotes; 99a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitData; 100f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling bool Use402Format; 101bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool UseExtraChecksum; 10208e13e4488cde76fc51f942e773874627a88eeaeBill Wendling bool NoRedZone; 103a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky 1041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Module *M; 105b1928704201034c785a26296a49f69355eb56a05Nick Lewycky LLVMContext *Ctx; 106b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 107b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 108b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 109b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0; 110b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", 111b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "Insert instrumentation for GCOV profiling", false, false) 112b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 113f5c95b889f270f170ff4f6a24b082be5bb68296eBill WendlingModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData, 1147c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky bool Use402Format, 11508e13e4488cde76fc51f942e773874627a88eeaeBill Wendling bool UseExtraChecksum, 11608e13e4488cde76fc51f942e773874627a88eeaeBill Wendling bool NoRedZone) { 11708e13e4488cde76fc51f942e773874627a88eeaeBill Wendling return new GCOVProfiler(EmitNotes, EmitData, Use402Format, UseExtraChecksum, 11808e13e4488cde76fc51f942e773874627a88eeaeBill Wendling NoRedZone); 119a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky} 120b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 121b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 122b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVRecord { 123b1928704201034c785a26296a49f69355eb56a05Nick Lewycky protected: 1241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *LinesTag; 1251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *FunctionTag; 1261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *BlockTag; 1271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *EdgeTag; 128b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 129b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GCOVRecord() {} 130b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeBytes(const char *Bytes, int Size) { 1321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky os->write(Bytes, Size); 133b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 134b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void write(uint32_t i) { 1361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(reinterpret_cast<char*>(&i), 4); 137b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Returns the length measured in 4-byte blocks that will be used to 140b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // represent this string in a GCOV file 1411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned lengthOfGCOVString(StringRef s) { 142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 14317df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // padding out to the next 4-byte word. The length is measured in 4-byte 14417df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // words including padding, not bytes of actual string. 145d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky return (s.size() / 4) + 1; 146b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 147b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeGCOVString(StringRef s) { 1491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = lengthOfGCOVString(s); 1501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 1511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(s.data(), s.size()); 152b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 153b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Write 1 to 4 bytes of NUL padding. 1547a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) > 0); 1557a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) <= 4); 1567a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 157b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 158b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 159b1928704201034c785a26296a49f69355eb56a05Nick Lewycky raw_ostream *os; 160b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 1611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::LinesTag = "\0\0\x45\x01"; 1621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::FunctionTag = "\0\0\0\1"; 1631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::BlockTag = "\0\0\x41\x01"; 1641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::EdgeTag = "\0\0\x43\x01"; 165b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction; 167b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock; 168b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 169b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Constructed only by requesting it from a GCOVBlock, this object stores a 17016c19a155c65fd41865562fe4e678ef32728510bDevang Patel // list of line numbers and a single filename, representing lines that belong 17116c19a155c65fd41865562fe4e678ef32728510bDevang Patel // to the block. 172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVLines : public GCOVRecord { 173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addLine(uint32_t Line) { 1751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Lines.push_back(Line); 176b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 177b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t length() { 179bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Here 2 = 1 for string length + 1 for '0' id#. 18016c19a155c65fd41865562fe4e678ef32728510bDevang Patel return lengthOfGCOVString(Filename) + 2 + Lines.size(); 181b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 182b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 18316c19a155c65fd41865562fe4e678ef32728510bDevang Patel void writeOut() { 18416c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(0); 18516c19a155c65fd41865562fe4e678ef32728510bDevang Patel writeGCOVString(Filename); 18616c19a155c65fd41865562fe4e678ef32728510bDevang Patel for (int i = 0, e = Lines.size(); i != e; ++i) 18716c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(Lines[i]); 18816c19a155c65fd41865562fe4e678ef32728510bDevang Patel } 189b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 19016c19a155c65fd41865562fe4e678ef32728510bDevang Patel GCOVLines(StringRef F, raw_ostream *os) 19116c19a155c65fd41865562fe4e678ef32728510bDevang Patel : Filename(F) { 192b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 193b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 194b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 195680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel private: 19616c19a155c65fd41865562fe4e678ef32728510bDevang Patel StringRef Filename; 1971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<uint32_t, 32> Lines; 198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Represent a basic block in GCOV. Each block has a unique number in the 201b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // function, number of lines belonging to each block, and a set of edges to 202b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // other blocks. 203b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock : public GCOVRecord { 204b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 20568155d31cd0175be89e26ee68387cb411fca537bDevang Patel GCOVLines &getFile(StringRef Filename) { 2061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVLines *&Lines = LinesByFile[Filename]; 2071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!Lines) { 20816c19a155c65fd41865562fe4e678ef32728510bDevang Patel Lines = new GCOVLines(Filename, os); 209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Lines; 211b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 212b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addEdge(GCOVBlock &Successor) { 2141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky OutEdges.push_back(&Successor); 215b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 216b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 2181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = 3; 2191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 2201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = LinesByFile.end(); I != E; ++I) { 22116c19a155c65fd41865562fe4e678ef32728510bDevang Patel Len += I->second->length(); 222b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 223b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(LinesTag, 4); 2251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 2261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Number); 2271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 22816c19a155c65fd41865562fe4e678ef32728510bDevang Patel E = LinesByFile.end(); I != E; ++I) 22916c19a155c65fd41865562fe4e678ef32728510bDevang Patel I->second->writeOut(); 2301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 2311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 234b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVBlock() { 2351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(LinesByFile); 236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 237b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 238b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 239b1928704201034c785a26296a49f69355eb56a05Nick Lewycky friend class GCOVFunction; 240b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock(uint32_t Number, raw_ostream *os) 2421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky : Number(Number) { 243b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 245b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Number; 2471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky StringMap<GCOVLines *> LinesByFile; 2481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<GCOVBlock *, 4> OutEdges; 249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 250b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A function has a unique identifier, a checksum (we leave as zero) and a 252b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // set of blocks and a map of edges between blocks. This is the only GCOV 253b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // object users can construct, the blocks and lines will be rooted here. 254b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction : public GCOVRecord { 255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 256bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVFunction(DISubprogram SP, raw_ostream *os, 257bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool Use402Format, bool UseExtraChecksum) { 258b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 259b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 260b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Function *F = SP.getFunction(); 261bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << "Function: " << F->getName() << "\n"); 262b1928704201034c785a26296a49f69355eb56a05Nick Lewycky uint32_t i = 0; 263b1928704201034c785a26296a49f69355eb56a05Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 2641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Blocks[BB] = new GCOVBlock(i++, os); 265b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ReturnBlock = new GCOVBlock(i++, os); 2671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 2681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(FunctionTag, 4); 269f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) + 2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1 + lengthOfGCOVString(SP.getFilename()) + 1; 271bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (UseExtraChecksum) 272bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky ++BlockLen; 2731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(BlockLen); 2741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP); 2751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Ident); 276bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // lineno checksum 277bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (UseExtraChecksum) 278bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // cfg checksum 2791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getName()); 2801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getFilename()); 2811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(SP.getLineNumber()); 282b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 283b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVFunction() { 2851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(Blocks); 2861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky delete ReturnBlock; 287b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getBlock(BasicBlock *BB) { 2901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Blocks[BB]; 291b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 292b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2931790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getReturnBlock() { 2941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *ReturnBlock; 295a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky } 296a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky 2971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 298b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit count of blocks. 2991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(BlockTag, 4); 3001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Blocks.size() + 1); 3011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Blocks.size() + 1; i != e; ++i) { 3021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // No flags on our blocks. 303b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 304bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Blocks.size() << " blocks.\n"); 305b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 306b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit edges between blocks. 3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &Block = *I->second; 3101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (Block.OutEdges.empty()) continue; 3111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(EdgeTag, 4); 3131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges.size() * 2 + 1); 3141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.Number); 3151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) { 316bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number 317bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky << "\n"); 3181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges[i]->Number); 3191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // no flags 320b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 321b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 322b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 323b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit lines for each block. 3241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky I->second->writeOut(); 327b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 328b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 329b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 330b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 3311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DenseMap<BasicBlock *, GCOVBlock *> Blocks; 3321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock *ReturnBlock; 333b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 334b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 335b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 33673996f44070df026e4d969b1b68461a70ebb3993Bill Wendlingstd::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem) { 337269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 338269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 339269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *N = GCov->getOperand(i); 340269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (N->getNumOperands() != 2) continue; 341fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 342269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); 343fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (!GCovFile || !CompileUnit) continue; 344fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (CompileUnit == CU) { 3456e5190c193f6267893daf6943af88e95039e739cBill Wendling SmallString<128> Filename = GCovFile->getString(); 3466e5190c193f6267893daf6943af88e95039e739cBill Wendling sys::path::replace_extension(Filename, NewStem); 3476e5190c193f6267893daf6943af88e95039e739cBill Wendling return Filename.str(); 348fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky } 349269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 350269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 351fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky 3526e5190c193f6267893daf6943af88e95039e739cBill Wendling SmallString<128> Filename = CU.getFilename(); 353fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky sys::path::replace_extension(Filename, NewStem); 3546e5190c193f6267893daf6943af88e95039e739cBill Wendling return sys::path::filename(Filename.str()); 355269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky} 356269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 3570c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) { 3581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky this->M = &M; 3590c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky Ctx = &M.getContext(); 3600c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 361f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitNotes) emitGCNO(); 362f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitData) return emitProfileArcs(); 363a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky return false; 3640c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky} 3650c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 366f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid GCOVProfiler::emitGCNO() { 367f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 368bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!CU_Nodes) return; 369bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 370bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 371bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Each compile unit gets its own .gcno file. This means that whether we run 372bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // this pass over the original .o's as they're produced, or run it after 373bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // LTO, we'll generate the same .gcno files. 374bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 375bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DICompileUnit CU(CU_Nodes->getOperand(i)); 376bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky std::string ErrorInfo; 377bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo, 378bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream::F_Binary); 379bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!Use402Format) 380bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("oncg*404MVLL", 12); 381bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky else 382bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("oncg*204MVLL", 12); 383bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 384bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DIArray SPs = CU.getSubprograms(); 385bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 386bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DISubprogram SP(SPs.getElement(i)); 387bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!SP.Verify()) continue; 388bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 389bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Function *F = SP.getFunction(); 390bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!F) continue; 391bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVFunction Func(SP, &out, Use402Format, UseExtraChecksum); 392bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 393bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 394bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVBlock &Block = Func.getBlock(BB); 395bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky TerminatorInst *TI = BB->getTerminator(); 396bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (int successors = TI->getNumSuccessors()) { 397bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (int i = 0; i != successors; ++i) { 398bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 399f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 400bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } else if (isa<ReturnInst>(TI)) { 401bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getReturnBlock()); 402bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 403bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 404bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky uint32_t Line = 0; 405bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); 406bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky I != IE; ++I) { 407bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky const DebugLoc &Loc = I->getDebugLoc(); 408bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Loc.isUnknown()) continue; 409bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Line == Loc.getLine()) continue; 410bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Line = Loc.getLine(); 411bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue; 412bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 413bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVLines &Lines = Block.getFile(SP.getFilename()); 414bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Lines.addLine(Loc.getLine()); 415b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 416b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 417bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Func.writeOut(); 418b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 419bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("\0\0\0\0\0\0\0\0", 8); // EOF 420bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.close(); 421b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 422b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 423b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 424f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() { 425f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 426f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!CU_Nodes) return false; 427f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 428f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool Result = false; 42977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling bool InsertIndCounterIncrCode = false; 430f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 431f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DICompileUnit CU(CU_Nodes->getOperand(i)); 432f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DIArray SPs = CU.getSubprograms(); 433f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; 434f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 435f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(SPs.getElement(i)); 436f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!SP.Verify()) continue; 437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Function *F = SP.getFunction(); 438f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!F) continue; 439f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!Result) Result = true; 440f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edges = 0; 441f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 442f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 443f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (isa<ReturnInst>(TI)) 444f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ++Edges; 445f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel else 446f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edges += TI->getNumSuccessors(); 447f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 448f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 449f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ArrayType *CounterTy = 4501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ArrayType::get(Type::getInt64Ty(*Ctx), Edges); 451f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *Counters = 4521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable(*M, CounterTy, false, 453b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GlobalValue::InternalLinkage, 4541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant::getNullValue(CounterTy), 455ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg "__llvm_gcov_ctr"); 456f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP)); 457f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 458f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgePreds; 459f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgeSuccs; 460f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 461f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edge = 0; 462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors) { 466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(TI); 467f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors == 1) { 469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge); 471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Count = Builder.CreateAdd(Count, 473f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt64Ty(*Ctx),1)); 474f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 475f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 476f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Sel = Builder.CreateSelect( 477b1928704201034c785a26296a49f69355eb56a05Nick Lewycky BI->getCondition(), 4781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt64Ty(*Ctx), Edge), 4791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1)); 480f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<Value *, 2> Idx; 481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx))); 482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Idx.push_back(Sel); 483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx); 484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Count = Builder.CreateAdd(Count, 486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt64Ty(*Ctx),1)); 487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else { 489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgePreds.insert(BB); 490f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0; i != Successors; ++i) 491f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgeSuccs.insert(TI->getSuccessor(i)); 492f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 493f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge += Successors; 494b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 495b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 496f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!ComplexEdgePreds.empty()) { 498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeTable = 4991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky buildEdgeLookupTable(F, Counters, 5001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ComplexEdgePreds, ComplexEdgeSuccs); 501f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeState = getEdgeStateValue(); 502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Type *Int32Ty = Type::getInt32Ty(*Ctx); 504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) { 505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator()); 506f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState); 507f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 508f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) { 509f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // call runtime to perform increment 51077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock::iterator InsertPt = 51177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling ComplexEdgeSuccs[i+1]->getFirstInsertionPt(); 512f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(InsertPt); 513f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *CounterPtrArray = 5141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0, 5151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky i * ComplexEdgePreds.size()); 516c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 517c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // Build code to increment the counter. 51877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling InsertIndCounterIncrCode = true; 51977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateCall2(getIncrementIndirectCounterFunc(), 52077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling EdgeState, CounterPtrArray); 521f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 522b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 523b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 5244a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 525f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel insertCounterWriteout(CountersBySP); 526253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling insertFlush(CountersBySP); 527b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 52877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 52977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (InsertIndCounterIncrCode) 53077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling insertIndirectCounterIncrement(); 53177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 532f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return Result; 533b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 534b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it 5361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update. 5371790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable( 5381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Function *F, 5391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counters, 5401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 5411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs) { 5421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // TODO: support invoke, threads. We rely on the fact that nothing can modify 5431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // the whole-Module pred edge# between the time we set it and the time we next 5441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // read it. Threads and invoke make this untrue. 5451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]]. 5479e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer size_t TableSize = Succs.size() * Preds.size(); 548db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); 5499e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize); 5501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5519e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer OwningArrayPtr<Constant *> EdgeTable(new Constant*[TableSize]); 5521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant *NullValue = Constant::getNullValue(Int64PtrTy); 5539e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer for (size_t i = 0; i != TableSize; ++i) 5541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[i] = NullValue; 5551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned Edge = 0; 5571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 5581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky TerminatorInst *TI = BB->getTerminator(); 5591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 5607a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) { 5611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0; i != Successors; ++i) { 5621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky BasicBlock *Succ = TI->getSuccessor(i); 5631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> builder(Succ); 5641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0, 5651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge + i); 5661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) + 5671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky (Preds.idFor(BB)-1)] = cast<Constant>(Counter); 5681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge += Successors; 5711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 5721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 5739e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer ArrayRef<Constant*> V(&EdgeTable[0], TableSize); 5741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *EdgeTableGV = 5751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable( 5761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *M, EdgeTableTy, true, GlobalValue::InternalLinkage, 577267010864e139781ef5949939e081c41f954de0aJay Foad ConstantArray::get(EdgeTableTy, V), 5781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcda_edge_table"); 5791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTableGV->setUnnamedAddr(true); 5801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return EdgeTableGV; 5811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 583b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() { 584db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 5855fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type::getInt8PtrTy(*Ctx), false); 5861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_start_file", FTy); 5871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 58977b19134104c3e96424dc010f2b69c3faf580e68Bill WendlingConstant *GCOVProfiler::getIncrementIndirectCounterFunc() { 59077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Int32Ty = Type::getInt32Ty(*Ctx); 591c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Type *Int64Ty = Type::getInt64Ty(*Ctx); 59277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Args[] = { 593b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow Int32Ty->getPointerTo(), // uint32_t *predecessor 594b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters 59577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling }; 59677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 59777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy); 598b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 599b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 600b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() { 6015fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[2] = { 6025409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt32Ty(*Ctx), // uint32_t ident 6035409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt8PtrTy(*Ctx), // const char *function_name 6045409a188328d9de3755febc23558d4fc1797d04eNick Lewycky }; 605c7a884040e4ec7795515978a94803894ad08c4caBill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 6061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 607b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 608b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 609b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() { 6105fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[] = { 611b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt32Ty(*Ctx), // uint32_t num_counters 612b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt64PtrTy(*Ctx), // uint64_t *counters 613b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 614db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 615b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Args, false); 6161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 617b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 618b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 619b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() { 620db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 622b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 623b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6241790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() { 6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!GV) { 6271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 6281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalValue::InternalLinkage, 6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt32Ty(*Ctx), 6301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 0xffffffff), 6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcov_global_state_pred"); 6321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV->setUnnamedAddr(true); 6331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GV; 6351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 636b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckyvoid GCOVProfiler::insertCounterWriteout( 63821b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) { 639253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 640253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Function *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 641253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!WriteoutF) 642253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage, 643253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling "__llvm_gcov_writeout", M); 644b1928704201034c785a26296a49f69355eb56a05Nick Lewycky WriteoutF->setUnnamedAddr(true); 645034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling WriteoutF->addFnAttr(Attribute::NoInline); 64608e13e4488cde76fc51f942e773874627a88eeaeBill Wendling if (NoRedZone) 647034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling WriteoutF->addFnAttr(Attribute::NoRedZone); 648253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 649253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF); 6501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> Builder(BB); 651b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 652b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *StartFile = getStartFileFunc(); 653b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitFunction = getEmitFunctionFunc(); 654b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitArcs = getEmitArcsFunc(); 655b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EndFile = getEndFileFunc(); 656b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 657f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 658f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (CU_Nodes) { 659f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 660032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling DICompileUnit CU(CU_Nodes->getOperand(i)); 661032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling std::string FilenameGcda = mangleName(CU, "gcda"); 662f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(StartFile, 663f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateGlobalStringPtr(FilenameGcda)); 66421b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator 6655409a188328d9de3755febc23558d4fc1797d04eNick Lewycky I = CountersBySP.begin(), E = CountersBySP.end(); 666f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel I != E; ++I) { 667f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(I->second); 668f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel intptr_t ident = reinterpret_cast<intptr_t>(I->second); 669f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitFunction, 670f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt32Ty(*Ctx), ident), 671f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateGlobalStringPtr(SP.getName())); 672f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 673f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *GV = I->first; 674f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Arcs = 675b1928704201034c785a26296a49f69355eb56a05Nick Lewycky cast<ArrayType>(GV->getType()->getElementType())->getNumElements(); 676f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitArcs, 677f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs), 678f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateConstGEP2_64(GV, 0, 0)); 679f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 680f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(EndFile); 681b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 682b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 6831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateRetVoid(); 684b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6854a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling // Create a small bit of code that registers the "__llvm_gcov_writeout" 6864a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling // function to be executed at exit. 6874a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6884a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, 6894a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling "__llvm_gcov_init", M); 6904a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling F->setUnnamedAddr(true); 6914a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling F->setLinkage(GlobalValue::InternalLinkage); 692034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling F->addFnAttr(Attribute::NoInline); 69308e13e4488cde76fc51f942e773874627a88eeaeBill Wendling if (NoRedZone) 694034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling F->addFnAttr(Attribute::NoRedZone); 6954a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 6964a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling BB = BasicBlock::Create(*Ctx, "entry", F); 6974a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.SetInsertPoint(BB); 6984a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 6994a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling FTy = FunctionType::get(Type::getInt32Ty(*Ctx), 7004a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling PointerType::get(FTy, 0), false); 701c1b6ea7b6ce3a738accbacddf52480bf94354d2fBill Wendling Constant *AtExitFn = M->getOrInsertFunction("atexit", FTy); 7024a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.CreateCall(AtExitFn, WriteoutF); 7034a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.CreateRetVoid(); 7044a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 7054a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling appendToGlobalCtors(*M, F, 0); 706b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 70777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 70877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendlingvoid GCOVProfiler::insertIndirectCounterIncrement() { 70977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Function *Fn = 71077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc()); 71177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->setUnnamedAddr(true); 71277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->setLinkage(GlobalValue::InternalLinkage); 713034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling Fn->addFnAttr(Attribute::NoInline); 71408e13e4488cde76fc51f942e773874627a88eeaeBill Wendling if (NoRedZone) 715034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling Fn->addFnAttr(Attribute::NoRedZone); 71677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 71777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Int32Ty = Type::getInt32Ty(*Ctx); 71877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Int64Ty = Type::getInt64Ty(*Ctx); 71977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Constant *NegOne = ConstantInt::get(Int32Ty, 0xffffffff); 72077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 72177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // Create basic blocks for function. 72277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn); 72377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling IRBuilder<> Builder(BB); 72477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 72577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn); 72677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn); 72777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn); 72877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 72977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // uint32_t pred = *predecessor; 73077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // if (pred == 0xffffffff) return; 73177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Argument *Arg = Fn->arg_begin(); 73277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg->setName("predecessor"); 73377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Pred = Builder.CreateLoad(Arg, "pred"); 73477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Cond = Builder.CreateICmpEQ(Pred, NegOne); 73577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BranchInst::Create(Exit, PredNotNegOne, Cond, BB); 73677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 73777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(PredNotNegOne); 73877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 73977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // uint64_t *counter = counters[pred]; 74077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // if (!counter) return; 74177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *ZExtPred = Builder.CreateZExt(Pred, Int64Ty); 74277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg = llvm::next(Fn->arg_begin()); 74377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg->setName("counters"); 74477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *GEP = Builder.CreateGEP(Arg, ZExtPred); 74577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Counter = Builder.CreateLoad(GEP, "counter"); 74677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Cond = Builder.CreateICmpEQ(Counter, 747b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow Constant::getNullValue(Int64Ty->getPointerTo())); 74877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateCondBr(Cond, Exit, CounterEnd); 74977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 75077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // ++*counter; 75177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(CounterEnd); 75277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter), 75377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling ConstantInt::get(Int64Ty, 1)); 75477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateStore(Add, Counter); 75577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateBr(Exit); 75677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 75777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // Fill in the exit block. 75877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(Exit); 75977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateRetVoid(); 76077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling} 761253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 762253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendlingvoid GCOVProfiler:: 763253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill WendlinginsertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) { 764253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 76578fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling Function *FlushF = M->getFunction("__gcov_flush"); 766253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!FlushF) 767253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF = Function::Create(FTy, GlobalValue::InternalLinkage, 76878fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling "__gcov_flush", M); 769253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else 770253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF->setLinkage(GlobalValue::InternalLinkage); 771253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF->setUnnamedAddr(true); 772034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling FlushF->addFnAttr(Attribute::NoInline); 77308e13e4488cde76fc51f942e773874627a88eeaeBill Wendling if (NoRedZone) 774034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling FlushF->addFnAttr(Attribute::NoRedZone); 775253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 776253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF); 777253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 778253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling // Write out the current counters. 779253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 780253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling assert(WriteoutF && "Need to create the writeout function first!"); 781253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 782253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling IRBuilder<> Builder(Entry); 783253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateCall(WriteoutF); 784253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 785032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling // Zero out the counters. 786032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator 787032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling I = CountersBySP.begin(), E = CountersBySP.end(); 788032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling I != E; ++I) { 789032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling GlobalVariable *GV = I->first; 790032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling Constant *Null = Constant::getNullValue(GV->getType()->getElementType()); 791ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling Builder.CreateStore(Null, GV); 792032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling } 793253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 794253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Type *RetTy = FlushF->getReturnType(); 795253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (RetTy == Type::getVoidTy(*Ctx)) 796253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateRetVoid(); 797253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else if (RetTy->isIntegerTy()) 79878fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling // Used if __gcov_flush was implicitly declared. 799253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateRet(ConstantInt::get(RetTy, 0)); 800253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else 80178fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling report_fatal_error("invalid return type for __gcov_flush"); 802253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling} 803