LLVM API Documentation

RSProfiling.cpp

Go to the documentation of this file.
00001 //===- RSProfiling.cpp - Various profiling using random sampling ----------===//
00002 //
00003 //                      The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // These passes implement a random sampling based profiling.  Different methods
00011 // of choosing when to sample are supported, as well as different types of
00012 // profiling.  This is done as two passes.  The first is a sequence of profiling
00013 // passes which insert profiling into the program, and remember what they 
00014 // inserted.
00015 //
00016 // The second stage duplicates all instructions in a function, ignoring the 
00017 // profiling code, then connects the two versions togeather at the entry and at
00018 // backedges.  At each connection point a choice is made as to whether to jump
00019 // to the profiled code (take a sample) or execute the unprofiled code.
00020 //
00021 // It is highly recommended that after this pass one runs mem2reg and adce
00022 // (instcombine load-vn gdce dse also are good to run afterwards)
00023 //
00024 // This design is intended to make the profiling passes independent of the RS
00025 // framework, but any profiling pass that implements the RSProfiling interface
00026 // is compatible with the rs framework (and thus can be sampled)
00027 //
00028 // TODO: obviously the block and function profiling are almost identical to the
00029 // existing ones, so they can be unified (esp since these passes are valid
00030 // without the rs framework).
00031 // TODO: Fix choice code so that frequency is not hard coded
00032 //
00033 //===----------------------------------------------------------------------===//
00034 
00035 #include "llvm/Pass.h"
00036 #include "llvm/Module.h"
00037 #include "llvm/Instructions.h"
00038 #include "llvm/Constants.h"
00039 #include "llvm/DerivedTypes.h"
00040 #include "llvm/Intrinsics.h"
00041 #include "llvm/Transforms/Scalar.h"
00042 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
00043 #include "llvm/Support/CommandLine.h"
00044 #include "llvm/Support/Compiler.h"
00045 #include "llvm/Support/Debug.h"
00046 #include "llvm/Transforms/Instrumentation.h"
00047 #include "RSProfiling.h"
00048 #include <set>
00049 #include <map>
00050 #include <queue>
00051 using namespace llvm;
00052 
00053 namespace {
00054   enum RandomMeth {
00055     GBV, GBVO, HOSTCC
00056   };
00057 }
00058 
00059 static cl::opt<RandomMeth> RandomMethod("profile-randomness",
00060     cl::desc("How to randomly choose to profile:"),
00061     cl::values(
00062                clEnumValN(GBV, "global", "global counter"),
00063                clEnumValN(GBVO, "ra_global", 
00064                           "register allocated global counter"),
00065                clEnumValN(HOSTCC, "rdcc", "cycle counter"),
00066                clEnumValEnd));
00067   
00068 namespace {
00069   /// NullProfilerRS - The basic profiler that does nothing.  It is the default
00070   /// profiler and thus terminates RSProfiler chains.  It is useful for 
00071   /// measuring framework overhead
00072   class VISIBILITY_HIDDEN NullProfilerRS : public RSProfilers {
00073   public:
00074     static char ID; // Pass identification, replacement for typeid
00075     bool isProfiling(Value* v) {
00076       return false;
00077     }
00078     bool runOnModule(Module &M) {
00079       return false;
00080     }
00081     void getAnalysisUsage(AnalysisUsage &AU) const {
00082       AU.setPreservesAll();
00083     }
00084   };
00085 }
00086 
00087 static RegisterAnalysisGroup<RSProfilers> A("Profiling passes");
00088 static RegisterPass<NullProfilerRS> NP("insert-null-profiling-rs",
00089                                        "Measure profiling framework overhead");
00090 static RegisterAnalysisGroup<RSProfilers, true> NPT(NP);
00091 
00092 namespace {
00093   /// Chooser - Something that chooses when to make a sample of the profiled code
00094   class VISIBILITY_HIDDEN Chooser {
00095   public:
00096     /// ProcessChoicePoint - is called for each basic block inserted to choose 
00097     /// between normal and sample code
00098     virtual void ProcessChoicePoint(BasicBlock*) = 0;
00099     /// PrepFunction - is called once per function before other work is done.
00100     /// This gives the opertunity to insert new allocas and such.
00101     virtual void PrepFunction(Function*) = 0;
00102     virtual ~Chooser() {}
00103   };
00104 
00105   //Things that implement sampling policies
00106   //A global value that is read-mod-stored to choose when to sample.
00107   //A sample is taken when the global counter hits 0
00108   class VISIBILITY_HIDDEN GlobalRandomCounter : public Chooser {
00109     GlobalVariable* Counter;
00110     Value* ResetValue;
00111     const Type* T;
00112   public:
00113     GlobalRandomCounter(Module& M, const Type* t, uint64_t resetval);
00114     virtual ~GlobalRandomCounter();
00115     virtual void PrepFunction(Function* F);
00116     virtual void ProcessChoicePoint(BasicBlock* bb);
00117   };
00118 
00119   //Same is GRC, but allow register allocation of the global counter
00120   class VISIBILITY_HIDDEN GlobalRandomCounterOpt : public Chooser {
00121     GlobalVariable* Counter;
00122     Value* ResetValue;
00123     AllocaInst* AI;
00124     const Type* T;
00125   public:
00126     GlobalRandomCounterOpt(Module& M, const Type* t, uint64_t resetval);
00127     virtual ~GlobalRandomCounterOpt();
00128     virtual void PrepFunction(Function* F);
00129     virtual void ProcessChoicePoint(BasicBlock* bb);
00130   };
00131 
00132   //Use the cycle counter intrinsic as a source of pseudo randomness when
00133   //deciding when to sample.
00134   class VISIBILITY_HIDDEN CycleCounter : public Chooser {
00135     uint64_t rm;
00136     Constant *F;
00137   public:
00138     CycleCounter(Module& m, uint64_t resetmask);
00139     virtual ~CycleCounter();
00140     virtual void PrepFunction(Function* F);
00141     virtual void ProcessChoicePoint(BasicBlock* bb);
00142   };
00143 
00144   /// ProfilerRS - Insert the random sampling framework
00145   struct VISIBILITY_HIDDEN ProfilerRS : public FunctionPass {
00146     static char ID; // Pass identification, replacement for typeid
00147     ProfilerRS() : FunctionPass(&ID) {}
00148 
00149     std::map<Value*, Value*> TransCache;
00150     std::set<BasicBlock*> ChoicePoints;
00151     Chooser* c;
00152 
00153     //Translate and duplicate values for the new profile free version of stuff
00154     Value* Translate(Value* v);
00155     //Duplicate an entire function (with out profiling)
00156     void Duplicate(Function& F, RSProfilers& LI);
00157     //Called once for each backedge, handle the insertion of choice points and
00158     //the interconection of the two versions of the code
00159     void ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F);
00160     bool runOnFunction(Function& F);
00161     bool doInitialization(Module &M);
00162     virtual void getAnalysisUsage(AnalysisUsage &AU) const;
00163   };
00164 }
00165 
00166 static RegisterPass<ProfilerRS>
00167 X("insert-rs-profiling-framework",
00168   "Insert random sampling instrumentation framework");
00169 
00170 char RSProfilers::ID = 0;
00171 char NullProfilerRS::ID = 0;
00172 char ProfilerRS::ID = 0;
00173 
00174 //Local utilities
00175 static void ReplacePhiPred(BasicBlock* btarget, 
00176                            BasicBlock* bold, BasicBlock* bnew);
00177 
00178 static void CollapsePhi(BasicBlock* btarget, BasicBlock* bsrc);
00179 
00180 template<class T>
00181 static void recBackEdge(BasicBlock* bb, T& BackEdges, 
00182                         std::map<BasicBlock*, int>& color,
00183                         std::map<BasicBlock*, int>& depth,
00184                         std::map<BasicBlock*, int>& finish,
00185                         int& time);
00186 
00187 //find the back edges and where they go to
00188 template<class T>
00189 static void getBackEdges(Function& F, T& BackEdges);
00190 
00191 
00192 ///////////////////////////////////////
00193 // Methods of choosing when to profile
00194 ///////////////////////////////////////
00195   
00196 GlobalRandomCounter::GlobalRandomCounter(Module& M, const Type* t, 
00197                                          uint64_t resetval) : T(t) {
00198   ConstantInt* Init = ConstantInt::get(T, resetval); 
00199   ResetValue = Init;
00200   Counter = new GlobalVariable(T, false, GlobalValue::InternalLinkage,
00201                                Init, "RandomSteeringCounter", &M);
00202 }
00203 
00204 GlobalRandomCounter::~GlobalRandomCounter() {}
00205 
00206 void GlobalRandomCounter::PrepFunction(Function* F) {}
00207 
00208 void GlobalRandomCounter::ProcessChoicePoint(BasicBlock* bb) {
00209   BranchInst* t = cast<BranchInst>(bb->getTerminator());
00210   
00211   //decrement counter
00212   LoadInst* l = new LoadInst(Counter, "counter", t);
00213   
00214   ICmpInst* s = new ICmpInst(ICmpInst::ICMP_EQ, l, ConstantInt::get(T, 0), 
00215                              "countercc", t);
00216 
00217   Value* nv = BinaryOperator::CreateSub(l, ConstantInt::get(T, 1),
00218                                         "counternew", t);
00219   new StoreInst(nv, Counter, t);
00220   t->setCondition(s);
00221   
00222   //reset counter
00223   BasicBlock* oldnext = t->getSuccessor(0);
00224   BasicBlock* resetblock = BasicBlock::Create("reset", oldnext->getParent(), 
00225                                               oldnext);
00226   TerminatorInst* t2 = BranchInst::Create(oldnext, resetblock);
00227   t->setSuccessor(0, resetblock);
00228   new StoreInst(ResetValue, Counter, t2);
00229   ReplacePhiPred(oldnext, bb, resetblock);
00230 }
00231 
00232 GlobalRandomCounterOpt::GlobalRandomCounterOpt(Module& M, const Type* t, 
00233                                                uint64_t resetval) 
00234   : AI(0), T(t) {
00235   ConstantInt* Init = ConstantInt::get(T, resetval);
00236   ResetValue  = Init;
00237   Counter = new GlobalVariable(T, false, GlobalValue::InternalLinkage,
00238                                Init, "RandomSteeringCounter", &M);
00239 }
00240 
00241 GlobalRandomCounterOpt::~GlobalRandomCounterOpt() {}
00242 
00243 void GlobalRandomCounterOpt::PrepFunction(Function* F) {
00244   //make a local temporary to cache the global
00245   BasicBlock& bb = F->getEntryBlock();
00246   BasicBlock::iterator InsertPt = bb.begin();
00247   AI = new AllocaInst(T, 0, "localcounter", InsertPt);
00248   LoadInst* l = new LoadInst(Counter, "counterload", InsertPt);
00249   new StoreInst(l, AI, InsertPt);
00250   
00251   //modify all functions and return values to restore the local variable to/from
00252   //the global variable
00253   for(Function::iterator fib = F->begin(), fie = F->end();
00254       fib != fie; ++fib)
00255     for(BasicBlock::iterator bib = fib->begin(), bie = fib->end();
00256         bib != bie; ++bib)
00257       if (isa<CallInst>(bib)) {
00258         LoadInst* l = new LoadInst(AI, "counter", bib);
00259         new StoreInst(l, Counter, bib);
00260         l = new LoadInst(Counter, "counter", ++bib);
00261         new StoreInst(l, AI, bib--);
00262       } else if (isa<InvokeInst>(bib)) {
00263         LoadInst* l = new LoadInst(AI, "counter", bib);
00264         new StoreInst(l, Counter, bib);
00265         
00266         BasicBlock* bb = cast<InvokeInst>(bib)->getNormalDest();
00267         BasicBlock::iterator i = bb->getFirstNonPHI();
00268         l = new LoadInst(Counter, "counter", i);
00269         
00270         bb = cast<InvokeInst>(bib)->getUnwindDest();
00271         i = bb->getFirstNonPHI();
00272         l = new LoadInst(Counter, "counter", i);
00273         new StoreInst(l, AI, i);
00274       } else if (isa<UnwindInst>(&*bib) || isa<ReturnInst>(&*bib)) {
00275         LoadInst* l = new LoadInst(AI, "counter", bib);
00276         new StoreInst(l, Counter, bib);
00277       }
00278 }
00279 
00280 void GlobalRandomCounterOpt::ProcessChoicePoint(BasicBlock* bb) {
00281   BranchInst* t = cast<BranchInst>(bb->getTerminator());
00282   
00283   //decrement counter
00284   LoadInst* l = new LoadInst(AI, "counter", t);
00285   
00286   ICmpInst* s = new ICmpInst(ICmpInst::ICMP_EQ, l, ConstantInt::get(T, 0), 
00287                              "countercc", t);
00288 
00289   Value* nv = BinaryOperator::CreateSub(l, ConstantInt::get(T, 1),
00290                                         "counternew", t);
00291   new StoreInst(nv, AI, t);
00292   t->setCondition(s);
00293   
00294   //reset counter
00295   BasicBlock* oldnext = t->getSuccessor(0);
00296   BasicBlock* resetblock = BasicBlock::Create("reset", oldnext->getParent(), 
00297                                               oldnext);
00298   TerminatorInst* t2 = BranchInst::Create(oldnext, resetblock);
00299   t->setSuccessor(0, resetblock);
00300   new StoreInst(ResetValue, AI, t2);
00301   ReplacePhiPred(oldnext, bb, resetblock);
00302 }
00303 
00304 
00305 CycleCounter::CycleCounter(Module& m, uint64_t resetmask) : rm(resetmask) {
00306   F = Intrinsic::getDeclaration(&m, Intrinsic::readcyclecounter);
00307 }
00308 
00309 CycleCounter::~CycleCounter() {}
00310 
00311 void CycleCounter::PrepFunction(Function* F) {}
00312 
00313 void CycleCounter::ProcessChoicePoint(BasicBlock* bb) {
00314   BranchInst* t = cast<BranchInst>(bb->getTerminator());
00315   
00316   CallInst* c = CallInst::Create(F, "rdcc", t);
00317   BinaryOperator* b = 
00318     BinaryOperator::CreateAnd(c, ConstantInt::get(Type::Int64Ty, rm),
00319                               "mrdcc", t);
00320   
00321   ICmpInst *s = new ICmpInst(ICmpInst::ICMP_EQ, b,
00322                              ConstantInt::get(Type::Int64Ty, 0), 
00323                              "mrdccc", t);
00324 
00325   t->setCondition(s);
00326 }
00327 
00328 ///////////////////////////////////////
00329 // Profiling:
00330 ///////////////////////////////////////
00331 bool RSProfilers_std::isProfiling(Value* v) {
00332   if (profcode.find(v) != profcode.end())
00333     return true;
00334   //else
00335   RSProfilers& LI = getAnalysis<RSProfilers>();
00336   return LI.isProfiling(v);
00337 }
00338 
00339 void RSProfilers_std::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,
00340                                           GlobalValue *CounterArray) {
00341   // Insert the increment after any alloca or PHI instructions...
00342   BasicBlock::iterator InsertPos = BB->getFirstNonPHI();
00343   while (isa<AllocaInst>(InsertPos))
00344     ++InsertPos;
00345   
00346   // Create the getelementptr constant expression
00347   std::vector<Constant*> Indices(2);
00348   Indices[0] = Constant::getNullValue(Type::Int32Ty);
00349   Indices[1] = ConstantInt::get(Type::Int32Ty, CounterNum);
00350   Constant *ElementPtr = ConstantExpr::getGetElementPtr(CounterArray,
00351                                                         &Indices[0], 2);
00352   
00353   // Load, increment and store the value back.
00354   Value *OldVal = new LoadInst(ElementPtr, "OldCounter", InsertPos);
00355   profcode.insert(OldVal);
00356   Value *NewVal = BinaryOperator::CreateAdd(OldVal,
00357                                             ConstantInt::get(Type::Int32Ty, 1),
00358                                             "NewCounter", InsertPos);
00359   profcode.insert(NewVal);
00360   profcode.insert(new StoreInst(NewVal, ElementPtr, InsertPos));
00361 }
00362 
00363 void RSProfilers_std::getAnalysisUsage(AnalysisUsage &AU) const {
00364   //grab any outstanding profiler, or get the null one
00365   AU.addRequired<RSProfilers>();
00366 }
00367 
00368 ///////////////////////////////////////
00369 // RS Framework
00370 ///////////////////////////////////////
00371 
00372 Value* ProfilerRS::Translate(Value* v) {
00373   if(TransCache[v])
00374     return TransCache[v];
00375   
00376   if (BasicBlock* bb = dyn_cast<BasicBlock>(v)) {
00377     if (bb == &bb->getParent()->getEntryBlock())
00378       TransCache[bb] = bb; //don't translate entry block
00379     else
00380       TransCache[bb] = BasicBlock::Create("dup_" + bb->getName(),
00381                                           bb->getParent(), NULL);
00382     return TransCache[bb];
00383   } else if (Instruction* i = dyn_cast<Instruction>(v)) {
00384     //we have already translated this
00385     //do not translate entry block allocas
00386     if(&i->getParent()->getParent()->getEntryBlock() == i->getParent()) {
00387       TransCache[i] = i;
00388       return i;
00389     } else {
00390       //translate this
00391       Instruction* i2 = i->clone();
00392       if (i->hasName())
00393         i2->setName("dup_" + i->getName());
00394       TransCache[i] = i2;
00395       //NumNewInst++;
00396       for (unsigned x = 0; x < i2->getNumOperands(); ++x)
00397         i2->setOperand(x, Translate(i2->getOperand(x)));
00398       return i2;
00399     }
00400   } else if (isa<Function>(v) || isa<Constant>(v) || isa<Argument>(v)) {
00401     TransCache[v] = v;
00402     return v;
00403   }
00404   assert(0 && "Value not handled");
00405   return 0;
00406 }
00407 
00408 void ProfilerRS::Duplicate(Function& F, RSProfilers& LI)
00409 {
00410   //perform a breadth first search, building up a duplicate of the code
00411   std::queue<BasicBlock*> worklist;
00412   std::set<BasicBlock*> seen;
00413   
00414   //This loop ensures proper BB order, to help performance
00415   for (Function::iterator fib = F.begin(), fie = F.end(); fib != fie; ++fib)
00416     worklist.push(fib);
00417   while (!worklist.empty()) {
00418     Translate(worklist.front());
00419     worklist.pop();
00420   }
00421   
00422   //remember than reg2mem created a new entry block we don't want to duplicate
00423   worklist.push(F.getEntryBlock().getTerminator()->getSuccessor(0));
00424   seen.insert(&F.getEntryBlock());
00425   
00426   while (!worklist.empty()) {
00427     BasicBlock* bb = worklist.front();
00428     worklist.pop();
00429     if(seen.find(bb) == seen.end()) {
00430       BasicBlock* bbtarget = cast<BasicBlock>(Translate(bb));
00431       BasicBlock::InstListType& instlist = bbtarget->getInstList();
00432       for (BasicBlock::iterator iib = bb->begin(), iie = bb->end(); 
00433            iib != iie; ++iib) {
00434         //NumOldInst++;
00435         if (!LI.isProfiling(&*iib)) {
00436           Instruction* i = cast<Instruction>(Translate(iib));
00437           instlist.insert(bbtarget->end(), i);
00438         }
00439       }
00440       //updated search state;
00441       seen.insert(bb);
00442       TerminatorInst* ti = bb->getTerminator();
00443       for (unsigned x = 0; x < ti->getNumSuccessors(); ++x) {
00444         BasicBlock* bbs = ti->getSuccessor(x);
00445         if (seen.find(bbs) == seen.end()) {
00446           worklist.push(bbs);
00447         }
00448       }
00449     }
00450   }
00451 }
00452 
00453 void ProfilerRS::ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F) {
00454   //given a backedge from B -> A, and translations A' and B',
00455   //a: insert C and C'
00456   //b: add branches in C to A and A' and in C' to A and A'
00457   //c: mod terminators@B, replace A with C
00458   //d: mod terminators@B', replace A' with C'
00459   //e: mod phis@A for pred B to be pred C
00460   //       if multiple entries, simplify to one
00461   //f: mod phis@A' for pred B' to be pred C'
00462   //       if multiple entries, simplify to one
00463   //g: for all phis@A with pred C using x
00464   //       add in edge from C' using x'
00465   //       add in edge from C using x in A'
00466   
00467   //a:
00468   Function::iterator BBN = src; ++BBN;
00469   BasicBlock* bbC = BasicBlock::Create("choice", &F, BBN);
00470   //ChoicePoints.insert(bbC);
00471   BBN = cast<BasicBlock>(Translate(src));
00472   BasicBlock* bbCp = BasicBlock::Create("choice", &F, ++BBN);
00473   ChoicePoints.insert(bbCp);
00474   
00475   //b:
00476   BranchInst::Create(cast<BasicBlock>(Translate(dst)), bbC);
00477   BranchInst::Create(dst, cast<BasicBlock>(Translate(dst)), 
00478                      ConstantInt::get(Type::Int1Ty, true), bbCp);
00479   //c:
00480   {
00481     TerminatorInst* iB = src->getTerminator();
00482     for (unsigned x = 0; x < iB->getNumSuccessors(); ++x)
00483       if (iB->getSuccessor(x) == dst)
00484         iB->setSuccessor(x, bbC);
00485   }
00486   //d:
00487   {
00488     TerminatorInst* iBp = cast<TerminatorInst>(Translate(src->getTerminator()));
00489     for (unsigned x = 0; x < iBp->getNumSuccessors(); ++x)
00490       if (iBp->getSuccessor(x) == cast<BasicBlock>(Translate(dst)))
00491         iBp->setSuccessor(x, bbCp);
00492   }
00493   //e:
00494   ReplacePhiPred(dst, src, bbC);
00495   //src could be a switch, in which case we are replacing several edges with one
00496   //thus collapse those edges int the Phi
00497   CollapsePhi(dst, bbC);
00498   //f:
00499   ReplacePhiPred(cast<BasicBlock>(Translate(dst)),
00500                  cast<BasicBlock>(Translate(src)),bbCp);
00501   CollapsePhi(cast<BasicBlock>(Translate(dst)), bbCp);
00502   //g:
00503   for(BasicBlock::iterator ib = dst->begin(), ie = dst->end(); ib != ie;
00504       ++ib)
00505     if (PHINode* phi = dyn_cast<PHINode>(&*ib)) {
00506       for(unsigned x = 0; x < phi->getNumIncomingValues(); ++x)
00507         if(bbC == phi->getIncomingBlock(x)) {
00508           phi->addIncoming(Translate(phi->getIncomingValue(x)), bbCp);
00509           cast<PHINode>(Translate(phi))->addIncoming(phi->getIncomingValue(x), 
00510                                                      bbC);
00511         }
00512       phi->removeIncomingValue(bbC);
00513     }
00514 }
00515 
00516 bool ProfilerRS::runOnFunction(Function& F) {
00517   if (!F.isDeclaration()) {
00518     std::set<std::pair<BasicBlock*, BasicBlock*> > BackEdges;
00519     RSProfilers& LI = getAnalysis<RSProfilers>();
00520     
00521     getBackEdges(F, BackEdges);
00522     Duplicate(F, LI);
00523     //assume that stuff worked.  now connect the duplicated basic blocks 
00524     //with the originals in such a way as to preserve ssa.  yuk!
00525     for (std::set<std::pair<BasicBlock*, BasicBlock*> >::iterator 
00526            ib = BackEdges.begin(), ie = BackEdges.end(); ib != ie; ++ib)
00527       ProcessBackEdge(ib->first, ib->second, F);
00528     
00529     //oh, and add the edge from the reg2mem created entry node to the 
00530     //duplicated second node
00531     TerminatorInst* T = F.getEntryBlock().getTerminator();
00532     ReplaceInstWithInst(T, BranchInst::Create(T->getSuccessor(0),
00533                                               cast<BasicBlock>(
00534                                                 Translate(T->getSuccessor(0))),
00535                                               ConstantInt::get(Type::Int1Ty,
00536                                                                true)));
00537     
00538     //do whatever is needed now that the function is duplicated
00539     c->PrepFunction(&F);
00540     
00541     //add entry node to choice points
00542     ChoicePoints.insert(&F.getEntryBlock());
00543     
00544     for (std::set<BasicBlock*>::iterator 
00545            ii = ChoicePoints.begin(), ie = ChoicePoints.end(); ii != ie; ++ii)
00546       c->ProcessChoicePoint(*ii);
00547     
00548     ChoicePoints.clear();
00549     TransCache.clear();
00550     
00551     return true;
00552   }
00553   return false;
00554 }
00555 
00556 bool ProfilerRS::doInitialization(Module &M) {
00557   switch (RandomMethod) {
00558   case GBV:
00559     c = new GlobalRandomCounter(M, Type::Int32Ty, (1 << 14) - 1);
00560     break;
00561   case GBVO:
00562     c = new GlobalRandomCounterOpt(M, Type::Int32Ty, (1 << 14) - 1);
00563     break;
00564   case HOSTCC:
00565     c = new CycleCounter(M, (1 << 14) - 1);
00566     break;
00567   };
00568   return true;
00569 }
00570 
00571 void ProfilerRS::getAnalysisUsage(AnalysisUsage &AU) const {
00572   AU.addRequired<RSProfilers>();
00573   AU.addRequiredID(DemoteRegisterToMemoryID);
00574 }
00575 
00576 ///////////////////////////////////////
00577 // Utilities:
00578 ///////////////////////////////////////
00579 static void ReplacePhiPred(BasicBlock* btarget, 
00580                            BasicBlock* bold, BasicBlock* bnew) {
00581   for(BasicBlock::iterator ib = btarget->begin(), ie = btarget->end();
00582       ib != ie; ++ib)
00583     if (PHINode* phi = dyn_cast<PHINode>(&*ib)) {
00584       for(unsigned x = 0; x < phi->getNumIncomingValues(); ++x)
00585         if(bold == phi->getIncomingBlock(x))
00586           phi->setIncomingBlock(x, bnew);
00587     }
00588 }
00589 
00590 static void CollapsePhi(BasicBlock* btarget, BasicBlock* bsrc) {
00591   for(BasicBlock::iterator ib = btarget->begin(), ie = btarget->end();
00592       ib != ie; ++ib)
00593     if (PHINode* phi = dyn_cast<PHINode>(&*ib)) {
00594       std::map<BasicBlock*, Value*> counter;
00595       for(unsigned i = 0; i < phi->getNumIncomingValues(); ) {
00596         if (counter[phi->getIncomingBlock(i)]) {
00597           assert(phi->getIncomingValue(i) == counter[phi->getIncomingBlock(i)]);
00598           phi->removeIncomingValue(i, false);
00599         } else {
00600           counter[phi->getIncomingBlock(i)] = phi->getIncomingValue(i);
00601           ++i;
00602         }
00603       }
00604     } 
00605 }
00606 
00607 template<class T>
00608 static void recBackEdge(BasicBlock* bb, T& BackEdges, 
00609                         std::map<BasicBlock*, int>& color,
00610                         std::map<BasicBlock*, int>& depth,
00611                         std::map<BasicBlock*, int>& finish,
00612                         int& time)
00613 {
00614   color[bb] = 1;
00615   ++time;
00616   depth[bb] = time;
00617   TerminatorInst* t= bb->getTerminator();
00618   for(unsigned i = 0; i < t->getNumSuccessors(); ++i) {
00619     BasicBlock* bbnew = t->getSuccessor(i);
00620     if (color[bbnew] == 0)
00621       recBackEdge(bbnew, BackEdges, color, depth, finish, time);
00622     else if (color[bbnew] == 1) {
00623       BackEdges.insert(std::make_pair(bb, bbnew));
00624       //NumBackEdges++;
00625     }
00626   }
00627   color[bb] = 2;
00628   ++time;
00629   finish[bb] = time;
00630 }
00631 
00632 
00633 
00634 //find the back edges and where they go to
00635 template<class T>
00636 static void getBackEdges(Function& F, T& BackEdges) {
00637   std::map<BasicBlock*, int> color;
00638   std::map<BasicBlock*, int> depth;
00639   std::map<BasicBlock*, int> finish;
00640   int time = 0;
00641   recBackEdge(&F.getEntryBlock(), BackEdges, color, depth, finish, time);
00642   DOUT << F.getName() << " " << BackEdges.size() << "\n";
00643 }
00644 
00645 
00646 //Creation functions
00647 ModulePass* llvm::createNullProfilerRSPass() {
00648   return new NullProfilerRS();
00649 }
00650 
00651 FunctionPass* llvm::createRSProfilingPass() {
00652   return new ProfilerRS();
00653 }