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