GCOVProfiling.cpp revision 39c41c3c93e0d223792acb093adce21a714b01c6
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" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Instructions.h" 300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Pass.h" 32a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky#include "llvm/Support/CommandLine.h" 3306cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/Debug.h" 3406cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/DebugLoc.h" 3539c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling#include "llvm/Support/FileSystem.h" 3606cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/InstIterator.h" 3706cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/PathV2.h" 3806cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Support/raw_ostream.h" 3906cb8ed00696eb14d1b831921452e50ec0568ea2Chandler Carruth#include "llvm/Transforms/Utils/ModuleUtils.h" 40b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <string> 41b1928704201034c785a26296a49f69355eb56a05Nick Lewycky#include <utility> 42b1928704201034c785a26296a49f69355eb56a05Nick Lewyckyusing namespace llvm; 43b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 44a204ef3168c8804808c716115ba915c89d8849b9Nick Lewyckystatic cl::opt<std::string> 45a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyDefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden, 46a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky cl::ValueRequired); 47a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 48a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyGCOVOptions GCOVOptions::getDefault() { 49a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky GCOVOptions Options; 50a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky Options.EmitNotes = true; 51a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky Options.EmitData = true; 52a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky Options.UseCfgChecksum = false; 53a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky Options.NoRedZone = false; 54a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky Options.FunctionNamesInData = true; 55a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 56a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (DefaultGCOVVersion.size() != 4) { 57a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") + 58a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky DefaultGCOVVersion); 59a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky } 60a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4); 61a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky return Options; 62a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky} 63a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 64b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 65b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVProfiler : public ModulePass { 66b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 67b1928704201034c785a26296a49f69355eb56a05Nick Lewycky static char ID; 68a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky GCOVProfiler() : ModulePass(ID), Options(GCOVOptions::getDefault()) { 69a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[0] = Options.Version[3]; 70a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[1] = Options.Version[2]; 71a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[2] = Options.Version[1]; 72a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[3] = Options.Version[0]; 73a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[4] = '\0'; 74a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 75a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky } 76a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky GCOVProfiler(const GCOVOptions &Options) : ModulePass(ID), Options(Options){ 77a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky assert((Options.EmitNotes || Options.EmitData) && 78a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky "GCOVProfiler asked to do nothing?"); 79a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[0] = Options.Version[3]; 80a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[1] = Options.Version[2]; 81a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[2] = Options.Version[1]; 82a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[3] = Options.Version[0]; 83a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky ReversedVersion[4] = '\0'; 84b1928704201034c785a26296a49f69355eb56a05Nick Lewycky initializeGCOVProfilerPass(*PassRegistry::getPassRegistry()); 85b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 86b1928704201034c785a26296a49f69355eb56a05Nick Lewycky virtual const char *getPassName() const { 87b1928704201034c785a26296a49f69355eb56a05Nick Lewycky return "GCOV Profiler"; 88b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 89a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 90b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 91269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky bool runOnModule(Module &M); 92269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 9364a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky // Create the .gcno files for the Module based on DebugInfo. 9464a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky void emitProfileNotes(); 95b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 960c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // Modify the program to track transitions along edges and call into the 970c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky // profiling runtime to emit .gcda files when run. 98f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool emitProfileArcs(); 990c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 100b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Get pointers to the functions in the runtime library. 101b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getStartFileFunc(); 10277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Constant *getIncrementIndirectCounterFunc(); 103b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitFunctionFunc(); 104b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEmitArcsFunc(); 10518764716861243c58a711a92190624dc2f6aafc9Bill Wendling Constant *getDeleteWriteoutFunctionListFunc(); 106d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling Constant *getDeleteFlushFunctionListFunc(); 107b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *getEndFileFunc(); 108b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Create or retrieve an i32 state value that is used to represent the 1101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // pred block number for certain non-trivial edges. 1111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *getEdgeStateValue(); 1121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // Produce a table of pointers to counters, by predecessor and successor 1141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // block number. 1151790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *buildEdgeLookupTable(Function *F, 1161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counter, 11764a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky const UniqueVector<BasicBlock *>&Preds, 11864a0a33307723957bf2f15e3181a290853c6f833Nick Lewycky const UniqueVector<BasicBlock*>&Succs); 1191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 120b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Add the function to write out all our counters to the global destructor 121b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // list. 122d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling Function *insertCounterWriteout(ArrayRef<std::pair<GlobalVariable*, 123d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling MDNode*> >); 124d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling Function *insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> >); 12577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling void insertIndirectCounterIncrement(); 126b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 12739c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling std::string mangleName(DICompileUnit CU, const char *NewStem, 12839c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling bool FullPath); 129269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 130a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky GCOVOptions Options; 131a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky 132a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky // Reversed, NUL-terminated copy of Options.Version. 133a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky char ReversedVersion[5]; 134a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky 1351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Module *M; 136b1928704201034c785a26296a49f69355eb56a05Nick Lewycky LLVMContext *Ctx; 137b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 138b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 139b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 140b1928704201034c785a26296a49f69355eb56a05Nick Lewyckychar GCOVProfiler::ID = 0; 141b1928704201034c785a26296a49f69355eb56a05Nick LewyckyINITIALIZE_PASS(GCOVProfiler, "insert-gcov-profiling", 142b1928704201034c785a26296a49f69355eb56a05Nick Lewycky "Insert instrumentation for GCOV profiling", false, false) 143b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 144a204ef3168c8804808c716115ba915c89d8849b9Nick LewyckyModulePass *llvm::createGCOVProfilerPass(const GCOVOptions &Options) { 145a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky return new GCOVProfiler(Options); 146a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky} 147b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1485d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewyckystatic std::string getFunctionName(DISubprogram SP) { 1495d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky if (!SP.getLinkageName().empty()) 1505d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky return SP.getLinkageName(); 1515d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky return SP.getName(); 1525d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky} 1535d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky 154b1928704201034c785a26296a49f69355eb56a05Nick Lewyckynamespace { 155b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVRecord { 156b1928704201034c785a26296a49f69355eb56a05Nick Lewycky protected: 1571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *LinesTag; 1581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *FunctionTag; 1591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *BlockTag; 1601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky static const char *EdgeTag; 161b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 162b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GCOVRecord() {} 163b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeBytes(const char *Bytes, int Size) { 1651790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky os->write(Bytes, Size); 166b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 167b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void write(uint32_t i) { 1691790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(reinterpret_cast<char*>(&i), 4); 170b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 171b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 172b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Returns the length measured in 4-byte blocks that will be used to 173b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // represent this string in a GCOV file 1741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned lengthOfGCOVString(StringRef s) { 175b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 17617df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // padding out to the next 4-byte word. The length is measured in 4-byte 17717df2c3240837b4382898ead8c3ead407a338520Nick Lewycky // words including padding, not bytes of actual string. 178d363ff334d796c7f3df834d928a10d88ed758454Nick Lewycky return (s.size() / 4) + 1; 179b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 180b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 1811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeGCOVString(StringRef s) { 1821790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = lengthOfGCOVString(s); 1831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 1841790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(s.data(), s.size()); 185b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 186b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Write 1 to 4 bytes of NUL padding. 1877a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) > 0); 1887a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky assert((unsigned)(4 - (s.size() % 4)) <= 4); 1897a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 190b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 191b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 192b1928704201034c785a26296a49f69355eb56a05Nick Lewycky raw_ostream *os; 193b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 1941790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::LinesTag = "\0\0\x45\x01"; 1951790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::FunctionTag = "\0\0\0\1"; 1961790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::BlockTag = "\0\0\x41\x01"; 1971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const char *GCOVRecord::EdgeTag = "\0\0\x43\x01"; 198b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 199b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction; 200b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock; 201b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 202b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Constructed only by requesting it from a GCOVBlock, this object stores a 20316c19a155c65fd41865562fe4e678ef32728510bDevang Patel // list of line numbers and a single filename, representing lines that belong 20416c19a155c65fd41865562fe4e678ef32728510bDevang Patel // to the block. 205b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVLines : public GCOVRecord { 206b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 2071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addLine(uint32_t Line) { 2081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Lines.push_back(Line); 209b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 210b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t length() { 212bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Here 2 = 1 for string length + 1 for '0' id#. 21316c19a155c65fd41865562fe4e678ef32728510bDevang Patel return lengthOfGCOVString(Filename) + 2 + Lines.size(); 214b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 215b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 21616c19a155c65fd41865562fe4e678ef32728510bDevang Patel void writeOut() { 21716c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(0); 21816c19a155c65fd41865562fe4e678ef32728510bDevang Patel writeGCOVString(Filename); 21916c19a155c65fd41865562fe4e678ef32728510bDevang Patel for (int i = 0, e = Lines.size(); i != e; ++i) 22016c19a155c65fd41865562fe4e678ef32728510bDevang Patel write(Lines[i]); 22116c19a155c65fd41865562fe4e678ef32728510bDevang Patel } 222b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 22316c19a155c65fd41865562fe4e678ef32728510bDevang Patel GCOVLines(StringRef F, raw_ostream *os) 22416c19a155c65fd41865562fe4e678ef32728510bDevang Patel : Filename(F) { 225b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 226b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 227b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 228680018ff8965610b3f1c976b0be1dfd45116b218Devang Patel private: 22916c19a155c65fd41865562fe4e678ef32728510bDevang Patel StringRef Filename; 2301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<uint32_t, 32> Lines; 231b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 232b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 233b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Represent a basic block in GCOV. Each block has a unique number in the 234b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // function, number of lines belonging to each block, and a set of edges to 235b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // other blocks. 236b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVBlock : public GCOVRecord { 237b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 23868155d31cd0175be89e26ee68387cb411fca537bDevang Patel GCOVLines &getFile(StringRef Filename) { 2391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVLines *&Lines = LinesByFile[Filename]; 2401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!Lines) { 24116c19a155c65fd41865562fe4e678ef32728510bDevang Patel Lines = new GCOVLines(Filename, os); 242b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Lines; 244b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 245b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void addEdge(GCOVBlock &Successor) { 2471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky OutEdges.push_back(&Successor); 248b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 249b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 2511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Len = 3; 2521790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 2531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = LinesByFile.end(); I != E; ++I) { 25416c19a155c65fd41865562fe4e678ef32728510bDevang Patel Len += I->second->length(); 255b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 256b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(LinesTag, 4); 2581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Len); 2591790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Number); 2601790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (StringMap<GCOVLines *>::iterator I = LinesByFile.begin(), 26116c19a155c65fd41865562fe4e678ef32728510bDevang Patel E = LinesByFile.end(); I != E; ++I) 26216c19a155c65fd41865562fe4e678ef32728510bDevang Patel I->second->writeOut(); 2631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 2641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); 265b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 266b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 267b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVBlock() { 2681790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(LinesByFile); 269b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 270b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 271b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 272b1928704201034c785a26296a49f69355eb56a05Nick Lewycky friend class GCOVFunction; 273b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock(uint32_t Number, raw_ostream *os) 2751790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky : Number(Number) { 276b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 277b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 278b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 2791790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky uint32_t Number; 2801790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky StringMap<GCOVLines *> LinesByFile; 2811790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky SmallVector<GCOVBlock *, 4> OutEdges; 282b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 283b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 284b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // A function has a unique identifier, a checksum (we leave as zero) and a 285b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // set of blocks and a map of edges between blocks. This is the only GCOV 286b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // object users can construct, the blocks and lines will be rooted here. 287b1928704201034c785a26296a49f69355eb56a05Nick Lewycky class GCOVFunction : public GCOVRecord { 288b1928704201034c785a26296a49f69355eb56a05Nick Lewycky public: 289d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky GCOVFunction(DISubprogram SP, raw_ostream *os, uint32_t Ident, 290a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky bool UseCfgChecksum) { 291b1928704201034c785a26296a49f69355eb56a05Nick Lewycky this->os = os; 292b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 293b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Function *F = SP.getFunction(); 294bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << "Function: " << F->getName() << "\n"); 295b1928704201034c785a26296a49f69355eb56a05Nick Lewycky uint32_t i = 0; 296b1928704201034c785a26296a49f69355eb56a05Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 2971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Blocks[BB] = new GCOVBlock(i++, os); 298b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 2991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ReturnBlock = new GCOVBlock(i++, os); 3001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 3011790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(FunctionTag, 4); 3025d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(getFunctionName(SP)) + 3031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 1 + lengthOfGCOVString(SP.getFilename()) + 1; 304a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (UseCfgChecksum) 305bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky ++BlockLen; 3061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(BlockLen); 3071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Ident); 308bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // lineno checksum 309a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (UseCfgChecksum) 310bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky write(0); // cfg checksum 3115d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky writeGCOVString(getFunctionName(SP)); 3121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeGCOVString(SP.getFilename()); 3131790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(SP.getLineNumber()); 314b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 315b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 316b1928704201034c785a26296a49f69355eb56a05Nick Lewycky ~GCOVFunction() { 3171790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DeleteContainerSeconds(Blocks); 3181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky delete ReturnBlock; 319b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 320b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 3211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getBlock(BasicBlock *BB) { 3221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *Blocks[BB]; 323b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 324b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 3251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &getReturnBlock() { 3261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return *ReturnBlock; 327a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky } 328a4c4c0e1298f4dd9791eff2bae857e7be6d0ab56Nick Lewycky 3291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky void writeOut() { 330b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit count of blocks. 3311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(BlockTag, 4); 3321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Blocks.size() + 1); 3331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Blocks.size() + 1; i != e; ++i) { 3341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // No flags on our blocks. 335b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 336bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Blocks.size() << " blocks.\n"); 337b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 338b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit edges between blocks. 3391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3411790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock &Block = *I->second; 3421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (Block.OutEdges.empty()) continue; 3431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 3441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky writeBytes(EdgeTag, 4); 3451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges.size() * 2 + 1); 3461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.Number); 3471790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) { 348bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DEBUG(dbgs() << Block.Number << " -> " << Block.OutEdges[i]->Number 349bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky << "\n"); 3501790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(Block.OutEdges[i]->Number); 3511790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky write(0); // no flags 352b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 353b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 354b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 355b1928704201034c785a26296a49f69355eb56a05Nick Lewycky // Emit lines for each block. 3561790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (DenseMap<BasicBlock *, GCOVBlock *>::iterator I = Blocks.begin(), 3571790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky E = Blocks.end(); I != E; ++I) { 3581790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky I->second->writeOut(); 359b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 360b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 361b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 362b1928704201034c785a26296a49f69355eb56a05Nick Lewycky private: 3631790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky DenseMap<BasicBlock *, GCOVBlock *> Blocks; 3641790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GCOVBlock *ReturnBlock; 365b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 366b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 367b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 36839c41c3c93e0d223792acb093adce21a714b01c6Bill Wendlingstd::string GCOVProfiler::mangleName(DICompileUnit CU, const char *NewStem, 36939c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling bool FullPath) { 370269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 371269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 372269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *N = GCov->getOperand(i); 373269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky if (N->getNumOperands() != 2) continue; 374fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 375269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky MDNode *CompileUnit = dyn_cast<MDNode>(N->getOperand(1)); 376fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (!GCovFile || !CompileUnit) continue; 377fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky if (CompileUnit == CU) { 3786e5190c193f6267893daf6943af88e95039e739cBill Wendling SmallString<128> Filename = GCovFile->getString(); 3796e5190c193f6267893daf6943af88e95039e739cBill Wendling sys::path::replace_extension(Filename, NewStem); 3806e5190c193f6267893daf6943af88e95039e739cBill Wendling return Filename.str(); 381fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky } 382269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 383269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky } 384fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky 3856e5190c193f6267893daf6943af88e95039e739cBill Wendling SmallString<128> Filename = CU.getFilename(); 386fcf74ed5a2bc10570dec2084a2db1f6580b1210dNick Lewycky sys::path::replace_extension(Filename, NewStem); 38739c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling StringRef FName = sys::path::filename(Filename); 38839c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling if (!FullPath) 38939c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling return FName; 39039c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling SmallString<128> CurPath; 39139c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling if (sys::fs::current_path(CurPath)) return FName; 39239c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling sys::path::append(CurPath, FName.str()); 39339c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling return CurPath.str(); 394269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky} 395269687fa350c1aa044bc063c64362a04ecabaa33Nick Lewycky 3960c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewyckybool GCOVProfiler::runOnModule(Module &M) { 3971790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky this->M = &M; 3980c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky Ctx = &M.getContext(); 3990c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 400a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (Options.EmitNotes) emitProfileNotes(); 401a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (Options.EmitData) return emitProfileArcs(); 402a61e52c9b7cf874b46cef687c1c4627a35952542Nick Lewycky return false; 4030c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky} 4040c4de8a4eb5fd6437b571611794ef84427fc4755Nick Lewycky 40564a0a33307723957bf2f15e3181a290853c6f833Nick Lewyckyvoid GCOVProfiler::emitProfileNotes() { 406f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 407bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!CU_Nodes) return; 408bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 409bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 410bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // Each compile unit gets its own .gcno file. This means that whether we run 411bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // this pass over the original .o's as they're produced, or run it after 412bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky // LTO, we'll generate the same .gcno files. 413bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 414bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DICompileUnit CU(CU_Nodes->getOperand(i)); 415bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky std::string ErrorInfo; 41639c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling raw_fd_ostream out(mangleName(CU, "gcno", false).c_str(), ErrorInfo, 417bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky raw_fd_ostream::F_Binary); 418d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky out.write("oncg", 4); 419a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky out.write(ReversedVersion, 4); 420d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky out.write("MVLL", 4); 421bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 422bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DIArray SPs = CU.getSubprograms(); 423bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 424bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky DISubprogram SP(SPs.getElement(i)); 425bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!SP.Verify()) continue; 426bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 427bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Function *F = SP.getFunction(); 428bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (!F) continue; 429a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky GCOVFunction Func(SP, &out, i, Options.UseCfgChecksum); 430bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 431bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 432bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVBlock &Block = Func.getBlock(BB); 433bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky TerminatorInst *TI = BB->getTerminator(); 434bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (int successors = TI->getNumSuccessors()) { 435bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (int i = 0; i != successors; ++i) { 436bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 437f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 438bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } else if (isa<ReturnInst>(TI)) { 439bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Block.addEdge(Func.getReturnBlock()); 440bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky } 441bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 442bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky uint32_t Line = 0; 443bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky for (BasicBlock::iterator I = BB->begin(), IE = BB->end(); 444bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky I != IE; ++I) { 445bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky const DebugLoc &Loc = I->getDebugLoc(); 446bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Loc.isUnknown()) continue; 447bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (Line == Loc.getLine()) continue; 448bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Line = Loc.getLine(); 449bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky if (SP != getDISubprogram(Loc.getScope(*Ctx))) continue; 450bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky 451bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky GCOVLines &Lines = Block.getFile(SP.getFilename()); 452bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Lines.addLine(Loc.getLine()); 453b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 454b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 455bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky Func.writeOut(); 456b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 457bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.write("\0\0\0\0\0\0\0\0", 8); // EOF 458bba40db07234cef7867b45c67f50632e684cbb15Nick Lewycky out.close(); 459b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 460b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 461b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 462f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patelbool GCOVProfiler::emitProfileArcs() { 463f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 464f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!CU_Nodes) return false; 465f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 466f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel bool Result = false; 46777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling bool InsertIndCounterIncrCode = false; 468f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 469f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DICompileUnit CU(CU_Nodes->getOperand(i)); 470f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DIArray SPs = CU.getSubprograms(); 471f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; 472f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) { 473f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel DISubprogram SP(SPs.getElement(i)); 474f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!SP.Verify()) continue; 475f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Function *F = SP.getFunction(); 476f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!F) continue; 477f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!Result) Result = true; 478f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edges = 0; 479f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 480f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 481f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (isa<ReturnInst>(TI)) 482f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ++Edges; 483f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel else 484f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edges += TI->getNumSuccessors(); 485f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 486f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 487f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ArrayType *CounterTy = 4881790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ArrayType::get(Type::getInt64Ty(*Ctx), Edges); 489f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *Counters = 4901790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable(*M, CounterTy, false, 491b1928704201034c785a26296a49f69355eb56a05Nick Lewycky GlobalValue::InternalLinkage, 4921790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant::getNullValue(CounterTy), 493ce718ff9f42c7da092eaa01dd0242e8d5ba84713Hans Wennborg "__llvm_gcov_ctr"); 494f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel CountersBySP.push_back(std::make_pair(Counters, (MDNode*)SP)); 495f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 496f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgePreds; 497f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel UniqueVector<BasicBlock *> ComplexEdgeSuccs; 498f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 499f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Edge = 0; 500f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 501f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel TerminatorInst *TI = BB->getTerminator(); 502f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 503f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors) { 504f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(TI); 505f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 506f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (Successors == 1) { 507f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 508f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge); 509f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 510bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 511f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 512f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 513bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Value *Sel = Builder.CreateSelect(BI->getCondition(), 514bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.getInt64(Edge), 515bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.getInt64(Edge + 1)); 516f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel SmallVector<Value *, 2> Idx; 517bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Idx.push_back(Builder.getInt64(0)); 518f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Idx.push_back(Sel); 519f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Counter = Builder.CreateInBoundsGEP(Counters, Idx); 520f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *Count = Builder.CreateLoad(Counter); 521bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 522f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateStore(Count, Counter); 523f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } else { 524f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgePreds.insert(BB); 525f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0; i != Successors; ++i) 526f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel ComplexEdgeSuccs.insert(TI->getSuccessor(i)); 527f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 528f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Edge += Successors; 529b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 530b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 531f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 532f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (!ComplexEdgePreds.empty()) { 533f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeTable = 5341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky buildEdgeLookupTable(F, Counters, 5351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ComplexEdgePreds, ComplexEdgeSuccs); 536f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel GlobalVariable *EdgeState = getEdgeStateValue(); 537f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel 538f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) { 539f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(ComplexEdgePreds[i+1]->getTerminator()); 540bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.CreateStore(Builder.getInt32(i), EdgeState); 541f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 542f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) { 543f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel // call runtime to perform increment 54477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock::iterator InsertPt = 54577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling ComplexEdgeSuccs[i+1]->getFirstInsertionPt(); 546f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel IRBuilder<> Builder(InsertPt); 547f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Value *CounterPtrArray = 5481790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0, 5491790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky i * ComplexEdgePreds.size()); 550c7a884040e4ec7795515978a94803894ad08c4caBill Wendling 551c7a884040e4ec7795515978a94803894ad08c4caBill Wendling // Build code to increment the counter. 55277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling InsertIndCounterIncrCode = true; 55377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateCall2(getIncrementIndirectCounterFunc(), 55477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling EdgeState, CounterPtrArray); 555f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 556b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 557b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 5584a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling 559d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling Function *WriteoutF = insertCounterWriteout(CountersBySP); 560d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling Function *FlushF = insertFlush(CountersBySP); 561d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 562d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling // Create a small bit of code that registers the "__llvm_gcov_writeout" to 56318764716861243c58a711a92190624dc2f6aafc9Bill Wendling // be executed at exit and the "__llvm_gcov_flush" function to be executed 56418764716861243c58a711a92190624dc2f6aafc9Bill Wendling // when "__gcov_flush" is called. 565d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 566d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, 567d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling "__llvm_gcov_init", M); 568d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling F->setUnnamedAddr(true); 569d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling F->setLinkage(GlobalValue::InternalLinkage); 570d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling F->addFnAttr(Attribute::NoInline); 571d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling if (Options.NoRedZone) 572d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling F->addFnAttr(Attribute::NoRedZone); 573d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 574d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F); 575d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling IRBuilder<> Builder(BB); 576d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 577d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 5788640c6a5227b75666e02424e2181289692138348Bill Wendling Type *Params[] = { 5798640c6a5227b75666e02424e2181289692138348Bill Wendling PointerType::get(FTy, 0), 5808640c6a5227b75666e02424e2181289692138348Bill Wendling PointerType::get(FTy, 0) 5818640c6a5227b75666e02424e2181289692138348Bill Wendling }; 5828640c6a5227b75666e02424e2181289692138348Bill Wendling FTy = FunctionType::get(Builder.getVoidTy(), Params, false); 5838640c6a5227b75666e02424e2181289692138348Bill Wendling 5848640c6a5227b75666e02424e2181289692138348Bill Wendling // Inialize the environment and register the local writeout and flush 5858640c6a5227b75666e02424e2181289692138348Bill Wendling // functions. 5868640c6a5227b75666e02424e2181289692138348Bill Wendling Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy); 5878640c6a5227b75666e02424e2181289692138348Bill Wendling Builder.CreateCall2(GCOVInit, WriteoutF, FlushF); 588d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling Builder.CreateRetVoid(); 589d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 590d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling appendToGlobalCtors(*M, F, 0); 591b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 59277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 59377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling if (InsertIndCounterIncrCode) 59477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling insertIndirectCounterIncrement(); 59577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 596f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel return Result; 597b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 598b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 5991790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// All edges with successors that aren't branches are "complex", because it 6001790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky// requires complex logic to pick which counter to update. 6011790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::buildEdgeLookupTable( 6021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Function *F, 6031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *Counters, 6041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Preds, 6051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky const UniqueVector<BasicBlock *> &Succs) { 6061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // TODO: support invoke, threads. We rely on the fact that nothing can modify 6071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // the whole-Module pred edge# between the time we set it and the time we next 6081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // read it. Threads and invoke make this untrue. 6091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 6101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]]. 6119e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer size_t TableSize = Succs.size() * Preds.size(); 612db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); 6139e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize); 6141790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 6159e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer OwningArrayPtr<Constant *> EdgeTable(new Constant*[TableSize]); 6161790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Constant *NullValue = Constant::getNullValue(Int64PtrTy); 6179e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer for (size_t i = 0; i != TableSize; ++i) 6181790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[i] = NullValue; 6191790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 6201790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky unsigned Edge = 0; 6211790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { 6221790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky TerminatorInst *TI = BB->getTerminator(); 6231790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 6247a2ba2fbe4b0ccaacc2cedbc1bfd2a3764170efeNick Lewycky if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) { 6251790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky for (int i = 0; i != Successors; ++i) { 6261790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky BasicBlock *Succ = TI->getSuccessor(i); 627bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky IRBuilder<> Builder(Succ); 628bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 6291790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge + i); 6301790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTable[((Succs.idFor(Succ)-1) * Preds.size()) + 6311790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky (Preds.idFor(BB)-1)] = cast<Constant>(Counter); 6321790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6331790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6341790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky Edge += Successors; 6351790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 6361790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 6379e6ee16b1814268897965b81e82a74ef39173ee1Benjamin Kramer ArrayRef<Constant*> V(&EdgeTable[0], TableSize); 6381790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *EdgeTableGV = 6391790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky new GlobalVariable( 6401790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky *M, EdgeTableTy, true, GlobalValue::InternalLinkage, 641267010864e139781ef5949939e081c41f954de0aJay Foad ConstantArray::get(EdgeTableTy, V), 6421790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcda_edge_table"); 6431790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky EdgeTableGV->setUnnamedAddr(true); 6441790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return EdgeTableGV; 6451790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 6461790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 647b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getStartFileFunc() { 648d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Type *Args[] = { 649d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Type::getInt8PtrTy(*Ctx), // const char *orig_filename 650d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Type::getInt8PtrTy(*Ctx), // const char version[4] 651d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky }; 652d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 6531790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_start_file", FTy); 6541790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 6551790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 65677b19134104c3e96424dc010f2b69c3faf580e68Bill WendlingConstant *GCOVProfiler::getIncrementIndirectCounterFunc() { 65777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Int32Ty = Type::getInt32Ty(*Ctx); 658c7a884040e4ec7795515978a94803894ad08c4caBill Wendling Type *Int64Ty = Type::getInt64Ty(*Ctx); 65977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Type *Args[] = { 660b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow Int32Ty->getPointerTo(), // uint32_t *predecessor 661b8bce928f4ffdf50eff69334f3e25b27848536b6Micah Villmow Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters 66277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling }; 66377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 66477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy); 665b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 666b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 667b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitFunctionFunc() { 66817d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky Type *Args[3] = { 6695409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt32Ty(*Ctx), // uint32_t ident 6705409a188328d9de3755febc23558d4fc1797d04eNick Lewycky Type::getInt8PtrTy(*Ctx), // const char *function_name 67117d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky Type::getInt8Ty(*Ctx), // uint8_t use_extra_checksum 6725409a188328d9de3755febc23558d4fc1797d04eNick Lewycky }; 673c7a884040e4ec7795515978a94803894ad08c4caBill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 6741790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 675b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 676b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 677b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEmitArcsFunc() { 6785fdd6c8793462549e3593890ec61573da06e3346Jay Foad Type *Args[] = { 679b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt32Ty(*Ctx), // uint32_t num_counters 680b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Type::getInt64PtrTy(*Ctx), // uint64_t *counters 681b1928704201034c785a26296a49f69355eb56a05Nick Lewycky }; 682d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 6831790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 684b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 685b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 68618764716861243c58a711a92190624dc2f6aafc9Bill WendlingConstant *GCOVProfiler::getDeleteWriteoutFunctionListFunc() { 68718764716861243c58a711a92190624dc2f6aafc9Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 68818764716861243c58a711a92190624dc2f6aafc9Bill Wendling return M->getOrInsertFunction("llvm_delete_writeout_function_list", FTy); 68918764716861243c58a711a92190624dc2f6aafc9Bill Wendling} 69018764716861243c58a711a92190624dc2f6aafc9Bill Wendling 691d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingConstant *GCOVProfiler::getDeleteFlushFunctionListFunc() { 692d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 693d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling return M->getOrInsertFunction("llvm_delete_flush_function_list", FTy); 694d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling} 695d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 696b1928704201034c785a26296a49f69355eb56a05Nick LewyckyConstant *GCOVProfiler::getEndFileFunc() { 697db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 6981790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 699b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 700b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 7011790c9cbb6714e81eab1412909a2320acaecc43bNick LewyckyGlobalVariable *GCOVProfiler::getEdgeStateValue() { 7021790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 7031790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky if (!GV) { 7041790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 7051790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GlobalValue::InternalLinkage, 7061790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky ConstantInt::get(Type::getInt32Ty(*Ctx), 7071790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky 0xffffffff), 7081790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky "__llvm_gcov_global_state_pred"); 7091790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky GV->setUnnamedAddr(true); 7101790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky } 7111790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky return GV; 7121790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky} 713b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 714d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingFunction *GCOVProfiler::insertCounterWriteout( 71521b742ffce7bec3d71e09c7c6d901a756d55feb3Bill Wendling ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) { 716253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 717253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Function *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 718253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!WriteoutF) 719253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage, 720253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling "__llvm_gcov_writeout", M); 721b1928704201034c785a26296a49f69355eb56a05Nick Lewycky WriteoutF->setUnnamedAddr(true); 722034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling WriteoutF->addFnAttr(Attribute::NoInline); 723a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (Options.NoRedZone) 724034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling WriteoutF->addFnAttr(Attribute::NoRedZone); 725253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 726253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF); 7271790c9cbb6714e81eab1412909a2320acaecc43bNick Lewycky IRBuilder<> Builder(BB); 728b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 729b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *StartFile = getStartFileFunc(); 730b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitFunction = getEmitFunctionFunc(); 731b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EmitArcs = getEmitArcsFunc(); 732b1928704201034c785a26296a49f69355eb56a05Nick Lewycky Constant *EndFile = getEndFileFunc(); 733b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 734f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 735f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel if (CU_Nodes) { 736f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 737032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling DICompileUnit CU(CU_Nodes->getOperand(i)); 73839c41c3c93e0d223792acb093adce21a714b01c6Bill Wendling std::string FilenameGcda = mangleName(CU, "gcda", true); 739d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Builder.CreateCall2(StartFile, 740d9686a98b8145010516c44a3a5b9b96bf934b9acNick Lewycky Builder.CreateGlobalStringPtr(FilenameGcda), 741a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky Builder.CreateGlobalStringPtr(ReversedVersion)); 7428fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky for (unsigned j = 0, e = CountersBySP.size(); j != e; ++j) { 7438fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky DISubprogram SP(CountersBySP[j].second); 7445d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky Builder.CreateCall3( 7455d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky EmitFunction, Builder.getInt32(j), 7465d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky Options.FunctionNamesInData ? 7475d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky Builder.CreateGlobalStringPtr(getFunctionName(SP)) : 7485d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky Constant::getNullValue(Builder.getInt8PtrTy()), 7495d22d02fac5ef25414c0fdd843b0fabba4998d6eNick Lewycky Builder.getInt8(Options.UseCfgChecksum)); 75017d2f776011cba33f7f5afb03c8066d35dbf8afcNick Lewycky 7518fa6dc431deb7a9aadc23ec0a7bdcb2d02330972Nick Lewycky GlobalVariable *GV = CountersBySP[j].first; 752f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel unsigned Arcs = 753b1928704201034c785a26296a49f69355eb56a05Nick Lewycky cast<ArrayType>(GV->getType()->getElementType())->getNumElements(); 754f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall2(EmitArcs, 755bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.getInt32(Arcs), 756f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateConstGEP2_64(GV, 0, 0)); 757f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel } 758f6d3a4c7c4d14ad7a4e07e9f80f94f73651960d8Devang Patel Builder.CreateCall(EndFile); 759b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 760b1928704201034c785a26296a49f69355eb56a05Nick Lewycky } 761b1928704201034c785a26296a49f69355eb56a05Nick Lewycky 7624a8fefaf8303f30514bc2a40d840a1709dae65cfBill Wendling Builder.CreateRetVoid(); 763d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling return WriteoutF; 764b1928704201034c785a26296a49f69355eb56a05Nick Lewycky} 76577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 76677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendlingvoid GCOVProfiler::insertIndirectCounterIncrement() { 76777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Function *Fn = 76877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc()); 76977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->setUnnamedAddr(true); 77077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Fn->setLinkage(GlobalValue::InternalLinkage); 771034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling Fn->addFnAttr(Attribute::NoInline); 772a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (Options.NoRedZone) 773034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling Fn->addFnAttr(Attribute::NoRedZone); 77477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 77577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // Create basic blocks for function. 77677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn); 77777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling IRBuilder<> Builder(BB); 77877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 77977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn); 78077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn); 78177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn); 78277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 78377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // uint32_t pred = *predecessor; 78477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // if (pred == 0xffffffff) return; 78577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Argument *Arg = Fn->arg_begin(); 78677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg->setName("predecessor"); 78777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Pred = Builder.CreateLoad(Arg, "pred"); 788bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Value *Cond = Builder.CreateICmpEQ(Pred, Builder.getInt32(0xffffffff)); 78977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling BranchInst::Create(Exit, PredNotNegOne, Cond, BB); 79077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 79177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(PredNotNegOne); 79277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 79377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // uint64_t *counter = counters[pred]; 79477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // if (!counter) return; 795bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Value *ZExtPred = Builder.CreateZExt(Pred, Builder.getInt64Ty()); 79677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg = llvm::next(Fn->arg_begin()); 79777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Arg->setName("counters"); 79877b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *GEP = Builder.CreateGEP(Arg, ZExtPred); 79977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Counter = Builder.CreateLoad(GEP, "counter"); 80058591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky Cond = Builder.CreateICmpEQ(Counter, 80158591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky Constant::getNullValue( 80258591b1647e0f1f213e5acd7bfa87c226ced0033Nick Lewycky Builder.getInt64Ty()->getPointerTo())); 80377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateCondBr(Cond, Exit, CounterEnd); 80477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 80577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // ++*counter; 80677b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(CounterEnd); 80777b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter), 808bd2d1245e7db11b58b52c5b36fe76925683aaea5Nick Lewycky Builder.getInt64(1)); 80977b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateStore(Add, Counter); 81077b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateBr(Exit); 81177b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling 81277b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling // Fill in the exit block. 81377b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.SetInsertPoint(Exit); 81477b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling Builder.CreateRetVoid(); 81577b19134104c3e96424dc010f2b69c3faf580e68Bill Wendling} 816253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 817d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill WendlingFunction *GCOVProfiler:: 818253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill WendlinginsertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) { 819253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 820d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling Function *FlushF = M->getFunction("__llvm_gcov_flush"); 821253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (!FlushF) 822253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF = Function::Create(FTy, GlobalValue::InternalLinkage, 823d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling "__llvm_gcov_flush", M); 824253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else 825253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF->setLinkage(GlobalValue::InternalLinkage); 826253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling FlushF->setUnnamedAddr(true); 827034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling FlushF->addFnAttr(Attribute::NoInline); 828a204ef3168c8804808c716115ba915c89d8849b9Nick Lewycky if (Options.NoRedZone) 829034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling FlushF->addFnAttr(Attribute::NoRedZone); 830253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 831253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF); 832253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 833253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling // Write out the current counters. 834253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 835253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling assert(WriteoutF && "Need to create the writeout function first!"); 836253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 837253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling IRBuilder<> Builder(Entry); 838253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateCall(WriteoutF); 839253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 840032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling // Zero out the counters. 841032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling for (ArrayRef<std::pair<GlobalVariable *, MDNode *> >::iterator 842032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling I = CountersBySP.begin(), E = CountersBySP.end(); 843032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling I != E; ++I) { 844032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling GlobalVariable *GV = I->first; 845032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling Constant *Null = Constant::getNullValue(GV->getType()->getElementType()); 846ec3fc2eac0e9203dd1094b9ce458e8c1b42b832fBill Wendling Builder.CreateStore(Null, GV); 847032dbee2a9d401ee05beb648465f21168e279bdaBill Wendling } 848253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling 849253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Type *RetTy = FlushF->getReturnType(); 850253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling if (RetTy == Type::getVoidTy(*Ctx)) 851253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateRetVoid(); 852253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else if (RetTy->isIntegerTy()) 853d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling // Used if __llvm_gcov_flush was implicitly declared. 854253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling Builder.CreateRet(ConstantInt::get(RetTy, 0)); 855253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling else 856d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling report_fatal_error("invalid return type for __llvm_gcov_flush"); 857d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling 858d195eb6b83c2f3c70c9d1a59e26e8d6d2a3d38d3Bill Wendling return FlushF; 859253353c9cf1ff16d9c30a89c2fb96160ac5a9d65Bill Wendling} 860