GCOVProfiling.cpp revision 4a8fefaf8303f30514bc2a40d840a1709dae65cf
13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch//===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===// 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The LLVM Compiler Infrastructure 459151504615d929945dc59db37bf1166937748c6Steve Block// 559151504615d929945dc59db37bf1166937748c6Steve Block// This file is distributed under the University of Illinois Open Source 659151504615d929945dc59db37bf1166937748c6Steve Block// License. See LICENSE.TXT for details. 759151504615d929945dc59db37bf1166937748c6Steve Block// 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch//===----------------------------------------------------------------------===// 9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// This pass implements GCOV-style profiling. When this pass is run it emits 1159151504615d929945dc59db37bf1166937748c6Steve Block// "gcno" files next to the existing source, and instruments the code that runs 1259151504615d929945dc59db37bf1166937748c6Steve Block// to records the edges between blocks that run and emit a complementary "gcda" 1359151504615d929945dc59db37bf1166937748c6Steve Block// file on exit. 1459151504615d929945dc59db37bf1166937748c6Steve Block// 15f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch//===----------------------------------------------------------------------===// 16f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 17f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#define DEBUG_TYPE "insert-gcov-profiling" 18f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 19f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "ProfilingUtils.h" 20f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Transforms/Instrumentation.h" 21f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Analysis/DebugInfo.h" 22f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Module.h" 23f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Pass.h" 24f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Instructions.h" 25f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Transforms/Utils/ModuleUtils.h" 26f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Support/raw_ostream.h" 2744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "llvm/Support/Debug.h" 28f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Support/DebugLoc.h" 29f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Support/InstIterator.h" 30f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Support/IRBuilder.h" 31f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/Support/PathV2.h" 32f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/ADT/DenseMap.h" 33f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/ADT/Statistic.h" 34f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/ADT/STLExtras.h" 35f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include "llvm/ADT/StringExtras.h" 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "llvm/ADT/StringMap.h" 3744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "llvm/ADT/UniqueVector.h" 38f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include <string> 39f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#include <utility> 40f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochusing namespace llvm; 41f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 42f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochnamespace { 43f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch class GCOVProfiler : public ModulePass { 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 45f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static char ID; 46f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVProfiler() 47f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch : ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false), 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UseExtraChecksum(false) { 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 50f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 51f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format = false, 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool useExtraChecksum = false) 53f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData), 54f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Use402Format(use402Format), UseExtraChecksum(useExtraChecksum) { 55f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?"); 56f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 57f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 5859151504615d929945dc59db37bf1166937748c6Steve Block virtual const char *getPassName() const { 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return "GCOV Profiler"; 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 62f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool runOnModule(Module &M); 63f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create the GCNO files for the Module based on DebugInfo. 65f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void emitGCNO(); 66f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 67f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Modify the program to track transitions along edges and call into the 68f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // profiling runtime to emit .gcda files when run. 69f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool emitProfileArcs(); 70f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 71f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Get pointers to the functions in the runtime library. 72f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Constant *getStartFileFunc(); 73f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Constant *getIncrementIndirectCounterFunc(); 74f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Constant *getEmitFunctionFunc(); 75f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Constant *getEmitArcsFunc(); 76f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Constant *getEndFileFunc(); 7759151504615d929945dc59db37bf1166937748c6Steve Block 78f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Create or retrieve an i32 state value that is used to represent the 7959151504615d929945dc59db37bf1166937748c6Steve Block // pred block number for certain non-trivial edges. 80f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GlobalVariable *getEdgeStateValue(); 81f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 82f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Produce a table of pointers to counters, by predecessor and successor 8359151504615d929945dc59db37bf1166937748c6Steve Block // block number. 84f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GlobalVariable *buildEdgeLookupTable(Function *F, 85f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GlobalVariable *Counter, 86f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const UniqueVector<BasicBlock *> &Preds, 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const UniqueVector<BasicBlock *> &Succs); 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Add the function to write out all our counters to the global destructor 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // list. 91f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void insertCounterWriteout(SmallVector<std::pair<GlobalVariable *, 92f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch MDNode *>, 8> &); 93f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void insertIndirectCounterIncrement(); 9459151504615d929945dc59db37bf1166937748c6Steve Block 95f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch std::string mangleName(DICompileUnit CU, std::string NewStem); 9659151504615d929945dc59db37bf1166937748c6Steve Block 97f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool EmitNotes; 98f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool EmitData; 99f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool Use402Format; 100f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool UseExtraChecksum; 101f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 102f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Module *M; 103f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch LLVMContext *Ctx; 104f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch }; 105f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 106f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 10759151504615d929945dc59db37bf1166937748c6Steve Blockchar GCOVProfiler::ID = 0; 108f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", 109f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch "Insert instrumentation for GCOV profiling", false, false) 110f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 111f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData, 112f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool Use402Format, 113f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool UseExtraChecksum) { 114f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return new GCOVProfiler(EmitNotes, EmitData, Use402Format, UseExtraChecksum); 115f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 116f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 117f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochnamespace { 118f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch class GCOVRecord { 119f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch protected: 120f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static const char *LinesTag; 121f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static const char *FunctionTag; 122f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static const char *BlockTag; 123f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static const char *EdgeTag; 124f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 125f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVRecord() {} 126f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 127f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void writeBytes(const char *Bytes, int Size) { 128f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch os->write(Bytes, Size); 129f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 130f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 131f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void write(uint32_t i) { 132f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch writeBytes(reinterpret_cast<char*>(&i), 4); 133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns the length measured in 4-byte blocks that will be used to 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // represent this string in a GCOV file 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch unsigned lengthOfGCOVString(StringRef s) { 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // padding out to the next 4-byte word. The length is measured in 4-byte 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // words including padding, not bytes of actual string. 141f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return (s.size() / 4) + 1; 142f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 143f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 144f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void writeGCOVString(StringRef s) { 145f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch uint32_t Len = lengthOfGCOVString(s); 146f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(Len); 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch writeBytes(s.data(), s.size()); 148f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 149f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Write 1 to 4 bytes of NUL padding. 150f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch assert((unsigned)(4 - (s.size() % 4)) > 0); 151f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch assert((unsigned)(4 - (s.size() % 4)) <= 4); 152f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 153f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 154f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 155f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch raw_ostream *os; 156f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch }; 15744f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char *GCOVRecord::LinesTag = "\0\0\x45\x01"; 15844f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char *GCOVRecord::FunctionTag = "\0\0\0\1"; 15944f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char *GCOVRecord::BlockTag = "\0\0\x41\x01"; 16044f0eee88ff00398ff7f715fab053374d808c90dSteve Block const char *GCOVRecord::EdgeTag = "\0\0\x43\x01"; 16144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 162f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch class GCOVFunction; 163f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch class GCOVBlock; 164f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 16544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Constructed only by requesting it from a GCOVBlock, this object stores a 166f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // list of line numbers and a single filename, representing lines that belong 167f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // to the block. 16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block class GCOVLines : public GCOVRecord { 169f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch public: 170f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void addLine(uint32_t Line) { 171f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Lines.push_back(Line); 17244f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 173f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 174f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch uint32_t length() { 17544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Here 2 = 1 for string length + 1 for '0' id#. 17644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return lengthOfGCOVString(Filename) + 2 + Lines.size(); 177f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 178f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 179f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void writeOut() { 18044f0eee88ff00398ff7f715fab053374d808c90dSteve Block write(0); 181f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch writeGCOVString(Filename); 182f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0, e = Lines.size(); i != e; ++i) 18344f0eee88ff00398ff7f715fab053374d808c90dSteve Block write(Lines[i]); 184f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 185f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 186f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVLines(StringRef F, raw_ostream *os) 187f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch : Filename(F) { 188f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch this->os = os; 189f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 19059151504615d929945dc59db37bf1166937748c6Steve Block 19159151504615d929945dc59db37bf1166937748c6Steve Block private: 19259151504615d929945dc59db37bf1166937748c6Steve Block StringRef Filename; 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallVector<uint32_t, 32> Lines; 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Represent a basic block in GCOV. Each block has a unique number in the 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // function, number of lines belonging to each block, and a set of edges to 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // other blocks. 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class GCOVBlock : public GCOVRecord { 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public: 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GCOVLines &getFile(StringRef Filename) { 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GCOVLines *&Lines = LinesByFile[Filename]; 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if (!Lines) { 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Lines = new GCOVLines(Filename, os); 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *Lines; 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void addEdge(GCOVBlock &Successor) { 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutEdges.push_back(&Successor); 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void writeOut() { 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch uint32_t Len = 3; 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch E = LinesByFile.end(); I != E; ++I) { 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Len += I->second->length(); 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch writeBytes(LinesTag, 4); 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch write(Len); 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch write(Number); 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch E = LinesByFile.end(); I != E; ++I) 225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch I->second->writeOut(); 226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch write(0); 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch write(0); 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ~GCOVBlock() { 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DeleteContainerSeconds(LinesByFile); 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 233f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 234f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch private: 235f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch friend class GCOVFunction; 23659151504615d929945dc59db37bf1166937748c6Steve Block 237f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVBlock(uint32_t Number, raw_ostream *os) 238f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch : Number(Number) { 239f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch this->os = os; 240f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 241f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t Number; 243f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch StringMap<GCOVLines *> LinesByFile; 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SmallVector<GCOVBlock *, 4> OutEdges; 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch }; 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 24759151504615d929945dc59db37bf1166937748c6Steve Block // A function has a unique identifier, a checksum (we leave as zero) and a 24859151504615d929945dc59db37bf1166937748c6Steve Block // set of blocks and a map of edges between blocks. This is the only GCOV 249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // object users can construct, the blocks and lines will be rooted here. 250f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch class GCOVFunction : public GCOVRecord { 251f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch public: 252f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVFunction(DISubprogram SP, raw_ostream *os, 253f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool Use402Format, bool UseExtraChecksum) { 254f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch this->os = os; 255f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 256f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Function *F = SP.getFunction(); 257f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DEBUG(dbgs() << "Function: " << F->getName() << "\n"); 2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch uint32_t i = 0; 2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Blocks[BB] = new GCOVBlock(i++, os); 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 262f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ReturnBlock = new GCOVBlock(i++, os); 263f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 264f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch writeBytes(FunctionTag, 4); 265f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) + 266f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 1 + lengthOfGCOVString(SP.getFilename()) + 1; 267f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (UseExtraChecksum) 268f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ++BlockLen; 269f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(BlockLen); 270f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP); 271f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(Ident); 272f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(0); // lineno checksum 273f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (UseExtraChecksum) 274f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(0); // cfg checksum 275f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch writeGCOVString(SP.getName()); 276f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch writeGCOVString(SP.getFilename()); 277f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(SP.getLineNumber()); 278f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 279f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~GCOVFunction() { 281f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DeleteContainerSeconds(Blocks); 282f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch delete ReturnBlock; 283f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 284f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch GCOVBlock &getBlock(BasicBlock *BB) { 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return *Blocks[BB]; 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 289f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVBlock &getReturnBlock() { 290f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return *ReturnBlock; 291f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 292f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 293f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch void writeOut() { 294f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Emit count of blocks. 295f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch writeBytes(BlockTag, 4); 296f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(Blocks.size() + 1); 297f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0, e = Blocks.size() + 1; i != e; ++i) { 298f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(0); // No flags on our blocks. 299f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 300f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DEBUG(dbgs() << Blocks.size() << " blocks.\n"); 301f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 302f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Emit edges between blocks. 303f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 304f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch E = Blocks.end(); I != E; ++I) { 305f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVBlock &Block = *I->second; 306f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (Block.OutEdges.empty()) continue; 307f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 308f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch writeBytes(EdgeTag, 4); 309f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(Block.OutEdges.size() * 2 + 1); 310f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(Block.Number); 311f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) { 312f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number 313f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch << "\n"); 314f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(Block.OutEdges[i]->Number); 315f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch write(0); // no flags 316f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 317f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 318f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 319f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Emit lines for each block. 320f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 321f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch E = Blocks.end(); I != E; ++I) { 322f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch I->second->writeOut(); 323f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 324f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 325f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 326f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch private: 327f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DenseMap<BasicBlock *, GCOVBlock *> Blocks; 328f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVBlock *ReturnBlock; 329f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch }; 330f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 331f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 332f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstd::string GCOVProfiler::mangleName(DICompileUnit CU, std::string NewStem) { 333f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 334f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 335f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch MDNode *N = GCov->getOperand(i); 336f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (N->getNumOperands() != 2) continue; 337f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 338f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); 339f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!GCovFile || !CompileUnit) continue; 340f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (CompileUnit == CU) { 341f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SmallString<128> Filename = GCovFile->getString(); 342f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch sys::path::replace_extension(Filename, NewStem); 343f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return Filename.str(); 344f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 345f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 346f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 347f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 348f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SmallString<128> Filename = CU.getFilename(); 349f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch sys::path::replace_extension(Filename, NewStem); 350f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return sys::path::filename(Filename.str()); 35159151504615d929945dc59db37bf1166937748c6Steve Block} 352f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 353f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochbool GCOVProfiler::runOnModule(Module &M) { 35459151504615d929945dc59db37bf1166937748c6Steve Block this->M = &M; 35559151504615d929945dc59db37bf1166937748c6Steve Block Ctx = &M.getContext(); 35659151504615d929945dc59db37bf1166937748c6Steve Block 357f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (EmitNotes) emitGCNO(); 358f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (EmitData) return emitProfileArcs(); 359f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return false; 360f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 361f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 362f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochvoid GCOVProfiler::emitGCNO() { 363f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 364f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!CU_Nodes) return; 365f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 366f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 367f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Each compile unit gets its own .gcno file. This means that whether we run 368f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // this pass over the original .o's as they're produced, or run it after 369f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // LTO, we'll generate the same .gcno files. 370f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 371f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DICompileUnit CU(CU_Nodes->getOperand(i)); 372f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch std::string ErrorInfo; 373f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo, 374f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch raw_fd_ostream::F_Binary); 375f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!Use402Format) 376f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch out.write("oncg*404MVLL", 12); 37759151504615d929945dc59db37bf1166937748c6Steve Block else 3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch out.write("oncg*204MVLL", 12); 3793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch 3803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch DIArray SPs = CU.getSubprograms(); 3813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 382f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DISubprogram SP(SPs.getElement(i)); 383f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!SP.Verify()) continue; 384f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 38559151504615d929945dc59db37bf1166937748c6Steve Block Function *F = SP.getFunction(); 386f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!F) continue; 38759151504615d929945dc59db37bf1166937748c6Steve Block GCOVFunction Func(SP, &out, Use402Format, UseExtraChecksum); 38859151504615d929945dc59db37bf1166937748c6Steve Block 389f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 390f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GCOVBlock &Block = Func.getBlock(BB); 391f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch TerminatorInst *TI = BB->getTerminator(); 39259151504615d929945dc59db37bf1166937748c6Steve Block if (int successors = TI->getNumSuccessors()) { 393f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0; i != successors; ++i) { 39459151504615d929945dc59db37bf1166937748c6Steve Block Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 395f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 396f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else if (isa<ReturnInst>(TI)) { 39759151504615d929945dc59db37bf1166937748c6Steve Block Block.addEdge(Func.getReturnBlock()); 39859151504615d929945dc59db37bf1166937748c6Steve Block } 399f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 400f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch uint32_t Line = 0; 40159151504615d929945dc59db37bf1166937748c6Steve Block for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); 402f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch I != IE; ++I) { 40359151504615d929945dc59db37bf1166937748c6Steve Block const DebugLoc &Loc = I->getDebugLoc(); 40459151504615d929945dc59db37bf1166937748c6Steve Block if (Loc.isUnknown()) continue; 405f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (Line == Loc.getLine()) continue; 40659151504615d929945dc59db37bf1166937748c6Steve Block Line = Loc.getLine(); 40759151504615d929945dc59db37bf1166937748c6Steve Block if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue; 40859151504615d929945dc59db37bf1166937748c6Steve Block 40959151504615d929945dc59db37bf1166937748c6Steve Block GCOVLines &Lines = Block.getFile(SP.getFilename()); 410f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Lines.addLine(Loc.getLine()); 411f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 412f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 413f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Func.writeOut(); 414f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 41559151504615d929945dc59db37bf1166937748c6Steve Block out.write("\0\0\0\0\0\0\0\0", 8); // EOF 41659151504615d929945dc59db37bf1166937748c6Steve Block out.close(); 417f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 41859151504615d929945dc59db37bf1166937748c6Steve Block} 41959151504615d929945dc59db37bf1166937748c6Steve Block 42059151504615d929945dc59db37bf1166937748c6Steve Blockbool GCOVProfiler::emitProfileArcs() { 42159151504615d929945dc59db37bf1166937748c6Steve Block NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 42259151504615d929945dc59db37bf1166937748c6Steve Block if (!CU_Nodes) return false; 423f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 424f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool Result = false; 425f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool InsertIndCounterIncrCode = false; 42659151504615d929945dc59db37bf1166937748c6Steve Block for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 427f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DICompileUnit CU(CU_Nodes->getOperand(i)); 428f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DIArray SPs = CU.getSubprograms(); 429f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; 430f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 431f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch DISubprogram SP(SPs.getElement(i)); 432f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!SP.Verify()) continue; 433f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Function *F = SP.getFunction(); 434f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!F) continue; 435f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!Result) Result = true; 436f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch unsigned Edges = 0; 43759151504615d929945dc59db37bf1166937748c6Steve Block for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 43859151504615d929945dc59db37bf1166937748c6Steve Block TerminatorInst *TI = BB->getTerminator(); 439f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (isa<ReturnInst>(TI)) 440f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ++Edges; 441f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch else 44259151504615d929945dc59db37bf1166937748c6Steve Block Edges += TI->getNumSuccessors(); 443f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 444f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 445f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ArrayType *CounterTy = 446f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ArrayType::get(Type::getInt64Ty(*Ctx), Edges); 447f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GlobalVariable *Counters = 448f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch new GlobalVariable(*M, CounterTy, false, 44959151504615d929945dc59db37bf1166937748c6Steve Block GlobalValue::InternalLinkage, 450f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Constant::getNullValue(CounterTy), 45159151504615d929945dc59db37bf1166937748c6Steve Block "__llvm_gcov_ctr", 0, false, 0); 452f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP)); 45359151504615d929945dc59db37bf1166937748c6Steve Block 45459151504615d929945dc59db37bf1166937748c6Steve Block UniqueVector<BasicBlock *> ComplexEdgePreds; 45559151504615d929945dc59db37bf1166937748c6Steve Block UniqueVector<BasicBlock *> ComplexEdgeSuccs; 45659151504615d929945dc59db37bf1166937748c6Steve Block 457f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch unsigned Edge = 0; 45859151504615d929945dc59db37bf1166937748c6Steve Block for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 459f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch TerminatorInst *TI = BB->getTerminator(); 46059151504615d929945dc59db37bf1166937748c6Steve Block int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 461f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (Successors) { 46259151504615d929945dc59db37bf1166937748c6Steve Block IRBuilder<> Builder(TI); 46359151504615d929945dc59db37bf1166937748c6Steve Block 46459151504615d929945dc59db37bf1166937748c6Steve Block if (Successors == 1) { 46559151504615d929945dc59db37bf1166937748c6Steve Block Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 466f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Edge); 46759151504615d929945dc59db37bf1166937748c6Steve Block Value *Count = Builder.CreateLoad(Counter); 468f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Count = Builder.CreateAdd(Count, 469f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ConstantInt::get(Type::getInt64Ty(*Ctx),1)); 470f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Builder.CreateStore(Count, Counter); 47159151504615d929945dc59db37bf1166937748c6Steve Block } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 47259151504615d929945dc59db37bf1166937748c6Steve Block Value *Sel = Builder.CreateSelect( 47359151504615d929945dc59db37bf1166937748c6Steve Block BI->getCondition(), 47459151504615d929945dc59db37bf1166937748c6Steve Block ConstantInt::get(Type::getInt64Ty(*Ctx), Edge), 47559151504615d929945dc59db37bf1166937748c6Steve Block ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1)); 47659151504615d929945dc59db37bf1166937748c6Steve Block SmallVector<Value *, 2> Idx; 47759151504615d929945dc59db37bf1166937748c6Steve Block Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx))); 478f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Idx.push_back(Sel); 479f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx); 480f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Value *Count = Builder.CreateLoad(Counter); 48159151504615d929945dc59db37bf1166937748c6Steve Block Count = Builder.CreateAdd(Count, 482f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ConstantInt::get(Type::getInt64Ty(*Ctx),1)); 483f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Builder.CreateStore(Count, Counter); 484f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } else { 485f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ComplexEdgePreds.insert(BB); 486f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0; i != Successors; ++i) 487f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ComplexEdgeSuccs.insert(TI->getSuccessor(i)); 488f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 489f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Edge += Successors; 490f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 491f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 492f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 493f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (!ComplexEdgePreds.empty()) { 494f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GlobalVariable *EdgeTable = 495f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch buildEdgeLookupTable(F, Counters, 496f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ComplexEdgePreds, ComplexEdgeSuccs); 49759151504615d929945dc59db37bf1166937748c6Steve Block GlobalVariable *EdgeState = getEdgeStateValue(); 49859151504615d929945dc59db37bf1166937748c6Steve Block 499f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Type *Int32Ty = Type::getInt32Ty(*Ctx); 500f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) { 501f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator()); 502f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState); 503f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 50459151504615d929945dc59db37bf1166937748c6Steve Block for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) { 50559151504615d929945dc59db37bf1166937748c6Steve Block // call runtime to perform increment 506f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch BasicBlock::iterator InsertPt = 507f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch ComplexEdgeSuccs[i+1]->getFirstInsertionPt(); 508f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch IRBuilder<> Builder(InsertPt); 50959151504615d929945dc59db37bf1166937748c6Steve Block Value *CounterPtrArray = 510f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0, 511f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch i * ComplexEdgePreds.size()); 51259151504615d929945dc59db37bf1166937748c6Steve Block 513f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // Build code to increment the counter. 514f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch InsertIndCounterIncrCode = true; 515f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Builder.CreateCall2(getIncrementIndirectCounterFunc(), 516f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch EdgeState, CounterPtrArray); 517f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 51859151504615d929945dc59db37bf1166937748c6Steve Block } 51959151504615d929945dc59db37bf1166937748c6Steve Block } 52059151504615d929945dc59db37bf1166937748c6Steve Block 52159151504615d929945dc59db37bf1166937748c6Steve Block insertCounterWriteout(CountersBySP); 52259151504615d929945dc59db37bf1166937748c6Steve Block } 52359151504615d929945dc59db37bf1166937748c6Steve Block 52459151504615d929945dc59db37bf1166937748c6Steve Block if (InsertIndCounterIncrCode) 52559151504615d929945dc59db37bf1166937748c6Steve Block insertIndirectCounterIncrement(); 526f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 52759151504615d929945dc59db37bf1166937748c6Steve Block return Result; 528f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// All edges with successors that aren't branches are "complex", because it 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// requires complex logic to pick which counter to update. 532f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochGlobalVariable *GCOVProfiler::buildEdgeLookupTable( 533f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Function *F, 534f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch GlobalVariable *Counters, 535f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const UniqueVector<BasicBlock *> &Preds, 536f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch const UniqueVector<BasicBlock *> &Succs) { 537f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // TODO: support invoke, threads. We rely on the fact that nothing can modify 538f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // the whole-Module pred edge# between the time we set it and the time we next 539f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch // read it. Threads and invoke make this untrue. 540f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 54159151504615d929945dc59db37bf1166937748c6Steve Block // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]]. 542f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); 54359151504615d929945dc59db37bf1166937748c6Steve Block ArrayType *EdgeTableTy = ArrayType::get( 544f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Int64PtrTy, Succs.size() * Preds.size()); 545f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 546f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Constant **EdgeTable = new Constant*[Succs.size() * Preds.size()]; 54759151504615d929945dc59db37bf1166937748c6Steve Block Constant *NullValue = Constant::getNullValue(Int64PtrTy); 54859151504615d929945dc59db37bf1166937748c6Steve Block for (int i = 0, ie = Succs.size() * Preds.size(); i != ie; ++i) 54959151504615d929945dc59db37bf1166937748c6Steve Block EdgeTable[i] = NullValue; 55059151504615d929945dc59db37bf1166937748c6Steve Block 55159151504615d929945dc59db37bf1166937748c6Steve Block unsigned Edge = 0; 55259151504615d929945dc59db37bf1166937748c6Steve Block for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 553f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch TerminatorInst *TI = BB->getTerminator(); 554f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 555f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) { 556f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch for (int i = 0; i != Successors; ++i) { 55759151504615d929945dc59db37bf1166937748c6Steve Block BasicBlock *Succ = TI->getSuccessor(i); 5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch IRBuilder<> builder(Succ); 5593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0, 5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch Edge + i); 5613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) + 56244f0eee88ff00398ff7f715fab053374d808c90dSteve Block (Preds.idFor(BB)-1)] = cast<Constant>(Counter); 563f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch } 56459151504615d929945dc59db37bf1166937748c6Steve Block } 56559151504615d929945dc59db37bf1166937748c6Steve Block Edge += Successors; 566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 56859151504615d929945dc59db37bf1166937748c6Steve Block ArrayRef<Constant*> V(&EdgeTable[0], Succs.size() * Preds.size()); 56959151504615d929945dc59db37bf1166937748c6Steve Block GlobalVariable *EdgeTableGV = 570 new GlobalVariable( 571 *M, EdgeTableTy, true, GlobalValue::InternalLinkage, 572 ConstantArray::get(EdgeTableTy, V), 573 "__llvm_gcda_edge_table"); 574 EdgeTableGV->setUnnamedAddr(true); 575 return EdgeTableGV; 576} 577 578Constant *GCOVProfiler::getStartFileFunc() { 579 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 580 Type::getInt8PtrTy(*Ctx), false); 581 return M->getOrInsertFunction("llvm_gcda_start_file", FTy); 582} 583 584Constant *GCOVProfiler::getIncrementIndirectCounterFunc() { 585 Type *Int32Ty = Type::getInt32Ty(*Ctx); 586 Type *Int64Ty = Type::getInt64Ty(*Ctx); 587 Type *Args[] = { 588 Int32Ty->getPointerTo(), // uint32_t *predecessor 589 Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters 590 }; 591 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 592 return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy); 593} 594 595Constant *GCOVProfiler::getEmitFunctionFunc() { 596 Type *Args[2] = { 597 Type::getInt32Ty(*Ctx), // uint32_t ident 598 Type::getInt8PtrTy(*Ctx), // const char *function_name 599 }; 600 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 601 return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 602} 603 604Constant *GCOVProfiler::getEmitArcsFunc() { 605 Type *Args[] = { 606 Type::getInt32Ty(*Ctx), // uint32_t num_counters 607 Type::getInt64PtrTy(*Ctx), // uint64_t *counters 608 }; 609 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), 610 Args, false); 611 return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 612} 613 614Constant *GCOVProfiler::getEndFileFunc() { 615 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 616 return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 617} 618 619GlobalVariable *GCOVProfiler::getEdgeStateValue() { 620 GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 621 if (!GV) { 622 GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 623 GlobalValue::InternalLinkage, 624 ConstantInt::get(Type::getInt32Ty(*Ctx), 625 0xffffffff), 626 "__llvm_gcov_global_state_pred"); 627 GV->setUnnamedAddr(true); 628 } 629 return GV; 630} 631 632void GCOVProfiler::insertCounterWriteout( 633 SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> &CountersBySP) { 634 FunctionType *WriteoutFTy = 635 FunctionType::get(Type::getVoidTy(*Ctx), false); 636 Function *WriteoutF = Function::Create(WriteoutFTy, 637 GlobalValue::InternalLinkage, 638 "__llvm_gcov_writeout", M); 639 WriteoutF->setUnnamedAddr(true); 640 BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF); 641 IRBuilder<> Builder(BB); 642 643 Constant *StartFile = getStartFileFunc(); 644 Constant *EmitFunction = getEmitFunctionFunc(); 645 Constant *EmitArcs = getEmitArcsFunc(); 646 Constant *EndFile = getEndFileFunc(); 647 648 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 649 if (CU_Nodes) { 650 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 651 DICompileUnit compile_unit(CU_Nodes->getOperand(i)); 652 std::string FilenameGcda = mangleName(compile_unit, "gcda"); 653 Builder.CreateCall(StartFile, 654 Builder.CreateGlobalStringPtr(FilenameGcda)); 655 for (SmallVector<std::pair<GlobalVariable *, MDNode *>, 8>::iterator 656 I = CountersBySP.begin(), E = CountersBySP.end(); 657 I != E; ++I) { 658 DISubprogram SP(I->second); 659 intptr_t ident = reinterpret_cast<intptr_t>(I->second); 660 Builder.CreateCall2(EmitFunction, 661 ConstantInt::get(Type::getInt32Ty(*Ctx), ident), 662 Builder.CreateGlobalStringPtr(SP.getName())); 663 664 GlobalVariable *GV = I->first; 665 unsigned Arcs = 666 cast<ArrayType>(GV->getType()->getElementType())->getNumElements(); 667 Builder.CreateCall2(EmitArcs, 668 ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs), 669 Builder.CreateConstGEP2_64(GV, 0, 0)); 670 } 671 Builder.CreateCall(EndFile); 672 } 673 } 674 Builder.CreateRetVoid(); 675 676 // Create a small bit of code that registers the "__llvm_gcov_writeout" 677 // function to be executed at exit. 678 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 679 Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, 680 "__llvm_gcov_init", M); 681 F->setUnnamedAddr(true); 682 F->setLinkage(GlobalValue::InternalLinkage); 683 F->addFnAttr(Attribute::NoInline); 684 685 BB = BasicBlock::Create(*Ctx, "entry", F); 686 Builder.SetInsertPoint(BB); 687 688 FTy = FunctionType::get(Type::getInt32Ty(*Ctx), 689 PointerType::get(FTy, 0), false); 690 Function *AtExitFn = 691 Function::Create(FTy, GlobalValue::ExternalLinkage, "atexit", M); 692 Builder.CreateCall(AtExitFn, WriteoutF); 693 Builder.CreateRetVoid(); 694 695 appendToGlobalCtors(*M, F, 0); 696} 697 698void GCOVProfiler::insertIndirectCounterIncrement() { 699 Function *Fn = 700 cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc()); 701 Fn->setUnnamedAddr(true); 702 Fn->setLinkage(GlobalValue::InternalLinkage); 703 Fn->addFnAttr(Attribute::NoInline); 704 705 Type *Int32Ty = Type::getInt32Ty(*Ctx); 706 Type *Int64Ty = Type::getInt64Ty(*Ctx); 707 Constant *NegOne = ConstantInt::get(Int32Ty, 0xffffffff); 708 709 // Create basic blocks for function. 710 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn); 711 IRBuilder<> Builder(BB); 712 713 BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn); 714 BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn); 715 BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn); 716 717 // uint32_t pred = *predecessor; 718 // if (pred == 0xffffffff) return; 719 Argument *Arg = Fn->arg_begin(); 720 Arg->setName("predecessor"); 721 Value *Pred = Builder.CreateLoad(Arg, "pred"); 722 Value *Cond = Builder.CreateICmpEQ(Pred, NegOne); 723 BranchInst::Create(Exit, PredNotNegOne, Cond, BB); 724 725 Builder.SetInsertPoint(PredNotNegOne); 726 727 // uint64_t *counter = counters[pred]; 728 // if (!counter) return; 729 Value *ZExtPred = Builder.CreateZExt(Pred, Int64Ty); 730 Arg = llvm::next(Fn->arg_begin()); 731 Arg->setName("counters"); 732 Value *GEP = Builder.CreateGEP(Arg, ZExtPred); 733 Value *Counter = Builder.CreateLoad(GEP, "counter"); 734 Cond = Builder.CreateICmpEQ(Counter, 735 Constant::getNullValue(Int64Ty->getPointerTo())); 736 Builder.CreateCondBr(Cond, Exit, CounterEnd); 737 738 // ++*counter; 739 Builder.SetInsertPoint(CounterEnd); 740 Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter), 741 ConstantInt::get(Int64Ty, 1)); 742 Builder.CreateStore(Add, Counter); 743 Builder.CreateBr(Exit); 744 745 // Fill in the exit block. 746 Builder.SetInsertPoint(Exit); 747 Builder.CreateRetVoid(); 748} 749