X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FInstrumentation%2FRSProfiling.cpp;h=45a7c712d8c7168368c3418de95d400abd64772a;hb=8f613f30a78aa9d93d08a209b6c159c2000d8d6c;hp=5d6654d504ae84238fdf25d3a188ce47d52c8f95;hpb=b83eb6447ba155342598f0fabe1f08f5baa9164a;p=oota-llvm.git diff --git a/lib/Transforms/Instrumentation/RSProfiling.cpp b/lib/Transforms/Instrumentation/RSProfiling.cpp index 5d6654d504a..45a7c712d8c 100644 --- a/lib/Transforms/Instrumentation/RSProfiling.cpp +++ b/lib/Transforms/Instrumentation/RSProfiling.cpp @@ -2,8 +2,8 @@ // // 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. // //===----------------------------------------------------------------------===// // @@ -18,7 +18,7 @@ // 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 @@ -37,44 +37,41 @@ #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 #include #include -#include -#include - using namespace llvm; namespace { - Statistic<> NumBackEdges("bedge", "Number of BackEdges"); - enum RandomMeth { GBV, GBVO, HOSTCC }; +} - cl::opt 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 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)); +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 NullProfilerRS : public RSProfilers { + class VISIBILITY_HIDDEN NullProfilerRS : public RSProfilers { public: + static char ID; // Pass identification, replacement for typeid bool isProfiling(Value* v) { return false; } @@ -85,14 +82,16 @@ namespace { AU.setPreservesAll(); } }; +} - static RegisterAnalysisGroup A("Profiling passes"); - static RegisterPass NP("insert-null-profiling-rs", - "Measure profiling framework overhead"); - static RegisterAnalysisGroup NPT(NP); +static RegisterAnalysisGroup A("Profiling passes"); +static RegisterPass NP("insert-null-profiling-rs", + "Measure profiling framework overhead"); +static RegisterAnalysisGroup NPT(NP); +namespace { /// Chooser - Something that chooses when to make a sample of the profiled code - class Chooser { + class VISIBILITY_HIDDEN Chooser { public: /// ProcessChoicePoint - is called for each basic block inserted to choose /// between normal and sample code @@ -106,7 +105,7 @@ namespace { //Things that implement sampling policies //A global value that is read-mod-stored to choose when to sample. //A sample is taken when the global counter hits 0 - class GlobalRandomCounter : public Chooser { + class VISIBILITY_HIDDEN GlobalRandomCounter : public Chooser { GlobalVariable* Counter; Value* ResetValue; const Type* T; @@ -118,7 +117,7 @@ namespace { }; //Same is GRC, but allow register allocation of the global counter - class GlobalRandomCounterOpt : public Chooser { + class VISIBILITY_HIDDEN GlobalRandomCounterOpt : public Chooser { GlobalVariable* Counter; Value* ResetValue; AllocaInst* AI; @@ -132,9 +131,9 @@ namespace { //Use the cycle counter intrinsic as a source of pseudo randomness when //deciding when to sample. - class CycleCounter : public Chooser { + class VISIBILITY_HIDDEN CycleCounter : public Chooser { uint64_t rm; - Function* F; + Constant *F; public: CycleCounter(Module& m, uint64_t resetmask); virtual ~CycleCounter(); @@ -143,7 +142,10 @@ namespace { }; /// ProfilerRS - Insert the random sampling framework - struct ProfilerRS : public FunctionPass { + struct VISIBILITY_HIDDEN ProfilerRS : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + ProfilerRS() : FunctionPass((intptr_t)&ID) {} + std::map TransCache; std::set ChoicePoints; Chooser* c; @@ -159,11 +161,16 @@ namespace { bool doInitialization(Module &M); virtual void getAnalysisUsage(AnalysisUsage &AU) const; }; - - RegisterPass X("insert-rs-profiling-framework", - "Insert random sampling instrumentation framework"); } +static RegisterPass +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, BasicBlock* bold, BasicBlock* bnew); @@ -204,19 +211,19 @@ void GlobalRandomCounter::ProcessChoicePoint(BasicBlock* bb) { //decrement counter LoadInst* l = new LoadInst(Counter, "counter", t); - SetCondInst* s = new SetCondInst(Instruction::SetEQ, l, - ConstantInt::get(T, 0), - "countercc", t); - Value* nv = BinaryOperator::createSub(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); @@ -236,9 +243,10 @@ 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 to restore the local variable to/from //the global variable @@ -246,25 +254,23 @@ void GlobalRandomCounterOpt::PrepFunction(Function* F) { fib != fie; ++fib) for(BasicBlock::iterator bib = fib->begin(), bie = fib->end(); bib != bie; ++bib) - if (isa(&*bib)) { + if (isa(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(&*bib)) { + l = new LoadInst(Counter, "counter", ++bib); + new StoreInst(l, AI, bib--); + } else if (isa(bib)) { LoadInst* l = new LoadInst(AI, "counter", bib); new StoreInst(l, Counter, bib); - BasicBlock* bb = cast(&*bib)->getNormalDest(); - Instruction* i = bb->begin(); - while (isa(i)) i = i->getNext(); + BasicBlock* bb = cast(bib)->getNormalDest(); + BasicBlock::iterator i = bb->getFirstNonPHI(); l = new LoadInst(Counter, "counter", i); - bb = cast(&*bib)->getUnwindDest(); - i = bb->begin(); - while (isa(i)) i = i->getNext(); + bb = cast(bib)->getUnwindDest(); + i = bb->getFirstNonPHI(); l = new LoadInst(Counter, "counter", i); - new StoreInst(l, AI, l->getNext()); + new StoreInst(l, AI, i); } else if (isa(&*bib) || isa(&*bib)) { LoadInst* l = new LoadInst(AI, "counter", bib); new StoreInst(l, Counter, bib); @@ -277,19 +283,19 @@ void GlobalRandomCounterOpt::ProcessChoicePoint(BasicBlock* bb) { //decrement counter LoadInst* l = new LoadInst(AI, "counter", t); - SetCondInst* s = new SetCondInst(Instruction::SetEQ, l, - ConstantInt::get(T, 0), - "countercc", t); - Value* nv = BinaryOperator::createSub(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); @@ -297,7 +303,7 @@ void GlobalRandomCounterOpt::ProcessChoicePoint(BasicBlock* bb) { 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() {} @@ -307,14 +313,15 @@ void CycleCounter::PrepFunction(Function* F) {} void CycleCounter::ProcessChoicePoint(BasicBlock* bb) { BranchInst* t = cast(bb->getTerminator()); - CallInst* c = new CallInst(F, "rdcc", t); + CallInst* c = CallInst::Create(F, "rdcc", t); BinaryOperator* b = - BinaryOperator::createAnd(c, ConstantInt::get(Type::ULongTy, rm), - "mrdcc", t); + BinaryOperator::CreateAnd(c, ConstantInt::get(Type::Int64Ty, rm), + "mrdcc", t); - SetCondInst* s = new SetCondInst(Instruction::SetEQ, b, - ConstantInt::get(Type::ULongTy, 0), - "mrdccc", t); + ICmpInst *s = new ICmpInst(ICmpInst::ICMP_EQ, b, + ConstantInt::get(Type::Int64Ty, 0), + "mrdccc", t); + t->setCondition(s); } @@ -332,22 +339,23 @@ bool RSProfilers_std::isProfiling(Value* v) { void RSProfilers_std::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum, GlobalValue *CounterArray) { // Insert the increment after any alloca or PHI instructions... - BasicBlock::iterator InsertPos = BB->begin(); - while (isa(InsertPos) || isa(InsertPos)) + BasicBlock::iterator InsertPos = BB->getFirstNonPHI(); + while (isa(InsertPos)) ++InsertPos; // Create the getelementptr constant expression std::vector Indices(2); - Indices[0] = Constant::getNullValue(Type::IntTy); - Indices[1] = ConstantInt::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::createAdd(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)); } @@ -369,8 +377,8 @@ Value* ProfilerRS::Translate(Value* v) { 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(v)) { //we have already translated this @@ -457,16 +465,17 @@ void ProfilerRS::ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F) // 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(Translate(src))->getNext() ); + BBN = cast(Translate(src)); + BasicBlock* bbCp = BasicBlock::Create("choice", &F, ++BBN); ChoicePoints.insert(bbCp); //b: - new BranchInst(cast(Translate(dst)), bbC); - new BranchInst(dst, cast(Translate(dst)), - ConstantBool::get(true), bbCp); + BranchInst::Create(cast(Translate(dst)), bbC); + BranchInst::Create(dst, cast(Translate(dst)), + ConstantInt::get(Type::Int1Ty, true), bbCp); //c: { TerminatorInst* iB = src->getTerminator(); @@ -488,7 +497,7 @@ void ProfilerRS::ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F) CollapsePhi(dst, bbC); //f: ReplacePhiPred(cast(Translate(dst)), - cast(Translate(src)),bbCp); + cast(Translate(src)),bbCp); CollapsePhi(cast(Translate(dst)), bbCp); //g: for(BasicBlock::iterator ib = dst->begin(), ie = dst->end(); ib != ie; @@ -498,14 +507,14 @@ void ProfilerRS::ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F) if(bbC == phi->getIncomingBlock(x)) { phi->addIncoming(Translate(phi->getIncomingValue(x)), bbCp); cast(Translate(phi))->addIncoming(phi->getIncomingValue(x), - bbC); + bbC); } phi->removeIncomingValue(bbC); } } bool ProfilerRS::runOnFunction(Function& F) { - if (!F.isExternal()) { + if (!F.isDeclaration()) { std::set > BackEdges; RSProfilers& LI = getAnalysis(); @@ -514,15 +523,17 @@ bool ProfilerRS::runOnFunction(Function& F) { //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 >::iterator - ib = BackEdges.begin(), ie = BackEdges.end(); ib != ie; ++ib) + 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 TerminatorInst* T = F.getEntryBlock().getTerminator(); - ReplaceInstWithInst(T, new BranchInst(T->getSuccessor(0), - cast(Translate(T->getSuccessor(0))), - ConstantBool::get(true))); + ReplaceInstWithInst(T, BranchInst::Create(T->getSuccessor(0), + cast( + Translate(T->getSuccessor(0))), + ConstantInt::get(Type::Int1Ty, + true))); //do whatever is needed now that the function is duplicated c->PrepFunction(&F); @@ -531,7 +542,7 @@ bool ProfilerRS::runOnFunction(Function& F) { ChoicePoints.insert(&F.getEntryBlock()); for (std::set::iterator - ii = ChoicePoints.begin(), ie = ChoicePoints.end(); ii != ie; ++ii) + ii = ChoicePoints.begin(), ie = ChoicePoints.end(); ii != ie; ++ii) c->ProcessChoicePoint(*ii); ChoicePoints.clear(); @@ -545,10 +556,10 @@ bool ProfilerRS::runOnFunction(Function& F) { 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); @@ -580,7 +591,6 @@ static void CollapsePhi(BasicBlock* btarget, BasicBlock* bsrc) { for(BasicBlock::iterator ib = btarget->begin(), ie = btarget->end(); ib != ie; ++ib) if (PHINode* phi = dyn_cast(&*ib)) { - unsigned total = phi->getNumIncomingValues(); std::map counter; for(unsigned i = 0; i < phi->getNumIncomingValues(); ) { if (counter[phi->getIncomingBlock(i)]) { @@ -629,7 +639,7 @@ static void getBackEdges(Function& F, T& BackEdges) { std::map 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"; }