llvm-6502/lib/Transforms/Instrumentation/BlockProfiling.cpp
Devang Patel 3e15bf33e0 Use 'static const char' instead of 'static const int'.
Due to darwin gcc bug, one version of darwin linker coalesces
static const int, which defauts PassID based pass identification.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36652 91177308-0d34-0410-b5e6-96231b3b80d8
2007-05-02 21:39:20 +00:00

127 lines
4.3 KiB
C++

//===- BlockProfiling.cpp - Insert counters for block profiling -----------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass instruments the specified program with counters for basic block or
// function profiling. This is the most basic form of profiling, which can tell
// which blocks are hot, but cannot reliably detect hot paths through the CFG.
// Block profiling counts the number of times each basic block executes, and
// function profiling counts the number of times each function is called.
//
// Note that this implementation is very naive. Control equivalent regions of
// the CFG should not require duplicate counters, but we do put duplicate
// counters in.
//
//===----------------------------------------------------------------------===//
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Streams.h"
#include "llvm/Transforms/Instrumentation.h"
#include "RSProfiling.h"
#include "ProfilingUtils.h"
using namespace llvm;
namespace {
class VISIBILITY_HIDDEN FunctionProfiler : public RSProfilers_std {
public:
static const char ID;
bool runOnModule(Module &M);
};
const char FunctionProfiler::ID = 0;
RegisterPass<FunctionProfiler> X("insert-function-profiling",
"Insert instrumentation for function profiling");
RegisterAnalysisGroup<RSProfilers> XG(X);
}
ModulePass *llvm::createFunctionProfilerPass() {
return new FunctionProfiler();
}
bool FunctionProfiler::runOnModule(Module &M) {
Function *Main = M.getFunction("main");
if (Main == 0) {
cerr << "WARNING: cannot insert function profiling into a module"
<< " with no main function!\n";
return false; // No main, no instrumentation!
}
unsigned NumFunctions = 0;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration())
++NumFunctions;
const Type *ATy = ArrayType::get(Type::Int32Ty, NumFunctions);
GlobalVariable *Counters =
new GlobalVariable(ATy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(ATy), "FuncProfCounters", &M);
// Instrument all of the functions...
unsigned i = 0;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration())
// Insert counter at the start of the function
IncrementCounterInBlock(I->begin(), i++, Counters);
// Add the initialization call to main.
InsertProfilingInitCall(Main, "llvm_start_func_profiling", Counters);
return true;
}
namespace {
class BlockProfiler : public RSProfilers_std {
bool runOnModule(Module &M);
public:
static const char ID;
};
const char BlockProfiler::ID = 0;
RegisterPass<BlockProfiler> Y("insert-block-profiling",
"Insert instrumentation for block profiling");
RegisterAnalysisGroup<RSProfilers> YG(Y);
}
ModulePass *llvm::createBlockProfilerPass() { return new BlockProfiler(); }
bool BlockProfiler::runOnModule(Module &M) {
Function *Main = M.getFunction("main");
if (Main == 0) {
cerr << "WARNING: cannot insert block profiling into a module"
<< " with no main function!\n";
return false; // No main, no instrumentation!
}
unsigned NumBlocks = 0;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
NumBlocks += I->size();
const Type *ATy = ArrayType::get(Type::Int32Ty, NumBlocks);
GlobalVariable *Counters =
new GlobalVariable(ATy, false, GlobalValue::InternalLinkage,
Constant::getNullValue(ATy), "BlockProfCounters", &M);
// Instrument all of the blocks...
unsigned i = 0;
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
for (Function::iterator BB = I->begin(), E = I->end(); BB != E; ++BB)
// Insert counter at the start of the block
IncrementCounterInBlock(BB, i++, Counters);
// Add the initialization call to main.
InsertProfilingInitCall(Main, "llvm_start_block_profiling", Counters);
return true;
}