#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/EHPersonalities.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CRC.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation/CFGMST.h"
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
#include "llvm/Transforms/Utils/Instrumentation.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <algorithm>
#include <memory>
#include <string>
#include <utility>
usingnamespacellvm;
endian;
#define DEBUG_TYPE …
enum : uint32_t { … };
static cl::opt<std::string> DefaultGCOVVersion("default-gcov-version",
cl::init("408*"), cl::Hidden,
cl::ValueRequired);
static cl::opt<bool> AtomicCounter("gcov-atomic-counter", cl::Hidden,
cl::desc("Make counter updates atomic"));
static unsigned wordsOfString(StringRef s) { … }
GCOVOptions GCOVOptions::getDefault() { … }
namespace {
class GCOVFunction;
class GCOVProfiler { … };
struct BBInfo { … };
struct Edge { … };
}
static StringRef getFunctionName(const DISubprogram *SP) { … }
static SmallString<128> getFilename(const DISubprogram *SP) { … }
namespace {
class GCOVRecord { … };
class GCOVFunction;
class GCOVBlock;
class GCOVLines : public GCOVRecord { … };
class GCOVBlock : public GCOVRecord { … };
class GCOVFunction : public GCOVRecord { … };
}
std::vector<Regex> GCOVProfiler::createRegexesFromString(StringRef RegexesStr) { … }
bool GCOVProfiler::doesFilenameMatchARegex(StringRef Filename,
std::vector<Regex> &Regexes) { … }
bool GCOVProfiler::isFunctionInstrumented(const Function &F) { … }
std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
GCovFileType OutputType) { … }
bool GCOVProfiler::runOnModule(
Module &M, function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
std::function<const TargetLibraryInfo &(Function &F)> GetTLI) { … }
PreservedAnalyses GCOVProfilerPass::run(Module &M,
ModuleAnalysisManager &AM) { … }
static bool functionHasLines(const Function &F, unsigned &EndLine) { … }
static bool isUsingScopeBasedEH(Function &F) { … }
bool GCOVProfiler::AddFlushBeforeForkAndExec() { … }
static BasicBlock *getInstrBB(CFGMST<Edge, BBInfo> &MST, Edge &E,
const DenseSet<const BasicBlock *> &ExecBlocks) { … }
#ifndef NDEBUG
static void dumpEdges(CFGMST<Edge, BBInfo> &MST, GCOVFunction &GF) {
size_t ID = 0;
for (const auto &E : make_pointee_range(MST.allEdges())) {
GCOVBlock &Src = E.SrcBB ? GF.getBlock(E.SrcBB) : GF.getEntryBlock();
GCOVBlock &Dst = E.DestBB ? GF.getBlock(E.DestBB) : GF.getReturnBlock();
dbgs() << " Edge " << ID++ << ": " << Src.Number << "->" << Dst.Number
<< E.infoString() << "\n";
}
}
#endif
bool GCOVProfiler::emitProfileNotes(
NamedMDNode *CUNode, bool HasExecOrFork,
function_ref<BlockFrequencyInfo *(Function &F)> GetBFI,
function_ref<BranchProbabilityInfo *(Function &F)> GetBPI,
function_ref<const TargetLibraryInfo &(Function &F)> GetTLI) { … }
Function *GCOVProfiler::createInternalFunction(FunctionType *FTy,
StringRef Name,
StringRef MangledType ) { … }
void GCOVProfiler::emitGlobalConstructor(
SmallVectorImpl<std::pair<GlobalVariable *, MDNode *>> &CountersBySP) { … }
FunctionCallee GCOVProfiler::getStartFileFunc(const TargetLibraryInfo *TLI) { … }
FunctionCallee GCOVProfiler::getEmitFunctionFunc(const TargetLibraryInfo *TLI) { … }
FunctionCallee GCOVProfiler::getEmitArcsFunc(const TargetLibraryInfo *TLI) { … }
FunctionCallee GCOVProfiler::getSummaryInfoFunc() { … }
FunctionCallee GCOVProfiler::getEndFileFunc() { … }
Function *GCOVProfiler::insertCounterWriteout(
ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) { … }
Function *GCOVProfiler::insertReset(
ArrayRef<std::pair<GlobalVariable *, MDNode *>> CountersBySP) { … }