119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                      The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This pass implements GCOV-style profiling. When this pass is run it emits
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// "gcno" files next to the existing source, and instruments the code that runs
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// to records the edges between blocks that run and emit a complementary "gcda"
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// file on exit.
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define DEBUG_TYPE "insert-gcov-profiling"
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "ProfilingUtils.h"
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Transforms/Instrumentation.h"
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/DebugInfo.h"
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Module.h"
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Pass.h"
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Instructions.h"
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/raw_ostream.h"
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/Debug.h"
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/DebugLoc.h"
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/InstIterator.h"
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/IRBuilder.h"
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/PathV2.h"
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/DenseMap.h"
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Statistic.h"
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/STLExtras.h"
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/StringExtras.h"
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/StringMap.h"
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/UniqueVector.h"
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <string>
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include <utility>
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class GCOVProfiler : public ModulePass {
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static char ID;
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVProfiler()
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        : ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false) {
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format = false)
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData),
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Use402Format(use402Format) {
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?");
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual const char *getPassName() const {
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return "GCOV Profiler";
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  private:
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool runOnModule(Module &M);
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Create the GCNO files for the Module based on DebugInfo.
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void emitGCNO();
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Modify the program to track transitions along edges and call into the
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // profiling runtime to emit .gcda files when run.
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool emitProfileArcs();
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Get pointers to the functions in the runtime library.
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getStartFileFunc();
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getIncrementIndirectCounterFunc();
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getEmitFunctionFunc();
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getEmitArcsFunc();
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getEndFileFunc();
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Create or retrieve an i32 state value that is used to represent the
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // pred block number for certain non-trivial edges.
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GlobalVariable *getEdgeStateValue();
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Produce a table of pointers to counters, by predecessor and successor
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // block number.
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GlobalVariable *buildEdgeLookupTable(Function *F,
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         GlobalVariable *Counter,
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         const UniqueVector<BasicBlock *> &Preds,
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         const UniqueVector<BasicBlock *> &Succs);
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Add the function to write out all our counters to the global destructor
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // list.
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void insertCounterWriteout(SmallVector<std::pair<GlobalVariable *,
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                     MDNode *>, 8> &);
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::string mangleName(DICompileUnit CU, std::string NewStem);
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool EmitNotes;
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool EmitData;
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Use402Format;
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Module *M;
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext *Ctx;
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanchar GCOVProfiler::ID = 0;
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                "Insert instrumentation for GCOV profiling", false, false)
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData,
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         bool Use402Format) {
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new GCOVProfiler(EmitNotes, EmitData, Use402Format);
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class GCOVRecord {
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   protected:
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static const char *LinesTag;
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static const char *FunctionTag;
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static const char *BlockTag;
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static const char *EdgeTag;
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVRecord() {}
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void writeBytes(const char *Bytes, int Size) {
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      os->write(Bytes, Size);
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void write(uint32_t i) {
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeBytes(reinterpret_cast<char*>(&i), 4);
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Returns the length measured in 4-byte blocks that will be used to
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // represent this string in a GCOV file
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned lengthOfGCOVString(StringRef s) {
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // padding out to the next 4-byte word. The length is measured in 4-byte
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // words including padding, not bytes of actual string.
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return (s.size() / 4) + 1;
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void writeGCOVString(StringRef s) {
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint32_t Len = lengthOfGCOVString(s);
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(Len);
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeBytes(s.data(), s.size());
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Write 1 to 4 bytes of NUL padding.
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert((unsigned)(4 - (s.size() % 4)) > 0);
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert((unsigned)(4 - (s.size() % 4)) <= 4);
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeBytes("\0\0\0\0", 4 - (s.size() % 4));
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    raw_ostream *os;
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const char *GCOVRecord::LinesTag = "\0\0\x45\x01";
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const char *GCOVRecord::FunctionTag = "\0\0\0\1";
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const char *GCOVRecord::BlockTag = "\0\0\x41\x01";
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const char *GCOVRecord::EdgeTag = "\0\0\x43\x01";
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class GCOVFunction;
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class GCOVBlock;
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Constructed only by requesting it from a GCOVBlock, this object stores a
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // list of line numbers and a single filename, representing lines that belong
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // to the block.
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class GCOVLines : public GCOVRecord {
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   public:
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void addLine(uint32_t Line) {
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Lines.push_back(Line);
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint32_t length() {
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Here 2 = 1 for string lenght + 1 for '0' id#.
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return lengthOfGCOVString(Filename) + 2 + Lines.size();
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void writeOut() {
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(0);
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeGCOVString(Filename);
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (int i = 0, e = Lines.size(); i != e; ++i)
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        write(Lines[i]);
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVLines(StringRef F, raw_ostream *os)
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      : Filename(F) {
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      this->os = os;
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   private:
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringRef Filename;
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallVector<uint32_t, 32> Lines;
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Represent a basic block in GCOV. Each block has a unique number in the
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // function, number of lines belonging to each block, and a set of edges to
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // other blocks.
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class GCOVBlock : public GCOVRecord {
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   public:
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVLines &getFile(StringRef Filename) {
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      GCOVLines *&Lines = LinesByFile[Filename];
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Lines) {
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Lines = new GCOVLines(Filename, os);
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return *Lines;
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void addEdge(GCOVBlock &Successor) {
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OutEdges.push_back(&Successor);
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void writeOut() {
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint32_t Len = 3;
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               E = LinesByFile.end(); I != E; ++I) {
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Len += I->second->length();
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeBytes(LinesTag, 4);
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(Len);
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(Number);
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               E = LinesByFile.end(); I != E; ++I)
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        I->second->writeOut();
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(0);
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(0);
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ~GCOVBlock() {
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DeleteContainerSeconds(LinesByFile);
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   private:
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    friend class GCOVFunction;
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVBlock(uint32_t Number, raw_ostream *os)
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        : Number(Number) {
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      this->os = os;
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    uint32_t Number;
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StringMap<GCOVLines *> LinesByFile;
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallVector<GCOVBlock *, 4> OutEdges;
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // A function has a unique identifier, a checksum (we leave as zero) and a
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // set of blocks and a map of edges between blocks. This is the only GCOV
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // object users can construct, the blocks and lines will be rooted here.
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class GCOVFunction : public GCOVRecord {
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   public:
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVFunction(DISubprogram SP, raw_ostream *os, bool Use402Format) {
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      this->os = os;
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Function *F = SP.getFunction();
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint32_t i = 0;
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Blocks[BB] = new GCOVBlock(i++, os);
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ReturnBlock = new GCOVBlock(i++, os);
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeBytes(FunctionTag, 4);
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) +
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          1 + lengthOfGCOVString(SP.getFilename()) + 1;
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Use402Format)
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ++BlockLen; // For second checksum.
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(BlockLen);
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP);
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(Ident);
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(0);  // checksum #1
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Use402Format)
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        write(0);  // checksum #2
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeGCOVString(SP.getName());
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeGCOVString(SP.getFilename());
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(SP.getLineNumber());
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ~GCOVFunction() {
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DeleteContainerSeconds(Blocks);
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      delete ReturnBlock;
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVBlock &getBlock(BasicBlock *BB) {
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return *Blocks[BB];
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVBlock &getReturnBlock() {
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return *ReturnBlock;
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void writeOut() {
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Emit count of blocks.
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      writeBytes(BlockTag, 4);
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      write(Blocks.size() + 1);
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        write(0);  // No flags on our blocks.
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Emit edges between blocks.
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               E = Blocks.end(); I != E; ++I) {
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        GCOVBlock &Block = *I->second;
29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Block.OutEdges.empty()) continue;
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        writeBytes(EdgeTag, 4);
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        write(Block.OutEdges.size() * 2 + 1);
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        write(Block.Number);
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          write(Block.OutEdges[i]->Number);
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          write(0);  // no flags
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Emit lines for each block.
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               E = Blocks.end(); I != E; ++I) {
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        I->second->writeOut();
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   private:
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DenseMap<BasicBlock *, GCOVBlock *> Blocks;
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GCOVBlock *ReturnBlock;
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstd::string GCOVProfiler::mangleName(DICompileUnit CU, std::string NewStem) {
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MDNode *N = GCov->getOperand(i);
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (N->getNumOperands() != 2) continue;
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1));
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!GCovFile || !CompileUnit) continue;
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (CompileUnit == CU) {
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        SmallString<128> Filename = GCovFile->getString();
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        sys::path::replace_extension(Filename, NewStem);
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return Filename.str();
33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallString<128> Filename = CU.getFilename();
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  sys::path::replace_extension(Filename, NewStem);
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return sys::path::filename(Filename.str());
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GCOVProfiler::runOnModule(Module &M) {
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  this->M = &M;
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Ctx = &M.getContext();
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (EmitNotes) emitGCNO();
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (EmitData) return emitProfileArcs();
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid GCOVProfiler::emitGCNO() {
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DenseMap<const MDNode *, raw_fd_ostream *> GcnoFiles;
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CU_Nodes) {
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Each compile unit gets its own .gcno file. This means that whether we run
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // this pass over the original .o's as they're produced, or run it after
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // LTO, we'll generate the same .gcno files.
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DICompileUnit CU(CU_Nodes->getOperand(i));
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      raw_fd_ostream *&out = GcnoFiles[CU];
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      std::string ErrorInfo;
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      out = new raw_fd_ostream(mangleName(CU, "gcno").c_str(), ErrorInfo,
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               raw_fd_ostream::F_Binary);
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Use402Format)
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        out->write("oncg*404MVLL", 12);
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        out->write("oncg*204MVLL", 12);
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DIArray SPs = CU.getSubprograms();
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DISubprogram SP(SPs.getElement(i));
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (!SP.Verify()) continue;
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        raw_fd_ostream *&os = GcnoFiles[CU];
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Function *F = SP.getFunction();
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (!F) continue;
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        GCOVFunction Func(SP, os, Use402Format);
38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          GCOVBlock &Block = Func.getBlock(BB);
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          TerminatorInst *TI = BB->getTerminator();
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (int successors = TI->getNumSuccessors()) {
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            for (int i = 0; i != successors; ++i) {
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            }
38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          } else if (isa<ReturnInst>(TI)) {
38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Block.addEdge(Func.getReturnBlock());
39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          uint32_t Line = 0;
39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); I != IE; ++I) {
39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            const DebugLoc &Loc = I->getDebugLoc();
39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (Loc.isUnknown()) continue;
39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (Line == Loc.getLine()) continue;
39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Line = Loc.getLine();
39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue;
39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            GCOVLines &Lines = Block.getFile(SP.getFilename());
40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Lines.addLine(Loc.getLine());
40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Func.writeOut();
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (DenseMap<const MDNode *, raw_fd_ostream *>::iterator
41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           I = GcnoFiles.begin(), E = GcnoFiles.end(); I != E; ++I) {
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    raw_fd_ostream *&out = I->second;
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    out->write("\0\0\0\0\0\0\0\0", 8);  // EOF
41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    out->close();
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    delete out;
41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool GCOVProfiler::emitProfileArcs() {
41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!CU_Nodes) return false;
42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool Result = false;
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DICompileUnit CU(CU_Nodes->getOperand(i));
42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DIArray SPs = CU.getSubprograms();
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DISubprogram SP(SPs.getElement(i));
42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!SP.Verify()) continue;
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Function *F = SP.getFunction();
43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!F) continue;
43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Result) Result = true;
43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned Edges = 0;
43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        TerminatorInst *TI = BB->getTerminator();
43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (isa<ReturnInst>(TI))
43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          ++Edges;
43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else
43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Edges += TI->getNumSuccessors();
44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ArrayType *CounterTy =
44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      GlobalVariable *Counters =
44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        new GlobalVariable(*M, CounterTy, false,
44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           GlobalValue::InternalLinkage,
44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           Constant::getNullValue(CounterTy),
44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           "__llvm_gcov_ctr", 0, false, 0);
44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      UniqueVector<BasicBlock *> ComplexEdgePreds;
45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      UniqueVector<BasicBlock *> ComplexEdgeSuccs;
45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      unsigned Edge = 0;
45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        TerminatorInst *TI = BB->getTerminator();
45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Successors) {
45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          IRBuilder<> Builder(TI);
46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Successors == 1) {
46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                                Edge);
46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Value *Count = Builder.CreateLoad(Counter);
46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Count = Builder.CreateAdd(Count,
46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      ConstantInt::get(Type::getInt64Ty(*Ctx),1));
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Builder.CreateStore(Count, Counter);
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Value *Sel = Builder.CreateSelect(
47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              BI->getCondition(),
47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              ConstantInt::get(Type::getInt64Ty(*Ctx), Edge),
47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1));
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            SmallVector<Value *, 2> Idx;
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx)));
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Idx.push_back(Sel);
47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx);
47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Value *Count = Builder.CreateLoad(Counter);
47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Count = Builder.CreateAdd(Count,
47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      ConstantInt::get(Type::getInt64Ty(*Ctx),1));
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Builder.CreateStore(Count, Counter);
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          } else {
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            ComplexEdgePreds.insert(BB);
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            for (int i = 0; i != Successors; ++i)
48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              ComplexEdgeSuccs.insert(TI->getSuccessor(i));
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Edge += Successors;
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!ComplexEdgePreds.empty()) {
49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        GlobalVariable *EdgeTable =
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          buildEdgeLookupTable(F, Counters,
49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               ComplexEdgePreds, ComplexEdgeSuccs);
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        GlobalVariable *EdgeState = getEdgeStateValue();
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type *Int32Ty = Type::getInt32Ty(*Ctx);
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator());
49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState);
50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // call runtime to perform increment
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          BasicBlock::iterator InsertPt =
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            ComplexEdgeSuccs[i+1]->getFirstInsertionPt();
50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          IRBuilder<> Builder(InsertPt);
50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Value *CounterPtrArray =
50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                               i * ComplexEdgePreds.size());
50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Builder.CreateCall2(getIncrementIndirectCounterFunc(),
51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              EdgeState, CounterPtrArray);
51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // clear the predecessor number
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Builder.CreateStore(ConstantInt::get(Int32Ty, 0xffffffff), EdgeState);
51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    insertCounterWriteout(CountersBySP);
51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Result;
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// All edges with successors that aren't branches are "complex", because it
52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// requires complex logic to pick which counter to update.
52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanGlobalVariable *GCOVProfiler::buildEdgeLookupTable(
52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Function *F,
52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GlobalVariable *Counters,
52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const UniqueVector<BasicBlock *> &Preds,
52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const UniqueVector<BasicBlock *> &Succs) {
52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // TODO: support invoke, threads. We rely on the fact that nothing can modify
52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the whole-Module pred edge# between the time we set it and the time we next
53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // read it. Threads and invoke make this untrue.
53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]].
53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ArrayType *EdgeTableTy = ArrayType::get(
53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Int64PtrTy, Succs.size() * Preds.size());
53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Constant **EdgeTable = new Constant*[Succs.size() * Preds.size()];
53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Constant *NullValue = Constant::getNullValue(Int64PtrTy);
53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (int i = 0, ie = Succs.size() * Preds.size(); i != ie; ++i)
54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EdgeTable[i] = NullValue;
54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  unsigned Edge = 0;
54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TerminatorInst *TI = BB->getTerminator();
54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) {
54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (int i = 0; i != Successors; ++i) {
54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        BasicBlock *Succ = TI->getSuccessor(i);
54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        IRBuilder<> builder(Succ);
55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0,
55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                                            Edge + i);
55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) +
55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  (Preds.idFor(BB)-1)] = cast<Constant>(Counter);
55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Edge += Successors;
55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ArrayRef<Constant*> V(&EdgeTable[0], Succs.size() * Preds.size());
56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  GlobalVariable *EdgeTableGV =
56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      new GlobalVariable(
56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          *M, EdgeTableTy, true, GlobalValue::InternalLinkage,
56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          ConstantArray::get(EdgeTableTy, V),
56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          "__llvm_gcda_edge_table");
56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EdgeTableGV->setUnnamedAddr(true);
56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return EdgeTableGV;
56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *GCOVProfiler::getStartFileFunc() {
57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              Type::getInt8PtrTy(*Ctx), false);
57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *GCOVProfiler::getIncrementIndirectCounterFunc() {
57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *Args[] = {
57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type::getInt32PtrTy(*Ctx),                  // uint32_t *predecessor
57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type::getInt64PtrTy(*Ctx)->getPointerTo(),  // uint64_t **state_table_row
57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              Args, false);
58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return M->getOrInsertFunction("llvm_gcda_increment_indirect_counter", FTy);
58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *GCOVProfiler::getEmitFunctionFunc() {
58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *Args[2] = {
58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type::getInt32Ty(*Ctx),    // uint32_t ident
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type::getInt8PtrTy(*Ctx),  // const char *function_name
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              Args, false);
59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *GCOVProfiler::getEmitArcsFunc() {
59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *Args[] = {
59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type::getInt32Ty(*Ctx),     // uint32_t num_counters
59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type::getInt64PtrTy(*Ctx),  // uint64_t *counters
59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              Args, false);
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *GCOVProfiler::getEndFileFunc() {
60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanGlobalVariable *GCOVProfiler::getEdgeStateValue() {
61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred");
61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!GV) {
61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false,
61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            GlobalValue::InternalLinkage,
61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            ConstantInt::get(Type::getInt32Ty(*Ctx),
61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             0xffffffff),
61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            "__llvm_gcov_global_state_pred");
61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    GV->setUnnamedAddr(true);
61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return GV;
62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid GCOVProfiler::insertCounterWriteout(
62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> &CountersBySP) {
62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  FunctionType *WriteoutFTy =
62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FunctionType::get(Type::getVoidTy(*Ctx), false);
62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Function *WriteoutF = Function::Create(WriteoutFTy,
62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         GlobalValue::InternalLinkage,
62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                         "__llvm_gcov_writeout", M);
63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  WriteoutF->setUnnamedAddr(true);
63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF);
63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  IRBuilder<> Builder(BB);
63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Constant *StartFile = getStartFileFunc();
63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Constant *EmitFunction = getEmitFunctionFunc();
63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Constant *EmitArcs = getEmitArcsFunc();
63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Constant *EndFile = getEndFileFunc();
63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (CU_Nodes) {
64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DICompileUnit compile_unit(CU_Nodes->getOperand(i));
64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      std::string FilenameGcda = mangleName(compile_unit, "gcda");
64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Builder.CreateCall(StartFile,
64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         Builder.CreateGlobalStringPtr(FilenameGcda));
64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (SmallVector<std::pair<GlobalVariable *, MDNode *>, 8>::iterator
64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             I = CountersBySP.begin(), E = CountersBySP.end();
64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           I != E; ++I) {
64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DISubprogram SP(I->second);
65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        intptr_t ident = reinterpret_cast<intptr_t>(I->second);
65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Builder.CreateCall2(EmitFunction,
65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            ConstantInt::get(Type::getInt32Ty(*Ctx), ident),
65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            Builder.CreateGlobalStringPtr(SP.getName()));
65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        GlobalVariable *GV = I->first;
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        unsigned Arcs =
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Builder.CreateCall2(EmitArcs,
65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs),
66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            Builder.CreateConstGEP2_64(GV, 0, 0));
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Builder.CreateCall(EndFile);
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Builder.CreateRetVoid();
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  InsertProfilingShutdownCall(WriteoutF, M);
66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
669