Added documented rsprofiler interface. Also remove new profiler passes, the

old ones have been updated to implement the interface.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24499 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Lenharth 2005-11-28 18:00:38 +00:00
parent 1981c2e8dc
commit bb227c1b79
6 changed files with 93 additions and 139 deletions

View File

@ -44,8 +44,6 @@ ModulePass *createTraceBasicBlockPass();
FunctionPass *createProfilePathsPass(); FunctionPass *createProfilePathsPass();
// Random Sampling Profiling Framework // Random Sampling Profiling Framework
ModulePass* createBlockProfilerRSPass();
ModulePass* createFunctionProfilerRSPass();
ModulePass* createNullProfilerRSPass(); ModulePass* createNullProfilerRSPass();
FunctionPass* createRSProfilingPass(); FunctionPass* createRSProfilingPass();

View File

@ -106,8 +106,6 @@ namespace {
(void) llvm::createTraceValuesPassForFunction(); (void) llvm::createTraceValuesPassForFunction();
(void) llvm::createUnifyFunctionExitNodesPass(); (void) llvm::createUnifyFunctionExitNodesPass();
(void) llvm::createCondPropagationPass(); (void) llvm::createCondPropagationPass();
(void) llvm::createBlockProfilerRSPass();
(void) llvm::createFunctionProfilerRSPass();
(void) llvm::createNullProfilerRSPass(); (void) llvm::createNullProfilerRSPass();
(void) llvm::createRSProfilingPass(); (void) llvm::createRSProfilingPass();

View File

@ -0,0 +1,30 @@
//===- RSProfiling.cpp - Various profiling using random sampling ----------===//
//
// 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 file defines the abstract interface that a profiler must implement to
// support the random profiling transform.
//
//===----------------------------------------------------------------------===//
namespace llvm {
//===--------------------------------------------------------------------===//
/// RSProfilers - The basic Random Sampling Profiler Interface Any profiler
/// that implements this interface can be transformed by the random sampling
/// pass to be sample based rather than always on.
///
/// The only exposed function can be queried to find out if an instruction
/// was original or if it was inserted by the profiler. Implementations of
/// this interface are expected to chain to other implementations, such that
/// multiple profilers can be support simultaniously.
struct RSProfilers : public ModulePass {
/// isProfiling - This method returns true if the value passed it was
/// inserted by the profiler.
virtual bool isProfiling(Value* v) = 0;
};
};

View File

@ -24,18 +24,21 @@
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation.h"
#include "RSProfiling.h"
#include "ProfilingUtils.h" #include "ProfilingUtils.h"
#include <iostream> #include <iostream>
using namespace llvm; using namespace llvm;
namespace { namespace {
class FunctionProfiler : public ModulePass { class FunctionProfiler : public RSProfilers_std {
bool runOnModule(Module &M); bool runOnModule(Module &M);
}; };
RegisterOpt<FunctionProfiler> X("insert-function-profiling", RegisterOpt<FunctionProfiler> X("insert-function-profiling",
"Insert instrumentation for function profiling"); "Insert instrumentation for function profiling");
RegisterAnalysisGroup<RSProfilers, FunctionProfiler> XG;
} }
ModulePass *llvm::createFunctionProfilerPass() { ModulePass *llvm::createFunctionProfilerPass() {
@ -74,12 +77,13 @@ bool FunctionProfiler::runOnModule(Module &M) {
namespace { namespace {
class BlockProfiler : public ModulePass { class BlockProfiler : public RSProfilers_std {
bool runOnModule(Module &M); bool runOnModule(Module &M);
}; };
RegisterOpt<BlockProfiler> Y("insert-block-profiling", RegisterOpt<BlockProfiler> Y("insert-block-profiling",
"Insert instrumentation for block profiling"); "Insert instrumentation for block profiling");
RegisterAnalysisGroup<RSProfilers, BlockProfiler> YG;
} }
ModulePass *llvm::createBlockProfilerPass() { return new BlockProfiler(); } ModulePass *llvm::createBlockProfilerPass() { return new BlockProfiler(); }

View File

@ -10,7 +10,9 @@
// These passes implement a random sampling based profiling. Different methods // These passes implement a random sampling based profiling. Different methods
// of choosing when to sample are supported, as well as different types of // of choosing when to sample are supported, as well as different types of
// profiling. This is done as two passes. The first is a sequence of profiling // profiling. This is done as two passes. The first is a sequence of profiling
// passes which insert profiling into the program, and remember what they inserted. // passes which insert profiling into the program, and remember what they
// inserted.
//
// The second stage duplicates all instructions in a function, ignoring the // The second stage duplicates all instructions in a function, ignoring the
// profiling code, then connects the two versions togeather at the entry and at // profiling code, then connects the two versions togeather at the entry and at
// backedges. At each connection point a choice is made as to whether to jump // backedges. At each connection point a choice is made as to whether to jump
@ -31,9 +33,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Pass.h" #include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/BasicBlock.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
@ -43,7 +43,7 @@
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Instrumentation.h"
#include "ProfilingUtils.h" //#include "ProfilingUtils.h"
#include "RSProfiling.h" #include "RSProfiling.h"
#include <set> #include <set>
@ -65,19 +65,11 @@ namespace {
cl::desc("How to randomly choose to profile:"), cl::desc("How to randomly choose to profile:"),
cl::values( cl::values(
clEnumValN(GBV, "global", "global counter"), clEnumValN(GBV, "global", "global counter"),
clEnumValN(GBVO, "ra_global", "register allocated global counter"), clEnumValN(GBVO, "ra_global",
"register allocated global counter"),
clEnumValN(HOSTCC, "rdcc", "cycle counter"), clEnumValN(HOSTCC, "rdcc", "cycle counter"),
clEnumValEnd)); clEnumValEnd));
class FunctionProfilerRS : public RSProfilers {
bool runOnModule(Module &M);
};
class BlockProfilerRS : public RSProfilers {
bool runOnModule(Module &M);
};
class NullProfilerRS : public RSProfilers { class NullProfilerRS : public RSProfilers {
public: public:
bool isProfiling(Value* v) { bool isProfiling(Value* v) {
@ -95,13 +87,6 @@ namespace {
static RegisterOpt<NullProfilerRS> NP("insert-null-profiling-rs", static RegisterOpt<NullProfilerRS> NP("insert-null-profiling-rs",
"Measure profiling framework overhead"); "Measure profiling framework overhead");
static RegisterAnalysisGroup<RSProfilers, NullProfilerRS, true> NPT; static RegisterAnalysisGroup<RSProfilers, NullProfilerRS, true> NPT;
static RegisterOpt<BlockProfilerRS> BBP("insert-block-profiling-rs",
"Add block count instrumentation");
static RegisterAnalysisGroup<RSProfilers, BlockProfilerRS> BBPT;
static RegisterOpt<FunctionProfilerRS> FP("insert-function-profiling-rs",
"Add function count instrumentation");
static RegisterAnalysisGroup<RSProfilers, FunctionProfilerRS> FPT;
//Something that chooses how to sample //Something that chooses how to sample
class Chooser { class Chooser {
@ -203,17 +188,18 @@ void GlobalRandomCounter::ProcessChoicePoint(BasicBlock* bb) {
//decrement counter //decrement counter
LoadInst* l = new LoadInst(Counter, "counter", t); LoadInst* l = new LoadInst(Counter, "counter", t);
SetCondInst* s = new SetCondInst(Instruction::SetEQ, l, ConstantUInt::get(T, 0), SetCondInst* s = new SetCondInst(Instruction::SetEQ, l,
ConstantUInt::get(T, 0),
"countercc", t); "countercc", t);
Value* nv = BinaryOperator::create(Instruction::Sub, l, Value* nv = BinaryOperator::createSub(l, ConstantInt::get(T, 1),
ConstantInt::get(T, 1),
"counternew", t); "counternew", t);
new StoreInst(nv, Counter, t); new StoreInst(nv, Counter, t);
t->setCondition(s); t->setCondition(s);
//reset counter //reset counter
BasicBlock* oldnext = t->getSuccessor(0); BasicBlock* oldnext = t->getSuccessor(0);
BasicBlock* resetblock = new BasicBlock("reset", oldnext->getParent(), oldnext); BasicBlock* resetblock = new BasicBlock("reset", oldnext->getParent(),
oldnext);
TerminatorInst* t2 = new BranchInst(oldnext, resetblock); TerminatorInst* t2 = new BranchInst(oldnext, resetblock);
t->setSuccessor(0, resetblock); t->setSuccessor(0, resetblock);
new StoreInst(ResetValue, Counter, t2); new StoreInst(ResetValue, Counter, t2);
@ -274,17 +260,18 @@ void GlobalRandomCounterOpt::ProcessChoicePoint(BasicBlock* bb) {
//decrement counter //decrement counter
LoadInst* l = new LoadInst(AI, "counter", t); LoadInst* l = new LoadInst(AI, "counter", t);
SetCondInst* s = new SetCondInst(Instruction::SetEQ, l, ConstantUInt::get(T, 0), SetCondInst* s = new SetCondInst(Instruction::SetEQ, l,
ConstantUInt::get(T, 0),
"countercc", t); "countercc", t);
Value* nv = BinaryOperator::create(Instruction::Sub, l, Value* nv = BinaryOperator::createSub(l, ConstantInt::get(T, 1),
ConstantInt::get(T, 1),
"counternew", t); "counternew", t);
new StoreInst(nv, AI, t); new StoreInst(nv, AI, t);
t->setCondition(s); t->setCondition(s);
//reset counter //reset counter
BasicBlock* oldnext = t->getSuccessor(0); BasicBlock* oldnext = t->getSuccessor(0);
BasicBlock* resetblock = new BasicBlock("reset", oldnext->getParent(), oldnext); BasicBlock* resetblock = new BasicBlock("reset", oldnext->getParent(),
oldnext);
TerminatorInst* t2 = new BranchInst(oldnext, resetblock); TerminatorInst* t2 = new BranchInst(oldnext, resetblock);
t->setSuccessor(0, resetblock); t->setSuccessor(0, resetblock);
new StoreInst(ResetValue, AI, t2); new StoreInst(ResetValue, AI, t2);
@ -304,9 +291,12 @@ void CycleCounter::ProcessChoicePoint(BasicBlock* bb) {
BranchInst* t = cast<BranchInst>(bb->getTerminator()); BranchInst* t = cast<BranchInst>(bb->getTerminator());
CallInst* c = new CallInst(F, "rdcc", t); CallInst* c = new CallInst(F, "rdcc", t);
BinaryOperator* b = BinaryOperator::create(Instruction::And, c, ConstantUInt::get(Type::ULongTy, rm), "mrdcc", t); BinaryOperator* b =
BinaryOperator::createAnd(c, ConstantUInt::get(Type::ULongTy, rm),
"mrdcc", t);
SetCondInst* s = new SetCondInst(Instruction::SetEQ, b, ConstantUInt::get(Type::ULongTy, 0), SetCondInst* s = new SetCondInst(Instruction::SetEQ, b,
ConstantUInt::get(Type::ULongTy, 0),
"mrdccc", t); "mrdccc", t);
t->setCondition(s); t->setCondition(s);
} }
@ -314,7 +304,7 @@ void CycleCounter::ProcessChoicePoint(BasicBlock* bb) {
/////////////////////////////////////// ///////////////////////////////////////
// Profiling: // Profiling:
/////////////////////////////////////// ///////////////////////////////////////
bool RSProfilers::isProfiling(Value* v) { bool RSProfilers_std::isProfiling(Value* v) {
if (profcode.find(v) != profcode.end()) if (profcode.find(v) != profcode.end())
return true; return true;
//else //else
@ -322,7 +312,7 @@ bool RSProfilers::isProfiling(Value* v) {
return LI.isProfiling(v); return LI.isProfiling(v);
} }
void RSProfilers::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, void RSProfilers_std::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,
GlobalValue *CounterArray) { GlobalValue *CounterArray) {
// Insert the increment after any alloca or PHI instructions... // Insert the increment after any alloca or PHI instructions...
BasicBlock::iterator InsertPos = BB->begin(); BasicBlock::iterator InsertPos = BB->begin();
@ -338,77 +328,18 @@ void RSProfilers::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,
// Load, increment and store the value back. // Load, increment and store the value back.
Value *OldVal = new LoadInst(ElementPtr, "OldCounter", InsertPos); Value *OldVal = new LoadInst(ElementPtr, "OldCounter", InsertPos);
profcode.insert(OldVal); profcode.insert(OldVal);
Value *NewVal = BinaryOperator::create(Instruction::Add, OldVal, Value *NewVal = BinaryOperator::createAdd(OldVal,
ConstantInt::get(Type::UIntTy, 1), ConstantInt::get(Type::UIntTy, 1),
"NewCounter", InsertPos); "NewCounter", InsertPos);
profcode.insert(NewVal); profcode.insert(NewVal);
profcode.insert(new StoreInst(NewVal, ElementPtr, InsertPos)); profcode.insert(new StoreInst(NewVal, ElementPtr, InsertPos));
} }
void RSProfilers::getAnalysisUsage(AnalysisUsage &AU) const { void RSProfilers_std::getAnalysisUsage(AnalysisUsage &AU) const {
//grab any outstanding profiler, or get the null one //grab any outstanding profiler, or get the null one
AU.addRequired<RSProfilers>(); AU.addRequired<RSProfilers>();
} }
bool FunctionProfilerRS::runOnModule(Module &M) {
Function *Main = M.getMainFunction();
if (Main == 0) {
std::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->isExternal())
++NumFunctions;
const Type *ATy = ArrayType::get(Type::UIntTy, 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->isExternal())
// 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;
}
bool BlockProfilerRS::runOnModule(Module &M) {
Function *Main = M.getMainFunction();
if (Main == 0) {
std::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::UIntTy, 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;
}
/////////////////////////////////////// ///////////////////////////////////////
// RS Framework // RS Framework
/////////////////////////////////////// ///////////////////////////////////////
@ -421,7 +352,8 @@ Value* ProfilerRS::Translate(Value* v) {
if (bb == &bb->getParent()->getEntryBlock()) if (bb == &bb->getParent()->getEntryBlock())
TransCache[bb] = bb; //don't translate entry block TransCache[bb] = bb; //don't translate entry block
else else
TransCache[bb] = new BasicBlock("dup_" + bb->getName(), bb->getParent(), NULL); TransCache[bb] = new BasicBlock("dup_" + bb->getName(), bb->getParent(),
NULL);
return TransCache[bb]; return TransCache[bb];
} else if (Instruction* i = dyn_cast<Instruction>(v)) { } else if (Instruction* i = dyn_cast<Instruction>(v)) {
//we have already translated this //we have already translated this
@ -510,13 +442,14 @@ void ProfilerRS::ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F)
//a: //a:
BasicBlock* bbC = new BasicBlock("choice", &F, src->getNext() ); BasicBlock* bbC = new BasicBlock("choice", &F, src->getNext() );
//ChoicePoints.insert(bbC); //ChoicePoints.insert(bbC);
BasicBlock* bbCp = new BasicBlock("choice", &F, cast<BasicBlock>(Translate(src))->getNext() ); BasicBlock* bbCp =
new BasicBlock("choice", &F, cast<BasicBlock>(Translate(src))->getNext() );
ChoicePoints.insert(bbCp); ChoicePoints.insert(bbCp);
//b: //b:
//new BranchInst(dst, cast<BasicBlock>(Translate(dst)), ConstantBool::get(true), bbC);
new BranchInst(cast<BasicBlock>(Translate(dst)), bbC); new BranchInst(cast<BasicBlock>(Translate(dst)), bbC);
new BranchInst(dst, cast<BasicBlock>(Translate(dst)), ConstantBool::get(true), bbCp); new BranchInst(dst, cast<BasicBlock>(Translate(dst)),
ConstantBool::get(true), bbCp);
//c: //c:
{ {
TerminatorInst* iB = src->getTerminator(); TerminatorInst* iB = src->getTerminator();
@ -537,7 +470,8 @@ void ProfilerRS::ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F)
//thus collapse those edges int the Phi //thus collapse those edges int the Phi
CollapsePhi(dst, bbC); CollapsePhi(dst, bbC);
//f: //f:
ReplacePhiPred(cast<BasicBlock>(Translate(dst)),cast<BasicBlock>(Translate(src)),bbCp); ReplacePhiPred(cast<BasicBlock>(Translate(dst)),
cast<BasicBlock>(Translate(src)),bbCp);
CollapsePhi(cast<BasicBlock>(Translate(dst)), bbCp); CollapsePhi(cast<BasicBlock>(Translate(dst)), bbCp);
//g: //g:
for(BasicBlock::iterator ib = dst->begin(), ie = dst->end(); ib != ie; for(BasicBlock::iterator ib = dst->begin(), ie = dst->end(); ib != ie;
@ -546,7 +480,8 @@ void ProfilerRS::ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F)
for(unsigned x = 0; x < phi->getNumIncomingValues(); ++x) for(unsigned x = 0; x < phi->getNumIncomingValues(); ++x)
if(bbC == phi->getIncomingBlock(x)) { if(bbC == phi->getIncomingBlock(x)) {
phi->addIncoming(Translate(phi->getIncomingValue(x)), bbCp); phi->addIncoming(Translate(phi->getIncomingValue(x)), bbCp);
cast<PHINode>(Translate(phi))->addIncoming(phi->getIncomingValue(x), bbC); cast<PHINode>(Translate(phi))->addIncoming(phi->getIncomingValue(x),
bbC);
} }
phi->removeIncomingValue(bbC); phi->removeIncomingValue(bbC);
} }
@ -558,19 +493,15 @@ bool ProfilerRS::runOnFunction(Function& F) {
RSProfilers& LI = getAnalysis<RSProfilers>(); RSProfilers& LI = getAnalysis<RSProfilers>();
getBackEdges(F, BackEdges); getBackEdges(F, BackEdges);
DEBUG(
for (std::set<std::pair<BasicBlock*, BasicBlock*> >::iterator ii = BackEdges.begin();
ii != BackEdges.end(); ++ii)
std::cerr << ii->first->getName() << " -> " << ii->second->getName() << "\n";
);
Duplicate(F, LI); Duplicate(F, LI);
//assume that stuff worked. now connect the duplicated basic blocks //assume that stuff worked. now connect the duplicated basic blocks
//with the originals in such a way as to preserve ssa. yuk! //with the originals in such a way as to preserve ssa. yuk!
for (std::set<std::pair<BasicBlock*, BasicBlock*> >::iterator ib = BackEdges.begin(), for (std::set<std::pair<BasicBlock*, BasicBlock*> >::iterator
ie = BackEdges.end(); ib != ie; ++ib) ib = BackEdges.begin(), ie = BackEdges.end(); ib != ie; ++ib)
ProcessBackEdge(ib->first, ib->second, F); ProcessBackEdge(ib->first, ib->second, F);
//oh, and add the edge from the reg2mem created entry node to the duplicated second node //oh, and add the edge from the reg2mem created entry node to the
//duplicated second node
TerminatorInst* T = F.getEntryBlock().getTerminator(); TerminatorInst* T = F.getEntryBlock().getTerminator();
ReplaceInstWithInst(T, new BranchInst(T->getSuccessor(0), ReplaceInstWithInst(T, new BranchInst(T->getSuccessor(0),
cast<BasicBlock>(Translate(T->getSuccessor(0))), cast<BasicBlock>(Translate(T->getSuccessor(0))),
@ -582,8 +513,8 @@ bool ProfilerRS::runOnFunction(Function& F) {
//add entry node to choice points //add entry node to choice points
ChoicePoints.insert(&F.getEntryBlock()); ChoicePoints.insert(&F.getEntryBlock());
for (std::set<BasicBlock*>::iterator ii = ChoicePoints.begin(), ie = ChoicePoints.end(); for (std::set<BasicBlock*>::iterator
ii != ie; ++ii) ii = ChoicePoints.begin(), ie = ChoicePoints.end(); ii != ie; ++ii)
c->ProcessChoicePoint(*ii); c->ProcessChoicePoint(*ii);
ChoicePoints.clear(); ChoicePoints.clear();
@ -636,7 +567,7 @@ static void CollapsePhi(BasicBlock* btarget, BasicBlock* bsrc) {
std::map<BasicBlock*, Value*> counter; std::map<BasicBlock*, Value*> counter;
for(unsigned i = 0; i < phi->getNumIncomingValues(); ) { for(unsigned i = 0; i < phi->getNumIncomingValues(); ) {
if (counter[phi->getIncomingBlock(i)]) { if (counter[phi->getIncomingBlock(i)]) {
assert (phi->getIncomingValue(i) == counter[phi->getIncomingBlock(i)]); assert(phi->getIncomingValue(i) == counter[phi->getIncomingBlock(i)]);
phi->removeIncomingValue(i, false); phi->removeIncomingValue(i, false);
} else { } else {
counter[phi->getIncomingBlock(i)] = phi->getIncomingValue(i); counter[phi->getIncomingBlock(i)] = phi->getIncomingValue(i);
@ -686,14 +617,6 @@ static void getBackEdges(Function& F, T& BackEdges) {
//Creation functions //Creation functions
ModulePass* llvm::createBlockProfilerRSPass() {
return new BlockProfilerRS();
}
ModulePass* llvm::createFunctionProfilerRSPass() {
return new FunctionProfilerRS();
}
ModulePass* llvm::createNullProfilerRSPass() { ModulePass* llvm::createNullProfilerRSPass() {
return new NullProfilerRS(); return new NullProfilerRS();
} }

View File

@ -1,4 +1,4 @@
//===- RSProfiling.cpp - Various profiling using random sampling ----------===// //===- RSProfiling.h - Various profiling using random sampling ----------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -10,18 +10,19 @@
// See notes in RSProfiling.cpp // See notes in RSProfiling.cpp
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Transforms/RSProfiling.h"
namespace llvm { namespace llvm {
// By default, we provide some convienence stuff to clients, so they /// RSProfilers_std - a simple support class for profilers that handles most
// can just store the instructions they create to do profiling. /// of the work of chaining and tracking inserted code.
// also, handle all chaining issues. struct RSProfilers_std : public RSProfilers {
// a client is free to overwrite these, as long as it implements the
// chaining itself.
struct RSProfilers : public ModulePass {
std::set<Value*> profcode; std::set<Value*> profcode;
// Lookup up values in profcode
virtual bool isProfiling(Value* v); virtual bool isProfiling(Value* v);
virtual ~RSProfilers() {} // handles required chaining
virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual void getAnalysisUsage(AnalysisUsage &AU) const;
// places counter updates in basic blocks and recordes added instructions in
// profcode
void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, void IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,
GlobalValue *CounterArray); GlobalValue *CounterArray);
}; };