aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Instrumentation/LineProfiling.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/Instrumentation/LineProfiling.cpp')
-rw-r--r--lib/Transforms/Instrumentation/LineProfiling.cpp217
1 files changed, 0 insertions, 217 deletions
diff --git a/lib/Transforms/Instrumentation/LineProfiling.cpp b/lib/Transforms/Instrumentation/LineProfiling.cpp
deleted file mode 100644
index 5628c3a811..0000000000
--- a/lib/Transforms/Instrumentation/LineProfiling.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-//===- LineProfiling.cpp - Insert counters for line profiling -------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This pass creates counters for the number of times that the original source
-// lines of code were executed.
-//
-// The lines are found from existing debug info in the LLVM IR. Iterating
-// through LLVM instructions, every time the debug location changes we insert a
-// new counter and instructions to increment the counter there. A global
-// destructor runs to dump the counters out to a file.
-//
-//===----------------------------------------------------------------------===//
-
-#define DEBUG_TYPE "insert-line-profiling"
-
-#include "ProfilingUtils.h"
-#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Analysis/DebugInfo.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/Instructions.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/DebugLoc.h"
-#include "llvm/Support/InstIterator.h"
-#include "llvm/Support/IRBuilder.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
-#include <set>
-#include <string>
-using namespace llvm;
-
-STATISTIC(NumUpdatesInserted, "The # of counter increments inserted.");
-
-namespace {
- class LineProfiler : public ModulePass {
- bool runOnModule(Module &M);
- public:
- static char ID;
- LineProfiler() : ModulePass(ID) {
- initializeLineProfilerPass(*PassRegistry::getPassRegistry());
- }
- virtual const char *getPassName() const {
- return "Line Profiler";
- }
-
- private:
- // Get pointers to the functions in the runtime library.
- Constant *getStartFileFunc();
- Constant *getCounterFunc();
- Constant *getEndFileFunc();
-
- // Insert an increment of the counter before instruction I.
- void InsertCounterUpdateBefore(Instruction *I);
-
- // Add the function to write out all our counters to the global destructor
- // list.
- void InsertCounterWriteout();
-
- // Mapping from the source location to the counter tracking that location.
- DenseMap<DebugLoc, GlobalVariable *> counters;
-
- Module *Mod;
- LLVMContext *Ctx;
- };
-}
-
-char LineProfiler::ID = 0;
-INITIALIZE_PASS(LineProfiler, "insert-line-profiling",
- "Insert instrumentation for line profiling", false, false)
-
-ModulePass *llvm::createLineProfilerPass() { return new LineProfiler(); }
-
-bool LineProfiler::runOnModule(Module &M) {
- Mod = &M;
- Ctx = &M.getContext();
-
- DebugLoc last_line; // initializes to unknown
- bool Changed = false;
- for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
- for (inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE; ++II) {
- const DebugLoc &loc = II->getDebugLoc();
- if (loc.isUnknown()) continue;
- if (loc == last_line) continue;
- last_line = loc;
-
- InsertCounterUpdateBefore(&*II);
- ++NumUpdatesInserted;
- Changed = true;
- }
- }
-
- if (Changed) {
- InsertCounterWriteout();
- }
-
- return Changed;
-}
-
-void LineProfiler::InsertCounterUpdateBefore(Instruction *I) {
- const DebugLoc &loc = I->getDebugLoc();
- GlobalVariable *&counter = counters[loc];
- const Type *Int64Ty = Type::getInt64Ty(*Ctx);
- if (!counter) {
- counter = new GlobalVariable(*Mod, Int64Ty, false,
- GlobalValue::InternalLinkage,
- Constant::getNullValue(Int64Ty),
- "__llvm_prof_linecov_ctr", 0, false, 0);
- counter->setVisibility(GlobalVariable::HiddenVisibility);
- counter->setUnnamedAddr(true);
- }
-
- if (isa<PHINode>(I)) {
- // We may not error out or crash in this case, because a module could put
- // changing line numbers on phi nodes and still pass the verifier.
- dbgs() << "Refusing to insert code before phi: " << *I << "\n";
- I = I->getParent()->getFirstNonPHI();
- }
-
- IRBuilder<> builder(I);
- Value *ctr = builder.CreateLoad(counter);
- ctr = builder.CreateAdd(ctr, ConstantInt::get(Int64Ty, 1));
- builder.CreateStore(ctr, counter);
-}
-
-static DISubprogram FindSubprogram(DIScope scope) {
- while (!scope.isSubprogram()) {
- assert(scope.isLexicalBlock() &&
- "Debug location not lexical block or subprogram");
- scope = DILexicalBlock(scope).getContext();
- }
- return DISubprogram(scope);
-}
-
-Constant *LineProfiler::getStartFileFunc() {
- const Type *Args[1] = { Type::getInt8PtrTy(*Ctx) };
- const FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
- Args, false);
- return Mod->getOrInsertFunction("llvm_prof_linectr_start_file", FTy);
-}
-
-Constant *LineProfiler::getCounterFunc() {
- const Type *Args[] = {
- Type::getInt8PtrTy(*Ctx), // const char *dir
- Type::getInt8PtrTy(*Ctx), // const char *file
- Type::getInt32Ty(*Ctx), // uint32_t line
- Type::getInt32Ty(*Ctx), // uint32_t column
- Type::getInt64PtrTy(*Ctx), // int64_t *counter
- };
- const FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx),
- Args, false);
- return Mod->getOrInsertFunction("llvm_prof_linectr_emit_counter", FTy);
-}
-
-Constant *LineProfiler::getEndFileFunc() {
- const FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false);
- return Mod->getOrInsertFunction("llvm_prof_linectr_end_file", FTy);
-}
-
-void LineProfiler::InsertCounterWriteout() {
- std::set<std::string> compile_units;
- for (DenseMap<DebugLoc, GlobalVariable *>::iterator I = counters.begin(),
- E = counters.end(); I != E; ++I) {
- const DebugLoc &loc = I->first;
- DISubprogram subprogram(FindSubprogram(DIScope(loc.getScope(*Ctx))));
- compile_units.insert(subprogram.getCompileUnit().getFilename().str());
- }
-
- const FunctionType *WriteoutFTy =
- FunctionType::get(Type::getVoidTy(*Ctx), false);
- Function *WriteoutF = Function::Create(WriteoutFTy,
- GlobalValue::InternalLinkage,
- "__llvm_prof_linecov_dtor",
- Mod);
- WriteoutF->setUnnamedAddr(true);
- BasicBlock *BB = BasicBlock::Create(*Ctx, "", WriteoutF);
- IRBuilder<> builder(BB);
-
- Constant *StartFile = getStartFileFunc();
- Constant *EmitCounter = getCounterFunc();
- Constant *EndFile = getEndFileFunc();
-
- for (std::set<std::string>::const_iterator CUI = compile_units.begin(),
- CUE = compile_units.end(); CUI != CUE; ++CUI) {
- builder.CreateCall(StartFile,
- builder.CreateGlobalStringPtr(*CUI));
- for (DenseMap<DebugLoc, GlobalVariable *>::iterator I = counters.begin(),
- E = counters.end(); I != E; ++I) {
- const DebugLoc &loc = I->first;
- DISubprogram subprogram(FindSubprogram(DIScope(loc.getScope(*Ctx))));
- DICompileUnit compileunit(subprogram.getCompileUnit());
-
- if (compileunit.getFilename() != *CUI)
- continue;
-
- Value *Args[] = {
- builder.CreateGlobalStringPtr(subprogram.getDirectory()),
- builder.CreateGlobalStringPtr(subprogram.getFilename()),
- ConstantInt::get(Type::getInt32Ty(*Ctx), loc.getLine()),
- ConstantInt::get(Type::getInt32Ty(*Ctx), loc.getCol()),
- I->second
- };
- builder.CreateCall(EmitCounter, Args);
- }
- builder.CreateCall(EndFile);
- }
- builder.CreateRetVoid();
-
- InsertProfilingShutdownCall(WriteoutF, Mod);
-}