LLVM API Documentation

GCOVProfiling.cpp
Go to the documentation of this file.
00001 //===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===//
00002 //
00003 //                      The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This pass implements GCOV-style profiling. When this pass is run it emits
00011 // "gcno" files next to the existing source, and instruments the code that runs
00012 // to records the edges between blocks that run and emit a complementary "gcda"
00013 // file on exit.
00014 //
00015 //===----------------------------------------------------------------------===//
00016 
00017 #include "llvm/Transforms/Instrumentation.h"
00018 #include "llvm/ADT/DenseMap.h"
00019 #include "llvm/ADT/Hashing.h"
00020 #include "llvm/ADT/STLExtras.h"
00021 #include "llvm/ADT/Statistic.h"
00022 #include "llvm/ADT/StringExtras.h"
00023 #include "llvm/ADT/StringMap.h"
00024 #include "llvm/ADT/UniqueVector.h"
00025 #include "llvm/IR/DebugInfo.h"
00026 #include "llvm/IR/DebugLoc.h"
00027 #include "llvm/IR/IRBuilder.h"
00028 #include "llvm/IR/InstIterator.h"
00029 #include "llvm/IR/Instructions.h"
00030 #include "llvm/IR/IntrinsicInst.h"
00031 #include "llvm/IR/Module.h"
00032 #include "llvm/Pass.h"
00033 #include "llvm/Support/CommandLine.h"
00034 #include "llvm/Support/Debug.h"
00035 #include "llvm/Support/FileSystem.h"
00036 #include "llvm/Support/Path.h"
00037 #include "llvm/Support/raw_ostream.h"
00038 #include "llvm/Transforms/Utils/ModuleUtils.h"
00039 #include <algorithm>
00040 #include <memory>
00041 #include <string>
00042 #include <utility>
00043 using namespace llvm;
00044 
00045 #define DEBUG_TYPE "insert-gcov-profiling"
00046 
00047 static cl::opt<std::string>
00048 DefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden,
00049                    cl::ValueRequired);
00050 
00051 GCOVOptions GCOVOptions::getDefault() {
00052   GCOVOptions Options;
00053   Options.EmitNotes = true;
00054   Options.EmitData = true;
00055   Options.UseCfgChecksum = false;
00056   Options.NoRedZone = false;
00057   Options.FunctionNamesInData = true;
00058 
00059   if (DefaultGCOVVersion.size() != 4) {
00060     llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") +
00061                              DefaultGCOVVersion);
00062   }
00063   memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4);
00064   return Options;
00065 }
00066 
00067 namespace {
00068   class GCOVFunction;
00069 
00070   class GCOVProfiler : public ModulePass {
00071   public:
00072     static char ID;
00073     GCOVProfiler() : ModulePass(ID), Options(GCOVOptions::getDefault()) {
00074       init();
00075     }
00076     GCOVProfiler(const GCOVOptions &Options) : ModulePass(ID), Options(Options){
00077       assert((Options.EmitNotes || Options.EmitData) &&
00078              "GCOVProfiler asked to do nothing?");
00079       init();
00080     }
00081     const char *getPassName() const override {
00082       return "GCOV Profiler";
00083     }
00084 
00085   private:
00086     void init() {
00087       ReversedVersion[0] = Options.Version[3];
00088       ReversedVersion[1] = Options.Version[2];
00089       ReversedVersion[2] = Options.Version[1];
00090       ReversedVersion[3] = Options.Version[0];
00091       ReversedVersion[4] = '\0';
00092       initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
00093     }
00094     bool runOnModule(Module &M) override;
00095 
00096     // Create the .gcno files for the Module based on DebugInfo.
00097     void emitProfileNotes();
00098 
00099     // Modify the program to track transitions along edges and call into the
00100     // profiling runtime to emit .gcda files when run.
00101     bool emitProfileArcs();
00102 
00103     // Get pointers to the functions in the runtime library.
00104     Constant *getStartFileFunc();
00105     Constant *getIncrementIndirectCounterFunc();
00106     Constant *getEmitFunctionFunc();
00107     Constant *getEmitArcsFunc();
00108     Constant *getSummaryInfoFunc();
00109     Constant *getDeleteWriteoutFunctionListFunc();
00110     Constant *getDeleteFlushFunctionListFunc();
00111     Constant *getEndFileFunc();
00112 
00113     // Create or retrieve an i32 state value that is used to represent the
00114     // pred block number for certain non-trivial edges.
00115     GlobalVariable *getEdgeStateValue();
00116 
00117     // Produce a table of pointers to counters, by predecessor and successor
00118     // block number.
00119     GlobalVariable *buildEdgeLookupTable(Function *F,
00120                                          GlobalVariable *Counter,
00121                                          const UniqueVector<BasicBlock *>&Preds,
00122                                          const UniqueVector<BasicBlock*>&Succs);
00123 
00124     // Add the function to write out all our counters to the global destructor
00125     // list.
00126     Function *insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*,
00127                                                        MDNode*> >);
00128     Function *insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
00129     void insertIndirectCounterIncrement();
00130 
00131     std::string mangleName(DICompileUnit CU, const char *NewStem);
00132 
00133     GCOVOptions Options;
00134 
00135     // Reversed, NUL-terminated copy of Options.Version.
00136     char ReversedVersion[5];
00137     // Checksum, produced by hash of EdgeDestinations
00138     SmallVector<uint32_t, 4> FileChecksums;
00139 
00140     Module *M;
00141     LLVMContext *Ctx;
00142     SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs;
00143   };
00144 }
00145 
00146 char GCOVProfiler::ID = 0;
00147 INITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
00148                 "Insert instrumentation for GCOV profiling", false, false)
00149 
00150 ModulePass *llvm::createGCOVProfilerPass(const GCOVOptions &Options) {
00151   return new GCOVProfiler(Options);
00152 }
00153 
00154 static StringRef getFunctionName(DISubprogram SP) {
00155   if (!SP.getLinkageName().empty())
00156     return SP.getLinkageName();
00157   return SP.getName();
00158 }
00159 
00160 namespace {
00161   class GCOVRecord {
00162    protected:
00163     static const char *const LinesTag;
00164     static const char *const FunctionTag;
00165     static const char *const BlockTag;
00166     static const char *const EdgeTag;
00167 
00168     GCOVRecord() {}
00169 
00170     void writeBytes(const char *Bytes, int Size) {
00171       os->write(Bytes, Size);
00172     }
00173 
00174     void write(uint32_t i) {
00175       writeBytes(reinterpret_cast<char*>(&i), 4);
00176     }
00177 
00178     // Returns the length measured in 4-byte blocks that will be used to
00179     // represent this string in a GCOV file
00180     static unsigned lengthOfGCOVString(StringRef s) {
00181       // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
00182       // padding out to the next 4-byte word. The length is measured in 4-byte
00183       // words including padding, not bytes of actual string.
00184       return (s.size() / 4) + 1;
00185     }
00186 
00187     void writeGCOVString(StringRef s) {
00188       uint32_t Len = lengthOfGCOVString(s);
00189       write(Len);
00190       writeBytes(s.data(), s.size());
00191 
00192       // Write 1 to 4 bytes of NUL padding.
00193       assert((unsigned)(4 - (s.size() % 4)) > 0);
00194       assert((unsigned)(4 - (s.size() % 4)) <= 4);
00195       writeBytes("\0\0\0\0", 4 - (s.size() % 4));
00196     }
00197 
00198     raw_ostream *os;
00199   };
00200   const char *const GCOVRecord::LinesTag = "\0\0\x45\x01";
00201   const char *const GCOVRecord::FunctionTag = "\0\0\0\1";
00202   const char *const GCOVRecord::BlockTag = "\0\0\x41\x01";
00203   const char *const GCOVRecord::EdgeTag = "\0\0\x43\x01";
00204 
00205   class GCOVFunction;
00206   class GCOVBlock;
00207 
00208   // Constructed only by requesting it from a GCOVBlock, this object stores a
00209   // list of line numbers and a single filename, representing lines that belong
00210   // to the block.
00211   class GCOVLines : public GCOVRecord {
00212    public:
00213     void addLine(uint32_t Line) {
00214       assert(Line != 0 && "Line zero is not a valid real line number.");
00215       Lines.push_back(Line);
00216     }
00217 
00218     uint32_t length() const {
00219       // Here 2 = 1 for string length + 1 for '0' id#.
00220       return lengthOfGCOVString(Filename) + 2 + Lines.size();
00221     }
00222 
00223     void writeOut() {
00224       write(0);
00225       writeGCOVString(Filename);
00226       for (int i = 0, e = Lines.size(); i != e; ++i)
00227         write(Lines[i]);
00228     }
00229 
00230     GCOVLines(StringRef F, raw_ostream *os)
00231       : Filename(F) {
00232       this->os = os;
00233     }
00234 
00235    private:
00236     StringRef Filename;
00237     SmallVector<uint32_t, 32> Lines;
00238   };
00239 
00240 
00241   // Represent a basic block in GCOV. Each block has a unique number in the
00242   // function, number of lines belonging to each block, and a set of edges to
00243   // other blocks.
00244   class GCOVBlock : public GCOVRecord {
00245    public:
00246     GCOVLines &getFile(StringRef Filename) {
00247       GCOVLines *&Lines = LinesByFile[Filename];
00248       if (!Lines) {
00249         Lines = new GCOVLines(Filename, os);
00250       }
00251       return *Lines;
00252     }
00253 
00254     void addEdge(GCOVBlock &Successor) {
00255       OutEdges.push_back(&Successor);
00256     }
00257 
00258     void writeOut() {
00259       uint32_t Len = 3;
00260       SmallVector<StringMapEntry<GCOVLines *> *, 32> SortedLinesByFile;
00261       for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
00262                E = LinesByFile.end(); I != E; ++I) {
00263         Len += I->second->length();
00264         SortedLinesByFile.push_back(&*I);
00265       }
00266 
00267       writeBytes(LinesTag, 4);
00268       write(Len);
00269       write(Number);
00270 
00271       std::sort(SortedLinesByFile.begin(), SortedLinesByFile.end(),
00272                 [](StringMapEntry<GCOVLines *> *LHS,
00273                    StringMapEntry<GCOVLines *> *RHS) {
00274         return LHS->getKey() < RHS->getKey();
00275       });
00276       for (SmallVectorImpl<StringMapEntry<GCOVLines *> *>::iterator
00277                I = SortedLinesByFile.begin(), E = SortedLinesByFile.end();
00278            I != E; ++I)
00279         (*I)->getValue()->writeOut();
00280       write(0);
00281       write(0);
00282     }
00283 
00284     ~GCOVBlock() {
00285       DeleteContainerSeconds(LinesByFile);
00286     }
00287 
00288    private:
00289     friend class GCOVFunction;
00290 
00291     GCOVBlock(uint32_t Number, raw_ostream *os)
00292         : Number(Number) {
00293       this->os = os;
00294     }
00295 
00296     uint32_t Number;
00297     StringMap<GCOVLines *> LinesByFile;
00298     SmallVector<GCOVBlock *, 4> OutEdges;
00299   };
00300 
00301   // A function has a unique identifier, a checksum (we leave as zero) and a
00302   // set of blocks and a map of edges between blocks. This is the only GCOV
00303   // object users can construct, the blocks and lines will be rooted here.
00304   class GCOVFunction : public GCOVRecord {
00305    public:
00306     GCOVFunction(DISubprogram SP, raw_ostream *os, uint32_t Ident,
00307                  bool UseCfgChecksum) :
00308         SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0) {
00309       this->os = os;
00310 
00311       Function *F = SP.getFunction();
00312       DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n");
00313       uint32_t i = 0;
00314       for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
00315         Blocks[BB] = new GCOVBlock(i++, os);
00316       }
00317       ReturnBlock = new GCOVBlock(i++, os);
00318 
00319       std::string FunctionNameAndLine;
00320       raw_string_ostream FNLOS(FunctionNameAndLine);
00321       FNLOS << getFunctionName(SP) << SP.getLineNumber();
00322       FNLOS.flush();
00323       FuncChecksum = hash_value(FunctionNameAndLine);
00324     }
00325 
00326     ~GCOVFunction() {
00327       DeleteContainerSeconds(Blocks);
00328       delete ReturnBlock;
00329     }
00330 
00331     GCOVBlock &getBlock(BasicBlock *BB) {
00332       return *Blocks[BB];
00333     }
00334 
00335     GCOVBlock &getReturnBlock() {
00336       return *ReturnBlock;
00337     }
00338 
00339     std::string getEdgeDestinations() {
00340       std::string EdgeDestinations;
00341       raw_string_ostream EDOS(EdgeDestinations);
00342       Function *F = Blocks.begin()->first->getParent();
00343       for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
00344         GCOVBlock &Block = *Blocks[I];
00345         for (int i = 0, e = Block.OutEdges.size(); i != e; ++i)
00346           EDOS << Block.OutEdges[i]->Number;
00347       }
00348       return EdgeDestinations;
00349     }
00350 
00351     uint32_t getFuncChecksum() {
00352       return FuncChecksum;
00353     }
00354 
00355     void setCfgChecksum(uint32_t Checksum) {
00356       CfgChecksum = Checksum;
00357     }
00358 
00359     void writeOut() {
00360       writeBytes(FunctionTag, 4);
00361       uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(getFunctionName(SP)) +
00362           1 + lengthOfGCOVString(SP.getFilename()) + 1;
00363       if (UseCfgChecksum)
00364         ++BlockLen;
00365       write(BlockLen);
00366       write(Ident);
00367       write(FuncChecksum);
00368       if (UseCfgChecksum)
00369         write(CfgChecksum);
00370       writeGCOVString(getFunctionName(SP));
00371       writeGCOVString(SP.getFilename());
00372       write(SP.getLineNumber());
00373 
00374       // Emit count of blocks.
00375       writeBytes(BlockTag, 4);
00376       write(Blocks.size() + 1);
00377       for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
00378         write(0);  // No flags on our blocks.
00379       }
00380       DEBUG(dbgs() << Blocks.size() << " blocks.\n");
00381 
00382       // Emit edges between blocks.
00383       if (Blocks.empty()) return;
00384       Function *F = Blocks.begin()->first->getParent();
00385       for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
00386         GCOVBlock &Block = *Blocks[I];
00387         if (Block.OutEdges.empty()) continue;
00388 
00389         writeBytes(EdgeTag, 4);
00390         write(Block.OutEdges.size() * 2 + 1);
00391         write(Block.Number);
00392         for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
00393           DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number
00394                        << "\n");
00395           write(Block.OutEdges[i]->Number);
00396           write(0);  // no flags
00397         }
00398       }
00399 
00400       // Emit lines for each block.
00401       for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
00402         Blocks[I]->writeOut();
00403       }
00404     }
00405 
00406    private:
00407     DISubprogram SP;
00408     uint32_t Ident;
00409     uint32_t FuncChecksum;
00410     bool UseCfgChecksum;
00411     uint32_t CfgChecksum;
00412     DenseMap<BasicBlock *, GCOVBlock *> Blocks;
00413     GCOVBlock *ReturnBlock;
00414   };
00415 }
00416 
00417 std::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem) {
00418   if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
00419     for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
00420       MDNode *N = GCov->getOperand(i);
00421       if (N->getNumOperands() != 2) continue;
00422       MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
00423       MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1));
00424       if (!GCovFile || !CompileUnit) continue;
00425       if (CompileUnit == CU) {
00426         SmallString<128> Filename = GCovFile->getString();
00427         sys::path::replace_extension(Filename, NewStem);
00428         return Filename.str();
00429       }
00430     }
00431   }
00432 
00433   SmallString<128> Filename = CU.getFilename();
00434   sys::path::replace_extension(Filename, NewStem);
00435   StringRef FName = sys::path::filename(Filename);
00436   SmallString<128> CurPath;
00437   if (sys::fs::current_path(CurPath)) return FName;
00438   sys::path::append(CurPath, FName.str());
00439   return CurPath.str();
00440 }
00441 
00442 bool GCOVProfiler::runOnModule(Module &M) {
00443   this->M = &M;
00444   Ctx = &M.getContext();
00445 
00446   if (Options.EmitNotes) emitProfileNotes();
00447   if (Options.EmitData) return emitProfileArcs();
00448   return false;
00449 }
00450 
00451 static bool functionHasLines(Function *F) {
00452   // Check whether this function actually has any source lines. Not only
00453   // do these waste space, they also can crash gcov.
00454   for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
00455     for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
00456          I != IE; ++I) {
00457       // Debug intrinsic locations correspond to the location of the
00458       // declaration, not necessarily any statements or expressions.
00459       if (isa<DbgInfoIntrinsic>(I)) continue;
00460 
00461       const DebugLoc &Loc = I->getDebugLoc();
00462       if (Loc.isUnknown()) continue;
00463 
00464       // Artificial lines such as calls to the global constructors.
00465       if (Loc.getLine() == 0) continue; 
00466 
00467       return true;
00468     }
00469   }
00470   return false;
00471 }
00472 
00473 void GCOVProfiler::emitProfileNotes() {
00474   NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
00475   if (!CU_Nodes) return;
00476 
00477   for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
00478     // Each compile unit gets its own .gcno file. This means that whether we run
00479     // this pass over the original .o's as they're produced, or run it after
00480     // LTO, we'll generate the same .gcno files.
00481 
00482     DICompileUnit CU(CU_Nodes->getOperand(i));
00483     std::error_code EC;
00484     raw_fd_ostream out(mangleName(CU, "gcno"), EC, sys::fs::F_None);
00485     std::string EdgeDestinations;
00486 
00487     DIArray SPs = CU.getSubprograms();
00488     for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
00489       DISubprogram SP(SPs.getElement(i));
00490       assert((!SP || SP.isSubprogram()) &&
00491         "A MDNode in subprograms of a CU should be null or a DISubprogram.");
00492       if (!SP)
00493         continue;
00494 
00495       Function *F = SP.getFunction();
00496       if (!F) continue;
00497       if (!functionHasLines(F)) continue;
00498 
00499       // gcov expects every function to start with an entry block that has a
00500       // single successor, so split the entry block to make sure of that.
00501       BasicBlock &EntryBlock = F->getEntryBlock();
00502       BasicBlock::iterator It = EntryBlock.begin();
00503       while (isa<AllocaInst>(*It) || isa<DbgInfoIntrinsic>(*It))
00504         ++It;
00505       EntryBlock.splitBasicBlock(It);
00506 
00507       Funcs.push_back(
00508           make_unique<GCOVFunction>(SP, &out, i, Options.UseCfgChecksum));
00509       GCOVFunction &Func = *Funcs.back();
00510 
00511       for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
00512         GCOVBlock &Block = Func.getBlock(BB);
00513         TerminatorInst *TI = BB->getTerminator();
00514         if (int successors = TI->getNumSuccessors()) {
00515           for (int i = 0; i != successors; ++i) {
00516             Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
00517           }
00518         } else if (isa<ReturnInst>(TI)) {
00519           Block.addEdge(Func.getReturnBlock());
00520         }
00521 
00522         uint32_t Line = 0;
00523         for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
00524              I != IE; ++I) {
00525           // Debug intrinsic locations correspond to the location of the
00526           // declaration, not necessarily any statements or expressions.
00527           if (isa<DbgInfoIntrinsic>(I)) continue;
00528 
00529           const DebugLoc &Loc = I->getDebugLoc();
00530           if (Loc.isUnknown()) continue;
00531 
00532           // Artificial lines such as calls to the global constructors.
00533           if (Loc.getLine() == 0) continue;
00534 
00535           if (Line == Loc.getLine()) continue;
00536           Line = Loc.getLine();
00537           if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue;
00538 
00539           GCOVLines &Lines = Block.getFile(SP.getFilename());
00540           Lines.addLine(Loc.getLine());
00541         }
00542       }
00543       EdgeDestinations += Func.getEdgeDestinations();
00544     }
00545 
00546     FileChecksums.push_back(hash_value(EdgeDestinations));
00547     out.write("oncg", 4);
00548     out.write(ReversedVersion, 4);
00549     out.write(reinterpret_cast<char*>(&FileChecksums.back()), 4);
00550 
00551     for (auto &Func : Funcs) {
00552       Func->setCfgChecksum(FileChecksums.back());
00553       Func->writeOut();
00554     }
00555 
00556     out.write("\0\0\0\0\0\0\0\0", 8);  // EOF
00557     out.close();
00558   }
00559 }
00560 
00561 bool GCOVProfiler::emitProfileArcs() {
00562   NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
00563   if (!CU_Nodes) return false;
00564 
00565   bool Result = false;
00566   bool InsertIndCounterIncrCode = false;
00567   for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
00568     DICompileUnit CU(CU_Nodes->getOperand(i));
00569     DIArray SPs = CU.getSubprograms();
00570     SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
00571     for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
00572       DISubprogram SP(SPs.getElement(i));
00573       assert((!SP || SP.isSubprogram()) &&
00574         "A MDNode in subprograms of a CU should be null or a DISubprogram.");
00575       if (!SP)
00576         continue;
00577       Function *F = SP.getFunction();
00578       if (!F) continue;
00579       if (!functionHasLines(F)) continue;
00580       if (!Result) Result = true;
00581       unsigned Edges = 0;
00582       for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
00583         TerminatorInst *TI = BB->getTerminator();
00584         if (isa<ReturnInst>(TI))
00585           ++Edges;
00586         else
00587           Edges += TI->getNumSuccessors();
00588       }
00589 
00590       ArrayType *CounterTy =
00591         ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
00592       GlobalVariable *Counters =
00593         new GlobalVariable(*M, CounterTy, false,
00594                            GlobalValue::InternalLinkage,
00595                            Constant::getNullValue(CounterTy),
00596                            "__llvm_gcov_ctr");
00597       CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
00598 
00599       UniqueVector<BasicBlock *> ComplexEdgePreds;
00600       UniqueVector<BasicBlock *> ComplexEdgeSuccs;
00601 
00602       unsigned Edge = 0;
00603       for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
00604         TerminatorInst *TI = BB->getTerminator();
00605         int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
00606         if (Successors) {
00607           if (Successors == 1) {
00608             IRBuilder<> Builder(BB->getFirstInsertionPt());
00609             Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
00610                                                                 Edge);
00611             Value *Count = Builder.CreateLoad(Counter);
00612             Count = Builder.CreateAdd(Count, Builder.getInt64(1));
00613             Builder.CreateStore(Count, Counter);
00614           } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
00615             IRBuilder<> Builder(BI);
00616             Value *Sel = Builder.CreateSelect(BI->getCondition(),
00617                                               Builder.getInt64(Edge),
00618                                               Builder.getInt64(Edge + 1));
00619             SmallVector<Value *, 2> Idx;
00620             Idx.push_back(Builder.getInt64(0));
00621             Idx.push_back(Sel);
00622             Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx);
00623             Value *Count = Builder.CreateLoad(Counter);
00624             Count = Builder.CreateAdd(Count, Builder.getInt64(1));
00625             Builder.CreateStore(Count, Counter);
00626           } else {
00627             ComplexEdgePreds.insert(BB);
00628             for (int i = 0; i != Successors; ++i)
00629               ComplexEdgeSuccs.insert(TI->getSuccessor(i));
00630           }
00631 
00632           Edge += Successors;
00633         }
00634       }
00635 
00636       if (!ComplexEdgePreds.empty()) {
00637         GlobalVariable *EdgeTable =
00638           buildEdgeLookupTable(F, Counters,
00639                                ComplexEdgePreds, ComplexEdgeSuccs);
00640         GlobalVariable *EdgeState = getEdgeStateValue();
00641 
00642         for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
00643           IRBuilder<> Builder(ComplexEdgePreds[i + 1]->getFirstInsertionPt());
00644           Builder.CreateStore(Builder.getInt32(i), EdgeState);
00645         }
00646 
00647         for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
00648           // Call runtime to perform increment.
00649           IRBuilder<> Builder(ComplexEdgeSuccs[i+1]->getFirstInsertionPt());
00650           Value *CounterPtrArray =
00651             Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
00652                                                i * ComplexEdgePreds.size());
00653 
00654           // Build code to increment the counter.
00655           InsertIndCounterIncrCode = true;
00656           Builder.CreateCall2(getIncrementIndirectCounterFunc(),
00657                               EdgeState, CounterPtrArray);
00658         }
00659       }
00660     }
00661 
00662     Function *WriteoutF = insertCounterWriteout(CountersBySP);
00663     Function *FlushF = insertFlush(CountersBySP);
00664 
00665     // Create a small bit of code that registers the "__llvm_gcov_writeout" to
00666     // be executed at exit and the "__llvm_gcov_flush" function to be executed
00667     // when "__gcov_flush" is called.
00668     FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
00669     Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
00670                                    "__llvm_gcov_init", M);
00671     F->setUnnamedAddr(true);
00672     F->setLinkage(GlobalValue::InternalLinkage);
00673     F->addFnAttr(Attribute::NoInline);
00674     if (Options.NoRedZone)
00675       F->addFnAttr(Attribute::NoRedZone);
00676 
00677     BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
00678     IRBuilder<> Builder(BB);
00679 
00680     FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
00681     Type *Params[] = {
00682       PointerType::get(FTy, 0),
00683       PointerType::get(FTy, 0)
00684     };
00685     FTy = FunctionType::get(Builder.getVoidTy(), Params, false);
00686 
00687     // Initialize the environment and register the local writeout and flush
00688     // functions.
00689     Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
00690     Builder.CreateCall2(GCOVInit, WriteoutF, FlushF);
00691     Builder.CreateRetVoid();
00692 
00693     appendToGlobalCtors(*M, F, 0);
00694   }
00695 
00696   if (InsertIndCounterIncrCode)
00697     insertIndirectCounterIncrement();
00698 
00699   return Result;
00700 }
00701 
00702 // All edges with successors that aren't branches are "complex", because it
00703 // requires complex logic to pick which counter to update.
00704 GlobalVariable *GCOVProfiler::buildEdgeLookupTable(
00705     Function *F,
00706     GlobalVariable *Counters,
00707     const UniqueVector<BasicBlock *> &Preds,
00708     const UniqueVector<BasicBlock *> &Succs) {
00709   // TODO: support invoke, threads. We rely on the fact that nothing can modify
00710   // the whole-Module pred edge# between the time we set it and the time we next
00711   // read it. Threads and invoke make this untrue.
00712 
00713   // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]].
00714   size_t TableSize = Succs.size() * Preds.size();
00715   Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
00716   ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize);
00717 
00718   std::unique_ptr<Constant * []> EdgeTable(new Constant *[TableSize]);
00719   Constant *NullValue = Constant::getNullValue(Int64PtrTy);
00720   for (size_t i = 0; i != TableSize; ++i)
00721     EdgeTable[i] = NullValue;
00722 
00723   unsigned Edge = 0;
00724   for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
00725     TerminatorInst *TI = BB->getTerminator();
00726     int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
00727     if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) {
00728       for (int i = 0; i != Successors; ++i) {
00729         BasicBlock *Succ = TI->getSuccessor(i);
00730         IRBuilder<> Builder(Succ);
00731         Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
00732                                                             Edge + i);
00733         EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) +
00734                   (Preds.idFor(BB)-1)] = cast<Constant>(Counter);
00735       }
00736     }
00737     Edge += Successors;
00738   }
00739 
00740   GlobalVariable *EdgeTableGV =
00741       new GlobalVariable(
00742           *M, EdgeTableTy, true, GlobalValue::InternalLinkage,
00743           ConstantArray::get(EdgeTableTy,
00744                              makeArrayRef(&EdgeTable[0],TableSize)),
00745           "__llvm_gcda_edge_table");
00746   EdgeTableGV->setUnnamedAddr(true);
00747   return EdgeTableGV;
00748 }
00749 
00750 Constant *GCOVProfiler::getStartFileFunc() {
00751   Type *Args[] = {
00752     Type::getInt8PtrTy(*Ctx),  // const char *orig_filename
00753     Type::getInt8PtrTy(*Ctx),  // const char version[4]
00754     Type::getInt32Ty(*Ctx),    // uint32_t checksum
00755   };
00756   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
00757   return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
00758 }
00759 
00760 Constant *GCOVProfiler::getIncrementIndirectCounterFunc() {
00761   Type *Int32Ty = Type::getInt32Ty(*Ctx);
00762   Type *Int64Ty = Type::getInt64Ty(*Ctx);
00763   Type *Args[] = {
00764     Int32Ty->getPointerTo(),                // uint32_t *predecessor
00765     Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters
00766   };
00767   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
00768   return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy);
00769 }
00770 
00771 Constant *GCOVProfiler::getEmitFunctionFunc() {
00772   Type *Args[] = {
00773     Type::getInt32Ty(*Ctx),    // uint32_t ident
00774     Type::getInt8PtrTy(*Ctx),  // const char *function_name
00775     Type::getInt32Ty(*Ctx),    // uint32_t func_checksum
00776     Type::getInt8Ty(*Ctx),     // uint8_t use_extra_checksum
00777     Type::getInt32Ty(*Ctx),    // uint32_t cfg_checksum
00778   };
00779   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
00780   return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
00781 }
00782 
00783 Constant *GCOVProfiler::getEmitArcsFunc() {
00784   Type *Args[] = {
00785     Type::getInt32Ty(*Ctx),     // uint32_t num_counters
00786     Type::getInt64PtrTy(*Ctx),  // uint64_t *counters
00787   };
00788   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
00789   return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
00790 }
00791 
00792 Constant *GCOVProfiler::getSummaryInfoFunc() {
00793   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
00794   return M->getOrInsertFunction("llvm_gcda_summary_info", FTy);
00795 }
00796 
00797 Constant *GCOVProfiler::getDeleteWriteoutFunctionListFunc() {
00798   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
00799   return M->getOrInsertFunction("llvm_delete_writeout_function_list", FTy);
00800 }
00801 
00802 Constant *GCOVProfiler::getDeleteFlushFunctionListFunc() {
00803   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
00804   return M->getOrInsertFunction("llvm_delete_flush_function_list", FTy);
00805 }
00806 
00807 Constant *GCOVProfiler::getEndFileFunc() {
00808   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
00809   return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
00810 }
00811 
00812 GlobalVariable *GCOVProfiler::getEdgeStateValue() {
00813   GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred");
00814   if (!GV) {
00815     GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false,
00816                             GlobalValue::InternalLinkage,
00817                             ConstantInt::get(Type::getInt32Ty(*Ctx),
00818                                              0xffffffff),
00819                             "__llvm_gcov_global_state_pred");
00820     GV->setUnnamedAddr(true);
00821   }
00822   return GV;
00823 }
00824 
00825 Function *GCOVProfiler::insertCounterWriteout(
00826     ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
00827   FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
00828   Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
00829   if (!WriteoutF)
00830     WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
00831                                  "__llvm_gcov_writeout", M);
00832   WriteoutF->setUnnamedAddr(true);
00833   WriteoutF->addFnAttr(Attribute::NoInline);
00834   if (Options.NoRedZone)
00835     WriteoutF->addFnAttr(Attribute::NoRedZone);
00836 
00837   BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
00838   IRBuilder<> Builder(BB);
00839 
00840   Constant *StartFile = getStartFileFunc();
00841   Constant *EmitFunction = getEmitFunctionFunc();
00842   Constant *EmitArcs = getEmitArcsFunc();
00843   Constant *SummaryInfo = getSummaryInfoFunc();
00844   Constant *EndFile = getEndFileFunc();
00845 
00846   NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
00847   if (CU_Nodes) {
00848     for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
00849       DICompileUnit CU(CU_Nodes->getOperand(i));
00850       std::string FilenameGcda = mangleName(CU, "gcda");
00851       uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i];
00852       Builder.CreateCall3(StartFile,
00853                           Builder.CreateGlobalStringPtr(FilenameGcda),
00854                           Builder.CreateGlobalStringPtr(ReversedVersion),
00855                           Builder.getInt32(CfgChecksum));
00856       for (unsigned j = 0, e = CountersBySP.size(); j != e; ++j) {
00857         DISubprogram SP(CountersBySP[j].second);
00858         uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum();
00859         Builder.CreateCall5(
00860             EmitFunction, Builder.getInt32(j),
00861             Options.FunctionNamesInData ?
00862               Builder.CreateGlobalStringPtr(getFunctionName(SP)) :
00863               Constant::getNullValue(Builder.getInt8PtrTy()),
00864             Builder.getInt32(FuncChecksum),
00865             Builder.getInt8(Options.UseCfgChecksum),
00866             Builder.getInt32(CfgChecksum));
00867 
00868         GlobalVariable *GV = CountersBySP[j].first;
00869         unsigned Arcs =
00870           cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
00871         Builder.CreateCall2(EmitArcs,
00872                             Builder.getInt32(Arcs),
00873                             Builder.CreateConstGEP2_64(GV, 0, 0));
00874       }
00875       Builder.CreateCall(SummaryInfo);
00876       Builder.CreateCall(EndFile);
00877     }
00878   }
00879 
00880   Builder.CreateRetVoid();
00881   return WriteoutF;
00882 }
00883 
00884 void GCOVProfiler::insertIndirectCounterIncrement() {
00885   Function *Fn =
00886     cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
00887   Fn->setUnnamedAddr(true);
00888   Fn->setLinkage(GlobalValue::InternalLinkage);
00889   Fn->addFnAttr(Attribute::NoInline);
00890   if (Options.NoRedZone)
00891     Fn->addFnAttr(Attribute::NoRedZone);
00892 
00893   // Create basic blocks for function.
00894   BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn);
00895   IRBuilder<> Builder(BB);
00896 
00897   BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn);
00898   BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn);
00899   BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn);
00900 
00901   // uint32_t pred = *predecessor;
00902   // if (pred == 0xffffffff) return;
00903   Argument *Arg = Fn->arg_begin();
00904   Arg->setName("predecessor");
00905   Value *Pred = Builder.CreateLoad(Arg, "pred");
00906   Value *Cond = Builder.CreateICmpEQ(Pred, Builder.getInt32(0xffffffff));
00907   BranchInst::Create(Exit, PredNotNegOne, Cond, BB);
00908 
00909   Builder.SetInsertPoint(PredNotNegOne);
00910 
00911   // uint64_t *counter = counters[pred];
00912   // if (!counter) return;
00913   Value *ZExtPred = Builder.CreateZExt(Pred, Builder.getInt64Ty());
00914   Arg = std::next(Fn->arg_begin());
00915   Arg->setName("counters");
00916   Value *GEP = Builder.CreateGEP(Arg, ZExtPred);
00917   Value *Counter = Builder.CreateLoad(GEP, "counter");
00918   Cond = Builder.CreateICmpEQ(Counter,
00919                               Constant::getNullValue(
00920                                   Builder.getInt64Ty()->getPointerTo()));
00921   Builder.CreateCondBr(Cond, Exit, CounterEnd);
00922 
00923   // ++*counter;
00924   Builder.SetInsertPoint(CounterEnd);
00925   Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter),
00926                                  Builder.getInt64(1));
00927   Builder.CreateStore(Add, Counter);
00928   Builder.CreateBr(Exit);
00929 
00930   // Fill in the exit block.
00931   Builder.SetInsertPoint(Exit);
00932   Builder.CreateRetVoid();
00933 }
00934 
00935 Function *GCOVProfiler::
00936 insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
00937   FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
00938   Function *FlushF = M->getFunction("__llvm_gcov_flush");
00939   if (!FlushF)
00940     FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
00941                               "__llvm_gcov_flush", M);
00942   else
00943     FlushF->setLinkage(GlobalValue::InternalLinkage);
00944   FlushF->setUnnamedAddr(true);
00945   FlushF->addFnAttr(Attribute::NoInline);
00946   if (Options.NoRedZone)
00947     FlushF->addFnAttr(Attribute::NoRedZone);
00948 
00949   BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
00950 
00951   // Write out the current counters.
00952   Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout");
00953   assert(WriteoutF && "Need to create the writeout function first!");
00954 
00955   IRBuilder<> Builder(Entry);
00956   Builder.CreateCall(WriteoutF);
00957 
00958   // Zero out the counters.
00959   for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator
00960          I = CountersBySP.begin(), E = CountersBySP.end();
00961        I != E; ++I) {
00962     GlobalVariable *GV = I->first;
00963     Constant *Null = Constant::getNullValue(GV->getType()->getElementType());
00964     Builder.CreateStore(Null, GV);
00965   }
00966 
00967   Type *RetTy = FlushF->getReturnType();
00968   if (RetTy == Type::getVoidTy(*Ctx))
00969     Builder.CreateRetVoid();
00970   else if (RetTy->isIntegerTy())
00971     // Used if __llvm_gcov_flush was implicitly declared.
00972     Builder.CreateRet(ConstantInt::get(RetTy, 0));
00973   else
00974     report_fatal_error("invalid return type for __llvm_gcov_flush");
00975 
00976   return FlushF;
00977 }