GCOVProfiling.cpp revision 034b94b17006f51722886b0f2283fb6fb19aca1f
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"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "ProfilingUtils.h"
21b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/DenseMap.h"
22b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/STLExtras.h"
2306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/ADT/Statistic.h"
24b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringExtras.h"
25b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/StringMap.h"
26b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include "llvm/ADT/UniqueVector.h"
27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/DebugInfo.h"
28d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/IRBuilder.h"
29d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Instructions.h"
30d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Module.h"
31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Pass.h"
3206cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/Debug.h"
3306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/DebugLoc.h"
3406cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/InstIterator.h"
3506cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/PathV2.h"
3606cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/raw_ostream.h"
3706cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Transforms/Utils/ModuleUtils.h"
38b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <string>
39b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <utility>
40b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyusing namespace llvm;
41b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
42b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace {
43b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVProfiler : public ModulePass {
44b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  public:
45b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    static char ID;
46a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    GCOVProfiler()
47bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        : ModulePass(ID), EmitNotes(true), EmitData(true), Use402Format(false),
4808e13e4488cde76fc51f942e773874627a88eeaeBill Wendling          UseExtraChecksum(false), NoRedZone(false) {
49a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
50a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    }
51f209dea96a34f8c3c06e19710e9ff008d4f18c6cRafael Espindola    GCOVProfiler(bool EmitNotes, bool EmitData, bool use402Format,
52f209dea96a34f8c3c06e19710e9ff008d4f18c6cRafael Espindola                 bool useExtraChecksum, bool NoRedZone_)
53f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling        : ModulePass(ID), EmitNotes(EmitNotes), EmitData(EmitData),
54f209dea96a34f8c3c06e19710e9ff008d4f18c6cRafael Espindola          Use402Format(use402Format), UseExtraChecksum(useExtraChecksum),
55f209dea96a34f8c3c06e19710e9ff008d4f18c6cRafael Espindola          NoRedZone(NoRedZone_) {
56a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky      assert((EmitNotes || EmitData) && "GCOVProfiler asked to do nothing?");
57b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      initializeGCOVProfilerPass(*PassRegistry::getPassRegistry());
58b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
59b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    virtual const char *getPassName() const {
60b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      return "GCOV Profiler";
61b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
62b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  private:
63269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    bool runOnModule(Module &M);
64269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
65b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Create the GCNO files for the Module based on DebugInfo.
66f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    void emitGCNO();
67b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
680c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky    // Modify the program to track transitions along edges and call into the
690c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky    // profiling runtime to emit .gcda files when run.
70f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    bool emitProfileArcs();
710c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
72b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Get pointers to the functions in the runtime library.
73b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getStartFileFunc();
7477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    Constant *getIncrementIndirectCounterFunc();
75b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEmitFunctionFunc();
76b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEmitArcsFunc();
77b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Constant *getEndFileFunc();
78b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // Create or retrieve an i32 state value that is used to represent the
801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // pred block number for certain non-trivial edges.
811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *getEdgeStateValue();
821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // Produce a table of pointers to counters, by predecessor and successor
841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    // block number.
851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *buildEdgeLookupTable(Function *F,
861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         GlobalVariable *Counter,
871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         const UniqueVector<BasicBlock *> &Preds,
881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                         const UniqueVector<BasicBlock *> &Succs);
891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
90b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Add the function to write out all our counters to the global destructor
91b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // list.
9221b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling    void insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
9377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    void insertIndirectCounterIncrement();
94253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    void insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >);
95b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
9673996f44070df026e4d969b1b68461a70ebb3993Bill Wendling    std::string mangleName(DICompileUnit CU, const char *NewStem);
97269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
98a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    bool EmitNotes;
99a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky    bool EmitData;
100f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling    bool Use402Format;
101bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    bool UseExtraChecksum;
10208e13e4488cde76fc51f942e773874627a88eeaeBill Wendling    bool NoRedZone;
103a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky
1041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Module *M;
105b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    LLVMContext *Ctx;
106b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
107b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
108b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
109b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0;
110b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling",
111b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                "Insert instrumentation for GCOV profiling", false, false)
112b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
113f5c95b889f270f170ff4f6a24b082be5bb68296eBill WendlingModulePass *llvm::createGCOVProfilerPass(bool EmitNotes, bool EmitData,
1147c0674100443b4115d2fd6472e59cd8dcb9cc6d4Nick Lewycky                                         bool Use402Format,
11508e13e4488cde76fc51f942e773874627a88eeaeBill Wendling                                         bool UseExtraChecksum,
11608e13e4488cde76fc51f942e773874627a88eeaeBill Wendling                                         bool NoRedZone) {
11708e13e4488cde76fc51f942e773874627a88eeaeBill Wendling  return new GCOVProfiler(EmitNotes, EmitData, Use402Format, UseExtraChecksum,
11808e13e4488cde76fc51f942e773874627a88eeaeBill Wendling                          NoRedZone);
119a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky}
120b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
121b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace {
122b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVRecord {
123b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   protected:
1241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    static const char *LinesTag;
1251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    static const char *FunctionTag;
1261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    static const char *BlockTag;
1271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    static const char *EdgeTag;
128b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
129b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    GCOVRecord() {}
130b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeBytes(const char *Bytes, int Size) {
1321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      os->write(Bytes, Size);
133b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
134b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void write(uint32_t i) {
1361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(reinterpret_cast<char*>(&i), 4);
137b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // Returns the length measured in 4-byte blocks that will be used to
140b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    // represent this string in a GCOV file
1411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    unsigned lengthOfGCOVString(StringRef s) {
142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs
14317df2c3240837b4382898ead8c3ead407a338520Nick Lewycky      // padding out to the next 4-byte word. The length is measured in 4-byte
14417df2c3240837b4382898ead8c3ead407a338520Nick Lewycky      // words including padding, not bytes of actual string.
145d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky      return (s.size() / 4) + 1;
146b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
147b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeGCOVString(StringRef s) {
1491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Len = lengthOfGCOVString(s);
1501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Len);
1511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(s.data(), s.size());
152b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
153b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Write 1 to 4 bytes of NUL padding.
1547a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      assert((unsigned)(4 - (s.size() % 4)) > 0);
1557a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      assert((unsigned)(4 - (s.size() % 4)) <= 4);
1567a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky      writeBytes("\0\0\0\0", 4 - (s.size() % 4));
157b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
158b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
159b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    raw_ostream *os;
160b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
1611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  const char *GCOVRecord::LinesTag = "\0\0\x45\x01";
1621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  const char *GCOVRecord::FunctionTag = "\0\0\0\1";
1631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  const char *GCOVRecord::BlockTag = "\0\0\x41\x01";
1641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  const char *GCOVRecord::EdgeTag = "\0\0\x43\x01";
165b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVFunction;
167b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVBlock;
168b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
169b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // Constructed only by requesting it from a GCOVBlock, this object stores a
17016c19a155c65fd41865562fe4e678ef32728510bDevang Patel  // list of line numbers and a single filename, representing lines that belong
17116c19a155c65fd41865562fe4e678ef32728510bDevang Patel  // to the block.
172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVLines : public GCOVRecord {
173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void addLine(uint32_t Line) {
1751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      Lines.push_back(Line);
176b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
177b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
1781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    uint32_t length() {
179bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      // Here 2 = 1 for string length + 1 for '0' id#.
18016c19a155c65fd41865562fe4e678ef32728510bDevang Patel      return lengthOfGCOVString(Filename) + 2 + Lines.size();
181b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
182b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
18316c19a155c65fd41865562fe4e678ef32728510bDevang Patel    void writeOut() {
18416c19a155c65fd41865562fe4e678ef32728510bDevang Patel      write(0);
18516c19a155c65fd41865562fe4e678ef32728510bDevang Patel      writeGCOVString(Filename);
18616c19a155c65fd41865562fe4e678ef32728510bDevang Patel      for (int i = 0, e = Lines.size(); i != e; ++i)
18716c19a155c65fd41865562fe4e678ef32728510bDevang Patel        write(Lines[i]);
18816c19a155c65fd41865562fe4e678ef32728510bDevang Patel    }
189b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
19016c19a155c65fd41865562fe4e678ef32728510bDevang Patel    GCOVLines(StringRef F, raw_ostream *os)
19116c19a155c65fd41865562fe4e678ef32728510bDevang Patel      : Filename(F) {
192b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
193b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
194b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
195680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel   private:
19616c19a155c65fd41865562fe4e678ef32728510bDevang Patel    StringRef Filename;
1971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    SmallVector<uint32_t, 32> Lines;
198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // Represent a basic block in GCOV. Each block has a unique number in the
201b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // function, number of lines belonging to each block, and a set of edges to
202b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // other blocks.
203b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVBlock : public GCOVRecord {
204b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
20568155d31cd0175be89e26ee68387cb411fca537bDevang Patel    GCOVLines &getFile(StringRef Filename) {
2061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      GCOVLines *&Lines = LinesByFile[Filename];
2071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      if (!Lines) {
20816c19a155c65fd41865562fe4e678ef32728510bDevang Patel        Lines = new GCOVLines(Filename, os);
209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
2101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *Lines;
211b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
212b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void addEdge(GCOVBlock &Successor) {
2141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      OutEdges.push_back(&Successor);
215b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
216b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeOut() {
2181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Len = 3;
2191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
2201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = LinesByFile.end(); I != E; ++I) {
22116c19a155c65fd41865562fe4e678ef32728510bDevang Patel        Len += I->second->length();
222b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
223b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(LinesTag, 4);
2251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Len);
2261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Number);
2271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(),
22816c19a155c65fd41865562fe4e678ef32728510bDevang Patel               E = LinesByFile.end(); I != E; ++I)
22916c19a155c65fd41865562fe4e678ef32728510bDevang Patel        I->second->writeOut();
2301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(0);
2311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(0);
232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
234b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    ~GCOVBlock() {
2351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      DeleteContainerSeconds(LinesByFile);
236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
237b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
238b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
239b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    friend class GCOVFunction;
240b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock(uint32_t Number, raw_ostream *os)
2421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        : Number(Number) {
243b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
245b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    uint32_t Number;
2471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    StringMap<GCOVLines *> LinesByFile;
2481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    SmallVector<GCOVBlock *, 4> OutEdges;
249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
250b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
251b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // A function has a unique identifier, a checksum (we leave as zero) and a
252b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // set of blocks and a map of edges between blocks. This is the only GCOV
253b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  // object users can construct, the blocks and lines will be rooted here.
254b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  class GCOVFunction : public GCOVRecord {
255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   public:
256bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    GCOVFunction(DISubprogram SP, raw_ostream *os,
257bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky                 bool Use402Format, bool UseExtraChecksum) {
258b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      this->os = os;
259b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
260b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      Function *F = SP.getFunction();
261bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      DEBUG(dbgs() << "Function: " << F->getName() << "\n");
262b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      uint32_t i = 0;
263b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
2641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        Blocks[BB] = new GCOVBlock(i++, os);
265b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
2661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      ReturnBlock = new GCOVBlock(i++, os);
2671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
2681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(FunctionTag, 4);
269f5c95b889f270f170ff4f6a24b082be5bb68296eBill Wendling      uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(SP.getName()) +
2701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          1 + lengthOfGCOVString(SP.getFilename()) + 1;
271bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      if (UseExtraChecksum)
272bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        ++BlockLen;
2731790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(BlockLen);
2741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      uint32_t Ident = reinterpret_cast<intptr_t>((MDNode*)SP);
2751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Ident);
276bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      write(0);  // lineno checksum
277bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      if (UseExtraChecksum)
278bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        write(0);  // cfg checksum
2791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeGCOVString(SP.getName());
2801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeGCOVString(SP.getFilename());
2811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(SP.getLineNumber());
282b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
283b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    ~GCOVFunction() {
2851790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      DeleteContainerSeconds(Blocks);
2861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      delete ReturnBlock;
287b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2891790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock &getBlock(BasicBlock *BB) {
2901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *Blocks[BB];
291b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
292b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
2931790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock &getReturnBlock() {
2941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      return *ReturnBlock;
295a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky    }
296a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky
2971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    void writeOut() {
298b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit count of blocks.
2991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      writeBytes(BlockTag, 4);
3001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      write(Blocks.size() + 1);
3011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (int i = 0, e = Blocks.size() + 1; i != e; ++i) {
3021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(0);  // No flags on our blocks.
303b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
304bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      DEBUG(dbgs() << Blocks.size() << " blocks.\n");
305b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
306b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit edges between blocks.
3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
3081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = Blocks.end(); I != E; ++I) {
3091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        GCOVBlock &Block = *I->second;
3101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        if (Block.OutEdges.empty()) continue;
3111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        writeBytes(EdgeTag, 4);
3131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(Block.OutEdges.size() * 2 + 1);
3141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        write(Block.Number);
3151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) {
316bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number
317bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky                       << "\n");
3181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(Block.OutEdges[i]->Number);
3191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          write(0);  // no flags
320b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
321b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
322b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
323b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      // Emit lines for each block.
3241790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(),
3251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky               E = Blocks.end(); I != E; ++I) {
3261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        I->second->writeOut();
327b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
328b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
329b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
330b1928704201034c785a26296a49f69355eb56a05Nick Lewycky   private:
3311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    DenseMap<BasicBlock *, GCOVBlock *> Blocks;
3321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GCOVBlock *ReturnBlock;
333b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
334b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
335b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
33673996f44070df026e4d969b1b68461a70ebb3993Bill Wendlingstd::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem) {
337269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky  if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
338269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
339269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      MDNode *N = GCov->getOperand(i);
340269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      if (N->getNumOperands() != 2) continue;
341fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0));
342269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky      MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1));
343fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      if (!GCovFile || !CompileUnit) continue;
344fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      if (CompileUnit == CU) {
3456e5190c193f6267893daf6943af88e95039e739cBill Wendling        SmallString<128> Filename = GCovFile->getString();
3466e5190c193f6267893daf6943af88e95039e739cBill Wendling        sys::path::replace_extension(Filename, NewStem);
3476e5190c193f6267893daf6943af88e95039e739cBill Wendling        return Filename.str();
348fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky      }
349269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky    }
350269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky  }
351fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky
3526e5190c193f6267893daf6943af88e95039e739cBill Wendling  SmallString<128> Filename = CU.getFilename();
353fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky  sys::path::replace_extension(Filename, NewStem);
3546e5190c193f6267893daf6943af88e95039e739cBill Wendling  return sys::path::filename(Filename.str());
355269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky}
356269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky
3570c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) {
3581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  this->M = &M;
3590c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky  Ctx = &M.getContext();
3600c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
361f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (EmitNotes) emitGCNO();
362f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (EmitData) return emitProfileArcs();
363a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky  return false;
3640c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky}
3650c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky
366f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelvoid GCOVProfiler::emitGCNO() {
367f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
368bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky  if (!CU_Nodes) return;
369bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
370bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
371bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // Each compile unit gets its own .gcno file. This means that whether we run
372bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // this pass over the original .o's as they're produced, or run it after
373bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    // LTO, we'll generate the same .gcno files.
374bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
375bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    DICompileUnit CU(CU_Nodes->getOperand(i));
376bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    std::string ErrorInfo;
377bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    raw_fd_ostream out(mangleName(CU, "gcno").c_str(), ErrorInfo,
378bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky                       raw_fd_ostream::F_Binary);
379bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    if (!Use402Format)
380bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      out.write("oncg*404MVLL", 12);
381bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    else
382bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      out.write("oncg*204MVLL", 12);
383bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
384bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    DIArray SPs = CU.getSubprograms();
385bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
386bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      DISubprogram SP(SPs.getElement(i));
387bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      if (!SP.Verify()) continue;
388bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
389bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      Function *F = SP.getFunction();
390bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      if (!F) continue;
391bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      GCOVFunction Func(SP, &out, Use402Format, UseExtraChecksum);
392bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
393bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
394bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        GCOVBlock &Block = Func.getBlock(BB);
395bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        TerminatorInst *TI = BB->getTerminator();
396bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        if (int successors = TI->getNumSuccessors()) {
397bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          for (int i = 0; i != successors; ++i) {
398bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky            Block.addEdge(Func.getBlock(TI->getSuccessor(i)));
399f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
400bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        } else if (isa<ReturnInst>(TI)) {
401bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          Block.addEdge(Func.getReturnBlock());
402bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        }
403bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
404bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        uint32_t Line = 0;
405bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky        for (BasicBlock::iterator I = BB->begin(), IE = BB->end();
406bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky             I != IE; ++I) {
407bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          const DebugLoc &Loc = I->getDebugLoc();
408bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          if (Loc.isUnknown()) continue;
409bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          if (Line == Loc.getLine()) continue;
410bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          Line = Loc.getLine();
411bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue;
412bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky
413bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          GCOVLines &Lines = Block.getFile(SP.getFilename());
414bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky          Lines.addLine(Loc.getLine());
415b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
416b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
417bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky      Func.writeOut();
418b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
419bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    out.write("\0\0\0\0\0\0\0\0", 8);  // EOF
420bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky    out.close();
421b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
422b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
423b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
424f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() {
425f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
426f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (!CU_Nodes) return false;
427f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
428f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  bool Result = false;
42977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  bool InsertIndCounterIncrCode = false;
430f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
431f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    DICompileUnit CU(CU_Nodes->getOperand(i));
432f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    DIArray SPs = CU.getSubprograms();
433f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP;
434f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) {
435f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      DISubprogram SP(SPs.getElement(i));
436f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!SP.Verify()) continue;
437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      Function *F = SP.getFunction();
438f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!F) continue;
439f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!Result) Result = true;
440f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      unsigned Edges = 0;
441f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
442f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        TerminatorInst *TI = BB->getTerminator();
443f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (isa<ReturnInst>(TI))
444f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          ++Edges;
445f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        else
446f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Edges += TI->getNumSuccessors();
447f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      }
448f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
449f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      ArrayType *CounterTy =
4501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        ArrayType::get(Type::getInt64Ty(*Ctx), Edges);
451f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      GlobalVariable *Counters =
4521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        new GlobalVariable(*M, CounterTy, false,
453b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                           GlobalValue::InternalLinkage,
4541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                           Constant::getNullValue(CounterTy),
455ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg                           "__llvm_gcov_ctr");
456f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP));
457f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
458f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      UniqueVector<BasicBlock *> ComplexEdgePreds;
459f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      UniqueVector<BasicBlock *> ComplexEdgeSuccs;
460f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
461f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      unsigned Edge = 0;
462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        TerminatorInst *TI = BB->getTerminator();
464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        if (Successors) {
466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          IRBuilder<> Builder(TI);
467f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          if (Successors == 1) {
469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0,
470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                                                                Edge);
471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Count = Builder.CreateLoad(Counter);
472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Count = Builder.CreateAdd(Count,
473f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                                      ConstantInt::get(Type::getInt64Ty(*Ctx),1));
474f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Builder.CreateStore(Count, Counter);
475f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) {
476f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Sel = Builder.CreateSelect(
477b1928704201034c785a26296a49f69355eb56a05Nick Lewycky              BI->getCondition(),
4781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky              ConstantInt::get(Type::getInt64Ty(*Ctx), Edge),
4791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky              ConstantInt::get(Type::getInt64Ty(*Ctx), Edge + 1));
480f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            SmallVector<Value *, 2> Idx;
481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Idx.push_back(Constant::getNullValue(Type::getInt64Ty(*Ctx)));
482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Idx.push_back(Sel);
483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx);
484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Value *Count = Builder.CreateLoad(Counter);
485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Count = Builder.CreateAdd(Count,
486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                                      ConstantInt::get(Type::getInt64Ty(*Ctx),1));
487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            Builder.CreateStore(Count, Counter);
488f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          } else {
489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            ComplexEdgePreds.insert(BB);
490f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel            for (int i = 0; i != Successors; ++i)
491f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel              ComplexEdgeSuccs.insert(TI->getSuccessor(i));
492f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          }
493f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Edge += Successors;
494b1928704201034c785a26296a49f69355eb56a05Nick Lewycky        }
495b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
496f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      if (!ComplexEdgePreds.empty()) {
498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *EdgeTable =
4991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          buildEdgeLookupTable(F, Counters,
5001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                               ComplexEdgePreds, ComplexEdgeSuccs);
501f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *EdgeState = getEdgeStateValue();
502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Type *Int32Ty = Type::getInt32Ty(*Ctx);
504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) {
505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator());
506f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Builder.CreateStore(ConstantInt::get(Int32Ty, i), EdgeState);
507f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        }
508f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) {
509f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          // call runtime to perform increment
51077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling          BasicBlock::iterator InsertPt =
51177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling            ComplexEdgeSuccs[i+1]->getFirstInsertionPt();
512f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          IRBuilder<> Builder(InsertPt);
513f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel          Value *CounterPtrArray =
5141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky            Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0,
5151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                               i * ComplexEdgePreds.size());
516c7a884040e4ec7795515978a94803894ad08c4caBill Wendling
517c7a884040e4ec7795515978a94803894ad08c4caBill Wendling          // Build code to increment the counter.
51877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling          InsertIndCounterIncrCode = true;
51977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling          Builder.CreateCall2(getIncrementIndirectCounterFunc(),
52077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling                              EdgeState, CounterPtrArray);
521f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        }
522b1928704201034c785a26296a49f69355eb56a05Nick Lewycky      }
523b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
5244a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling
525f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    insertCounterWriteout(CountersBySP);
526253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    insertFlush(CountersBySP);
527b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
52877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
52977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  if (InsertIndCounterIncrCode)
53077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    insertIndirectCounterIncrement();
53177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
532f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  return Result;
533b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
534b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it
5361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update.
5371790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable(
5381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Function *F,
5391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GlobalVariable *Counters,
5401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    const UniqueVector<BasicBlock *> &Preds,
5411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    const UniqueVector<BasicBlock *> &Succs) {
5421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // TODO: support invoke, threads. We rely on the fact that nothing can modify
5431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // the whole-Module pred edge# between the time we set it and the time we next
5441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // read it. Threads and invoke make this untrue.
5451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
5461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]].
5479e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  size_t TableSize = Succs.size() * Preds.size();
548db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx);
5499e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize);
5501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
5519e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  OwningArrayPtr<Constant *> EdgeTable(new Constant*[TableSize]);
5521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  Constant *NullValue = Constant::getNullValue(Int64PtrTy);
5539e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  for (size_t i = 0; i != TableSize; ++i)
5541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    EdgeTable[i] = NullValue;
5551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
5561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  unsigned Edge = 0;
5571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
5581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    TerminatorInst *TI = BB->getTerminator();
5591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors();
5607a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky    if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) {
5611790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      for (int i = 0; i != Successors; ++i) {
5621790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        BasicBlock *Succ = TI->getSuccessor(i);
5631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        IRBuilder<> builder(Succ);
5641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        Value *Counter = builder.CreateConstInBoundsGEP2_64(Counters, 0,
5651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                                            Edge + i);
5661790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky        EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) +
5671790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                  (Preds.idFor(BB)-1)] = cast<Constant>(Counter);
5681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      }
5691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    }
5701790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    Edge += Successors;
5711790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  }
5721790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
5739e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer  ArrayRef<Constant*> V(&EdgeTable[0], TableSize);
5741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  GlobalVariable *EdgeTableGV =
5751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky      new GlobalVariable(
5761790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          *M, EdgeTableTy, true, GlobalValue::InternalLinkage,
577267010864e139781ef5949939e081c41f954de0aJay Foad          ConstantArray::get(EdgeTableTy, V),
5781790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky          "__llvm_gcda_edge_table");
5791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  EdgeTableGV->setUnnamedAddr(true);
5801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return EdgeTableGV;
5811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
5821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
583b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() {
584db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
5855fdd6c8793462549e3593890ec61573da06e3346Jay Foad                                              Type::getInt8PtrTy(*Ctx), false);
5861790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_start_file", FTy);
5871790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
5881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky
58977b19134104c3e96424dc010f2b69c3faf580e68Bill WendlingConstant *GCOVProfiler::getIncrementIndirectCounterFunc() {
59077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Type *Int32Ty = Type::getInt32Ty(*Ctx);
591c7a884040e4ec7795515978a94803894ad08c4caBill Wendling  Type *Int64Ty = Type::getInt64Ty(*Ctx);
59277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Type *Args[] = {
593b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow    Int32Ty->getPointerTo(),                // uint32_t *predecessor
594b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow    Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters
59577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  };
59677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
59777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy);
598b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
599b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
600b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() {
6015fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Args[2] = {
6025409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    Type::getInt32Ty(*Ctx),    // uint32_t ident
6035409a188328d9de3755febc23558d4fc1797d04eNick Lewycky    Type::getInt8PtrTy(*Ctx),  // const char *function_name
6045409a188328d9de3755febc23558d4fc1797d04eNick Lewycky  };
605c7a884040e4ec7795515978a94803894ad08c4caBill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
6061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
607b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
608b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
609b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() {
6105fdd6c8793462549e3593890ec61573da06e3346Jay Foad  Type *Args[] = {
611b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Type::getInt32Ty(*Ctx),     // uint32_t num_counters
612b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    Type::getInt64PtrTy(*Ctx),  // uint64_t *counters
613b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  };
614db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
615b1928704201034c785a26296a49f69355eb56a05Nick Lewycky                                              Args, false);
6161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy);
617b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
618b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
619b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() {
620db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return M->getOrInsertFunction("llvm_gcda_end_file", FTy);
622b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
623b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
6241790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() {
6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred");
6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  if (!GV) {
6271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false,
6281790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            GlobalValue::InternalLinkage,
6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            ConstantInt::get(Type::getInt32Ty(*Ctx),
6301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                                             0xffffffff),
6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky                            "__llvm_gcov_global_state_pred");
6321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky    GV->setUnnamedAddr(true);
6331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  }
6341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  return GV;
6351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky}
636b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
6371790c9cbb6714e81eab1412909a2320acaecc43bNick Lewyckyvoid GCOVProfiler::insertCounterWriteout(
63821b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling    ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) {
639253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
640253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Function *WriteoutF = M->getFunction("__llvm_gcov_writeout");
641253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (!WriteoutF)
642253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage,
643253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling                                 "__llvm_gcov_writeout", M);
644b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  WriteoutF->setUnnamedAddr(true);
645034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  WriteoutF->addFnAttr(Attribute::NoInline);
64608e13e4488cde76fc51f942e773874627a88eeaeBill Wendling  if (NoRedZone)
647034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    WriteoutF->addFnAttr(Attribute::NoRedZone);
648253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
649253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF);
6501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  IRBuilder<> Builder(BB);
651b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
652b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *StartFile = getStartFileFunc();
653b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EmitFunction = getEmitFunctionFunc();
654b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EmitArcs = getEmitArcsFunc();
655b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  Constant *EndFile = getEndFileFunc();
656b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
657f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
658f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel  if (CU_Nodes) {
659f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel    for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) {
660032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling      DICompileUnit CU(CU_Nodes->getOperand(i));
661032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling      std::string FilenameGcda = mangleName(CU, "gcda");
662f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      Builder.CreateCall(StartFile,
663f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                         Builder.CreateGlobalStringPtr(FilenameGcda));
66421b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling      for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator
6655409a188328d9de3755febc23558d4fc1797d04eNick Lewycky             I = CountersBySP.begin(), E = CountersBySP.end();
666f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel           I != E; ++I) {
667f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        DISubprogram SP(I->second);
668f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        intptr_t ident = reinterpret_cast<intptr_t>(I->second);
669f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Builder.CreateCall2(EmitFunction,
670f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            ConstantInt::get(Type::getInt32Ty(*Ctx), ident),
671f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            Builder.CreateGlobalStringPtr(SP.getName()));
672f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel
673f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        GlobalVariable *GV = I->first;
674f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        unsigned Arcs =
675b1928704201034c785a26296a49f69355eb56a05Nick Lewycky          cast<ArrayType>(GV->getType()->getElementType())->getNumElements();
676f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel        Builder.CreateCall2(EmitArcs,
677f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            ConstantInt::get(Type::getInt32Ty(*Ctx), Arcs),
678f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel                            Builder.CreateConstGEP2_64(GV, 0, 0));
679f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      }
680f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel      Builder.CreateCall(EndFile);
681b1928704201034c785a26296a49f69355eb56a05Nick Lewycky    }
682b1928704201034c785a26296a49f69355eb56a05Nick Lewycky  }
6831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky  Builder.CreateRetVoid();
684b1928704201034c785a26296a49f69355eb56a05Nick Lewycky
6854a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  // Create a small bit of code that registers the "__llvm_gcov_writeout"
6864a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  // function to be executed at exit.
6874a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
6884a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  Function *F = Function::Create(FTy, GlobalValue::InternalLinkage,
6894a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling                                 "__llvm_gcov_init", M);
6904a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  F->setUnnamedAddr(true);
6914a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  F->setLinkage(GlobalValue::InternalLinkage);
692034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  F->addFnAttr(Attribute::NoInline);
69308e13e4488cde76fc51f942e773874627a88eeaeBill Wendling  if (NoRedZone)
694034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    F->addFnAttr(Attribute::NoRedZone);
6954a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling
6964a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  BB = BasicBlock::Create(*Ctx, "entry", F);
6974a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  Builder.SetInsertPoint(BB);
6984a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling
6994a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  FTy = FunctionType::get(Type::getInt32Ty(*Ctx),
7004a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling                          PointerType::get(FTy, 0), false);
701c1b6ea7b6ce3a738accbacddf52480bf94354d2fBill Wendling  Constant *AtExitFn = M->getOrInsertFunction("atexit", FTy);
7024a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  Builder.CreateCall(AtExitFn, WriteoutF);
7034a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  Builder.CreateRetVoid();
7044a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling
7054a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling  appendToGlobalCtors(*M, F, 0);
706b1928704201034c785a26296a49f69355eb56a05Nick Lewycky}
70777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
70877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendlingvoid GCOVProfiler::insertIndirectCounterIncrement() {
70977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Function *Fn =
71077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling    cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc());
71177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Fn->setUnnamedAddr(true);
71277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Fn->setLinkage(GlobalValue::InternalLinkage);
713034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  Fn->addFnAttr(Attribute::NoInline);
71408e13e4488cde76fc51f942e773874627a88eeaeBill Wendling  if (NoRedZone)
715034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    Fn->addFnAttr(Attribute::NoRedZone);
71677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
71777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Type *Int32Ty = Type::getInt32Ty(*Ctx);
71877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Type *Int64Ty = Type::getInt64Ty(*Ctx);
71977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Constant *NegOne = ConstantInt::get(Int32Ty, 0xffffffff);
72077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
72177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // Create basic blocks for function.
72277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn);
72377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  IRBuilder<> Builder(BB);
72477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
72577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn);
72677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn);
72777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn);
72877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
72977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // uint32_t pred = *predecessor;
73077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // if (pred == 0xffffffff) return;
73177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Argument *Arg = Fn->arg_begin();
73277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Arg->setName("predecessor");
73377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Pred = Builder.CreateLoad(Arg, "pred");
73477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Cond = Builder.CreateICmpEQ(Pred, NegOne);
73577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  BranchInst::Create(Exit, PredNotNegOne, Cond, BB);
73677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
73777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(PredNotNegOne);
73877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
73977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // uint64_t *counter = counters[pred];
74077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // if (!counter) return;
74177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *ZExtPred = Builder.CreateZExt(Pred, Int64Ty);
74277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Arg = llvm::next(Fn->arg_begin());
74377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Arg->setName("counters");
74477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *GEP = Builder.CreateGEP(Arg, ZExtPred);
74577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Counter = Builder.CreateLoad(GEP, "counter");
74677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Cond = Builder.CreateICmpEQ(Counter,
747b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow                              Constant::getNullValue(Int64Ty->getPointerTo()));
74877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateCondBr(Cond, Exit, CounterEnd);
74977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
75077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // ++*counter;
75177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(CounterEnd);
75277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter),
75377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling                                 ConstantInt::get(Int64Ty, 1));
75477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateStore(Add, Counter);
75577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateBr(Exit);
75677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling
75777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  // Fill in the exit block.
75877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.SetInsertPoint(Exit);
75977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling  Builder.CreateRetVoid();
76077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling}
761253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
762253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendlingvoid GCOVProfiler::
763253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill WendlinginsertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) {
764253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
76578fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling  Function *FlushF = M->getFunction("__gcov_flush");
766253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (!FlushF)
767253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    FlushF = Function::Create(FTy, GlobalValue::InternalLinkage,
76878fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling                              "__gcov_flush", M);
769253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else
770253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    FlushF->setLinkage(GlobalValue::InternalLinkage);
771253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  FlushF->setUnnamedAddr(true);
772034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling  FlushF->addFnAttr(Attribute::NoInline);
77308e13e4488cde76fc51f942e773874627a88eeaeBill Wendling  if (NoRedZone)
774034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    FlushF->addFnAttr(Attribute::NoRedZone);
775253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
776253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF);
777253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
778253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  // Write out the current counters.
779253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout");
780253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  assert(WriteoutF && "Need to create the writeout function first!");
781253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
782253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  IRBuilder<> Builder(Entry);
783253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Builder.CreateCall(WriteoutF);
784253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
785032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  // Zero out the counters.
786032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator
787032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling         I = CountersBySP.begin(), E = CountersBySP.end();
788032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling       I != E; ++I) {
789032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling    GlobalVariable *GV = I->first;
790032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling    Constant *Null = Constant::getNullValue(GV->getType()->getElementType());
791ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling    Builder.CreateStore(Null, GV);
792032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling  }
793253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling
794253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  Type *RetTy = FlushF->getReturnType();
795253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  if (RetTy == Type::getVoidTy(*Ctx))
796253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    Builder.CreateRetVoid();
797253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else if (RetTy->isIntegerTy())
79878fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling    // Used if __gcov_flush was implicitly declared.
799253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling    Builder.CreateRet(ConstantInt::get(RetTy, 0));
800253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling  else
80178fff8ec487a7c16633c5795e38e297ce6ddafa4Bill Wendling    report_fatal_error("invalid return type for __gcov_flush");
802253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling}
803