llvm-6502/lib/Transforms/Instrumentation/BlockProfiling.cpp
Reid Spencer 9133fe2895 Apply the VISIBILITY_HIDDEN field to the remaining anonymous classes in
the Transforms library. This reduces debug library size by 132 KB, debug
binary size by 376 KB, and reduces link time for llvm tools slightly.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33939 91177308-0d34-0410-b5e6-96231b3b80d8
2007-02-05 23:32:05 +00:00

120 lines
4.1 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 {
bool runOnModule(Module &M);
};
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);
};
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;
}