mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
Added documented rsprofiler interface. Also remove new profiler passes, the
old ones have been updated to implement the interface. llvm-svn: 24499
This commit is contained in:
parent
6992d365bf
commit
cad1d52b64
@ -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();
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
30
include/llvm/Transforms/RSProfiling.h
Normal file
30
include/llvm/Transforms/RSProfiling.h
Normal 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;
|
||||||
|
};
|
||||||
|
};
|
@ -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(); }
|
||||||
|
@ -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();
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user