//
// 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 is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// These passes implement a random sampling based profiling. Different methods
// 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
-// 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
// 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
// to the profiled code (take a sample) or execute the unprofiled code.
//
-// It is highly recommeneded that after this pass one runs mem2reg and adce
+// It is highly recommended that after this pass one runs mem2reg and adce
// (instcombine load-vn gdce dse also are good to run afterwards)
//
// This design is intended to make the profiling passes independent of the RS
//===----------------------------------------------------------------------===//
#include "llvm/Pass.h"
-#include "llvm/Function.h"
#include "llvm/Module.h"
-#include "llvm/BasicBlock.h"
#include "llvm/Instructions.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/Intrinsics.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
-#include "llvm/ADT/Statistic.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/Instrumentation.h"
-#include "ProfilingUtils.h"
#include "RSProfiling.h"
-
#include <set>
#include <map>
#include <queue>
#include <list>
-#include <iostream>
-
using namespace llvm;
namespace {
- Statistic<> NumBackEdges("bedge", "Number of BackEdges");
-
enum RandomMeth {
GBV, GBVO, HOSTCC
};
+}
- cl::opt<RandomMeth> RandomMethod("profile-randomness",
- cl::desc("How to randomly choose to profile:"),
- cl::values(
- clEnumValN(GBV, "global", "global counter"),
- clEnumValN(GBVO, "ra_global", "register allocated global counter"),
- clEnumValN(HOSTCC, "rdcc", "cycle counter"),
- clEnumValEnd));
+static cl::opt<RandomMeth> RandomMethod("profile-randomness",
+ cl::desc("How to randomly choose to profile:"),
+ cl::values(
+ clEnumValN(GBV, "global", "global counter"),
+ clEnumValN(GBVO, "ra_global",
+ "register allocated global counter"),
+ clEnumValN(HOSTCC, "rdcc", "cycle counter"),
+ clEnumValEnd));
-
- class FunctionProfilerRS : public RSProfilers {
- bool runOnModule(Module &M);
- };
-
- class BlockProfilerRS : public RSProfilers {
- bool runOnModule(Module &M);
- };
-
- class NullProfilerRS : public RSProfilers {
+namespace {
+ /// NullProfilerRS - The basic profiler that does nothing. It is the default
+ /// profiler and thus terminates RSProfiler chains. It is useful for
+ /// measuring framework overhead
+ class VISIBILITY_HIDDEN NullProfilerRS : public RSProfilers {
public:
+ static char ID; // Pass identification, replacement for typeid
bool isProfiling(Value* v) {
return false;
}
AU.setPreservesAll();
}
};
+}
- static RegisterAnalysisGroup<RSProfilers> A("Profiling passes");
- static RegisterOpt<NullProfilerRS> NP("insert-null-profiling-rs",
- "Measure profiling framework overhead");
- 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;
-
+static RegisterAnalysisGroup<RSProfilers> A("Profiling passes");
+static RegisterPass<NullProfilerRS> NP("insert-null-profiling-rs",
+ "Measure profiling framework overhead");
+static RegisterAnalysisGroup<RSProfilers, true> NPT(NP);
- //Something that chooses how to sample
- class Chooser {
+namespace {
+ /// Chooser - Something that chooses when to make a sample of the profiled code
+ class VISIBILITY_HIDDEN Chooser {
public:
+ /// ProcessChoicePoint - is called for each basic block inserted to choose
+ /// between normal and sample code
virtual void ProcessChoicePoint(BasicBlock*) = 0;
+ /// PrepFunction - is called once per function before other work is done.
+ /// This gives the opertunity to insert new allocas and such.
virtual void PrepFunction(Function*) = 0;
virtual ~Chooser() {}
};
//Things that implement sampling policies
- class GlobalRandomCounter : public Chooser {
+ //A global value that is read-mod-stored to choose when to sample.
+ //A sample is taken when the global counter hits 0
+ class VISIBILITY_HIDDEN GlobalRandomCounter : public Chooser {
GlobalVariable* Counter;
Value* ResetValue;
const Type* T;
virtual void ProcessChoicePoint(BasicBlock* bb);
};
- class GlobalRandomCounterOpt : public Chooser {
+ //Same is GRC, but allow register allocation of the global counter
+ class VISIBILITY_HIDDEN GlobalRandomCounterOpt : public Chooser {
GlobalVariable* Counter;
Value* ResetValue;
AllocaInst* AI;
virtual void ProcessChoicePoint(BasicBlock* bb);
};
- class CycleCounter : public Chooser {
+ //Use the cycle counter intrinsic as a source of pseudo randomness when
+ //deciding when to sample.
+ class VISIBILITY_HIDDEN CycleCounter : public Chooser {
uint64_t rm;
- Function* F;
+ Constant *F;
public:
CycleCounter(Module& m, uint64_t resetmask);
virtual ~CycleCounter();
virtual void ProcessChoicePoint(BasicBlock* bb);
};
+ /// ProfilerRS - Insert the random sampling framework
+ struct VISIBILITY_HIDDEN ProfilerRS : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ ProfilerRS() : FunctionPass((intptr_t)&ID) {}
- struct ProfilerRS : public FunctionPass {
std::map<Value*, Value*> TransCache;
std::set<BasicBlock*> ChoicePoints;
Chooser* c;
+ //Translate and duplicate values for the new profile free version of stuff
Value* Translate(Value* v);
+ //Duplicate an entire function (with out profiling)
void Duplicate(Function& F, RSProfilers& LI);
+ //Called once for each backedge, handle the insertion of choice points and
+ //the interconection of the two versions of the code
void ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F);
bool runOnFunction(Function& F);
bool doInitialization(Module &M);
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
};
+}
- RegisterOpt<ProfilerRS> X("insert-rs-profiling-framework",
- "Insert random sampling instrumentation framework");
-};
+static RegisterPass<ProfilerRS>
+X("insert-rs-profiling-framework",
+ "Insert random sampling instrumentation framework");
+
+char RSProfilers::ID = 0;
+char NullProfilerRS::ID = 0;
+char ProfilerRS::ID = 0;
//Local utilities
static void ReplacePhiPred(BasicBlock* btarget,
GlobalRandomCounter::GlobalRandomCounter(Module& M, const Type* t,
uint64_t resetval) : T(t) {
+ ConstantInt* Init = ConstantInt::get(T, resetval);
+ ResetValue = Init;
Counter = new GlobalVariable(T, false, GlobalValue::InternalLinkage,
- ConstantUInt::get(T, resetval),
- "RandomSteeringCounter", &M);
- ResetValue = ConstantUInt::get(T, resetval);
+ Init, "RandomSteeringCounter", &M);
}
GlobalRandomCounter::~GlobalRandomCounter() {}
//decrement counter
LoadInst* l = new LoadInst(Counter, "counter", t);
- SetCondInst* s = new SetCondInst(Instruction::SetEQ, l, ConstantUInt::get(T, 0),
- "countercc", t);
- Value* nv = BinaryOperator::create(Instruction::Sub, l,
- ConstantInt::get(T, 1),
- "counternew", t);
+ ICmpInst* s = new ICmpInst(ICmpInst::ICMP_EQ, l, ConstantInt::get(T, 0),
+ "countercc", t);
+
+ Value* nv = BinaryOperator::createSub(l, ConstantInt::get(T, 1),
+ "counternew", t);
new StoreInst(nv, Counter, t);
t->setCondition(s);
//reset counter
BasicBlock* oldnext = t->getSuccessor(0);
- BasicBlock* resetblock = new BasicBlock("reset", oldnext->getParent(), oldnext);
- TerminatorInst* t2 = new BranchInst(oldnext, resetblock);
+ BasicBlock* resetblock = BasicBlock::Create("reset", oldnext->getParent(),
+ oldnext);
+ TerminatorInst* t2 = BranchInst::Create(oldnext, resetblock);
t->setSuccessor(0, resetblock);
new StoreInst(ResetValue, Counter, t2);
ReplacePhiPred(oldnext, bb, resetblock);
GlobalRandomCounterOpt::GlobalRandomCounterOpt(Module& M, const Type* t,
uint64_t resetval)
: AI(0), T(t) {
+ ConstantInt* Init = ConstantInt::get(T, resetval);
+ ResetValue = Init;
Counter = new GlobalVariable(T, false, GlobalValue::InternalLinkage,
- ConstantUInt::get(T, resetval),
- "RandomSteeringCounter", &M);
- ResetValue = ConstantUInt::get(T, resetval);
+ Init, "RandomSteeringCounter", &M);
}
GlobalRandomCounterOpt::~GlobalRandomCounterOpt() {}
void GlobalRandomCounterOpt::PrepFunction(Function* F) {
//make a local temporary to cache the global
BasicBlock& bb = F->getEntryBlock();
- AI = new AllocaInst(T, 0, "localcounter", bb.begin());
- LoadInst* l = new LoadInst(Counter, "counterload", AI->getNext());
- new StoreInst(l, AI, l->getNext());
+ BasicBlock::iterator InsertPt = bb.begin();
+ AI = new AllocaInst(T, 0, "localcounter", InsertPt);
+ LoadInst* l = new LoadInst(Counter, "counterload", InsertPt);
+ new StoreInst(l, AI, InsertPt);
- //modify all functions and return values
+ //modify all functions and return values to restore the local variable to/from
+ //the global variable
for(Function::iterator fib = F->begin(), fie = F->end();
fib != fie; ++fib)
for(BasicBlock::iterator bib = fib->begin(), bie = fib->end();
bib != bie; ++bib)
- if (isa<CallInst>(&*bib)) {
+ if (isa<CallInst>(bib)) {
LoadInst* l = new LoadInst(AI, "counter", bib);
new StoreInst(l, Counter, bib);
- l = new LoadInst(Counter, "counter", bib->getNext());
- new StoreInst(l, AI, l->getNext());
- } else if (isa<InvokeInst>(&*bib)) {
+ l = new LoadInst(Counter, "counter", ++bib);
+ new StoreInst(l, AI, bib--);
+ } else if (isa<InvokeInst>(bib)) {
LoadInst* l = new LoadInst(AI, "counter", bib);
new StoreInst(l, Counter, bib);
- BasicBlock* bb = cast<InvokeInst>(&*bib)->getNormalDest();
- Instruction* i = bb->begin();
- while (isa<PHINode>(i)) i = i->getNext();
+ BasicBlock* bb = cast<InvokeInst>(bib)->getNormalDest();
+ BasicBlock::iterator i = bb->begin();
+ while (isa<PHINode>(i))
+ ++i;
l = new LoadInst(Counter, "counter", i);
- bb = cast<InvokeInst>(&*bib)->getUnwindDest();
+ bb = cast<InvokeInst>(bib)->getUnwindDest();
i = bb->begin();
- while (isa<PHINode>(i)) i = i->getNext();
+ while (isa<PHINode>(i)) ++i;
l = new LoadInst(Counter, "counter", i);
- new StoreInst(l, AI, l->getNext());
+ new StoreInst(l, AI, i);
} else if (isa<UnwindInst>(&*bib) || isa<ReturnInst>(&*bib)) {
LoadInst* l = new LoadInst(AI, "counter", bib);
new StoreInst(l, Counter, bib);
//decrement counter
LoadInst* l = new LoadInst(AI, "counter", t);
- SetCondInst* s = new SetCondInst(Instruction::SetEQ, l, ConstantUInt::get(T, 0),
- "countercc", t);
- Value* nv = BinaryOperator::create(Instruction::Sub, l,
- ConstantInt::get(T, 1),
- "counternew", t);
+ ICmpInst* s = new ICmpInst(ICmpInst::ICMP_EQ, l, ConstantInt::get(T, 0),
+ "countercc", t);
+
+ Value* nv = BinaryOperator::createSub(l, ConstantInt::get(T, 1),
+ "counternew", t);
new StoreInst(nv, AI, t);
t->setCondition(s);
//reset counter
BasicBlock* oldnext = t->getSuccessor(0);
- BasicBlock* resetblock = new BasicBlock("reset", oldnext->getParent(), oldnext);
- TerminatorInst* t2 = new BranchInst(oldnext, resetblock);
+ BasicBlock* resetblock = BasicBlock::Create("reset", oldnext->getParent(),
+ oldnext);
+ TerminatorInst* t2 = BranchInst::Create(oldnext, resetblock);
t->setSuccessor(0, resetblock);
new StoreInst(ResetValue, AI, t2);
ReplacePhiPred(oldnext, bb, resetblock);
CycleCounter::CycleCounter(Module& m, uint64_t resetmask) : rm(resetmask) {
- F = m.getOrInsertFunction("llvm.readcyclecounter", Type::ULongTy, NULL);
+ F = Intrinsic::getDeclaration(&m, Intrinsic::readcyclecounter);
}
CycleCounter::~CycleCounter() {}
void CycleCounter::ProcessChoicePoint(BasicBlock* bb) {
BranchInst* t = cast<BranchInst>(bb->getTerminator());
- CallInst* c = new CallInst(F, "rdcc", t);
- BinaryOperator* b = BinaryOperator::create(Instruction::And, c, ConstantUInt::get(Type::ULongTy, rm), "mrdcc", t);
+ CallInst* c = CallInst::Create(F, "rdcc", t);
+ BinaryOperator* b =
+ BinaryOperator::createAnd(c, ConstantInt::get(Type::Int64Ty, rm),
+ "mrdcc", t);
- SetCondInst* s = new SetCondInst(Instruction::SetEQ, b, ConstantUInt::get(Type::ULongTy, 0),
- "mrdccc", t);
+ ICmpInst *s = new ICmpInst(ICmpInst::ICMP_EQ, b,
+ ConstantInt::get(Type::Int64Ty, 0),
+ "mrdccc", t);
+
t->setCondition(s);
}
///////////////////////////////////////
// Profiling:
///////////////////////////////////////
-bool RSProfilers::isProfiling(Value* v) {
+bool RSProfilers_std::isProfiling(Value* v) {
if (profcode.find(v) != profcode.end())
return true;
//else
return LI.isProfiling(v);
}
-void RSProfilers::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,
+void RSProfilers_std::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,
GlobalValue *CounterArray) {
// Insert the increment after any alloca or PHI instructions...
BasicBlock::iterator InsertPos = BB->begin();
// Create the getelementptr constant expression
std::vector<Constant*> Indices(2);
- Indices[0] = Constant::getNullValue(Type::IntTy);
- Indices[1] = ConstantSInt::get(Type::IntTy, CounterNum);
- Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray, Indices);
+ Indices[0] = Constant::getNullValue(Type::Int32Ty);
+ Indices[1] = ConstantInt::get(Type::Int32Ty, CounterNum);
+ Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray,
+ &Indices[0], 2);
// Load, increment and store the value back.
Value *OldVal = new LoadInst(ElementPtr, "OldCounter", InsertPos);
profcode.insert(OldVal);
- Value *NewVal = BinaryOperator::create(Instruction::Add, OldVal,
- ConstantInt::get(Type::UIntTy, 1),
- "NewCounter", InsertPos);
+ Value *NewVal = BinaryOperator::createAdd(OldVal,
+ ConstantInt::get(Type::Int32Ty, 1),
+ "NewCounter", InsertPos);
profcode.insert(NewVal);
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
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
///////////////////////////////////////
if (bb == &bb->getParent()->getEntryBlock())
TransCache[bb] = bb; //don't translate entry block
else
- TransCache[bb] = new BasicBlock("dup_" + bb->getName(), bb->getParent(), NULL);
+ TransCache[bb] = BasicBlock::Create("dup_" + bb->getName(), bb->getParent(),
+ NULL);
return TransCache[bb];
} else if (Instruction* i = dyn_cast<Instruction>(v)) {
//we have already translated this
// add in edge from C using x in A'
//a:
- BasicBlock* bbC = new BasicBlock("choice", &F, src->getNext() );
+ Function::iterator BBN = src; ++BBN;
+ BasicBlock* bbC = BasicBlock::Create("choice", &F, BBN);
//ChoicePoints.insert(bbC);
- BasicBlock* bbCp = new BasicBlock("choice", &F, cast<BasicBlock>(Translate(src))->getNext() );
+ BBN = cast<BasicBlock>(Translate(src));
+ BasicBlock* bbCp = BasicBlock::Create("choice", &F, ++BBN);
ChoicePoints.insert(bbCp);
//b:
- //new BranchInst(dst, cast<BasicBlock>(Translate(dst)), ConstantBool::get(true), bbC);
- new BranchInst(cast<BasicBlock>(Translate(dst)), bbC);
- new BranchInst(dst, cast<BasicBlock>(Translate(dst)), ConstantBool::get(true), bbCp);
+ BranchInst::Create(cast<BasicBlock>(Translate(dst)), bbC);
+ BranchInst::Create(dst, cast<BasicBlock>(Translate(dst)),
+ ConstantInt::get(Type::Int1Ty, true), bbCp);
//c:
{
TerminatorInst* iB = src->getTerminator();
//thus collapse those edges int the Phi
CollapsePhi(dst, bbC);
//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);
//g:
for(BasicBlock::iterator ib = dst->begin(), ie = dst->end(); ib != ie;
for(unsigned x = 0; x < phi->getNumIncomingValues(); ++x)
if(bbC == phi->getIncomingBlock(x)) {
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);
}
}
bool ProfilerRS::runOnFunction(Function& F) {
- if (!F.isExternal()) {
+ if (!F.isDeclaration()) {
std::set<std::pair<BasicBlock*, BasicBlock*> > BackEdges;
RSProfilers& LI = getAnalysis<RSProfilers>();
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);
//assume that stuff worked. now connect the duplicated basic blocks
//with the originals in such a way as to preserve ssa. yuk!
- for (std::set<std::pair<BasicBlock*, BasicBlock*> >::iterator ib = BackEdges.begin(),
- ie = BackEdges.end(); ib != ie; ++ib)
+ for (std::set<std::pair<BasicBlock*, BasicBlock*> >::iterator
+ ib = BackEdges.begin(), ie = BackEdges.end(); ib != ie; ++ib)
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();
- ReplaceInstWithInst(T, new BranchInst(T->getSuccessor(0),
- cast<BasicBlock>(Translate(T->getSuccessor(0))),
- ConstantBool::get(true)));
+ ReplaceInstWithInst(T, BranchInst::Create(T->getSuccessor(0),
+ cast<BasicBlock>(
+ Translate(T->getSuccessor(0))),
+ ConstantInt::get(Type::Int1Ty,
+ true)));
//do whatever is needed now that the function is duplicated
c->PrepFunction(&F);
//add entry node to choice points
ChoicePoints.insert(&F.getEntryBlock());
- for (std::set<BasicBlock*>::iterator ii = ChoicePoints.begin(), ie = ChoicePoints.end();
- ii != ie; ++ii)
+ for (std::set<BasicBlock*>::iterator
+ ii = ChoicePoints.begin(), ie = ChoicePoints.end(); ii != ie; ++ii)
c->ProcessChoicePoint(*ii);
ChoicePoints.clear();
bool ProfilerRS::doInitialization(Module &M) {
switch (RandomMethod) {
case GBV:
- c = new GlobalRandomCounter(M, Type::UIntTy, (1 << 14) - 1);
+ c = new GlobalRandomCounter(M, Type::Int32Ty, (1 << 14) - 1);
break;
case GBVO:
- c = new GlobalRandomCounterOpt(M, Type::UIntTy, (1 << 14) - 1);
+ c = new GlobalRandomCounterOpt(M, Type::Int32Ty, (1 << 14) - 1);
break;
case HOSTCC:
c = new CycleCounter(M, (1 << 14) - 1);
for(BasicBlock::iterator ib = btarget->begin(), ie = btarget->end();
ib != ie; ++ib)
if (PHINode* phi = dyn_cast<PHINode>(&*ib)) {
- unsigned total = phi->getNumIncomingValues();
std::map<BasicBlock*, Value*> counter;
for(unsigned i = 0; i < phi->getNumIncomingValues(); ) {
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);
} else {
counter[phi->getIncomingBlock(i)] = phi->getIncomingValue(i);
std::map<BasicBlock*, int> finish;
int time = 0;
recBackEdge(&F.getEntryBlock(), BackEdges, color, depth, finish, time);
- DEBUG(std::cerr << F.getName() << " " << BackEdges.size() << "\n");
+ DOUT << F.getName() << " " << BackEdges.size() << "\n";
}
//Creation functions
-ModulePass* llvm::createBlockProfilerRSPass() {
- return new BlockProfilerRS();
-}
-
-ModulePass* llvm::createFunctionProfilerRSPass() {
- return new FunctionProfilerRS();
-}
-
ModulePass* llvm::createNullProfilerRSPass() {
return new NullProfilerRS();
}