GCOVProfiling.cpp revision f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8
1b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===//
2b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
3b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//                      The LLVM Compiler Infrastructure
4b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
5b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// This file is distributed under the University of Illinois Open Source
6b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// License. See LICENSE.TXT for details.
7b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
8b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===----------------------------------------------------------------------===//
9b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
10b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// This pass implements GCOV-style profiling. When this pass is run it emits
11b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// "gcno" files next to the existing source, and instruments the code that runs
12b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// to records the edges between blocks that run and emit a complementary "gcda"
13b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// file on exit.
14b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
15b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===----------------------------------------------------------------------===//
16b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
17b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#define DEBUG_TYPE "insert-gcov-profiling"
18b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
19b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "ProfilingUtils.h"
20b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Transforms/Instrumentation.h"
21b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Analysis/DebugInfo.h"
22b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Module.h"
23b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Pass.h"
24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Instructions.h"
25b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/raw_ostream.h"
26b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/Debug.h"
27b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/DebugLoc.h"
28b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/InstIterator.h"
29b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/IRBuilder.h"
30b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Support/PathV2.h"
31b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/DenseMap.h"
32b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/Statistic.h"
33b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/STLExtras.h"
34b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringExtras.h"
35b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringMap.h"
36b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/UniqueVector.h"
37b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <string>
38b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <utility>
39b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyusing namespace llvm;
40b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
41b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace {
42b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVProfiler : public ModulePass {
43b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  public:
44b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    static char ID;
45a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    GCOVProfiler()
46f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling        : ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false) {
47a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
48a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    }
49f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling    GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format = false)
50f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling        : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData),
51f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling          Use402Format(use402Format) {
52a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky      assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?");
53b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
54b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
55b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    virtual const char *getPassName() const {
56b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      return "GCOV Profiler";
57b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
58b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
59b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  private:
60269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    bool runOnModule(Module &M);
61269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
62b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Create the GCNO files for the Module based on DebugInfo.
63f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    void emitGCNO();
64b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
650c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky    // Modify the program to track transitions along edges and call into the
660c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky    // profiling runtime to emit .gcda files when run.
67f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    bool emitProfileArcs();
680c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
69b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Get pointers to the functions in the runtime library.
70b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getStartFileFunc();
711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Constant *getIncrementIndirectCounterFunc();
72b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEmitFunctionFunc();
73b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEmitArcsFunc();
74b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEndFileFunc();
75b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // Create or retrieve an i32 state value that is used to represent the
771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // pred block number for certain non-trivial edges.
781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *getEdgeStateValue();
791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // Produce a table of pointers to counters, by predecessor and successor
811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // block number.
821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *buildEdgeLookupTable(Function *F,
831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         GlobalVariable *Counter,
841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         const UniqueVector<BasicBlock *> &Preds,
851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         const UniqueVector<BasicBlock *> &Succs);
861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
87b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Add the function to write out all our counters to the global destructor
88b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // list.
89f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    void insertCounterWriteout(SmallVector<std::pair<GlobalVariable *,
905409a188328d9de3755febc23558d4fc1797d04eNick Lewycky                                                     MDNode *>, 8> &);
91b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
92269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    std::string mangleName(DICompileUnit CU, std::string NewStem);
93269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
94a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    bool EmitNotes;
95a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    bool EmitData;
96f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling    bool Use402Format;
97a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky
981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Module *M;
99b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    LLVMContext *Ctx;
100b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
101b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
102b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
103b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0;
104b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
105b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                "Insert instrumentation for GCOV profiling", false, false)
106b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
107f5c95b889f270f170ff4f6a24b082be5bb68296eBill WendlingModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData,
108f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling                                         bool Use402Format) {
109f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling  return new GCOVProfiler(EmitNotes, EmitData, Use402Format);
110a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky}
111b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckystatic DISubprogram findSubprogram(DIScope Scope) {
1131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  while (!Scope.isSubprogram()) {
1141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    assert(Scope.isLexicalBlock() &&
115b1928704201034c785a26296a49f69355eb56a05Nick Lewycky           "Debug location not lexical block or subprogram");
1161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Scope = DILexicalBlock(Scope).getContext();
117b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
1181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return DISubprogram(Scope);
119b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
120b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
121b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace {
122b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVRecord {
123b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   protected:
1241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    static const char *LinesTag;
1251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    static const char *FunctionTag;
1261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    static const char *BlockTag;
1271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    static const char *EdgeTag;
128b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
129b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    GCOVRecord() {}
130b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeBytes(const char *Bytes, int Size) {
1321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      os->write(Bytes, Size);
133b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
134b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void write(uint32_t i) {
1361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(reinterpret_cast<char*>(&i), 4);
137b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Returns the length measured in 4-byte blocks that will be used to
140b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // represent this string in a GCOV file
1411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    unsigned lengthOfGCOVString(StringRef s) {
142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
14317df2c3240837b4382898ead8c3ead407a338520Nick Lewycky      // padding out to the next 4-byte word. The length is measured in 4-byte
14417df2c3240837b4382898ead8c3ead407a338520Nick Lewycky      // words including padding, not bytes of actual string.
145d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky      return (s.size() / 4) + 1;
146b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
147b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeGCOVString(StringRef s) {
1491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Len = lengthOfGCOVString(s);
1501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Len);
1511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(s.data(), s.size());
152b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
153b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Write 1 to 4 bytes of NUL padding.
1547a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      assert((unsigned)(4 - (s.size() % 4)) > 0);
1557a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      assert((unsigned)(4 - (s.size() % 4)) <= 4);
1567a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      writeBytes("\0\0\0\0", 4 - (s.size() % 4));
157b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
158b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
159b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    raw_ostream *os;
160b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
1611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  const char *GCOVRecord::LinesTag = "\0\0\x45\x01";
1621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  const char *GCOVRecord::FunctionTag = "\0\0\0\1";
1631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  const char *GCOVRecord::BlockTag = "\0\0\x41\x01";
1641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  const char *GCOVRecord::EdgeTag = "\0\0\x43\x01";
165b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVFunction;
167b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVBlock;
168b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
169b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // Constructed only by requesting it from a GCOVBlock, this object stores a
170b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // list of line numbers and a single filename, representing lines that belong
171b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // to the block.
172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVLines : public GCOVRecord {
173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void addLine(uint32_t Line) {
1751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      Lines.push_back(Line);
176b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
177b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    uint32_t length() {
1791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return lengthOfGCOVString(Filename) + 2 + Lines.size();
180b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
181b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
182b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
183b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    friend class GCOVBlock;
184b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVLines(std::string Filename, raw_ostream *os)
1861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        : Filename(Filename) {
187b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
188b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
189b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    std::string Filename;
1911790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    SmallVector<uint32_t, 32> Lines;
192b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
193b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
194b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // Represent a basic block in GCOV. Each block has a unique number in the
195b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // function, number of lines belonging to each block, and a set of edges to
196b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // other blocks.
197b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVBlock : public GCOVRecord {
198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
1991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVLines &getFile(std::string Filename) {
2001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      GCOVLines *&Lines = LinesByFile[Filename];
2011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      if (!Lines) {
2021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        Lines = new GCOVLines(Filename, os);
203b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
2041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *Lines;
205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
206b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void addEdge(GCOVBlock &Successor) {
2081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      OutEdges.push_back(&Successor);
209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
210b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeOut() {
2121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Len = 3;
2131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
2141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = LinesByFile.end(); I != E; ++I) {
2151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        Len += I->second->length();
216b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
217b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(LinesTag, 4);
2191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Len);
2201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Number);
2211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
2221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = LinesByFile.end(); I != E; ++I) {
2231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(0);
2241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        writeGCOVString(I->second->Filename);
2251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        for (int i = 0, e = I->second->Lines.size(); i != e; ++i) {
2261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(I->second->Lines[i]);
227b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
228b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
2291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(0);
2301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(0);
231b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    ~GCOVBlock() {
2341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      DeleteContainerSeconds(LinesByFile);
235b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
237b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
238b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    friend class GCOVFunction;
239b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock(uint32_t Number, raw_ostream *os)
2411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        : Number(Number) {
242b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
243b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    uint32_t Number;
2461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    StringMap<GCOVLines *> LinesByFile;
2471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    SmallVector<GCOVBlock *, 4> OutEdges;
248b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
250b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // A function has a unique identifier, a checksum (we leave as zero) and a
251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // set of blocks and a map of edges between blocks. This is the only GCOV
252b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // object users can construct, the blocks and lines will be rooted here.
253b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVFunction : public GCOVRecord {
254b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
255f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling    GCOVFunction(DISubprogram SP, raw_ostream *os, bool Use402Format) {
256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
257b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
258b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      Function *F = SP.getFunction();
259b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      uint32_t i = 0;
260b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
2611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        Blocks[BB] = new GCOVBlock(i++, os);
262b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
2631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      ReturnBlock = new GCOVBlock(i++, os);
2641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
2651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(FunctionTag, 4);
266f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling      uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) +
2671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          1 + lengthOfGCOVString(SP.getFilename()) + 1;
268f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling      if (!Use402Format)
269f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling        ++BlockLen; // For second checksum.
2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(BlockLen);
2711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP);
2721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Ident);
2735409a188328d9de3755febc23558d4fc1797d04eNick Lewycky      write(0);  // checksum #1
274f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling      if (!Use402Format)
275f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling        write(0);  // checksum #2
2761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeGCOVString(SP.getName());
2771790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeGCOVString(SP.getFilename());
2781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(SP.getLineNumber());
279b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
280b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
281b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    ~GCOVFunction() {
2821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      DeleteContainerSeconds(Blocks);
2831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      delete ReturnBlock;
284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
285b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock &getBlock(BasicBlock *BB) {
2871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *Blocks[BB];
288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
289b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock &getReturnBlock() {
2911790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *ReturnBlock;
292a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky    }
293a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky
2941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeOut() {
295b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit count of blocks.
2961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(BlockTag, 4);
2971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Blocks.size() + 1);
2981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
2991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(0);  // No flags on our blocks.
300b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
301b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
302b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit edges between blocks.
3031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
3041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = Blocks.end(); I != E; ++I) {
3051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        GCOVBlock &Block = *I->second;
3061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        if (Block.OutEdges.empty()) continue;
3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
3081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        writeBytes(EdgeTag, 4);
3091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(Block.OutEdges.size() * 2 + 1);
3101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(Block.Number);
3111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(Block.OutEdges[i]->Number);
3131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(0);  // no flags
314b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
315b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
316b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
317b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit lines for each block.
3181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
3191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = Blocks.end(); I != E; ++I) {
3201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        I->second->writeOut();
321b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
322b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
323b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
324b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
3251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    DenseMap<BasicBlock *, GCOVBlock *> Blocks;
3261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock *ReturnBlock;
327b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
328b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
329b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
330269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewyckystd::string GCOVProfiler::mangleName(DICompileUnit CU, std::string NewStem) {
331269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky  if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
332269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
333269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      MDNode *N = GCov->getOperand(i);
334269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      if (N->getNumOperands() != 2) continue;
335fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
336269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1));
337fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      if (!GCovFile || !CompileUnit) continue;
338fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      if (CompileUnit == CU) {
339fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky        SmallString<128> Filename = GCovFile->getString();
340fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky        sys::path::replace_extension(Filename, NewStem);
341fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky        return Filename.str();
342fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      }
343269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    }
344269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky  }
345fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky
346fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky  SmallString<128> Filename = CU.getFilename();
347fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky  sys::path::replace_extension(Filename, NewStem);
348fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky  return sys::path::filename(Filename.str());
349269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky}
350269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
3510c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) {
3521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  this->M = &M;
3530c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky  Ctx = &M.getContext();
3540c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
355f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (EmitNotes) emitGCNO();
356f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (EmitData) return emitProfileArcs();
357a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky  return false;
3580c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky}
3590c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
360f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid GCOVProfiler::emitGCNO() {
3611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  DenseMap<const MDNode *, raw_fd_ostream *> GcnoFiles;
362f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
363f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (CU_Nodes) {
364f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
365f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      // Each compile unit gets its own .gcno file. This means that whether we run
366f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      // this pass over the original .o's as they're produced, or run it after
367f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      // LTO, we'll generate the same .gcno files.
368f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
369f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      DICompileUnit CU(CU_Nodes->getOperand(i));
370f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      raw_fd_ostream *&out = GcnoFiles[CU];
371f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      std::string ErrorInfo;
372f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      out = new raw_fd_ostream(mangleName(CU, "gcno").c_str(), ErrorInfo,
373f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                               raw_fd_ostream::F_Binary);
374f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!Use402Format)
375f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        out->write("oncg*404MVLL", 12);
376f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      else
377f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        out->write("oncg*204MVLL", 12);
378f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
379f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      DIArray SPs = CU.getSubprograms();
380f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
381f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        DISubprogram SP(SPs.getElement(i));
382f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (!SP.Verify()) continue;
383f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        raw_fd_ostream *&os = GcnoFiles[SP.getCompileUnit()];
384f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
385f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Function *F = SP.getFunction();
386f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (!F) continue;
387f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GCOVFunction Func(SP, os, Use402Format);
388f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
389f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
390f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          GCOVBlock &Block = Func.getBlock(BB);
391f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          TerminatorInst *TI = BB->getTerminator();
392f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          if (int successors = TI->getNumSuccessors()) {
393f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            for (int i = 0; i != successors; ++i) {
394f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel              Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
395f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            }
396f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else if (isa<ReturnInst>(TI)) {
397f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Block.addEdge(Func.getReturnBlock());
398f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
399f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
400f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          uint32_t Line = 0;
401f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
402f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            const DebugLoc &Loc = I->getDebugLoc();
403f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            if (Loc.isUnknown()) continue;
404f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            if (Line == Loc.getLine()) continue;
405f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Line = Loc.getLine();
406f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            if (SP != findSubprogram(DIScope(Loc.getScope(*Ctx)))) continue;
407f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
408f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            GCOVLines &Lines = Block.getFile(SP.getFilename());
409f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Lines.addLine(Loc.getLine());
410f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
411b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
412f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Func.writeOut();
413b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
414b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
415b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
416b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
417b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  for (DenseMap<const MDNode *, raw_fd_ostream *>::iterator
4181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky           I = GcnoFiles.begin(), E = GcnoFiles.end(); I != E; ++I) {
4191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    raw_fd_ostream *&out = I->second;
4201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    out->write("\0\0\0\0\0\0\0\0", 8);  // EOF
4211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    out->close();
4221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    delete out;
423b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
424b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
425b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
426f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() {
427f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
428f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (!CU_Nodes) return false;
429f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
430f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  bool Result = false;
431f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
432f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    DICompileUnit CU(CU_Nodes->getOperand(i));
433f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    DIArray SPs = CU.getSubprograms();
434f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
435f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
436f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      DISubprogram SP(SPs.getElement(i));
437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!SP.Verify()) continue;
438f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      Function *F = SP.getFunction();
439f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!F) continue;
440f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!Result) Result = true;
441f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      unsigned Edges = 0;
442f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
443f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        TerminatorInst *TI = BB->getTerminator();
444f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (isa<ReturnInst>(TI))
445f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          ++Edges;
446f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        else
447f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Edges += TI->getNumSuccessors();
448f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      }
449f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
450f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      ArrayType *CounterTy =
4511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
452f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      GlobalVariable *Counters =
4531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        new GlobalVariable(*M, CounterTy, false,
454b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                           GlobalValue::InternalLinkage,
4551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                           Constant::getNullValue(CounterTy),
456b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                           "__llvm_gcov_ctr", 0, false, 0);
457f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
458f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
459f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      UniqueVector<BasicBlock *> ComplexEdgePreds;
460f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      UniqueVector<BasicBlock *> ComplexEdgeSuccs;
461f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      unsigned Edge = 0;
463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        TerminatorInst *TI = BB->getTerminator();
465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (Successors) {
467f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          IRBuilder<> Builder(TI);
468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          if (Successors == 1) {
470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                                                                Edge);
472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Count = Builder.CreateLoad(Counter);
473f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Count = Builder.CreateAdd(Count,
474f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                                      ConstantInt::get(Type::getInt64Ty(*Ctx),1));
475f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Builder.CreateStore(Count, Counter);
476f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
477f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Sel = Builder.CreateSelect(
478b1928704201034c785a26296a49f69355eb56a05Nick Lewycky              BI->getCondition(),
4791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky              ConstantInt::get(Type::getInt64Ty(*Ctx), Edge),
4801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky              ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1));
481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            SmallVector<Value *, 2> Idx;
482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx)));
483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Idx.push_back(Sel);
484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx);
485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Count = Builder.CreateLoad(Counter);
486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Count = Builder.CreateAdd(Count,
487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                                      ConstantInt::get(Type::getInt64Ty(*Ctx),1));
488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Builder.CreateStore(Count, Counter);
489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else {
490f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            ComplexEdgePreds.insert(BB);
491f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            for (int i = 0; i != Successors; ++i)
492f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel              ComplexEdgeSuccs.insert(TI->getSuccessor(i));
493f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
494f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Edge += Successors;
495b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
496b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!ComplexEdgePreds.empty()) {
499f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *EdgeTable =
5001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          buildEdgeLookupTable(F, Counters,
5011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                               ComplexEdgePreds, ComplexEdgeSuccs);
502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *EdgeState = getEdgeStateValue();
503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Type *Int32Ty = Type::getInt32Ty(*Ctx);
505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
506f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator());
507f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState);
508f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        }
509f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
510f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          // call runtime to perform increment
511f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          BasicBlock::iterator InsertPt =
512f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            ComplexEdgeSuccs[i+1]->getFirstInsertionPt();
513f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          IRBuilder<> Builder(InsertPt);
514f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Value *CounterPtrArray =
5151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky            Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
5161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                               i * ComplexEdgePreds.size());
517f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Builder.CreateCall2(getIncrementIndirectCounterFunc(),
518f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                              EdgeState, CounterPtrArray);
519f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          // clear the predecessor number
520f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Builder.CreateStore(ConstantInt::get(Int32Ty, 0xffffffff), EdgeState);
521f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        }
522b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
523b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
524f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    insertCounterWriteout(CountersBySP);
525b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
526f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  return Result;
527b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
528b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
5291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it
5301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update.
5311790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable(
5321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Function *F,
5331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *Counters,
5341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    const UniqueVector<BasicBlock *> &Preds,
5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    const UniqueVector<BasicBlock *> &Succs) {
5361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // TODO: support invoke, threads. We rely on the fact that nothing can modify
5371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // the whole-Module pred edge# between the time we set it and the time we next
5381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // read it. Threads and invoke make this untrue.
5391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
5401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]].
541db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
542db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  ArrayType *EdgeTableTy = ArrayType::get(
5431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      Int64PtrTy, Succs.size() * Preds.size());
5441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
5451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  Constant **EdgeTable = new Constant*[Succs.size() * Preds.size()];
5461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  Constant *NullValue = Constant::getNullValue(Int64PtrTy);
5471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  for (int i = 0, ie = Succs.size() * Preds.size(); i != ie; ++i)
5481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    EdgeTable[i] = NullValue;
5491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
5501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  unsigned Edge = 0;
5511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
5521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    TerminatorInst *TI = BB->getTerminator();
5531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
5547a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky    if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) {
5551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (int i = 0; i != Successors; ++i) {
5561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        BasicBlock *Succ = TI->getSuccessor(i);
5571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        IRBuilder<> builder(Succ);
5581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0,
5591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                                            Edge + i);
5601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) +
5611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                  (Preds.idFor(BB)-1)] = cast<Constant>(Counter);
5621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      }
5631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    }
5641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Edge += Successors;
5651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  }
5661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
567267010864e139781ef5949939e081c41f954de0aJay Foad  ArrayRef<Constant*> V(&EdgeTable[0], Succs.size() * Preds.size());
5681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  GlobalVariable *EdgeTableGV =
5691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      new GlobalVariable(
5701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          *M, EdgeTableTy, true, GlobalValue::InternalLinkage,
571267010864e139781ef5949939e081c41f954de0aJay Foad          ConstantArray::get(EdgeTableTy, V),
5721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          "__llvm_gcda_edge_table");
5731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  EdgeTableGV->setUnnamedAddr(true);
5741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return EdgeTableGV;
5751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
5761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
577b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() {
578db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
5795fdd6c8793462549e3593890ec61573da06e3346Jay Foad                                              Type::getInt8PtrTy(*Ctx), false);
5801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
5811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
5821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
5831790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyConstant *GCOVProfiler::getIncrementIndirectCounterFunc() {
5845fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Args[] = {
5851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Type::getInt32PtrTy(*Ctx),                  // uint32_t *predecessor
5861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Type::getInt64PtrTy(*Ctx)->getPointerTo(),  // uint64_t **state_table_row
5871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  };
588db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
5891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                              Args, false);
5901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_increment_indirect_counter", FTy);
591b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
592b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
593b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() {
5945fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Args[2] = {
5955409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    Type::getInt32Ty(*Ctx),    // uint32_t ident
5965409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    Type::getInt8PtrTy(*Ctx),  // const char *function_name
5975409a188328d9de3755febc23558d4fc1797d04eNick Lewycky  };
598db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
599b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                                              Args, false);
6001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
601b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
602b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
603b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() {
6045fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Args[] = {
605b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Type::getInt32Ty(*Ctx),     // uint32_t num_counters
606b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Type::getInt64PtrTy(*Ctx),  // uint64_t *counters
607b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
608db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
609b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                                              Args, false);
6101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
611b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
612b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
613b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() {
614db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
6151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
616b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
617b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
6181790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() {
6191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred");
6201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  if (!GV) {
6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false,
6221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            GlobalValue::InternalLinkage,
6231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            ConstantInt::get(Type::getInt32Ty(*Ctx),
6241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                             0xffffffff),
6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            "__llvm_gcov_global_state_pred");
6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GV->setUnnamedAddr(true);
6271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  }
6281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return GV;
6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
630b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckyvoid GCOVProfiler::insertCounterWriteout(
6325409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> &CountersBySP) {
633db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *WriteoutFTy =
634b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      FunctionType::get(Type::getVoidTy(*Ctx), false);
635b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Function *WriteoutF = Function::Create(WriteoutFTy,
636b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                                         GlobalValue::InternalLinkage,
6371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         "__llvm_gcov_writeout", M);
638b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  WriteoutF->setUnnamedAddr(true);
639b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF);
6401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  IRBuilder<> Builder(BB);
641b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
642b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *StartFile = getStartFileFunc();
643b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EmitFunction = getEmitFunctionFunc();
644b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EmitArcs = getEmitArcsFunc();
645b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EndFile = getEndFileFunc();
646b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
647f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
648f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (CU_Nodes) {
649f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
650f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      DICompileUnit compile_unit(CU_Nodes->getOperand(i));
651f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      std::string FilenameGcda = mangleName(compile_unit, "gcda");
652f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      Builder.CreateCall(StartFile,
653f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                         Builder.CreateGlobalStringPtr(FilenameGcda));
654f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (SmallVector<std::pair<GlobalVariable *, MDNode *>, 8>::iterator
6555409a188328d9de3755febc23558d4fc1797d04eNick Lewycky             I = CountersBySP.begin(), E = CountersBySP.end();
656f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel           I != E; ++I) {
657f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        DISubprogram SP(I->second);
658f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        intptr_t ident = reinterpret_cast<intptr_t>(I->second);
659f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Builder.CreateCall2(EmitFunction,
660f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            ConstantInt::get(Type::getInt32Ty(*Ctx), ident),
661f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            Builder.CreateGlobalStringPtr(SP.getName()));
662f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
663f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *GV = I->first;
664f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        unsigned Arcs =
665b1928704201034c785a26296a49f69355eb56a05Nick Lewycky          cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
666f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Builder.CreateCall2(EmitArcs,
667f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs),
668f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            Builder.CreateConstGEP2_64(GV, 0, 0));
669f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      }
670f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      Builder.CreateCall(EndFile);
671b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
672b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
6731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  Builder.CreateRetVoid();
674b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
6751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  InsertProfilingShutdownCall(WriteoutF, M);
676b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
677