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#include "llvm/Transforms/Instrumentation.h"
18b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/DenseMap.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/Hashing.h"
20b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/STLExtras.h"
2106cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/ADT/Statistic.h"
22b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringExtras.h"
23b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringMap.h"
24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/UniqueVector.h"
2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugInfo.h"
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DebugLoc.h"
270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h"
2836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstIterator.h"
290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h"
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/IntrinsicInst.h"
310b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h"
32d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Pass.h"
33a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "llvm/Support/CommandLine.h"
3406cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/Debug.h"
3539c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling#include "llvm/Support/FileSystem.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>
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include <memory>
41b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <string>
42b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <utility>
43b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyusing namespace llvm;
44b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
45dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "insert-gcov-profiling"
46dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
47a204ef3168c8804808c716115ba915c89d8849b9Nick Lewyckystatic cl::opt<std::string>
48a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyDefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden,
49a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky                   cl::ValueRequired);
504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<bool> DefaultExitBlockBeforeBody("gcov-exit-block-before-body",
514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                                cl::init(false), cl::Hidden);
52a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
53a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyGCOVOptions GCOVOptions::getDefault() {
54a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  GCOVOptions Options;
55a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.EmitNotes = true;
56a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.EmitData = true;
57a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.UseCfgChecksum = false;
58a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.NoRedZone = false;
59a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  Options.FunctionNamesInData = true;
604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  Options.ExitBlockBeforeBody = DefaultExitBlockBeforeBody;
61a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
62a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (DefaultGCOVVersion.size() != 4) {
63a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") +
64a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky                             DefaultGCOVVersion);
65a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  }
66a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4);
67a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  return Options;
68a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky}
69a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
70b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace {
7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  class GCOVFunction;
7236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
73b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVProfiler : public ModulePass {
74b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  public:
75b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    static char ID;
764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    GCOVProfiler() : GCOVProfiler(GCOVOptions::getDefault()) {}
774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    GCOVProfiler(const GCOVOptions &Opts) : ModulePass(ID), Options(Opts) {
78a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      assert((Options.EmitNotes || Options.EmitData) &&
79a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky             "GCOVProfiler asked to do nothing?");
80a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[0] = Options.Version[3];
81a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[1] = Options.Version[2];
82a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[2] = Options.Version[1];
83a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[3] = Options.Version[0];
84a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky      ReversedVersion[4] = '\0';
85b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
86b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    const char *getPassName() const override {
884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      return "GCOV Profiler";
894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    }
904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  private:
9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool runOnModule(Module &M) override;
93269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
9464a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky    // Create the .gcno files for the Module based on DebugInfo.
9564a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky    void emitProfileNotes();
96b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
970c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky    // Modify the program to track transitions along edges and call into the
980c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky    // profiling runtime to emit .gcda files when run.
99f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    bool emitProfileArcs();
1000c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
101b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Get pointers to the functions in the runtime library.
102b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getStartFileFunc();
10377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    Constant *getIncrementIndirectCounterFunc();
104b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEmitFunctionFunc();
105b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEmitArcsFunc();
106f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu    Constant *getSummaryInfoFunc();
10718764716861243c58a711a92190624dc2f6aafc9Bill Wendling    Constant *getDeleteWriteoutFunctionListFunc();
108d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Constant *getDeleteFlushFunctionListFunc();
109b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEndFileFunc();
110b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // Create or retrieve an i32 state value that is used to represent the
1121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // pred block number for certain non-trivial edges.
1131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *getEdgeStateValue();
1141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
1151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // Produce a table of pointers to counters, by predecessor and successor
1161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // block number.
1171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *buildEdgeLookupTable(Function *F,
1181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         GlobalVariable *Counter,
11964a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky                                         const UniqueVector<BasicBlock *>&Preds,
12064a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky                                         const UniqueVector<BasicBlock*>&Succs);
1211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
122b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Add the function to write out all our counters to the global destructor
123b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // list.
124d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*,
125d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling                                                       MDNode*> >);
126d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
12777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    void insertIndirectCounterIncrement();
128b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    std::string mangleName(const DICompileUnit *CU, const char *NewStem);
130269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
131a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    GCOVOptions Options;
132a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky
133a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky    // Reversed, NUL-terminated copy of Options.Version.
13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    char ReversedVersion[5];
13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Checksum, produced by hash of EdgeDestinations
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SmallVector<uint32_t, 4> FileChecksums;
137a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky
1381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Module *M;
139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    LLVMContext *Ctx;
140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs;
141cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    DenseMap<DISubprogram *, Function *> FnMap;
142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
143b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
144b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
145b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0;
146b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
147b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                "Insert instrumentation for GCOV profiling", false, false)
148b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
149a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyModulePass *llvm::createGCOVProfilerPass(const GCOVOptions &Options) {
150a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  return new GCOVProfiler(Options);
151a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky}
152b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic StringRef getFunctionName(const DISubprogram *SP) {
1540c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (!SP->getLinkageName().empty())
1550c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return SP->getLinkageName();
1560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return SP->getName();
1575d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky}
1585d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky
159b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace {
160b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVRecord {
161b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   protected:
162d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper    static const char *const LinesTag;
163d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper    static const char *const FunctionTag;
164d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper    static const char *const BlockTag;
165d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper    static const char *const EdgeTag;
166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    GCOVRecord() = default;
168b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeBytes(const char *Bytes, int Size) {
1701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      os->write(Bytes, Size);
171b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void write(uint32_t i) {
1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(reinterpret_cast<char*>(&i), 4);
175b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
176b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
177b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Returns the length measured in 4-byte blocks that will be used to
178b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // represent this string in a GCOV file
179619850cb3161733e9284ff3bf9a68d1a3b76f0b4Craig Topper    static unsigned lengthOfGCOVString(StringRef s) {
180b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
18117df2c3240837b4382898ead8c3ead407a338520Nick Lewycky      // padding out to the next 4-byte word. The length is measured in 4-byte
18217df2c3240837b4382898ead8c3ead407a338520Nick Lewycky      // words including padding, not bytes of actual string.
183d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky      return (s.size() / 4) + 1;
184b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
185b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeGCOVString(StringRef s) {
1871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Len = lengthOfGCOVString(s);
1881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Len);
1891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(s.data(), s.size());
190b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
191b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Write 1 to 4 bytes of NUL padding.
1927a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      assert((unsigned)(4 - (s.size() % 4)) > 0);
1937a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      assert((unsigned)(4 - (s.size() % 4)) <= 4);
1947a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      writeBytes("\0\0\0\0", 4 - (s.size() % 4));
195b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
196b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
197b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    raw_ostream *os;
198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
199d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper  const char *const GCOVRecord::LinesTag = "\0\0\x45\x01";
200d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper  const char *const GCOVRecord::FunctionTag = "\0\0\0\1";
201d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper  const char *const GCOVRecord::BlockTag = "\0\0\x41\x01";
202d6d6a97c3c41395dfed46572b69fb6a5d67a5a8bCraig Topper  const char *const GCOVRecord::EdgeTag = "\0\0\x43\x01";
203b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
204b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVFunction;
205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVBlock;
206b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
207b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // Constructed only by requesting it from a GCOVBlock, this object stores a
20816c19a155c65fd41865562fe4e678ef32728510bDevang Patel  // list of line numbers and a single filename, representing lines that belong
20916c19a155c65fd41865562fe4e678ef32728510bDevang Patel  // to the block.
210b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVLines : public GCOVRecord {
211b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
2121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void addLine(uint32_t Line) {
213c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      assert(Line != 0 && "Line zero is not a valid real line number.");
2141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      Lines.push_back(Line);
215b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
216b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
217619850cb3161733e9284ff3bf9a68d1a3b76f0b4Craig Topper    uint32_t length() const {
218bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      // Here 2 = 1 for string length + 1 for '0' id#.
21916c19a155c65fd41865562fe4e678ef32728510bDevang Patel      return lengthOfGCOVString(Filename) + 2 + Lines.size();
220b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
221b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
22216c19a155c65fd41865562fe4e678ef32728510bDevang Patel    void writeOut() {
22316c19a155c65fd41865562fe4e678ef32728510bDevang Patel      write(0);
22416c19a155c65fd41865562fe4e678ef32728510bDevang Patel      writeGCOVString(Filename);
22516c19a155c65fd41865562fe4e678ef32728510bDevang Patel      for (int i = 0, e = Lines.size(); i != e; ++i)
22616c19a155c65fd41865562fe4e678ef32728510bDevang Patel        write(Lines[i]);
22716c19a155c65fd41865562fe4e678ef32728510bDevang Patel    }
228b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    GCOVLines(StringRef F, raw_ostream *os)
23016c19a155c65fd41865562fe4e678ef32728510bDevang Patel      : Filename(F) {
231b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
234680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel   private:
23516c19a155c65fd41865562fe4e678ef32728510bDevang Patel    StringRef Filename;
2361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    SmallVector<uint32_t, 32> Lines;
237b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
238b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
239c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky
240b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // Represent a basic block in GCOV. Each block has a unique number in the
241b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // function, number of lines belonging to each block, and a set of edges to
242b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // other blocks.
243b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVBlock : public GCOVRecord {
244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
24568155d31cd0175be89e26ee68387cb411fca537bDevang Patel    GCOVLines &getFile(StringRef Filename) {
2461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      GCOVLines *&Lines = LinesByFile[Filename];
2471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      if (!Lines) {
24816c19a155c65fd41865562fe4e678ef32728510bDevang Patel        Lines = new GCOVLines(Filename, os);
249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
2501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *Lines;
251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
252b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void addEdge(GCOVBlock &Successor) {
2541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      OutEdges.push_back(&Successor);
255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeOut() {
2581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Len = 3;
259c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      SmallVector<StringMapEntry<GCOVLines *> *, 32> SortedLinesByFile;
2601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
2611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = LinesByFile.end(); I != E; ++I) {
26216c19a155c65fd41865562fe4e678ef32728510bDevang Patel        Len += I->second->length();
263c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky        SortedLinesByFile.push_back(&*I);
264b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
265b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(LinesTag, 4);
2671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Len);
2681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Number);
269c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky
27036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::sort(SortedLinesByFile.begin(), SortedLinesByFile.end(),
27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                [](StringMapEntry<GCOVLines *> *LHS,
27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                   StringMapEntry<GCOVLines *> *RHS) {
27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return LHS->getKey() < RHS->getKey();
27436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      });
2756227d5c690504c7ada5780c00a635b282c46e275Craig Topper      for (SmallVectorImpl<StringMapEntry<GCOVLines *> *>::iterator
276c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky               I = SortedLinesByFile.begin(), E = SortedLinesByFile.end();
27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           I != E; ++I)
278c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky        (*I)->getValue()->writeOut();
2791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(0);
2801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(0);
281b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
282b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
283b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    ~GCOVBlock() {
2841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      DeleteContainerSeconds(LinesByFile);
285b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
286b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
287ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    GCOVBlock(const GCOVBlock &RHS) : GCOVRecord(RHS), Number(RHS.Number) {
288ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Only allow copy before edges and lines have been added. After that,
289ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // there are inter-block pointers (eg: edges) that won't take kindly to
290ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // blocks being copied or moved around.
291ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      assert(LinesByFile.empty());
292ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      assert(OutEdges.empty());
293ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
294ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
295b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
296b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    friend class GCOVFunction;
297b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock(uint32_t Number, raw_ostream *os)
2991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        : Number(Number) {
300b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
301b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
302b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
3031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    uint32_t Number;
3041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    StringMap<GCOVLines *> LinesByFile;
3051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    SmallVector<GCOVBlock *, 4> OutEdges;
306b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
307b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
308b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // A function has a unique identifier, a checksum (we leave as zero) and a
309b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // set of blocks and a map of edges between blocks. This is the only GCOV
310b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // object users can construct, the blocks and lines will be rooted here.
311b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVFunction : public GCOVRecord {
312b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
313cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar     GCOVFunction(const DISubprogram *SP, Function *F, raw_ostream *os,
314cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                  uint32_t Ident, bool UseCfgChecksum, bool ExitBlockBeforeBody)
315ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines         : SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0),
316ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines           ReturnBlock(1, os) {
317b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
318b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n");
320ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
321b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      uint32_t i = 0;
322ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      for (auto &BB : *F) {
3234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        // Skip index 1 if it's assigned to the ReturnBlock.
3244c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        if (i == 1 && ExitBlockBeforeBody)
3254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar          ++i;
3264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        Blocks.insert(std::make_pair(&BB, GCOVBlock(i++, os)));
327b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
3284c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (!ExitBlockBeforeBody)
3294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar        ReturnBlock.Number = i;
3301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
33136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::string FunctionNameAndLine;
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      raw_string_ostream FNLOS(FunctionNameAndLine);
3330c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      FNLOS << getFunctionName(SP) << SP->getLine();
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FNLOS.flush();
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      FuncChecksum = hash_value(FunctionNameAndLine);
336b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
337b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
3381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock &getBlock(BasicBlock *BB) {
339ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return Blocks.find(BB)->second;
340b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
341b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
3421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock &getReturnBlock() {
343ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return ReturnBlock;
344a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky    }
345a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky
34636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::string getEdgeDestinations() {
34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::string EdgeDestinations;
34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      raw_string_ostream EDOS(EdgeDestinations);
34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Function *F = Blocks.begin()->first->getParent();
350cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      for (BasicBlock &I : *F) {
351cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        GCOVBlock &Block = getBlock(&I);
35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        for (int i = 0, e = Block.OutEdges.size(); i != e; ++i)
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          EDOS << Block.OutEdges[i]->Number;
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return EdgeDestinations;
35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t getFuncChecksum() {
35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return FuncChecksum;
36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void setCfgChecksum(uint32_t Checksum) {
36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CfgChecksum = Checksum;
36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeOut() {
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      writeBytes(FunctionTag, 4);
36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(getFunctionName(SP)) +
3690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                          1 + lengthOfGCOVString(SP->getFilename()) + 1;
37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (UseCfgChecksum)
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ++BlockLen;
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      write(BlockLen);
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      write(Ident);
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      write(FuncChecksum);
37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (UseCfgChecksum)
37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        write(CfgChecksum);
37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      writeGCOVString(getFunctionName(SP));
3780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      writeGCOVString(SP->getFilename());
3790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      write(SP->getLine());
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
381b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit count of blocks.
3821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(BlockTag, 4);
3831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Blocks.size() + 1);
3841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
3851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(0);  // No flags on our blocks.
386b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
387bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      DEBUG(dbgs() << Blocks.size() << " blocks.\n");
388b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
389b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit edges between blocks.
390c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      if (Blocks.empty()) return;
391c4e6b540f05932eea37ca10b6c1fded522777954Nick Lewycky      Function *F = Blocks.begin()->first->getParent();
392cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      for (BasicBlock &I : *F) {
393cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        GCOVBlock &Block = getBlock(&I);
3941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        if (Block.OutEdges.empty()) continue;
3951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
3961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        writeBytes(EdgeTag, 4);
3971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(Block.OutEdges.size() * 2 + 1);
3981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(Block.Number);
3991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
400bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number
401bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky                       << "\n");
4021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(Block.OutEdges[i]->Number);
4031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(0);  // no flags
404b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
405b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
406b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
407b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit lines for each block.
408cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      for (BasicBlock &I : *F)
409cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        getBlock(&I).writeOut();
410b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
411b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
412b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
4136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar     const DISubprogram *SP;
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t Ident;
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t FuncChecksum;
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool UseCfgChecksum;
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    uint32_t CfgChecksum;
418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    DenseMap<BasicBlock *, GCOVBlock> Blocks;
419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    GCOVBlock ReturnBlock;
420b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
421b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
422b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
4236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstd::string GCOVProfiler::mangleName(const DICompileUnit *CU,
4246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                     const char *NewStem) {
425269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky  if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
426269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
427269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      MDNode *N = GCov->getOperand(i);
428269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      if (N->getNumOperands() != 2) continue;
429fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
430269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1));
431fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      if (!GCovFile || !CompileUnit) continue;
432fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      if (CompileUnit == CU) {
4336e5190c193f6267893daf6943af88e95039e739cBill Wendling        SmallString<128> Filename = GCovFile->getString();
4346e5190c193f6267893daf6943af88e95039e739cBill Wendling        sys::path::replace_extension(Filename, NewStem);
4356e5190c193f6267893daf6943af88e95039e739cBill Wendling        return Filename.str();
436fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      }
437269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    }
438269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky  }
439fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky
4400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  SmallString<128> Filename = CU->getFilename();
441fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky  sys::path::replace_extension(Filename, NewStem);
44239c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  StringRef FName = sys::path::filename(Filename);
44339c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  SmallString<128> CurPath;
44439c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  if (sys::fs::current_path(CurPath)) return FName;
4450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  sys::path::append(CurPath, FName);
44639c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling  return CurPath.str();
447269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky}
448269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
4490c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) {
4501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  this->M = &M;
4510c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky  Ctx = &M.getContext();
4520c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
453cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  FnMap.clear();
454cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (Function &F : M) {
455cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (DISubprogram *SP = F.getSubprogram())
456cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      FnMap[SP] = &F;
457cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
458cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
459a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.EmitNotes) emitProfileNotes();
460a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.EmitData) return emitProfileArcs();
461a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky  return false;
4620c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky}
4630c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
464dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool functionHasLines(Function *F) {
465dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Check whether this function actually has any source lines. Not only
466dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // do these waste space, they also can crash gcov.
467dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
468dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
469dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines         I != IE; ++I) {
470c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // Debug intrinsic locations correspond to the location of the
471c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // declaration, not necessarily any statements or expressions.
472c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (isa<DbgInfoIntrinsic>(I)) continue;
473c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      const DebugLoc &Loc = I->getDebugLoc();
4750c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      if (!Loc)
4760c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        continue;
477c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
478c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      // Artificial lines such as calls to the global constructors.
4794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      if (Loc.getLine() == 0) continue;
480c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
481c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return true;
482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
48764a0a33307723957bf2f15e3181a290853c6f833Nick Lewyckyvoid GCOVProfiler::emitProfileNotes() {
488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
489bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky  if (!CU_Nodes) return;
490bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
491bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
492bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // Each compile unit gets its own .gcno file. This means that whether we run
493bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // this pass over the original .o's as they're produced, or run it after
494bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // LTO, we'll generate the same .gcno files.
495bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
4966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
49737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    std::error_code EC;
49837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    raw_fd_ostream out(mangleName(CU, "gcno"), EC, sys::fs::F_None);
49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    std::string EdgeDestinations;
500bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
50137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    unsigned FunctionIdent = 0;
5020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    for (auto *SP : CU->getSubprograms()) {
503cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Function *F = FnMap[SP];
504bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      if (!F) continue;
505dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!functionHasLines(F)) continue;
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // gcov expects every function to start with an entry block that has a
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // single successor, so split the entry block to make sure of that.
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BasicBlock &EntryBlock = F->getEntryBlock();
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      BasicBlock::iterator It = EntryBlock.begin();
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      while (isa<AllocaInst>(*It) || isa<DbgInfoIntrinsic>(*It))
51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        ++It;
51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      EntryBlock.splitBasicBlock(It);
51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
515cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Funcs.push_back(make_unique<GCOVFunction>(SP, F, &out, FunctionIdent++,
5164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                                Options.UseCfgChecksum,
5174c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                                                Options.ExitBlockBeforeBody));
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      GCOVFunction &Func = *Funcs.back();
519bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
520bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
521cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        GCOVBlock &Block = Func.getBlock(&*BB);
522bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        TerminatorInst *TI = BB->getTerminator();
523bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        if (int successors = TI->getNumSuccessors()) {
524bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          for (int i = 0; i != successors; ++i) {
525dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
526f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
527bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        } else if (isa<ReturnInst>(TI)) {
528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Block.addEdge(Func.getReturnBlock());
529bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        }
530bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
531bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        uint32_t Line = 0;
532bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
533bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky             I != IE; ++I) {
534c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          // Debug intrinsic locations correspond to the location of the
535c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          // declaration, not necessarily any statements or expressions.
536c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          if (isa<DbgInfoIntrinsic>(I)) continue;
537c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
538bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          const DebugLoc &Loc = I->getDebugLoc();
5390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          if (!Loc)
5400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            continue;
541c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
542c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          // Artificial lines such as calls to the global constructors.
543c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines          if (Loc.getLine() == 0) continue;
544c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
545bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          if (Line == Loc.getLine()) continue;
546bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          Line = Loc.getLine();
5470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          if (SP != getDISubprogram(Loc.getScope()))
5480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            continue;
549bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
5500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          GCOVLines &Lines = Block.getFile(SP->getFilename());
551bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          Lines.addLine(Loc.getLine());
552b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
553b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      EdgeDestinations += Func.getEdgeDestinations();
555b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    FileChecksums.push_back(hash_value(EdgeDestinations));
55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    out.write("oncg", 4);
55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    out.write(ReversedVersion, 4);
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    out.write(reinterpret_cast<char*>(&FileChecksums.back()), 4);
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    for (auto &Func : Funcs) {
56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Func->setCfgChecksum(FileChecksums.back());
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Func->writeOut();
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
567bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    out.write("\0\0\0\0\0\0\0\0", 8);  // EOF
568bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    out.close();
569b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
570b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
571b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
572f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() {
573f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
574f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (!CU_Nodes) return false;
575f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool Result = false;
57777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  bool InsertIndCounterIncrCode = false;
578f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
5796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
580f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
5810c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    for (auto *SP : CU->getSubprograms()) {
582cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Function *F = FnMap[SP];
583f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!F) continue;
584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      if (!functionHasLines(F)) continue;
585f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!Result) Result = true;
586f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      unsigned Edges = 0;
587f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
588f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        TerminatorInst *TI = BB->getTerminator();
589f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (isa<ReturnInst>(TI))
590f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          ++Edges;
591f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        else
592f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Edges += TI->getNumSuccessors();
593f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      }
59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
595f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      ArrayType *CounterTy =
5961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
597f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      GlobalVariable *Counters =
5981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        new GlobalVariable(*M, CounterTy, false,
599b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                           GlobalValue::InternalLinkage,
6001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                           Constant::getNullValue(CounterTy),
601ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg                           "__llvm_gcov_ctr");
6020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      CountersBySP.push_back(std::make_pair(Counters, SP));
60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
604f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      UniqueVector<BasicBlock *> ComplexEdgePreds;
605f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      UniqueVector<BasicBlock *> ComplexEdgeSuccs;
60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
607f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      unsigned Edge = 0;
608f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
609f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        TerminatorInst *TI = BB->getTerminator();
610f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
611f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (Successors) {
612f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          if (Successors == 1) {
613cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar            IRBuilder<> Builder(&*BB->getFirstInsertionPt());
614f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
615f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                                                                Edge);
616f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Count = Builder.CreateLoad(Counter);
617bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky            Count = Builder.CreateAdd(Count, Builder.getInt64(1));
618f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Builder.CreateStore(Count, Counter);
619f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
620f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling            IRBuilder<> Builder(BI);
621bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky            Value *Sel = Builder.CreateSelect(BI->getCondition(),
622bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky                                              Builder.getInt64(Edge),
623bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky                                              Builder.getInt64(Edge + 1));
624f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            SmallVector<Value *, 2> Idx;
625bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky            Idx.push_back(Builder.getInt64(0));
626f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Idx.push_back(Sel);
6270c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar            Value *Counter = Builder.CreateInBoundsGEP(Counters->getValueType(),
6280c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                                       Counters, Idx);
629f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Count = Builder.CreateLoad(Counter);
630bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky            Count = Builder.CreateAdd(Count, Builder.getInt64(1));
631f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Builder.CreateStore(Count, Counter);
632f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else {
633cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar            ComplexEdgePreds.insert(&*BB);
634f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            for (int i = 0; i != Successors; ++i)
635f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel              ComplexEdgeSuccs.insert(TI->getSuccessor(i));
636f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
637f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling
638f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Edge += Successors;
639b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
640b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
642f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!ComplexEdgePreds.empty()) {
643f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *EdgeTable =
6441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          buildEdgeLookupTable(F, Counters,
6451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                               ComplexEdgePreds, ComplexEdgeSuccs);
646f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *EdgeState = getEdgeStateValue();
64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
648f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
649cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          IRBuilder<> Builder(&*ComplexEdgePreds[i + 1]->getFirstInsertionPt());
650bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky          Builder.CreateStore(Builder.getInt32(i), EdgeState);
651f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        }
652f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling
653f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
654f675b3c6444af3e2f547b050eedb8a12584110efBill Wendling          // Call runtime to perform increment.
655cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          IRBuilder<> Builder(&*ComplexEdgeSuccs[i + 1]->getFirstInsertionPt());
656f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Value *CounterPtrArray =
6571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky            Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
6581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                               i * ComplexEdgePreds.size());
659c7a884040e4ec7795515978a94803894ad08c4caBill Wendling
660c7a884040e4ec7795515978a94803894ad08c4caBill Wendling          // Build code to increment the counter.
66177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling          InsertIndCounterIncrCode = true;
6626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar          Builder.CreateCall(getIncrementIndirectCounterFunc(),
6636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                             {EdgeState, CounterPtrArray});
664f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        }
665b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
666b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
6674a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling
668d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *WriteoutF = insertCounterWriteout(CountersBySP);
669d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *FlushF = insertFlush(CountersBySP);
670d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
671d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    // Create a small bit of code that registers the "__llvm_gcov_writeout" to
67218764716861243c58a711a92190624dc2f6aafc9Bill Wendling    // be executed at exit and the "__llvm_gcov_flush" function to be executed
67318764716861243c58a711a92190624dc2f6aafc9Bill Wendling    // when "__gcov_flush" is called.
674d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
675d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
676d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling                                   "__llvm_gcov_init", M);
677d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    F->setUnnamedAddr(true);
678d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    F->setLinkage(GlobalValue::InternalLinkage);
679d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    F->addFnAttr(Attribute::NoInline);
680d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    if (Options.NoRedZone)
681d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling      F->addFnAttr(Attribute::NoRedZone);
682d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
683d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F);
684d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    IRBuilder<> Builder(BB);
685d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
686d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
6878640c6a5227b75666e02424e2181289692138348Bill Wendling    Type *Params[] = {
6888640c6a5227b75666e02424e2181289692138348Bill Wendling      PointerType::get(FTy, 0),
6898640c6a5227b75666e02424e2181289692138348Bill Wendling      PointerType::get(FTy, 0)
6908640c6a5227b75666e02424e2181289692138348Bill Wendling    };
6918640c6a5227b75666e02424e2181289692138348Bill Wendling    FTy = FunctionType::get(Builder.getVoidTy(), Params, false);
6928640c6a5227b75666e02424e2181289692138348Bill Wendling
693d7da59004fc9262f33c96ad2736b36ff1235ce7bYuchen Wu    // Initialize the environment and register the local writeout and flush
6948640c6a5227b75666e02424e2181289692138348Bill Wendling    // functions.
6958640c6a5227b75666e02424e2181289692138348Bill Wendling    Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy);
6966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Builder.CreateCall(GCOVInit, {WriteoutF, FlushF});
697d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    Builder.CreateRetVoid();
698d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
699d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    appendToGlobalCtors(*M, F, 0);
700b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
70177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
70277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  if (InsertIndCounterIncrCode)
70377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    insertIndirectCounterIncrement();
70477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
705f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  return Result;
706b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
707b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
7081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it
7091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update.
7101790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable(
7111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Function *F,
7121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *Counters,
7131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    const UniqueVector<BasicBlock *> &Preds,
7141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    const UniqueVector<BasicBlock *> &Succs) {
7151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // TODO: support invoke, threads. We rely on the fact that nothing can modify
7161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // the whole-Module pred edge# between the time we set it and the time we next
7171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // read it. Threads and invoke make this untrue.
7181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
7191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]].
7209e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  size_t TableSize = Succs.size() * Preds.size();
721db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
7229e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize);
7231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  std::unique_ptr<Constant * []> EdgeTable(new Constant *[TableSize]);
7251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  Constant *NullValue = Constant::getNullValue(Int64PtrTy);
7269e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  for (size_t i = 0; i != TableSize; ++i)
7271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    EdgeTable[i] = NullValue;
7281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
7291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  unsigned Edge = 0;
7301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
7311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    TerminatorInst *TI = BB->getTerminator();
7321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
7337a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky    if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) {
7341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (int i = 0; i != Successors; ++i) {
7351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        BasicBlock *Succ = TI->getSuccessor(i);
736bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky        IRBuilder<> Builder(Succ);
737bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky        Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
7381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                                            Edge + i);
739cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        EdgeTable[((Succs.idFor(Succ) - 1) * Preds.size()) +
740cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                  (Preds.idFor(&*BB) - 1)] = cast<Constant>(Counter);
7411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      }
7421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    }
7431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Edge += Successors;
7441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  }
7451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
7461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  GlobalVariable *EdgeTableGV =
7471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      new GlobalVariable(
7481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          *M, EdgeTableTy, true, GlobalValue::InternalLinkage,
74937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          ConstantArray::get(EdgeTableTy,
75037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             makeArrayRef(&EdgeTable[0],TableSize)),
7511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          "__llvm_gcda_edge_table");
7521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  EdgeTableGV->setUnnamedAddr(true);
7531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return EdgeTableGV;
7541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
7551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
756b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() {
757d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky  Type *Args[] = {
758d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky    Type::getInt8PtrTy(*Ctx),  // const char *orig_filename
759d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky    Type::getInt8PtrTy(*Ctx),  // const char version[4]
76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Type::getInt32Ty(*Ctx),    // uint32_t checksum
761d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky  };
762d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
7631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
7641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
7651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
76677b19134104c3e96424dc010f2b69c3faf580e68Bill WendlingConstant *GCOVProfiler::getIncrementIndirectCounterFunc() {
76777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Type *Int32Ty = Type::getInt32Ty(*Ctx);
768c7a884040e4ec7795515978a94803894ad08c4caBill Wendling  Type *Int64Ty = Type::getInt64Ty(*Ctx);
76977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Type *Args[] = {
770b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow    Int32Ty->getPointerTo(),                // uint32_t *predecessor
771b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow    Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters
77277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  };
77377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
77477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy);
775b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
776b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
777b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() {
77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Type *Args[] = {
7795409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    Type::getInt32Ty(*Ctx),    // uint32_t ident
7805409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    Type::getInt8PtrTy(*Ctx),  // const char *function_name
78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Type::getInt32Ty(*Ctx),    // uint32_t func_checksum
78217d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky    Type::getInt8Ty(*Ctx),     // uint8_t use_extra_checksum
78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Type::getInt32Ty(*Ctx),    // uint32_t cfg_checksum
7845409a188328d9de3755febc23558d4fc1797d04eNick Lewycky  };
785c7a884040e4ec7795515978a94803894ad08c4caBill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
7861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
787b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
788b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
789b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() {
7905fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Args[] = {
791b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Type::getInt32Ty(*Ctx),     // uint32_t num_counters
792b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Type::getInt64PtrTy(*Ctx),  // uint64_t *counters
793b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
794d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
7951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
796b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
797b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
798f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen WuConstant *GCOVProfiler::getSummaryInfoFunc() {
799f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
800f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu  return M->getOrInsertFunction("llvm_gcda_summary_info", FTy);
801f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu}
802f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu
80318764716861243c58a711a92190624dc2f6aafc9Bill WendlingConstant *GCOVProfiler::getDeleteWriteoutFunctionListFunc() {
80418764716861243c58a711a92190624dc2f6aafc9Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
80518764716861243c58a711a92190624dc2f6aafc9Bill Wendling  return M->getOrInsertFunction("llvm_delete_writeout_function_list", FTy);
80618764716861243c58a711a92190624dc2f6aafc9Bill Wendling}
80718764716861243c58a711a92190624dc2f6aafc9Bill Wendling
808d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingConstant *GCOVProfiler::getDeleteFlushFunctionListFunc() {
809d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
810d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  return M->getOrInsertFunction("llvm_delete_flush_function_list", FTy);
811d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling}
812d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
813b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() {
814db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
8151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
816b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
817b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
8181790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() {
8191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred");
8201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  if (!GV) {
8211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false,
8221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            GlobalValue::InternalLinkage,
8231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            ConstantInt::get(Type::getInt32Ty(*Ctx),
8241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                             0xffffffff),
8251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            "__llvm_gcov_global_state_pred");
8261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GV->setUnnamedAddr(true);
8271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  }
8281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return GV;
8291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
830b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
831d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingFunction *GCOVProfiler::insertCounterWriteout(
83221b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling    ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
833253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
834253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
835253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (!WriteoutF)
836253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
837253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling                                 "__llvm_gcov_writeout", M);
838b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  WriteoutF->setUnnamedAddr(true);
839034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  WriteoutF->addFnAttr(Attribute::NoInline);
840a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.NoRedZone)
841034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    WriteoutF->addFnAttr(Attribute::NoRedZone);
842253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
843253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
8441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  IRBuilder<> Builder(BB);
845b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
846b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *StartFile = getStartFileFunc();
847b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EmitFunction = getEmitFunctionFunc();
848b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EmitArcs = getEmitArcsFunc();
849f42264e7e4cb947bcd1ff7dd48fd0ba4e9fbbf9fYuchen Wu  Constant *SummaryInfo = getSummaryInfoFunc();
850b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EndFile = getEndFileFunc();
851b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
852f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
853f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (CU_Nodes) {
854f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
8556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i));
856f2a2806baf3763d551a9f361124b608b2eed66faBill Wendling      std::string FilenameGcda = mangleName(CU, "gcda");
85736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i];
8586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Builder.CreateCall(StartFile,
8596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                         {Builder.CreateGlobalStringPtr(FilenameGcda),
86036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          Builder.CreateGlobalStringPtr(ReversedVersion),
8616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                          Builder.getInt32(CfgChecksum)});
8628fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky      for (unsigned j = 0, e = CountersBySP.size(); j != e; ++j) {
8636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        auto *SP = cast_or_null<DISubprogram>(CountersBySP[j].second);
86436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum();
8656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Builder.CreateCall(
8666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar            EmitFunction,
8676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar            {Builder.getInt32(j),
8686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar             Options.FunctionNamesInData
8696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                 ? Builder.CreateGlobalStringPtr(getFunctionName(SP))
8706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                 : Constant::getNullValue(Builder.getInt8PtrTy()),
8716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar             Builder.getInt32(FuncChecksum),
8726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar             Builder.getInt8(Options.UseCfgChecksum),
8736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar             Builder.getInt32(CfgChecksum)});
87417d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky
8758fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky        GlobalVariable *GV = CountersBySP[j].first;
876f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        unsigned Arcs =
877b1928704201034c785a26296a49f69355eb56a05Nick Lewycky          cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
8786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        Builder.CreateCall(EmitArcs, {Builder.getInt32(Arcs),
8796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                      Builder.CreateConstGEP2_64(GV, 0, 0)});
880f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      }
8816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Builder.CreateCall(SummaryInfo, {});
8826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Builder.CreateCall(EndFile, {});
883b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
884b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
885b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
8864a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  Builder.CreateRetVoid();
887d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  return WriteoutF;
888b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
88977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
89077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendlingvoid GCOVProfiler::insertIndirectCounterIncrement() {
89177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Function *Fn =
89277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
89377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Fn->setUnnamedAddr(true);
89477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Fn->setLinkage(GlobalValue::InternalLinkage);
895034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  Fn->addFnAttr(Attribute::NoInline);
896a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.NoRedZone)
897034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    Fn->addFnAttr(Attribute::NoRedZone);
89877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
89977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // Create basic blocks for function.
90077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn);
90177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  IRBuilder<> Builder(BB);
90277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
90377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn);
90477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn);
90577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn);
90677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
90777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // uint32_t pred = *predecessor;
90877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // if (pred == 0xffffffff) return;
909cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Argument *Arg = &*Fn->arg_begin();
91077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Arg->setName("predecessor");
91177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Pred = Builder.CreateLoad(Arg, "pred");
912bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky  Value *Cond = Builder.CreateICmpEQ(Pred, Builder.getInt32(0xffffffff));
91377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BranchInst::Create(Exit, PredNotNegOne, Cond, BB);
91477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
91577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(PredNotNegOne);
91677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
91777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // uint64_t *counter = counters[pred];
91877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // if (!counter) return;
919bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky  Value *ZExtPred = Builder.CreateZExt(Pred, Builder.getInt64Ty());
920cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Arg = &*std::next(Fn->arg_begin());
92177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Arg->setName("counters");
9220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  Value *GEP = Builder.CreateGEP(Type::getInt64PtrTy(*Ctx), Arg, ZExtPred);
92377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Counter = Builder.CreateLoad(GEP, "counter");
92458591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky  Cond = Builder.CreateICmpEQ(Counter,
92558591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky                              Constant::getNullValue(
92658591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky                                  Builder.getInt64Ty()->getPointerTo()));
92777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateCondBr(Cond, Exit, CounterEnd);
92877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
92977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // ++*counter;
93077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(CounterEnd);
93177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter),
932bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky                                 Builder.getInt64(1));
93377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateStore(Add, Counter);
93477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateBr(Exit);
93577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
93677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // Fill in the exit block.
93777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(Exit);
93877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateRetVoid();
93977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling}
940253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
941d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingFunction *GCOVProfiler::
942253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill WendlinginsertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
943253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
944d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  Function *FlushF = M->getFunction("__llvm_gcov_flush");
945253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (!FlushF)
946253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
947d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling                              "__llvm_gcov_flush", M);
948253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else
949253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    FlushF->setLinkage(GlobalValue::InternalLinkage);
950253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FlushF->setUnnamedAddr(true);
951034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  FlushF->addFnAttr(Attribute::NoInline);
952a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky  if (Options.NoRedZone)
953034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    FlushF->addFnAttr(Attribute::NoRedZone);
954253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
955253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
956253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
957253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  // Write out the current counters.
958253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout");
959253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  assert(WriteoutF && "Need to create the writeout function first!");
960253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
961253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  IRBuilder<> Builder(Entry);
9626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Builder.CreateCall(WriteoutF, {});
963253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
964032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  // Zero out the counters.
965032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator
966032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling         I = CountersBySP.begin(), E = CountersBySP.end();
967032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling       I != E; ++I) {
968032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling    GlobalVariable *GV = I->first;
969032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling    Constant *Null = Constant::getNullValue(GV->getType()->getElementType());
970ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling    Builder.CreateStore(Null, GV);
971032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  }
972253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
973253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Type *RetTy = FlushF->getReturnType();
974253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (RetTy == Type::getVoidTy(*Ctx))
975253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    Builder.CreateRetVoid();
976253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else if (RetTy->isIntegerTy())
977d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    // Used if __llvm_gcov_flush was implicitly declared.
978253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    Builder.CreateRet(ConstantInt::get(RetTy, 0));
979253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else
980d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling    report_fatal_error("invalid return type for __llvm_gcov_flush");
981d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling
982d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling  return FlushF;
983253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling}
984