GCOVProfiling.cpp revision f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9f
1b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===- GCOVProfiling.cpp - Insert edge counters for gcov profiling --------===//
2b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
3b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//                      The LLVM Compiler Infrastructure
4b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
5b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// This file is distributed under the University of Illinois Open Source
6b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// License. See LICENSE.TXT for details.
7b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
8b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===----------------------------------------------------------------------===//
9b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
10b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// This pass implements GCOV-style profiling. When this pass is run it emits
11b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// "gcno" files next to the existing source, and instruments the code that runs
12b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// to records the edges between blocks that run and emit a complementary "gcda"
13b1928704201034c785a26296a49f69355eb56a05Nick Lewycky// file on exit.
14b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//
15b1928704201034c785a26296a49f69355eb56a05Nick Lewycky//===----------------------------------------------------------------------===//
16b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
17b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#define DEBUG_TYPE "insert-gcov-profiling"
18b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
19b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/Transforms/Instrumentation.h"
20b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/DenseMap.h"
21b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/STLExtras.h"
2206cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/ADT/Statistic.h"
23b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringExtras.h"
24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringMap.h"
25b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/UniqueVector.h"
26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/DebugInfo.h"
270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h"
280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h"
290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Pass.h"
31a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "llvm/Support/CommandLine.h"
3206cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/Debug.h"
3306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/DebugLoc.h"
3439c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling#include "llvm/Support/FileSystem.h"
3506cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/InstIterator.h"
36a11c3e25015a62c817e60ec4f955a7f3f3bb6c67Rafael Espindola#include "llvm/Support/Path.h"
3706cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/raw_ostream.h"
3806cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Transforms/Utils/ModuleUtils.h"
39c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky#include <algorithm>
40b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <string>
41b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <utility>
42b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyusing namespace llvm;
43b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
44a204ef3168c8804808c716115ba915c89d8849b9Nick Lewyckystatic cl::opt<std::string>
45a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyDefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden,
46a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky                   cl::ValueRequired);
47a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
48a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyGCOVOptions GCOVOptions::getDefault() {
49a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  GCOVOptions Options;
50a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.EmitNotes = true;
51a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.EmitData = true;
52a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.UseCfgChecksum = false;
53a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.NoRedZone = false;
54a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.FunctionNamesInData = true;
55a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
56a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (DefaultGCOVVersion.size() != 4) {
57a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") +
58a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky                             DefaultGCOVVersion);
59a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  }
60a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4);
61a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  return Options;
62a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky}
63a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
64b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace {
65b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVProfiler : public ModulePass {
66b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  public:
67b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    static char ID;
68a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    GCOVProfiler() : ModulePass(ID), Options(GCOVOptions::getDefault()) {
69a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[0] = Options.Version[3];
70a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[1] = Options.Version[2];
71a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[2] = Options.Version[1];
72a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[3] = Options.Version[0];
73a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[4] = '\0';
74a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
75a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    }
76a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    GCOVProfiler(const GCOVOptions &Options) : ModulePass(ID), Options(Options){
77a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      assert((Options.EmitNotes || Options.EmitData) &&
78a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky             "GCOVProfiler asked to do nothing?");
79a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[0] = Options.Version[3];
80a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[1] = Options.Version[2];
81a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[2] = Options.Version[1];
82a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[3] = Options.Version[0];
83a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[4] = '\0';
84b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
85b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
86b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    virtual const char *getPassName() const {
87b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      return "GCOV Profiler";
88b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
89a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
90b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  private:
91269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    bool runOnModule(Module &M);
92269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
9364a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky    // Create the .gcno files for the Module based on DebugInfo.
9464a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky    void emitProfileNotes();
95b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
960c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky    // Modify the program to track transitions along edges and call into the
970c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky    // profiling runtime to emit .gcda files when run.
98f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    bool emitProfileArcs();
990c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
100b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Get pointers to the functions in the runtime library.
101b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getStartFileFunc();
10277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    Constant *getIncrementIndirectCounterFunc();
103b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEmitFunctionFunc();
104b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEmitArcsFunc();
105f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu    Constant *getSummaryInfoFunc();
10618764716861243c58a711a92190624dc2f6aafc9Bill Wendling    Constant *getDeleteWriteoutFunctionListFunc();
107d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Constant *getDeleteFlushFunctionListFunc();
108b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEndFileFunc();
109b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // Create or retrieve an i32 state value that is used to represent the
1111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // pred block number for certain non-trivial edges.
1121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *getEdgeStateValue();
1131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
1141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // Produce a table of pointers to counters, by predecessor and successor
1151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // block number.
1161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *buildEdgeLookupTable(Function *F,
1171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         GlobalVariable *Counter,
11864a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky                                         const UniqueVector<BasicBlock *>&Preds,
11964a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky                                         const UniqueVector<BasicBlock*>&Succs);
1201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
121b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Add the function to write out all our counters to the global destructor
122b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // list.
123d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*,
124d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling                                                       MDNode*> >);
125d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
12677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    void insertIndirectCounterIncrement();
127b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
128f2a2806baf3763d551a9f361124b608b2eed66faBill Wendling    std::string mangleName(DICompileUnit CU, const char *NewStem);
129269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
130a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    GCOVOptions Options;
131a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
132a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    // Reversed, NUL-terminated copy of Options.Version.
133a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    char ReversedVersion[5];
134a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky
1351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Module *M;
136b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    LLVMContext *Ctx;
137b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
140b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0;
141b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                "Insert instrumentation for GCOV profiling", false, false)
143b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
144a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyModulePass *llvm::createGCOVProfilerPass(const GCOVOptions &Options) {
145a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  return new GCOVProfiler(Options);
146a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky}
147b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1485d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewyckystatic std::string getFunctionName(DISubprogram SP) {
1495d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky  if (!SP.getLinkageName().empty())
1505d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky    return SP.getLinkageName();
1515d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky  return SP.getName();
1525d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky}
1535d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky
154b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace {
155b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVRecord {
156b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   protected:
157d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper    static const char *const LinesTag;
158d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper    static const char *const FunctionTag;
159d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper    static const char *const BlockTag;
160d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper    static const char *const EdgeTag;
161b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
162b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    GCOVRecord() {}
163b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeBytes(const char *Bytes, int Size) {
1651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      os->write(Bytes, Size);
166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
167b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void write(uint32_t i) {
1691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(reinterpret_cast<char*>(&i), 4);
170b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
171b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Returns the length measured in 4-byte blocks that will be used to
173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // represent this string in a GCOV file
174619850cb3161733e9284ff3bf9a68d1a3b76f0b4Craig Topper    static unsigned lengthOfGCOVString(StringRef s) {
175b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
17617df2c3240837b4382898ead8c3ead407a338520Nick Lewycky      // padding out to the next 4-byte word. The length is measured in 4-byte
17717df2c3240837b4382898ead8c3ead407a338520Nick Lewycky      // words including padding, not bytes of actual string.
178d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky      return (s.size() / 4) + 1;
179b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
180b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeGCOVString(StringRef s) {
1821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Len = lengthOfGCOVString(s);
1831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Len);
1841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(s.data(), s.size());
185b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
186b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Write 1 to 4 bytes of NUL padding.
1877a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      assert((unsigned)(4 - (s.size() % 4)) > 0);
1887a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      assert((unsigned)(4 - (s.size() % 4)) <= 4);
1897a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      writeBytes("\0\0\0\0", 4 - (s.size() % 4));
190b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
191b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
192b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    raw_ostream *os;
193b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
194d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper  const char *const GCOVRecord::LinesTag = "\0\0\x45\x01";
195d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper  const char *const GCOVRecord::FunctionTag = "\0\0\0\1";
196d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper  const char *const GCOVRecord::BlockTag = "\0\0\x41\x01";
197d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper  const char *const GCOVRecord::EdgeTag = "\0\0\x43\x01";
198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVFunction;
200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVBlock;
201b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
202b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // Constructed only by requesting it from a GCOVBlock, this object stores a
20316c19a155c65fd41865562fe4e678ef32728510bDevang Patel  // list of line numbers and a single filename, representing lines that belong
20416c19a155c65fd41865562fe4e678ef32728510bDevang Patel  // to the block.
205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVLines : public GCOVRecord {
206b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
2071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void addLine(uint32_t Line) {
2081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      Lines.push_back(Line);
209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
210b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
211619850cb3161733e9284ff3bf9a68d1a3b76f0b4Craig Topper    uint32_t length() const {
212bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      // Here 2 = 1 for string length + 1 for '0' id#.
21316c19a155c65fd41865562fe4e678ef32728510bDevang Patel      return lengthOfGCOVString(Filename) + 2 + Lines.size();
214b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
215b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
21616c19a155c65fd41865562fe4e678ef32728510bDevang Patel    void writeOut() {
21716c19a155c65fd41865562fe4e678ef32728510bDevang Patel      write(0);
21816c19a155c65fd41865562fe4e678ef32728510bDevang Patel      writeGCOVString(Filename);
21916c19a155c65fd41865562fe4e678ef32728510bDevang Patel      for (int i = 0, e = Lines.size(); i != e; ++i)
22016c19a155c65fd41865562fe4e678ef32728510bDevang Patel        write(Lines[i]);
22116c19a155c65fd41865562fe4e678ef32728510bDevang Patel    }
222b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
22316c19a155c65fd41865562fe4e678ef32728510bDevang Patel    GCOVLines(StringRef F, raw_ostream *os)
22416c19a155c65fd41865562fe4e678ef32728510bDevang Patel      : Filename(F) {
225b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
226b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
227b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
228680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel   private:
22916c19a155c65fd41865562fe4e678ef32728510bDevang Patel    StringRef Filename;
2301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    SmallVector<uint32_t, 32> Lines;
231b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
233c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky
234c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky  // Sorting function for deterministic behaviour in GCOVBlock::writeOut.
235c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky  struct StringKeySort {
236c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky    bool operator()(StringMapEntry<GCOVLines *> *LHS,
237c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky                    StringMapEntry<GCOVLines *> *RHS) const {
238c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      return LHS->getKey() < RHS->getKey();
239c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky    }
240c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky  };
241c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky
242b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // Represent a basic block in GCOV. Each block has a unique number in the
243b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // function, number of lines belonging to each block, and a set of edges to
244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // other blocks.
245b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVBlock : public GCOVRecord {
246b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
24768155d31cd0175be89e26ee68387cb411fca537bDevang Patel    GCOVLines &getFile(StringRef Filename) {
2481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      GCOVLines *&Lines = LinesByFile[Filename];
2491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      if (!Lines) {
25016c19a155c65fd41865562fe4e678ef32728510bDevang Patel        Lines = new GCOVLines(Filename, os);
251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
2521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *Lines;
253b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
254b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void addEdge(GCOVBlock &Successor) {
2561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      OutEdges.push_back(&Successor);
257b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
258b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeOut() {
2601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Len = 3;
261c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      SmallVector<StringMapEntry<GCOVLines *> *, 32> SortedLinesByFile;
2621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
2631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = LinesByFile.end(); I != E; ++I) {
26416c19a155c65fd41865562fe4e678ef32728510bDevang Patel        Len += I->second->length();
265c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky        SortedLinesByFile.push_back(&*I);
266b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
267b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(LinesTag, 4);
2691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Len);
2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Number);
271c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky
272c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      StringKeySort Sorter;
273c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      std::sort(SortedLinesByFile.begin(), SortedLinesByFile.end(), Sorter);
2746227d5c690504c7ada5780c00a635b282c46e275Craig Topper      for (SmallVectorImpl<StringMapEntry<GCOVLines *> *>::iterator
275c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky               I = SortedLinesByFile.begin(), E = SortedLinesByFile.end();
276c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky           I != E; ++I)
277c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky        (*I)->getValue()->writeOut();
2781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(0);
2791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(0);
280b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
281b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
282b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    ~GCOVBlock() {
2831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      DeleteContainerSeconds(LinesByFile);
284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
285b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
286b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
287b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    friend class GCOVFunction;
288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock(uint32_t Number, raw_ostream *os)
2901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        : Number(Number) {
291b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
292b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
293b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    uint32_t Number;
2951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    StringMap<GCOVLines *> LinesByFile;
2961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    SmallVector<GCOVBlock *, 4> OutEdges;
297b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
298b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
299b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // A function has a unique identifier, a checksum (we leave as zero) and a
300b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // set of blocks and a map of edges between blocks. This is the only GCOV
301b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // object users can construct, the blocks and lines will be rooted here.
302b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVFunction : public GCOVRecord {
303b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
304d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky    GCOVFunction(DISubprogram SP, raw_ostream *os, uint32_t Ident,
305a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky                 bool UseCfgChecksum) {
306b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
307b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
308b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      Function *F = SP.getFunction();
309bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      DEBUG(dbgs() << "Function: " << F->getName() << "\n");
310b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      uint32_t i = 0;
311b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        Blocks[BB] = new GCOVBlock(i++, os);
313b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
3141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      ReturnBlock = new GCOVBlock(i++, os);
3151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
3161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(FunctionTag, 4);
3175d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky      uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(getFunctionName(SP)) +
3181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          1 + lengthOfGCOVString(SP.getFilename()) + 1;
319a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      if (UseCfgChecksum)
320bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        ++BlockLen;
3211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(BlockLen);
3221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Ident);
323bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      write(0);  // lineno checksum
324a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      if (UseCfgChecksum)
325bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        write(0);  // cfg checksum
3265d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky      writeGCOVString(getFunctionName(SP));
3271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeGCOVString(SP.getFilename());
3281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(SP.getLineNumber());
329b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
330b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
331b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    ~GCOVFunction() {
3321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      DeleteContainerSeconds(Blocks);
3331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      delete ReturnBlock;
334b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
335b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
3361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock &getBlock(BasicBlock *BB) {
3371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *Blocks[BB];
338b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
339b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
3401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock &getReturnBlock() {
3411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *ReturnBlock;
342a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky    }
343a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky
3441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeOut() {
345b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit count of blocks.
3461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(BlockTag, 4);
3471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Blocks.size() + 1);
3481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
3491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(0);  // No flags on our blocks.
350b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
351bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      DEBUG(dbgs() << Blocks.size() << " blocks.\n");
352b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
353b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit edges between blocks.
354c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      if (Blocks.empty()) return;
355c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      Function *F = Blocks.begin()->first->getParent();
356c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
357c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky        GCOVBlock &Block = *Blocks[I];
3581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        if (Block.OutEdges.empty()) continue;
3591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
3601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        writeBytes(EdgeTag, 4);
3611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(Block.OutEdges.size() * 2 + 1);
3621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(Block.Number);
3631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
364bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number
365bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky                       << "\n");
3661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(Block.OutEdges[i]->Number);
3671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(0);  // no flags
368b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
369b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
370b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
371b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit lines for each block.
372c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
373c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky        Blocks[I]->writeOut();
374b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
375b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
376b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
377b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
3781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    DenseMap<BasicBlock *, GCOVBlock *> Blocks;
3791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock *ReturnBlock;
380b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
381b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
382b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
383f2a2806baf3763d551a9f361124b608b2eed66faBill Wendlingstd::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem) {
384269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky  if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
385269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
386269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      MDNode *N = GCov->getOperand(i);
387269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      if (N->getNumOperands() != 2) continue;
388fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
389269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1));
390fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      if (!GCovFile || !CompileUnit) continue;
391fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      if (CompileUnit == CU) {
3926e5190c193f6267893daf6943af88e95039e739cBill Wendling        SmallString<128> Filename = GCovFile->getString();
3936e5190c193f6267893daf6943af88e95039e739cBill Wendling        sys::path::replace_extension(Filename, NewStem);
3946e5190c193f6267893daf6943af88e95039e739cBill Wendling        return Filename.str();
395fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      }
396269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    }
397269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky  }
398fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky
3996e5190c193f6267893daf6943af88e95039e739cBill Wendling  SmallString<128> Filename = CU.getFilename();
400fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky  sys::path::replace_extension(Filename, NewStem);
40139c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  StringRef FName = sys::path::filename(Filename);
40239c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  SmallString<128> CurPath;
40339c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  if (sys::fs::current_path(CurPath)) return FName;
40439c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  sys::path::append(CurPath, FName.str());
40539c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  return CurPath.str();
406269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky}
407269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
4080c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) {
4091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  this->M = &M;
4100c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky  Ctx = &M.getContext();
4110c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
412a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.EmitNotes) emitProfileNotes();
413a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.EmitData) return emitProfileArcs();
414a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky  return false;
4150c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky}
4160c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
41764a0a33307723957bf2f15e3181a290853c6f833Nick Lewyckyvoid GCOVProfiler::emitProfileNotes() {
418f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
419bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky  if (!CU_Nodes) return;
420bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
421bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
422bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // Each compile unit gets its own .gcno file. This means that whether we run
423bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // this pass over the original .o's as they're produced, or run it after
424bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // LTO, we'll generate the same .gcno files.
425bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
426bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    DICompileUnit CU(CU_Nodes->getOperand(i));
427bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    std::string ErrorInfo;
428f2a2806baf3763d551a9f361124b608b2eed66faBill Wendling    raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo,
429c1b49b56d4132efa2e06deb8f23508d0de4c8800Rafael Espindola                       sys::fs::F_Binary);
430d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky    out.write("oncg", 4);
431a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    out.write(ReversedVersion, 4);
432d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky    out.write("MVLL", 4);
433bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
434bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    DIArray SPs = CU.getSubprograms();
435bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
436bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      DISubprogram SP(SPs.getElement(i));
437cbafae6d33031a72ba8219c28cb0e852511f79a3Manman Ren      assert((!SP || SP.isSubprogram()) &&
438cbafae6d33031a72ba8219c28cb0e852511f79a3Manman Ren        "A MDNode in subprograms of a CU should be null or a DISubprogram.");
439cbafae6d33031a72ba8219c28cb0e852511f79a3Manman Ren      if (!SP)
440cbafae6d33031a72ba8219c28cb0e852511f79a3Manman Ren        continue;
441bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
442bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      Function *F = SP.getFunction();
443bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      if (!F) continue;
444a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      GCOVFunction Func(SP, &out, i, Options.UseCfgChecksum);
445bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
446bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
447bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        GCOVBlock &Block = Func.getBlock(BB);
448bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        TerminatorInst *TI = BB->getTerminator();
449bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        if (int successors = TI->getNumSuccessors()) {
450bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          for (int i = 0; i != successors; ++i) {
451bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky            Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
452f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
453bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        } else if (isa<ReturnInst>(TI)) {
454bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          Block.addEdge(Func.getReturnBlock());
455bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        }
456bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
457bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        uint32_t Line = 0;
458bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
459bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky             I != IE; ++I) {
460bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          const DebugLoc &Loc = I->getDebugLoc();
461bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          if (Loc.isUnknown()) continue;
462bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          if (Line == Loc.getLine()) continue;
463bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          Line = Loc.getLine();
464bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue;
465bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
466bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          GCOVLines &Lines = Block.getFile(SP.getFilename());
467bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          Lines.addLine(Loc.getLine());
468b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
469b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
470bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      Func.writeOut();
471b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
472bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    out.write("\0\0\0\0\0\0\0\0", 8);  // EOF
473bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    out.close();
474b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
475b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
476b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
477f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() {
478f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
479f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (!CU_Nodes) return false;
480f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  bool Result = false;
48277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  bool InsertIndCounterIncrCode = false;
483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    DICompileUnit CU(CU_Nodes->getOperand(i));
485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    DIArray SPs = CU.getSubprograms();
486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      DISubprogram SP(SPs.getElement(i));
489cbafae6d33031a72ba8219c28cb0e852511f79a3Manman Ren      assert((!SP || SP.isSubprogram()) &&
490cbafae6d33031a72ba8219c28cb0e852511f79a3Manman Ren        "A MDNode in subprograms of a CU should be null or a DISubprogram.");
491cbafae6d33031a72ba8219c28cb0e852511f79a3Manman Ren      if (!SP)
492cbafae6d33031a72ba8219c28cb0e852511f79a3Manman Ren        continue;
493f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      Function *F = SP.getFunction();
494f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!F) continue;
495f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!Result) Result = true;
496f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      unsigned Edges = 0;
497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        TerminatorInst *TI = BB->getTerminator();
499f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (isa<ReturnInst>(TI))
500f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          ++Edges;
501f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        else
502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Edges += TI->getNumSuccessors();
503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      }
504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      ArrayType *CounterTy =
5061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
507f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      GlobalVariable *Counters =
5081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        new GlobalVariable(*M, CounterTy, false,
509b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                           GlobalValue::InternalLinkage,
5101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                           Constant::getNullValue(CounterTy),
511ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg                           "__llvm_gcov_ctr");
512f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
513f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
514f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      UniqueVector<BasicBlock *> ComplexEdgePreds;
515f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      UniqueVector<BasicBlock *> ComplexEdgeSuccs;
516f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
517f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      unsigned Edge = 0;
518f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
519f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        TerminatorInst *TI = BB->getTerminator();
520f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
521f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (Successors) {
522f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          if (Successors == 1) {
523f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling            IRBuilder<> Builder(BB->getFirstInsertionPt());
524f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
525f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                                                                Edge);
526f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Count = Builder.CreateLoad(Counter);
527bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky            Count = Builder.CreateAdd(Count, Builder.getInt64(1));
528f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Builder.CreateStore(Count, Counter);
529f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
530f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling            IRBuilder<> Builder(BI);
531bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky            Value *Sel = Builder.CreateSelect(BI->getCondition(),
532bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky                                              Builder.getInt64(Edge),
533bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky                                              Builder.getInt64(Edge + 1));
534f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            SmallVector<Value *, 2> Idx;
535bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky            Idx.push_back(Builder.getInt64(0));
536f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Idx.push_back(Sel);
537f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx);
538f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Count = Builder.CreateLoad(Counter);
539bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky            Count = Builder.CreateAdd(Count, Builder.getInt64(1));
540f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Builder.CreateStore(Count, Counter);
541f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else {
542f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            ComplexEdgePreds.insert(BB);
543f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            for (int i = 0; i != Successors; ++i)
544f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel              ComplexEdgeSuccs.insert(TI->getSuccessor(i));
545f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
546f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling
547f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Edge += Successors;
548b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
549b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
550f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
551f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!ComplexEdgePreds.empty()) {
552f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *EdgeTable =
5531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          buildEdgeLookupTable(F, Counters,
5541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                               ComplexEdgePreds, ComplexEdgeSuccs);
555f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *EdgeState = getEdgeStateValue();
556f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
557f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
558f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling          IRBuilder<> Builder(ComplexEdgePreds[i + 1]->getFirstInsertionPt());
559bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky          Builder.CreateStore(Builder.getInt32(i), EdgeState);
560f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        }
561f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling
562f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
563f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling          // Call runtime to perform increment.
564f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling          IRBuilder<> Builder(ComplexEdgeSuccs[i+1]->getFirstInsertionPt());
565f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Value *CounterPtrArray =
5661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky            Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
5671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                               i * ComplexEdgePreds.size());
568c7a884040e4ec7795515978a94803894ad08c4caBill Wendling
569c7a884040e4ec7795515978a94803894ad08c4caBill Wendling          // Build code to increment the counter.
57077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling          InsertIndCounterIncrCode = true;
57177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling          Builder.CreateCall2(getIncrementIndirectCounterFunc(),
57277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling                              EdgeState, CounterPtrArray);
573f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        }
574b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
575b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
5764a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling
577d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *WriteoutF = insertCounterWriteout(CountersBySP);
578d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *FlushF = insertFlush(CountersBySP);
579d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
580d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    // Create a small bit of code that registers the "__llvm_gcov_writeout" to
58118764716861243c58a711a92190624dc2f6aafc9Bill Wendling    // be executed at exit and the "__llvm_gcov_flush" function to be executed
58218764716861243c58a711a92190624dc2f6aafc9Bill Wendling    // when "__gcov_flush" is called.
583d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
584d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
585d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling                                   "__llvm_gcov_init", M);
586d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    F->setUnnamedAddr(true);
587d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    F->setLinkage(GlobalValue::InternalLinkage);
588d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    F->addFnAttr(Attribute::NoInline);
589d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    if (Options.NoRedZone)
590d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling      F->addFnAttr(Attribute::NoRedZone);
591d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
592d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
593d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    IRBuilder<> Builder(BB);
594d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
595d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
5968640c6a5227b75666e02424e2181289692138348Bill Wendling    Type *Params[] = {
5978640c6a5227b75666e02424e2181289692138348Bill Wendling      PointerType::get(FTy, 0),
5988640c6a5227b75666e02424e2181289692138348Bill Wendling      PointerType::get(FTy, 0)
5998640c6a5227b75666e02424e2181289692138348Bill Wendling    };
6008640c6a5227b75666e02424e2181289692138348Bill Wendling    FTy = FunctionType::get(Builder.getVoidTy(), Params, false);
6018640c6a5227b75666e02424e2181289692138348Bill Wendling
602d7da59004fc9262f33c96ad2736b36ff1235ce7bYuchen Wu    // Initialize the environment and register the local writeout and flush
6038640c6a5227b75666e02424e2181289692138348Bill Wendling    // functions.
6048640c6a5227b75666e02424e2181289692138348Bill Wendling    Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
6058640c6a5227b75666e02424e2181289692138348Bill Wendling    Builder.CreateCall2(GCOVInit, WriteoutF, FlushF);
606d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Builder.CreateRetVoid();
607d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
608d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    appendToGlobalCtors(*M, F, 0);
609b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
61077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
61177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  if (InsertIndCounterIncrCode)
61277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    insertIndirectCounterIncrement();
61377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
614f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  return Result;
615b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
616b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
6171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it
6181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update.
6191790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable(
6201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Function *F,
6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *Counters,
6221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    const UniqueVector<BasicBlock *> &Preds,
6231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    const UniqueVector<BasicBlock *> &Succs) {
6241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // TODO: support invoke, threads. We rely on the fact that nothing can modify
6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // the whole-Module pred edge# between the time we set it and the time we next
6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // read it. Threads and invoke make this untrue.
6271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
6281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]].
6299e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  size_t TableSize = Succs.size() * Preds.size();
630db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
6319e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize);
6321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
6339e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  OwningArrayPtr<Constant *> EdgeTable(new Constant*[TableSize]);
6341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  Constant *NullValue = Constant::getNullValue(Int64PtrTy);
6359e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  for (size_t i = 0; i != TableSize; ++i)
6361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    EdgeTable[i] = NullValue;
6371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
6381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  unsigned Edge = 0;
6391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
6401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    TerminatorInst *TI = BB->getTerminator();
6411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
6427a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky    if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) {
6431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (int i = 0; i != Successors; ++i) {
6441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        BasicBlock *Succ = TI->getSuccessor(i);
645bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky        IRBuilder<> Builder(Succ);
646bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky        Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
6471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                                            Edge + i);
6481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) +
6491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                  (Preds.idFor(BB)-1)] = cast<Constant>(Counter);
6501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      }
6511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    }
6521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Edge += Successors;
6531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  }
6541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
6559e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  ArrayRef<Constant*> V(&EdgeTable[0], TableSize);
6561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  GlobalVariable *EdgeTableGV =
6571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      new GlobalVariable(
6581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          *M, EdgeTableTy, true, GlobalValue::InternalLinkage,
659267010864e139781ef5949939e081c41f954de0aJay Foad          ConstantArray::get(EdgeTableTy, V),
6601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          "__llvm_gcda_edge_table");
6611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  EdgeTableGV->setUnnamedAddr(true);
6621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return EdgeTableGV;
6631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
6641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
665b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() {
666d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky  Type *Args[] = {
667d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky    Type::getInt8PtrTy(*Ctx),  // const char *orig_filename
668d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky    Type::getInt8PtrTy(*Ctx),  // const char version[4]
669d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky  };
670d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
6711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
6721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
6731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
67477b19134104c3e96424dc010f2b69c3faf580e68Bill WendlingConstant *GCOVProfiler::getIncrementIndirectCounterFunc() {
67577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Type *Int32Ty = Type::getInt32Ty(*Ctx);
676c7a884040e4ec7795515978a94803894ad08c4caBill Wendling  Type *Int64Ty = Type::getInt64Ty(*Ctx);
67777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Type *Args[] = {
678b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow    Int32Ty->getPointerTo(),                // uint32_t *predecessor
679b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow    Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters
68077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  };
68177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
68277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy);
683b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
684b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
685b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() {
68617d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky  Type *Args[3] = {
6875409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    Type::getInt32Ty(*Ctx),    // uint32_t ident
6885409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    Type::getInt8PtrTy(*Ctx),  // const char *function_name
68917d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky    Type::getInt8Ty(*Ctx),     // uint8_t use_extra_checksum
6905409a188328d9de3755febc23558d4fc1797d04eNick Lewycky  };
691c7a884040e4ec7795515978a94803894ad08c4caBill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
6921790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
693b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
694b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
695b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() {
6965fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Args[] = {
697b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Type::getInt32Ty(*Ctx),     // uint32_t num_counters
698b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Type::getInt64PtrTy(*Ctx),  // uint64_t *counters
699b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
700d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
7011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
702b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
703b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
704f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen WuConstant *GCOVProfiler::getSummaryInfoFunc() {
705f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
706f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu  return M->getOrInsertFunction("llvm_gcda_summary_info", FTy);
707f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu}
708f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu
70918764716861243c58a711a92190624dc2f6aafc9Bill WendlingConstant *GCOVProfiler::getDeleteWriteoutFunctionListFunc() {
71018764716861243c58a711a92190624dc2f6aafc9Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
71118764716861243c58a711a92190624dc2f6aafc9Bill Wendling  return M->getOrInsertFunction("llvm_delete_writeout_function_list", FTy);
71218764716861243c58a711a92190624dc2f6aafc9Bill Wendling}
71318764716861243c58a711a92190624dc2f6aafc9Bill Wendling
714d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingConstant *GCOVProfiler::getDeleteFlushFunctionListFunc() {
715d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
716d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  return M->getOrInsertFunction("llvm_delete_flush_function_list", FTy);
717d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling}
718d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
719b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() {
720db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
7211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
722b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
723b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
7241790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() {
7251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred");
7261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  if (!GV) {
7271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false,
7281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            GlobalValue::InternalLinkage,
7291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            ConstantInt::get(Type::getInt32Ty(*Ctx),
7301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                             0xffffffff),
7311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            "__llvm_gcov_global_state_pred");
7321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GV->setUnnamedAddr(true);
7331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  }
7341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return GV;
7351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
736b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
737d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingFunction *GCOVProfiler::insertCounterWriteout(
73821b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling    ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
739253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
740253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
741253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (!WriteoutF)
742253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
743253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling                                 "__llvm_gcov_writeout", M);
744b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  WriteoutF->setUnnamedAddr(true);
745034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  WriteoutF->addFnAttr(Attribute::NoInline);
746a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.NoRedZone)
747034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    WriteoutF->addFnAttr(Attribute::NoRedZone);
748253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
749253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
7501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  IRBuilder<> Builder(BB);
751b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
752b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *StartFile = getStartFileFunc();
753b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EmitFunction = getEmitFunctionFunc();
754b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EmitArcs = getEmitArcsFunc();
755f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu  Constant *SummaryInfo = getSummaryInfoFunc();
756b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EndFile = getEndFileFunc();
757b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
758f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
759f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (CU_Nodes) {
760f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
761032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling      DICompileUnit CU(CU_Nodes->getOperand(i));
762f2a2806baf3763d551a9f361124b608b2eed66faBill Wendling      std::string FilenameGcda = mangleName(CU, "gcda");
763d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky      Builder.CreateCall2(StartFile,
764d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky                          Builder.CreateGlobalStringPtr(FilenameGcda),
765a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky                          Builder.CreateGlobalStringPtr(ReversedVersion));
7668fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky      for (unsigned j = 0, e = CountersBySP.size(); j != e; ++j) {
7678fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky        DISubprogram SP(CountersBySP[j].second);
7685d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky        Builder.CreateCall3(
7695d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky            EmitFunction, Builder.getInt32(j),
7705d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky            Options.FunctionNamesInData ?
7715d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky              Builder.CreateGlobalStringPtr(getFunctionName(SP)) :
7725d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky              Constant::getNullValue(Builder.getInt8PtrTy()),
7735d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky            Builder.getInt8(Options.UseCfgChecksum));
77417d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky
7758fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky        GlobalVariable *GV = CountersBySP[j].first;
776f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        unsigned Arcs =
777b1928704201034c785a26296a49f69355eb56a05Nick Lewycky          cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
778f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Builder.CreateCall2(EmitArcs,
779bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky                            Builder.getInt32(Arcs),
780f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            Builder.CreateConstGEP2_64(GV, 0, 0));
781f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      }
782f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu      Builder.CreateCall(SummaryInfo);
783f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      Builder.CreateCall(EndFile);
784b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
785b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
786b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
7874a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  Builder.CreateRetVoid();
788d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  return WriteoutF;
789b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
79077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
79177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendlingvoid GCOVProfiler::insertIndirectCounterIncrement() {
79277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Function *Fn =
79377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
79477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Fn->setUnnamedAddr(true);
79577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Fn->setLinkage(GlobalValue::InternalLinkage);
796034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  Fn->addFnAttr(Attribute::NoInline);
797a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.NoRedZone)
798034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    Fn->addFnAttr(Attribute::NoRedZone);
79977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
80077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // Create basic blocks for function.
80177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn);
80277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  IRBuilder<> Builder(BB);
80377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
80477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn);
80577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn);
80677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn);
80777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
80877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // uint32_t pred = *predecessor;
80977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // if (pred == 0xffffffff) return;
81077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Argument *Arg = Fn->arg_begin();
81177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Arg->setName("predecessor");
81277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Pred = Builder.CreateLoad(Arg, "pred");
813bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky  Value *Cond = Builder.CreateICmpEQ(Pred, Builder.getInt32(0xffffffff));
81477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BranchInst::Create(Exit, PredNotNegOne, Cond, BB);
81577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
81677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(PredNotNegOne);
81777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
81877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // uint64_t *counter = counters[pred];
81977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // if (!counter) return;
820bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky  Value *ZExtPred = Builder.CreateZExt(Pred, Builder.getInt64Ty());
82177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Arg = llvm::next(Fn->arg_begin());
82277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Arg->setName("counters");
82377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *GEP = Builder.CreateGEP(Arg, ZExtPred);
82477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Counter = Builder.CreateLoad(GEP, "counter");
82558591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky  Cond = Builder.CreateICmpEQ(Counter,
82658591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky                              Constant::getNullValue(
82758591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky                                  Builder.getInt64Ty()->getPointerTo()));
82877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateCondBr(Cond, Exit, CounterEnd);
82977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
83077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // ++*counter;
83177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(CounterEnd);
83277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter),
833bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky                                 Builder.getInt64(1));
83477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateStore(Add, Counter);
83577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateBr(Exit);
83677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
83777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // Fill in the exit block.
83877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(Exit);
83977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateRetVoid();
84077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling}
841253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
842d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingFunction *GCOVProfiler::
843253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill WendlinginsertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
844253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
845d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  Function *FlushF = M->getFunction("__llvm_gcov_flush");
846253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (!FlushF)
847253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
848d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling                              "__llvm_gcov_flush", M);
849253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else
850253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    FlushF->setLinkage(GlobalValue::InternalLinkage);
851253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FlushF->setUnnamedAddr(true);
852034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  FlushF->addFnAttr(Attribute::NoInline);
853a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.NoRedZone)
854034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    FlushF->addFnAttr(Attribute::NoRedZone);
855253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
856253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
857253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
858253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  // Write out the current counters.
859253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout");
860253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  assert(WriteoutF && "Need to create the writeout function first!");
861253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
862253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  IRBuilder<> Builder(Entry);
863253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Builder.CreateCall(WriteoutF);
864253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
865032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  // Zero out the counters.
866032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator
867032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling         I = CountersBySP.begin(), E = CountersBySP.end();
868032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling       I != E; ++I) {
869032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling    GlobalVariable *GV = I->first;
870032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling    Constant *Null = Constant::getNullValue(GV->getType()->getElementType());
871ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling    Builder.CreateStore(Null, GV);
872032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  }
873253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
874253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Type *RetTy = FlushF->getReturnType();
875253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (RetTy == Type::getVoidTy(*Ctx))
876253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    Builder.CreateRetVoid();
877253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else if (RetTy->isIntegerTy())
878d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    // Used if __llvm_gcov_flush was implicitly declared.
879253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    Builder.CreateRet(ConstantInt::get(RetTy, 0));
880253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else
881d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    report_fatal_error("invalid return type for __llvm_gcov_flush");
882d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
883d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  return FlushF;
884253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling}
885