GCOVProfiling.cpp revision 8fa6dc431deb7a9aadc23ec0a7bdcb2d02330972
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" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/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() 47d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky : ModulePass(ID), EmitNotes(true), EmitData(true), 4852b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky UseExtraChecksum(false), NoRedZone(false), 4952b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky NoFunctionNamesInData(false) { 50d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky memcpy(Version, DefaultGCovVersion, 4); 51a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 52a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky } 53d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky GCOVProfiler(bool EmitNotes, bool EmitData, const char (&Version)[4], 5452b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky bool UseExtraChecksum, bool NoRedZone, 5552b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky bool NoFunctionNamesInData) 56f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData), 57d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky UseExtraChecksum(UseExtraChecksum), NoRedZone(NoRedZone), 58d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky NoFunctionNamesInData(NoFunctionNamesInData) { 59d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky memcpy(this->Version, Version, 4); 60a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?"); 61b1928704201034c785a26296a49f69355eb56a05Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 62b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 63b1928704201034c785a26296a49f69355eb56a05Nick Lewycky virtual const char *getPassName() const { 64b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return "GCOV Profiler"; 65b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 66b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 67269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky bool runOnModule(Module &M); 68269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 69b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Create the GCNO files for the Module based on DebugInfo. 70f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel void emitGCNO(); 71b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 720c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // Modify the program to track transitions along edges and call into the 730c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // profiling runtime to emit .gcda files when run. 74f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool emitProfileArcs(); 750c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 76b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Get pointers to the functions in the runtime library. 77b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getStartFileFunc(); 7877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Constant *getIncrementIndirectCounterFunc(); 79b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitFunctionFunc(); 80b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitArcsFunc(); 81b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEndFileFunc(); 82b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Create or retrieve an i32 state value that is used to represent the 841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // pred block number for certain non-trivial edges. 851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *getEdgeStateValue(); 861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Produce a table of pointers to counters, by predecessor and successor 881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // block number. 891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *buildEdgeLookupTable(Function *F, 901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counter, 911790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 921790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs); 931790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 94b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Add the function to write out all our counters to the global destructor 95b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // list. 9621b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling void insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*, MDNode*> >); 9777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling void insertIndirectCounterIncrement(); 98253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling void insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >); 99b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 10073996f44070df026e4d969b1b68461a70ebb3993Bill Wendling std::string mangleName(DICompileUnit CU, const char *NewStem); 101269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 102a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitNotes; 103a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky bool EmitData; 104d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky char Version[4]; 105bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky bool UseExtraChecksum; 10608e13e4488cde76fc51f942e773874627a88eeaeBill Wendling bool NoRedZone; 10752b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky bool NoFunctionNamesInData; 108a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky 1091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Module *M; 110b1928704201034c785a26296a49f69355eb56a05Nick Lewycky LLVMContext *Ctx; 111b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 112b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 113b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 114b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0; 115b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", 116b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "Insert instrumentation for GCOV profiling", false, false) 117b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 118f5c95b889f270f170ff4f6a24b082be5bb68296eBill WendlingModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData, 119d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky const char (&Version)[4], 12008e13e4488cde76fc51f942e773874627a88eeaeBill Wendling bool UseExtraChecksum, 12152b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky bool NoRedZone, 12252b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky bool NoFunctionNamesInData) { 123d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky return new GCOVProfiler(EmitNotes, EmitData, Version, UseExtraChecksum, 12452b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky NoRedZone, NoFunctionNamesInData); 125a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky} 126b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 127b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 128b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVRecord { 129b1928704201034c785a26296a49f69355eb56a05Nick Lewycky protected: 1301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *LinesTag; 1311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *FunctionTag; 1321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *BlockTag; 1331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *EdgeTag; 134b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 135b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GCOVRecord() {} 136b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeBytes(const char *Bytes, int Size) { 1381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky os->write(Bytes, Size); 139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 140b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void write(uint32_t i) { 1421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(reinterpret_cast<char*>(&i), 4); 143b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 144b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 145b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Returns the length measured in 4-byte blocks that will be used to 146b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // represent this string in a GCOV file 1471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned lengthOfGCOVString(StringRef s) { 148b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 14917df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // padding out to the next 4-byte word. The length is measured in 4-byte 15017df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // words including padding, not bytes of actual string. 151d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky return (s.size() / 4) + 1; 152b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 153b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeGCOVString(StringRef s) { 1551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = lengthOfGCOVString(s); 1561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 1571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(s.data(), s.size()); 158b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 159b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Write 1 to 4 bytes of NUL padding. 1607a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) > 0); 1617a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) <= 4); 1627a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 163b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 164b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 165b1928704201034c785a26296a49f69355eb56a05Nick Lewycky raw_ostream *os; 166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 1671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::LinesTag = "\0\0\x45\x01"; 1681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::FunctionTag = "\0\0\0\1"; 1691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::BlockTag = "\0\0\x41\x01"; 1701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::EdgeTag = "\0\0\x43\x01"; 171b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction; 173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock; 174b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 175b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Constructed only by requesting it from a GCOVBlock, this object stores a 17616c19a155c65fd41865562fe4e678ef32728510bDevang Patel // list of line numbers and a single filename, representing lines that belong 17716c19a155c65fd41865562fe4e678ef32728510bDevang Patel // to the block. 178b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVLines : public GCOVRecord { 179b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 1801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addLine(uint32_t Line) { 1811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Lines.push_back(Line); 182b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 183b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t length() { 185bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Here 2 = 1 for string length + 1 for '0' id#. 18616c19a155c65fd41865562fe4e678ef32728510bDevang Patel return lengthOfGCOVString(Filename) + 2 + Lines.size(); 187b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 188b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 18916c19a155c65fd41865562fe4e678ef32728510bDevang Patel void writeOut() { 19016c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(0); 19116c19a155c65fd41865562fe4e678ef32728510bDevang Patel writeGCOVString(Filename); 19216c19a155c65fd41865562fe4e678ef32728510bDevang Patel for (int i = 0, e = Lines.size(); i != e; ++i) 19316c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(Lines[i]); 19416c19a155c65fd41865562fe4e678ef32728510bDevang Patel } 195b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 19616c19a155c65fd41865562fe4e678ef32728510bDevang Patel GCOVLines(StringRef F, raw_ostream *os) 19716c19a155c65fd41865562fe4e678ef32728510bDevang Patel : Filename(F) { 198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 201680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel private: 20216c19a155c65fd41865562fe4e678ef32728510bDevang Patel StringRef Filename; 2031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<uint32_t, 32> Lines; 204b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 206b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Represent a basic block in GCOV. Each block has a unique number in the 207b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // function, number of lines belonging to each block, and a set of edges to 208b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // other blocks. 209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock : public GCOVRecord { 210b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 21168155d31cd0175be89e26ee68387cb411fca537bDevang Patel GCOVLines &getFile(StringRef Filename) { 2121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVLines *&Lines = LinesByFile[Filename]; 2131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!Lines) { 21416c19a155c65fd41865562fe4e678ef32728510bDevang Patel Lines = new GCOVLines(Filename, os); 215b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Lines; 217b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 218b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addEdge(GCOVBlock &Successor) { 2201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky OutEdges.push_back(&Successor); 221b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 222b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 2241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = 3; 2251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 2261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = LinesByFile.end(); I != E; ++I) { 22716c19a155c65fd41865562fe4e678ef32728510bDevang Patel Len += I->second->length(); 228b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 229b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(LinesTag, 4); 2311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 2321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Number); 2331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 23416c19a155c65fd41865562fe4e678ef32728510bDevang Patel E = LinesByFile.end(); I != E; ++I) 23516c19a155c65fd41865562fe4e678ef32728510bDevang Patel I->second->writeOut(); 2361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 2371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 238b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 239b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 240b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVBlock() { 2411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(LinesByFile); 242b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 243b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 245b1928704201034c785a26296a49f69355eb56a05Nick Lewycky friend class GCOVFunction; 246b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock(uint32_t Number, raw_ostream *os) 2481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky : Number(Number) { 249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 250b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Number; 2531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky StringMap<GCOVLines *> LinesByFile; 2541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<GCOVBlock *, 4> OutEdges; 255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 257b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A function has a unique identifier, a checksum (we leave as zero) and a 258b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // set of blocks and a map of edges between blocks. This is the only GCOV 259b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // object users can construct, the blocks and lines will be rooted here. 260b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction : public GCOVRecord { 261b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 262d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky GCOVFunction(DISubprogram SP, raw_ostream *os, uint32_t Ident, 263d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky bool UseExtraChecksum) { 264b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 265b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 266b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Function *F = SP.getFunction(); 267bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << "Function: " << F->getName() << "\n"); 268b1928704201034c785a26296a49f69355eb56a05Nick Lewycky uint32_t i = 0; 269b1928704201034c785a26296a49f69355eb56a05Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Blocks[BB] = new GCOVBlock(i++, os); 271b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ReturnBlock = new GCOVBlock(i++, os); 2731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 2741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(FunctionTag, 4); 275f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) + 2761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1 + lengthOfGCOVString(SP.getFilename()) + 1; 277bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (UseExtraChecksum) 278bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky ++BlockLen; 2791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(BlockLen); 2801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Ident); 281bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // lineno checksum 282bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (UseExtraChecksum) 283bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // cfg checksum 2841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getName()); 2851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getFilename()); 2861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(SP.getLineNumber()); 287b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 289b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVFunction() { 2901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(Blocks); 2911790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky delete ReturnBlock; 292b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 293b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getBlock(BasicBlock *BB) { 2951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Blocks[BB]; 296b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 297b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getReturnBlock() { 2991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *ReturnBlock; 300a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky } 301a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky 3021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 303b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit count of blocks. 3041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(BlockTag, 4); 3051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Blocks.size() + 1); 3061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Blocks.size() + 1; i != e; ++i) { 3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // No flags on our blocks. 308b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 309bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Blocks.size() << " blocks.\n"); 310b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 311b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit edges between blocks. 3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &Block = *I->second; 3151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (Block.OutEdges.empty()) continue; 3161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 3171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(EdgeTag, 4); 3181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges.size() * 2 + 1); 3191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.Number); 3201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) { 321bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number 322bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky << "\n"); 3231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges[i]->Number); 3241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // no flags 325b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 326b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 327b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 328b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit lines for each block. 3291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky I->second->writeOut(); 332b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 333b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 334b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 335b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 3361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DenseMap<BasicBlock *, GCOVBlock *> Blocks; 3371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock *ReturnBlock; 338b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 339b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 340b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 34173996f44070df026e4d969b1b68461a70ebb3993Bill Wendlingstd::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem) { 342269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 343269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 344269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *N = GCov->getOperand(i); 345269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (N->getNumOperands() != 2) continue; 346fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 347269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); 348fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (!GCovFile || !CompileUnit) continue; 349fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (CompileUnit == CU) { 3506e5190c193f6267893daf6943af88e95039e739cBill Wendling SmallString<128> Filename = GCovFile->getString(); 3516e5190c193f6267893daf6943af88e95039e739cBill Wendling sys::path::replace_extension(Filename, NewStem); 3526e5190c193f6267893daf6943af88e95039e739cBill Wendling return Filename.str(); 353fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky } 354269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 355269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 356fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky 3576e5190c193f6267893daf6943af88e95039e739cBill Wendling SmallString<128> Filename = CU.getFilename(); 358fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky sys::path::replace_extension(Filename, NewStem); 3596e5190c193f6267893daf6943af88e95039e739cBill Wendling return sys::path::filename(Filename.str()); 360269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky} 361269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 3620c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) { 3631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky this->M = &M; 3640c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky Ctx = &M.getContext(); 3650c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 366f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitNotes) emitGCNO(); 367f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (EmitData) return emitProfileArcs(); 368a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky return false; 3690c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky} 3700c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 371f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid GCOVProfiler::emitGCNO() { 372f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 373bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!CU_Nodes) return; 374bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 375bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 376bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Each compile unit gets its own .gcno file. This means that whether we run 377bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // this pass over the original .o's as they're produced, or run it after 378bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // LTO, we'll generate the same .gcno files. 379bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 380bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DICompileUnit CU(CU_Nodes->getOperand(i)); 381bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky std::string ErrorInfo; 382bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo, 383bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream::F_Binary); 384d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky out.write("oncg", 4); 385d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky out.write(Version, 4); 386d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky out.write("MVLL", 4); 387bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 388bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DIArray SPs = CU.getSubprograms(); 389bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 390bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DISubprogram SP(SPs.getElement(i)); 391bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!SP.Verify()) continue; 392bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 393bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Function *F = SP.getFunction(); 394bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!F) continue; 395d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky GCOVFunction Func(SP, &out, i, UseExtraChecksum); 396bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 397bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 398bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVBlock &Block = Func.getBlock(BB); 399bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky TerminatorInst *TI = BB->getTerminator(); 400bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (int successors = TI->getNumSuccessors()) { 401bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (int i = 0; i != successors; ++i) { 402bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 403f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 404bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } else if (isa<ReturnInst>(TI)) { 405bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getReturnBlock()); 406bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 407bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 408bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky uint32_t Line = 0; 409bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); 410bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky I != IE; ++I) { 411bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky const DebugLoc &Loc = I->getDebugLoc(); 412bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Loc.isUnknown()) continue; 413bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Line == Loc.getLine()) continue; 414bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Line = Loc.getLine(); 415bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue; 416bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 417bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVLines &Lines = Block.getFile(SP.getFilename()); 418bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Lines.addLine(Loc.getLine()); 419b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 420b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 421bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Func.writeOut(); 422b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 423bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("\0\0\0\0\0\0\0\0", 8); // EOF 424bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.close(); 425b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 426b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 427b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 428f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() { 429f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 430f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!CU_Nodes) return false; 431f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 432f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool Result = false; 43377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling bool InsertIndCounterIncrCode = false; 434f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 435f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DICompileUnit CU(CU_Nodes->getOperand(i)); 436f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DIArray SPs = CU.getSubprograms(); 437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; 438f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 439f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(SPs.getElement(i)); 440f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!SP.Verify()) continue; 441f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Function *F = SP.getFunction(); 442f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!F) continue; 443f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!Result) Result = true; 444f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edges = 0; 445f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 446f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 447f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (isa<ReturnInst>(TI)) 448f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ++Edges; 449f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel else 450f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edges += TI->getNumSuccessors(); 451f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 452f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 453f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ArrayType *CounterTy = 4541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ArrayType::get(Type::getInt64Ty(*Ctx), Edges); 455f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *Counters = 4561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable(*M, CounterTy, false, 457b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GlobalValue::InternalLinkage, 4581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant::getNullValue(CounterTy), 459ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg "__llvm_gcov_ctr"); 460f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP)); 461f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgePreds; 463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgeSuccs; 464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edge = 0; 466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 467f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors) { 470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(TI); 471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors == 1) { 473f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 474f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge); 475f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 476bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 477f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 478f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 479bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Value *Sel = Builder.CreateSelect(BI->getCondition(), 480bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.getInt64(Edge), 481bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.getInt64(Edge + 1)); 482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<Value *, 2> Idx; 483bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Idx.push_back(Builder.getInt64(0)); 484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Idx.push_back(Sel); 485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx); 486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 487bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else { 490f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgePreds.insert(BB); 491f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0; i != Successors; ++i) 492f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgeSuccs.insert(TI->getSuccessor(i)); 493f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 494f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge += Successors; 495b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 496b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!ComplexEdgePreds.empty()) { 499f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeTable = 5001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky buildEdgeLookupTable(F, Counters, 5011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ComplexEdgePreds, ComplexEdgeSuccs); 502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeState = getEdgeStateValue(); 503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) { 505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator()); 506bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.CreateStore(Builder.getInt32(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); 563bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky IRBuilder<> Builder(Succ); 564bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick 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() { 584d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Type *Args[] = { 585d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Type::getInt8PtrTy(*Ctx), // const char *orig_filename 586d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Type::getInt8PtrTy(*Ctx), // const char version[4] 587d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky }; 588d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 5891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_start_file", FTy); 5901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 5911790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 59277b19134104c3e96424dc010f2b69c3faf580e68Bill WendlingConstant *GCOVProfiler::getIncrementIndirectCounterFunc() { 59377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Int32Ty = Type::getInt32Ty(*Ctx); 594c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Type *Int64Ty = Type::getInt64Ty(*Ctx); 59577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Args[] = { 596b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow Int32Ty->getPointerTo(), // uint32_t *predecessor 597b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters 59877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling }; 59977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 60077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy); 601b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 602b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 603b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() { 60417d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky Type *Args[3] = { 6055409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt32Ty(*Ctx), // uint32_t ident 6065409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt8PtrTy(*Ctx), // const char *function_name 60717d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky Type::getInt8Ty(*Ctx), // uint8_t use_extra_checksum 6085409a188328d9de3755febc23558d4fc1797d04eNick Lewycky }; 609c7a884040e4ec7795515978a94803894ad08c4caBill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 6101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 611b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 612b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 613b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() { 6145fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[] = { 615b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt32Ty(*Ctx), // uint32_t num_counters 616b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt64PtrTy(*Ctx), // uint64_t *counters 617b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 618d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 6191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 620b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 621b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 622b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() { 623db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 625b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 626b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6271790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() { 6281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!GV) { 6301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalValue::InternalLinkage, 6321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt32Ty(*Ctx), 6331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 0xffffffff), 6341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcov_global_state_pred"); 6351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV->setUnnamedAddr(true); 6361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GV; 6381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 639b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckyvoid GCOVProfiler::insertCounterWriteout( 64121b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) { 642253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 643253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Function *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 644253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!WriteoutF) 645253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage, 646253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling "__llvm_gcov_writeout", M); 647b1928704201034c785a26296a49f69355eb56a05Nick Lewycky WriteoutF->setUnnamedAddr(true); 648034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling WriteoutF->addFnAttr(Attribute::NoInline); 64908e13e4488cde76fc51f942e773874627a88eeaeBill Wendling if (NoRedZone) 650034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling WriteoutF->addFnAttr(Attribute::NoRedZone); 651253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 652253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF); 6531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> Builder(BB); 654b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 655b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *StartFile = getStartFileFunc(); 656b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitFunction = getEmitFunctionFunc(); 657b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitArcs = getEmitArcsFunc(); 658b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EndFile = getEndFileFunc(); 659b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 660f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 661f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (CU_Nodes) { 662f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 663032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling DICompileUnit CU(CU_Nodes->getOperand(i)); 664032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling std::string FilenameGcda = mangleName(CU, "gcda"); 665d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Builder.CreateCall2(StartFile, 666d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Builder.CreateGlobalStringPtr(FilenameGcda), 667d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Builder.CreateGlobalStringPtr(Version)); 6688fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky for (unsigned j = 0, e = CountersBySP.size(); j != e; ++j) { 6698fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky DISubprogram SP(CountersBySP[j].second); 67017d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky Builder.CreateCall3(EmitFunction, 671d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Builder.getInt32(i), 67252b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky NoFunctionNamesInData ? 67352b4edf6a1b5d3a9f8a94a63c702d55ed446ecdbNick Lewycky Constant::getNullValue(Builder.getInt8PtrTy()) : 67417d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky Builder.CreateGlobalStringPtr(SP.getName()), 67517d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky Builder.getInt8(UseExtraChecksum)); 67617d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky 6778fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky GlobalVariable *GV = CountersBySP[j].first; 678f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Arcs = 679b1928704201034c785a26296a49f69355eb56a05Nick Lewycky cast<ArrayType>(GV->getType()->getElementType())->getNumElements(); 680f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitArcs, 681bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.getInt32(Arcs), 682f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateConstGEP2_64(GV, 0, 0)); 683f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 684f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(EndFile); 685b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 686b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 6871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateRetVoid(); 688b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 6894a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling // Create a small bit of code that registers the "__llvm_gcov_writeout" 6904a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling // function to be executed at exit. 6914a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6924a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, 6934a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling "__llvm_gcov_init", M); 6944a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling F->setUnnamedAddr(true); 6954a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling F->setLinkage(GlobalValue::InternalLinkage); 696034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling F->addFnAttr(Attribute::NoInline); 69708e13e4488cde76fc51f942e773874627a88eeaeBill Wendling if (NoRedZone) 698034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling F->addFnAttr(Attribute::NoRedZone); 6994a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 7004a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling BB = BasicBlock::Create(*Ctx, "entry", F); 7014a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.SetInsertPoint(BB); 7024a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 703bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky FTy = FunctionType::get(Builder.getInt32Ty(), 7044a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling PointerType::get(FTy, 0), false); 705c1b6ea7b6ce3a738accbacddf52480bf94354d2fBill Wendling Constant *AtExitFn = M->getOrInsertFunction("atexit", FTy); 7064a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.CreateCall(AtExitFn, WriteoutF); 7074a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.CreateRetVoid(); 7084a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 7094a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling appendToGlobalCtors(*M, F, 0); 710b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 71177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 71277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendlingvoid GCOVProfiler::insertIndirectCounterIncrement() { 71377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Function *Fn = 71477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc()); 71577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->setUnnamedAddr(true); 71677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->setLinkage(GlobalValue::InternalLinkage); 717034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling Fn->addFnAttr(Attribute::NoInline); 71808e13e4488cde76fc51f942e773874627a88eeaeBill Wendling if (NoRedZone) 719034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling Fn->addFnAttr(Attribute::NoRedZone); 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"); 734bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Value *Cond = Builder.CreateICmpEQ(Pred, Builder.getInt32(0xffffffff)); 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; 741bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Value *ZExtPred = Builder.CreateZExt(Pred, Builder.getInt64Ty()); 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"); 74658591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky Cond = Builder.CreateICmpEQ(Counter, 74758591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky Constant::getNullValue( 74858591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky Builder.getInt64Ty()->getPointerTo())); 74977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateCondBr(Cond, Exit, CounterEnd); 75077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 75177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // ++*counter; 75277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(CounterEnd); 75377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter), 754bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.getInt64(1)); 75577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateStore(Add, Counter); 75677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateBr(Exit); 75777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 75877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // Fill in the exit block. 75977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(Exit); 76077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateRetVoid(); 76177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling} 762253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 763253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendlingvoid GCOVProfiler:: 764253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill WendlinginsertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) { 765253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 76678fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling Function *FlushF = M->getFunction("__gcov_flush"); 767253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!FlushF) 768253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF = Function::Create(FTy, GlobalValue::InternalLinkage, 76978fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling "__gcov_flush", M); 770253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else 771253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF->setLinkage(GlobalValue::InternalLinkage); 772253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF->setUnnamedAddr(true); 773034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling FlushF->addFnAttr(Attribute::NoInline); 77408e13e4488cde76fc51f942e773874627a88eeaeBill Wendling if (NoRedZone) 775034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling FlushF->addFnAttr(Attribute::NoRedZone); 776253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 777253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF); 778253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 779253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling // Write out the current counters. 780253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 781253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling assert(WriteoutF && "Need to create the writeout function first!"); 782253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 783253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling IRBuilder<> Builder(Entry); 784253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateCall(WriteoutF); 785253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 786032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling // Zero out the counters. 787032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator 788032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling I = CountersBySP.begin(), E = CountersBySP.end(); 789032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling I != E; ++I) { 790032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling GlobalVariable *GV = I->first; 791032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling Constant *Null = Constant::getNullValue(GV->getType()->getElementType()); 792ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling Builder.CreateStore(Null, GV); 793032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling } 794253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 795253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Type *RetTy = FlushF->getReturnType(); 796253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (RetTy == Type::getVoidTy(*Ctx)) 797253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateRetVoid(); 798253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else if (RetTy->isIntegerTy()) 79978fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling // Used if __gcov_flush was implicitly declared. 800253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateRet(ConstantInt::get(RetTy, 0)); 801253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else 80278fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling report_fatal_error("invalid return type for __gcov_flush"); 803253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling} 804