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