Home | History | Annotate | Download | only in Instrumentation
      1 //===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===//
      2 //
      3 //                      The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This pass implements GCOV-style profiling. When this pass is run it emits
     11 // "gcno" files next to the existing source, and instruments the code that runs
     12 // to records the edges between blocks that run and emit a complementary "gcda"
     13 // file on exit.
     14 //
     15 //===----------------------------------------------------------------------===//
     16 
     17 #define DEBUG_TYPE "insert-gcov-profiling"
     18 
     19 #include "ProfilingUtils.h"
     20 #include "llvm/Transforms/Instrumentation.h"
     21 #include "llvm/Analysis/DebugInfo.h"
     22 #include "llvm/Module.h"
     23 #include "llvm/Pass.h"
     24 #include "llvm/Instructions.h"
     25 #include "llvm/Support/raw_ostream.h"
     26 #include "llvm/Support/Debug.h"
     27 #include "llvm/Support/DebugLoc.h"
     28 #include "llvm/Support/InstIterator.h"
     29 #include "llvm/Support/IRBuilder.h"
     30 #include "llvm/Support/PathV2.h"
     31 #include "llvm/ADT/DenseMap.h"
     32 #include "llvm/ADT/Statistic.h"
     33 #include "llvm/ADT/STLExtras.h"
     34 #include "llvm/ADT/StringExtras.h"
     35 #include "llvm/ADT/StringMap.h"
     36 #include "llvm/ADT/UniqueVector.h"
     37 #include <string>
     38 #include <utility>
     39 using namespace llvm;
     40 
     41 namespace {
     42   class GCOVProfiler : public ModulePass {
     43   public:
     44     static char ID;
     45     GCOVProfiler()
     46         : ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false) {
     47       initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
     48     }
     49     GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format = false)
     50         : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData),
     51           Use402Format(use402Format) {
     52       assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?");
     53       initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
     54     }
     55     virtual const char *getPassName() const {
     56       return "GCOV Profiler";
     57     }
     58 
     59   private:
     60     bool runOnModule(Module &M);
     61 
     62     // Create the GCNO files for the Module based on DebugInfo.
     63     void emitGCNO(DebugInfoFinder &DIF);
     64 
     65     // Modify the program to track transitions along edges and call into the
     66     // profiling runtime to emit .gcda files when run.
     67     bool emitProfileArcs(DebugInfoFinder &DIF);
     68 
     69     // Get pointers to the functions in the runtime library.
     70     Constant *getStartFileFunc();
     71     Constant *getIncrementIndirectCounterFunc();
     72     Constant *getEmitFunctionFunc();
     73     Constant *getEmitArcsFunc();
     74     Constant *getEndFileFunc();
     75 
     76     // Create or retrieve an i32 state value that is used to represent the
     77     // pred block number for certain non-trivial edges.
     78     GlobalVariable *getEdgeStateValue();
     79 
     80     // Produce a table of pointers to counters, by predecessor and successor
     81     // block number.
     82     GlobalVariable *buildEdgeLookupTable(Function *F,
     83                                          GlobalVariable *Counter,
     84                                          const UniqueVector<BasicBlock *> &Preds,
     85                                          const UniqueVector<BasicBlock *> &Succs);
     86 
     87     // Add the function to write out all our counters to the global destructor
     88     // list.
     89     void insertCounterWriteout(DebugInfoFinder &,
     90                                SmallVector<std::pair<GlobalVariable *,
     91                                                      MDNode *>, 8> &);
     92 
     93     std::string mangleName(DICompileUnit CU, std::string NewStem);
     94 
     95     bool EmitNotes;
     96     bool EmitData;
     97     bool Use402Format;
     98 
     99     Module *M;
    100     LLVMContext *Ctx;
    101   };
    102 }
    103 
    104 char GCOVProfiler::ID = 0;
    105 INITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
    106                 "Insert instrumentation for GCOV profiling", false, false)
    107 
    108 ModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData,
    109                                          bool Use402Format) {
    110   return new GCOVProfiler(EmitNotes, EmitData, Use402Format);
    111 }
    112 
    113 static DISubprogram findSubprogram(DIScope Scope) {
    114   while (!Scope.isSubprogram()) {
    115     assert(Scope.isLexicalBlock() &&
    116            "Debug location not lexical block or subprogram");
    117     Scope = DILexicalBlock(Scope).getContext();
    118   }
    119   return DISubprogram(Scope);
    120 }
    121 
    122 namespace {
    123   class GCOVRecord {
    124    protected:
    125     static const char *LinesTag;
    126     static const char *FunctionTag;
    127     static const char *BlockTag;
    128     static const char *EdgeTag;
    129 
    130     GCOVRecord() {}
    131 
    132     void writeBytes(const char *Bytes, int Size) {
    133       os->write(Bytes, Size);
    134     }
    135 
    136     void write(uint32_t i) {
    137       writeBytes(reinterpret_cast<char*>(&i), 4);
    138     }
    139 
    140     // Returns the length measured in 4-byte blocks that will be used to
    141     // represent this string in a GCOV file
    142     unsigned lengthOfGCOVString(StringRef s) {
    143       // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
    144       // padding out to the next 4-byte word. The length is measured in 4-byte
    145       // words including padding, not bytes of actual string.
    146       return (s.size() / 4) + 1;
    147     }
    148 
    149     void writeGCOVString(StringRef s) {
    150       uint32_t Len = lengthOfGCOVString(s);
    151       write(Len);
    152       writeBytes(s.data(), s.size());
    153 
    154       // Write 1 to 4 bytes of NUL padding.
    155       assert((unsigned)(4 - (s.size() % 4)) > 0);
    156       assert((unsigned)(4 - (s.size() % 4)) <= 4);
    157       writeBytes("\0\0\0\0", 4 - (s.size() % 4));
    158     }
    159 
    160     raw_ostream *os;
    161   };
    162   const char *GCOVRecord::LinesTag = "\0\0\x45\x01";
    163   const char *GCOVRecord::FunctionTag = "\0\0\0\1";
    164   const char *GCOVRecord::BlockTag = "\0\0\x41\x01";
    165   const char *GCOVRecord::EdgeTag = "\0\0\x43\x01";
    166 
    167   class GCOVFunction;
    168   class GCOVBlock;
    169 
    170   // Constructed only by requesting it from a GCOVBlock, this object stores a
    171   // list of line numbers and a single filename, representing lines that belong
    172   // to the block.
    173   class GCOVLines : public GCOVRecord {
    174    public:
    175     void addLine(uint32_t Line) {
    176       Lines.push_back(Line);
    177     }
    178 
    179     uint32_t length() {
    180       return lengthOfGCOVString(Filename) + 2 + Lines.size();
    181     }
    182 
    183    private:
    184     friend class GCOVBlock;
    185 
    186     GCOVLines(std::string Filename, raw_ostream *os)
    187         : Filename(Filename) {
    188       this->os = os;
    189     }
    190 
    191     std::string Filename;
    192     SmallVector<uint32_t, 32> Lines;
    193   };
    194 
    195   // Represent a basic block in GCOV. Each block has a unique number in the
    196   // function, number of lines belonging to each block, and a set of edges to
    197   // other blocks.
    198   class GCOVBlock : public GCOVRecord {
    199    public:
    200     GCOVLines &getFile(std::string Filename) {
    201       GCOVLines *&Lines = LinesByFile[Filename];
    202       if (!Lines) {
    203         Lines = new GCOVLines(Filename, os);
    204       }
    205       return *Lines;
    206     }
    207 
    208     void addEdge(GCOVBlock &Successor) {
    209       OutEdges.push_back(&Successor);
    210     }
    211 
    212     void writeOut() {
    213       uint32_t Len = 3;
    214       for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
    215                E = LinesByFile.end(); I != E; ++I) {
    216         Len += I->second->length();
    217       }
    218 
    219       writeBytes(LinesTag, 4);
    220       write(Len);
    221       write(Number);
    222       for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
    223                E = LinesByFile.end(); I != E; ++I) {
    224         write(0);
    225         writeGCOVString(I->second->Filename);
    226         for (int i = 0, e = I->second->Lines.size(); i != e; ++i) {
    227           write(I->second->Lines[i]);
    228         }
    229       }
    230       write(0);
    231       write(0);
    232     }
    233 
    234     ~GCOVBlock() {
    235       DeleteContainerSeconds(LinesByFile);
    236     }
    237 
    238    private:
    239     friend class GCOVFunction;
    240 
    241     GCOVBlock(uint32_t Number, raw_ostream *os)
    242         : Number(Number) {
    243       this->os = os;
    244     }
    245 
    246     uint32_t Number;
    247     StringMap<GCOVLines *> LinesByFile;
    248     SmallVector<GCOVBlock *, 4> OutEdges;
    249   };
    250 
    251   // A function has a unique identifier, a checksum (we leave as zero) and a
    252   // set of blocks and a map of edges between blocks. This is the only GCOV
    253   // object users can construct, the blocks and lines will be rooted here.
    254   class GCOVFunction : public GCOVRecord {
    255    public:
    256     GCOVFunction(DISubprogram SP, raw_ostream *os, bool Use402Format) {
    257       this->os = os;
    258 
    259       Function *F = SP.getFunction();
    260       uint32_t i = 0;
    261       for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    262         Blocks[BB] = new GCOVBlock(i++, os);
    263       }
    264       ReturnBlock = new GCOVBlock(i++, os);
    265 
    266       writeBytes(FunctionTag, 4);
    267       uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) +
    268           1 + lengthOfGCOVString(SP.getFilename()) + 1;
    269       if (!Use402Format)
    270         ++BlockLen; // For second checksum.
    271       write(BlockLen);
    272       uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP);
    273       write(Ident);
    274       write(0);  // checksum #1
    275       if (!Use402Format)
    276         write(0);  // checksum #2
    277       writeGCOVString(SP.getName());
    278       writeGCOVString(SP.getFilename());
    279       write(SP.getLineNumber());
    280     }
    281 
    282     ~GCOVFunction() {
    283       DeleteContainerSeconds(Blocks);
    284       delete ReturnBlock;
    285     }
    286 
    287     GCOVBlock &getBlock(BasicBlock *BB) {
    288       return *Blocks[BB];
    289     }
    290 
    291     GCOVBlock &getReturnBlock() {
    292       return *ReturnBlock;
    293     }
    294 
    295     void writeOut() {
    296       // Emit count of blocks.
    297       writeBytes(BlockTag, 4);
    298       write(Blocks.size() + 1);
    299       for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
    300         write(0);  // No flags on our blocks.
    301       }
    302 
    303       // Emit edges between blocks.
    304       for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
    305                E = Blocks.end(); I != E; ++I) {
    306         GCOVBlock &Block = *I->second;
    307         if (Block.OutEdges.empty()) continue;
    308 
    309         writeBytes(EdgeTag, 4);
    310         write(Block.OutEdges.size() * 2 + 1);
    311         write(Block.Number);
    312         for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
    313           write(Block.OutEdges[i]->Number);
    314           write(0);  // no flags
    315         }
    316       }
    317 
    318       // Emit lines for each block.
    319       for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
    320                E = Blocks.end(); I != E; ++I) {
    321         I->second->writeOut();
    322       }
    323     }
    324 
    325    private:
    326     DenseMap<BasicBlock *, GCOVBlock *> Blocks;
    327     GCOVBlock *ReturnBlock;
    328   };
    329 }
    330 
    331 std::string GCOVProfiler::mangleName(DICompileUnit CU, std::string NewStem) {
    332   if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
    333     for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
    334       MDNode *N = GCov->getOperand(i);
    335       if (N->getNumOperands() != 2) continue;
    336       MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
    337       MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1));
    338       if (!GCovFile || !CompileUnit) continue;
    339       if (CompileUnit == CU) {
    340         SmallString<128> Filename = GCovFile->getString();
    341         sys::path::replace_extension(Filename, NewStem);
    342         return Filename.str();
    343       }
    344     }
    345   }
    346 
    347   SmallString<128> Filename = CU.getFilename();
    348   sys::path::replace_extension(Filename, NewStem);
    349   return sys::path::filename(Filename.str());
    350 }
    351 
    352 bool GCOVProfiler::runOnModule(Module &M) {
    353   this->M = &M;
    354   Ctx = &M.getContext();
    355 
    356   DebugInfoFinder DIF;
    357   DIF.processModule(M);
    358 
    359   if (EmitNotes) emitGCNO(DIF);
    360   if (EmitData) return emitProfileArcs(DIF);
    361   return false;
    362 }
    363 
    364 void GCOVProfiler::emitGCNO(DebugInfoFinder &DIF) {
    365   DenseMap<const MDNode *, raw_fd_ostream *> GcnoFiles;
    366   for (DebugInfoFinder::iterator I = DIF.compile_unit_begin(),
    367            E = DIF.compile_unit_end(); I != E; ++I) {
    368     // Each compile unit gets its own .gcno file. This means that whether we run
    369     // this pass over the original .o's as they're produced, or run it after
    370     // LTO, we'll generate the same .gcno files.
    371 
    372     DICompileUnit CU(*I);
    373     raw_fd_ostream *&out = GcnoFiles[CU];
    374     std::string ErrorInfo;
    375     out = new raw_fd_ostream(mangleName(CU, "gcno").c_str(), ErrorInfo,
    376                              raw_fd_ostream::F_Binary);
    377     if (!Use402Format)
    378       out->write("oncg*404MVLL", 12);
    379     else
    380       out->write("oncg*402MVLL", 12);
    381   }
    382 
    383   for (DebugInfoFinder::iterator SPI = DIF.subprogram_begin(),
    384            SPE = DIF.subprogram_end(); SPI != SPE; ++SPI) {
    385     DISubprogram SP(*SPI);
    386     raw_fd_ostream *&os = GcnoFiles[SP.getCompileUnit()];
    387 
    388     Function *F = SP.getFunction();
    389     if (!F) continue;
    390     GCOVFunction Func(SP, os, Use402Format);
    391 
    392     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    393       GCOVBlock &Block = Func.getBlock(BB);
    394       TerminatorInst *TI = BB->getTerminator();
    395       if (int successors = TI->getNumSuccessors()) {
    396         for (int i = 0; i != successors; ++i) {
    397           Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
    398         }
    399       } else if (isa<ReturnInst>(TI)) {
    400         Block.addEdge(Func.getReturnBlock());
    401       }
    402 
    403       uint32_t Line = 0;
    404       for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
    405         const DebugLoc &Loc = I->getDebugLoc();
    406         if (Loc.isUnknown()) continue;
    407         if (Line == Loc.getLine()) continue;
    408         Line = Loc.getLine();
    409         if (SP != findSubprogram(DIScope(Loc.getScope(*Ctx)))) continue;
    410 
    411         GCOVLines &Lines = Block.getFile(SP.getFilename());
    412         Lines.addLine(Loc.getLine());
    413       }
    414     }
    415     Func.writeOut();
    416   }
    417 
    418   for (DenseMap<const MDNode *, raw_fd_ostream *>::iterator
    419            I = GcnoFiles.begin(), E = GcnoFiles.end(); I != E; ++I) {
    420     raw_fd_ostream *&out = I->second;
    421     out->write("\0\0\0\0\0\0\0\0", 8);  // EOF
    422     out->close();
    423     delete out;
    424   }
    425 }
    426 
    427 bool GCOVProfiler::emitProfileArcs(DebugInfoFinder &DIF) {
    428   if (DIF.subprogram_begin() == DIF.subprogram_end())
    429     return false;
    430 
    431   SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
    432   for (DebugInfoFinder::iterator SPI = DIF.subprogram_begin(),
    433            SPE = DIF.subprogram_end(); SPI != SPE; ++SPI) {
    434     DISubprogram SP(*SPI);
    435     Function *F = SP.getFunction();
    436     if (!F) continue;
    437 
    438     unsigned Edges = 0;
    439     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    440       TerminatorInst *TI = BB->getTerminator();
    441       if (isa<ReturnInst>(TI))
    442         ++Edges;
    443       else
    444         Edges += TI->getNumSuccessors();
    445     }
    446 
    447     ArrayType *CounterTy =
    448         ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
    449     GlobalVariable *Counters =
    450         new GlobalVariable(*M, CounterTy, false,
    451                            GlobalValue::InternalLinkage,
    452                            Constant::getNullValue(CounterTy),
    453                            "__llvm_gcov_ctr", 0, false, 0);
    454     CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
    455 
    456     UniqueVector<BasicBlock *> ComplexEdgePreds;
    457     UniqueVector<BasicBlock *> ComplexEdgeSuccs;
    458 
    459     unsigned Edge = 0;
    460     for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    461       TerminatorInst *TI = BB->getTerminator();
    462       int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
    463       if (Successors) {
    464         IRBuilder<> Builder(TI);
    465 
    466         if (Successors == 1) {
    467           Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
    468                                                               Edge);
    469           Value *Count = Builder.CreateLoad(Counter);
    470           Count = Builder.CreateAdd(Count,
    471                                     ConstantInt::get(Type::getInt64Ty(*Ctx),1));
    472           Builder.CreateStore(Count, Counter);
    473         } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
    474           Value *Sel = Builder.CreateSelect(
    475               BI->getCondition(),
    476               ConstantInt::get(Type::getInt64Ty(*Ctx), Edge),
    477               ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1));
    478           SmallVector<Value *, 2> Idx;
    479           Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx)));
    480           Idx.push_back(Sel);
    481           Value *Counter = Builder.CreateInBoundsGEP(Counters,
    482                                                      Idx.begin(), Idx.end());
    483           Value *Count = Builder.CreateLoad(Counter);
    484           Count = Builder.CreateAdd(Count,
    485                                     ConstantInt::get(Type::getInt64Ty(*Ctx),1));
    486           Builder.CreateStore(Count, Counter);
    487         } else {
    488           ComplexEdgePreds.insert(BB);
    489           for (int i = 0; i != Successors; ++i)
    490             ComplexEdgeSuccs.insert(TI->getSuccessor(i));
    491         }
    492         Edge += Successors;
    493       }
    494     }
    495 
    496     if (!ComplexEdgePreds.empty()) {
    497       GlobalVariable *EdgeTable =
    498           buildEdgeLookupTable(F, Counters,
    499                                ComplexEdgePreds, ComplexEdgeSuccs);
    500       GlobalVariable *EdgeState = getEdgeStateValue();
    501 
    502       Type *Int32Ty = Type::getInt32Ty(*Ctx);
    503       for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
    504         IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator());
    505         Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState);
    506       }
    507       for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
    508         // call runtime to perform increment
    509         IRBuilder<> Builder(ComplexEdgeSuccs[i+1]->getFirstNonPHI());
    510         Value *CounterPtrArray =
    511             Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
    512                                                i * ComplexEdgePreds.size());
    513         Builder.CreateCall2(getIncrementIndirectCounterFunc(),
    514                             EdgeState, CounterPtrArray);
    515         // clear the predecessor number
    516         Builder.CreateStore(ConstantInt::get(Int32Ty, 0xffffffff), EdgeState);
    517       }
    518     }
    519   }
    520 
    521   insertCounterWriteout(DIF, CountersBySP);
    522 
    523   return true;
    524 }
    525 
    526 // All edges with successors that aren't branches are "complex", because it
    527 // requires complex logic to pick which counter to update.
    528 GlobalVariable *GCOVProfiler::buildEdgeLookupTable(
    529     Function *F,
    530     GlobalVariable *Counters,
    531     const UniqueVector<BasicBlock *> &Preds,
    532     const UniqueVector<BasicBlock *> &Succs) {
    533   // TODO: support invoke, threads. We rely on the fact that nothing can modify
    534   // the whole-Module pred edge# between the time we set it and the time we next
    535   // read it. Threads and invoke make this untrue.
    536 
    537   // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]].
    538   Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
    539   ArrayType *EdgeTableTy = ArrayType::get(
    540       Int64PtrTy, Succs.size() * Preds.size());
    541 
    542   Constant **EdgeTable = new Constant*[Succs.size() * Preds.size()];
    543   Constant *NullValue = Constant::getNullValue(Int64PtrTy);
    544   for (int i = 0, ie = Succs.size() * Preds.size(); i != ie; ++i)
    545     EdgeTable[i] = NullValue;
    546 
    547   unsigned Edge = 0;
    548   for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
    549     TerminatorInst *TI = BB->getTerminator();
    550     int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
    551     if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) {
    552       for (int i = 0; i != Successors; ++i) {
    553         BasicBlock *Succ = TI->getSuccessor(i);
    554         IRBuilder<> builder(Succ);
    555         Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0,
    556                                                             Edge + i);
    557         EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) +
    558                   (Preds.idFor(BB)-1)] = cast<Constant>(Counter);
    559       }
    560     }
    561     Edge += Successors;
    562   }
    563 
    564   ArrayRef<Constant*> V(&EdgeTable[0], Succs.size() * Preds.size());
    565   GlobalVariable *EdgeTableGV =
    566       new GlobalVariable(
    567           *M, EdgeTableTy, true, GlobalValue::InternalLinkage,
    568           ConstantArray::get(EdgeTableTy, V),
    569           "__llvm_gcda_edge_table");
    570   EdgeTableGV->setUnnamedAddr(true);
    571   return EdgeTableGV;
    572 }
    573 
    574 Constant *GCOVProfiler::getStartFileFunc() {
    575   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
    576                                               Type::getInt8PtrTy(*Ctx), false);
    577   return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
    578 }
    579 
    580 Constant *GCOVProfiler::getIncrementIndirectCounterFunc() {
    581   Type *Args[] = {
    582     Type::getInt32PtrTy(*Ctx),                  // uint32_t *predecessor
    583     Type::getInt64PtrTy(*Ctx)->getPointerTo(),  // uint64_t **state_table_row
    584   };
    585   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
    586                                               Args, false);
    587   return M->getOrInsertFunction("llvm_gcda_increment_indirect_counter", FTy);
    588 }
    589 
    590 Constant *GCOVProfiler::getEmitFunctionFunc() {
    591   Type *Args[2] = {
    592     Type::getInt32Ty(*Ctx),    // uint32_t ident
    593     Type::getInt8PtrTy(*Ctx),  // const char *function_name
    594   };
    595   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
    596                                               Args, false);
    597   return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
    598 }
    599 
    600 Constant *GCOVProfiler::getEmitArcsFunc() {
    601   Type *Args[] = {
    602     Type::getInt32Ty(*Ctx),     // uint32_t num_counters
    603     Type::getInt64PtrTy(*Ctx),  // uint64_t *counters
    604   };
    605   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
    606                                               Args, false);
    607   return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
    608 }
    609 
    610 Constant *GCOVProfiler::getEndFileFunc() {
    611   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
    612   return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
    613 }
    614 
    615 GlobalVariable *GCOVProfiler::getEdgeStateValue() {
    616   GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred");
    617   if (!GV) {
    618     GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false,
    619                             GlobalValue::InternalLinkage,
    620                             ConstantInt::get(Type::getInt32Ty(*Ctx),
    621                                              0xffffffff),
    622                             "__llvm_gcov_global_state_pred");
    623     GV->setUnnamedAddr(true);
    624   }
    625   return GV;
    626 }
    627 
    628 void GCOVProfiler::insertCounterWriteout(
    629     DebugInfoFinder &DIF,
    630     SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> &CountersBySP) {
    631   FunctionType *WriteoutFTy =
    632       FunctionType::get(Type::getVoidTy(*Ctx), false);
    633   Function *WriteoutF = Function::Create(WriteoutFTy,
    634                                          GlobalValue::InternalLinkage,
    635                                          "__llvm_gcov_writeout", M);
    636   WriteoutF->setUnnamedAddr(true);
    637   BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF);
    638   IRBuilder<> Builder(BB);
    639 
    640   Constant *StartFile = getStartFileFunc();
    641   Constant *EmitFunction = getEmitFunctionFunc();
    642   Constant *EmitArcs = getEmitArcsFunc();
    643   Constant *EndFile = getEndFileFunc();
    644 
    645   for (DebugInfoFinder::iterator CUI = DIF.compile_unit_begin(),
    646            CUE = DIF.compile_unit_end(); CUI != CUE; ++CUI) {
    647     DICompileUnit compile_unit(*CUI);
    648     std::string FilenameGcda = mangleName(compile_unit, "gcda");
    649     Builder.CreateCall(StartFile,
    650                        Builder.CreateGlobalStringPtr(FilenameGcda));
    651     for (SmallVector<std::pair<GlobalVariable *, MDNode *>, 8>::iterator
    652              I = CountersBySP.begin(), E = CountersBySP.end();
    653          I != E; ++I) {
    654       DISubprogram SP(I->second);
    655       intptr_t ident = reinterpret_cast<intptr_t>(I->second);
    656       Builder.CreateCall2(EmitFunction,
    657                           ConstantInt::get(Type::getInt32Ty(*Ctx), ident),
    658                           Builder.CreateGlobalStringPtr(SP.getName()));
    659 
    660       GlobalVariable *GV = I->first;
    661       unsigned Arcs =
    662           cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
    663       Builder.CreateCall2(EmitArcs,
    664                           ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs),
    665                           Builder.CreateConstGEP2_64(GV, 0, 0));
    666     }
    667     Builder.CreateCall(EndFile);
    668   }
    669   Builder.CreateRetVoid();
    670 
    671   InsertProfilingShutdownCall(WriteoutF, M);
    672 }
    673