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