RSProfiling.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662
  1. //===- RSProfiling.cpp - Various profiling using random sampling ----------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // These passes implement a random sampling based profiling. Different methods
  11. // of choosing when to sample are supported, as well as different types of
  12. // profiling. This is done as two passes. The first is a sequence of profiling
  13. // passes which insert profiling into the program, and remember what they
  14. // inserted.
  15. //
  16. // The second stage duplicates all instructions in a function, ignoring the
  17. // profiling code, then connects the two versions togeather at the entry and at
  18. // backedges. At each connection point a choice is made as to whether to jump
  19. // to the profiled code (take a sample) or execute the unprofiled code.
  20. //
  21. // It is highly recommended that after this pass one runs mem2reg and adce
  22. // (instcombine load-vn gdce dse also are good to run afterwards)
  23. //
  24. // This design is intended to make the profiling passes independent of the RS
  25. // framework, but any profiling pass that implements the RSProfiling interface
  26. // is compatible with the rs framework (and thus can be sampled)
  27. //
  28. // TODO: obviously the block and function profiling are almost identical to the
  29. // existing ones, so they can be unified (esp since these passes are valid
  30. // without the rs framework).
  31. // TODO: Fix choice code so that frequency is not hard coded
  32. //
  33. //===----------------------------------------------------------------------===//
  34. #include "llvm/Pass.h"
  35. #include "llvm/LLVMContext.h"
  36. #include "llvm/Module.h"
  37. #include "llvm/Instructions.h"
  38. #include "llvm/Constants.h"
  39. #include "llvm/DerivedTypes.h"
  40. #include "llvm/Intrinsics.h"
  41. #include "llvm/Transforms/Scalar.h"
  42. #include "llvm/Transforms/Utils/BasicBlockUtils.h"
  43. #include "llvm/Support/CommandLine.h"
  44. #include "llvm/Support/Debug.h"
  45. #include "llvm/Support/ErrorHandling.h"
  46. #include "llvm/Support/raw_ostream.h"
  47. #include "llvm/Transforms/Instrumentation.h"
  48. #include "RSProfiling.h"
  49. #include <set>
  50. #include <map>
  51. #include <queue>
  52. using namespace llvm;
  53. namespace {
  54. enum RandomMeth {
  55. GBV, GBVO, HOSTCC
  56. };
  57. }
  58. static cl::opt<RandomMeth> RandomMethod("profile-randomness",
  59. cl::desc("How to randomly choose to profile:"),
  60. cl::values(
  61. clEnumValN(GBV, "global", "global counter"),
  62. clEnumValN(GBVO, "ra_global",
  63. "register allocated global counter"),
  64. clEnumValN(HOSTCC, "rdcc", "cycle counter"),
  65. clEnumValEnd));
  66. namespace {
  67. /// NullProfilerRS - The basic profiler that does nothing. It is the default
  68. /// profiler and thus terminates RSProfiler chains. It is useful for
  69. /// measuring framework overhead
  70. class NullProfilerRS : public RSProfilers {
  71. public:
  72. static char ID; // Pass identification, replacement for typeid
  73. bool isProfiling(Value* v) {
  74. return false;
  75. }
  76. bool runOnModule(Module &M) {
  77. return false;
  78. }
  79. void getAnalysisUsage(AnalysisUsage &AU) const {
  80. AU.setPreservesAll();
  81. }
  82. };
  83. }
  84. static RegisterAnalysisGroup<RSProfilers> A("Profiling passes");
  85. static RegisterPass<NullProfilerRS> NP("insert-null-profiling-rs",
  86. "Measure profiling framework overhead");
  87. static RegisterAnalysisGroup<RSProfilers, true> NPT(NP);
  88. namespace {
  89. /// Chooser - Something that chooses when to make a sample of the profiled code
  90. class Chooser {
  91. public:
  92. /// ProcessChoicePoint - is called for each basic block inserted to choose
  93. /// between normal and sample code
  94. virtual void ProcessChoicePoint(BasicBlock*) = 0;
  95. /// PrepFunction - is called once per function before other work is done.
  96. /// This gives the opertunity to insert new allocas and such.
  97. virtual void PrepFunction(Function*) = 0;
  98. virtual ~Chooser() {}
  99. };
  100. //Things that implement sampling policies
  101. //A global value that is read-mod-stored to choose when to sample.
  102. //A sample is taken when the global counter hits 0
  103. class GlobalRandomCounter : public Chooser {
  104. GlobalVariable* Counter;
  105. Value* ResetValue;
  106. const IntegerType* T;
  107. public:
  108. GlobalRandomCounter(Module& M, const IntegerType* t, uint64_t resetval);
  109. virtual ~GlobalRandomCounter();
  110. virtual void PrepFunction(Function* F);
  111. virtual void ProcessChoicePoint(BasicBlock* bb);
  112. };
  113. //Same is GRC, but allow register allocation of the global counter
  114. class GlobalRandomCounterOpt : public Chooser {
  115. GlobalVariable* Counter;
  116. Value* ResetValue;
  117. AllocaInst* AI;
  118. const IntegerType* T;
  119. public:
  120. GlobalRandomCounterOpt(Module& M, const IntegerType* t, uint64_t resetval);
  121. virtual ~GlobalRandomCounterOpt();
  122. virtual void PrepFunction(Function* F);
  123. virtual void ProcessChoicePoint(BasicBlock* bb);
  124. };
  125. //Use the cycle counter intrinsic as a source of pseudo randomness when
  126. //deciding when to sample.
  127. class CycleCounter : public Chooser {
  128. uint64_t rm;
  129. Constant *F;
  130. public:
  131. CycleCounter(Module& m, uint64_t resetmask);
  132. virtual ~CycleCounter();
  133. virtual void PrepFunction(Function* F);
  134. virtual void ProcessChoicePoint(BasicBlock* bb);
  135. };
  136. /// ProfilerRS - Insert the random sampling framework
  137. struct ProfilerRS : public FunctionPass {
  138. static char ID; // Pass identification, replacement for typeid
  139. ProfilerRS() : FunctionPass(&ID) {}
  140. std::map<Value*, Value*> TransCache;
  141. std::set<BasicBlock*> ChoicePoints;
  142. Chooser* c;
  143. //Translate and duplicate values for the new profile free version of stuff
  144. Value* Translate(Value* v);
  145. //Duplicate an entire function (with out profiling)
  146. void Duplicate(Function& F, RSProfilers& LI);
  147. //Called once for each backedge, handle the insertion of choice points and
  148. //the interconection of the two versions of the code
  149. void ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F);
  150. bool runOnFunction(Function& F);
  151. bool doInitialization(Module &M);
  152. virtual void getAnalysisUsage(AnalysisUsage &AU) const;
  153. };
  154. }
  155. static RegisterPass<ProfilerRS>
  156. X("insert-rs-profiling-framework",
  157. "Insert random sampling instrumentation framework");
  158. char RSProfilers::ID = 0;
  159. char NullProfilerRS::ID = 0;
  160. char ProfilerRS::ID = 0;
  161. //Local utilities
  162. static void ReplacePhiPred(BasicBlock* btarget,
  163. BasicBlock* bold, BasicBlock* bnew);
  164. static void CollapsePhi(BasicBlock* btarget, BasicBlock* bsrc);
  165. template<class T>
  166. static void recBackEdge(BasicBlock* bb, T& BackEdges,
  167. std::map<BasicBlock*, int>& color,
  168. std::map<BasicBlock*, int>& depth,
  169. std::map<BasicBlock*, int>& finish,
  170. int& time);
  171. //find the back edges and where they go to
  172. template<class T>
  173. static void getBackEdges(Function& F, T& BackEdges);
  174. ///////////////////////////////////////
  175. // Methods of choosing when to profile
  176. ///////////////////////////////////////
  177. GlobalRandomCounter::GlobalRandomCounter(Module& M, const IntegerType* t,
  178. uint64_t resetval) : T(t) {
  179. ConstantInt* Init = ConstantInt::get(T, resetval);
  180. ResetValue = Init;
  181. Counter = new GlobalVariable(M, T, false, GlobalValue::InternalLinkage,
  182. Init, "RandomSteeringCounter");
  183. }
  184. GlobalRandomCounter::~GlobalRandomCounter() {}
  185. void GlobalRandomCounter::PrepFunction(Function* F) {}
  186. void GlobalRandomCounter::ProcessChoicePoint(BasicBlock* bb) {
  187. BranchInst* t = cast<BranchInst>(bb->getTerminator());
  188. //decrement counter
  189. LoadInst* l = new LoadInst(Counter, "counter", t);
  190. ICmpInst* s = new ICmpInst(t, ICmpInst::ICMP_EQ, l,
  191. ConstantInt::get(T, 0),
  192. "countercc");
  193. Value* nv = BinaryOperator::CreateSub(l, ConstantInt::get(T, 1),
  194. "counternew", t);
  195. new StoreInst(nv, Counter, t);
  196. t->setCondition(s);
  197. //reset counter
  198. BasicBlock* oldnext = t->getSuccessor(0);
  199. BasicBlock* resetblock = BasicBlock::Create(bb->getContext(),
  200. "reset", oldnext->getParent(),
  201. oldnext);
  202. TerminatorInst* t2 = BranchInst::Create(oldnext, resetblock);
  203. t->setSuccessor(0, resetblock);
  204. new StoreInst(ResetValue, Counter, t2);
  205. ReplacePhiPred(oldnext, bb, resetblock);
  206. }
  207. GlobalRandomCounterOpt::GlobalRandomCounterOpt(Module& M, const IntegerType* t,
  208. uint64_t resetval)
  209. : AI(0), T(t) {
  210. ConstantInt* Init = ConstantInt::get(T, resetval);
  211. ResetValue = Init;
  212. Counter = new GlobalVariable(M, T, false, GlobalValue::InternalLinkage,
  213. Init, "RandomSteeringCounter");
  214. }
  215. GlobalRandomCounterOpt::~GlobalRandomCounterOpt() {}
  216. void GlobalRandomCounterOpt::PrepFunction(Function* F) {
  217. //make a local temporary to cache the global
  218. BasicBlock& bb = F->getEntryBlock();
  219. BasicBlock::iterator InsertPt = bb.begin();
  220. AI = new AllocaInst(T, 0, "localcounter", InsertPt);
  221. LoadInst* l = new LoadInst(Counter, "counterload", InsertPt);
  222. new StoreInst(l, AI, InsertPt);
  223. //modify all functions and return values to restore the local variable to/from
  224. //the global variable
  225. for(Function::iterator fib = F->begin(), fie = F->end();
  226. fib != fie; ++fib)
  227. for(BasicBlock::iterator bib = fib->begin(), bie = fib->end();
  228. bib != bie; ++bib)
  229. if (isa<CallInst>(bib)) {
  230. LoadInst* l = new LoadInst(AI, "counter", bib);
  231. new StoreInst(l, Counter, bib);
  232. l = new LoadInst(Counter, "counter", ++bib);
  233. new StoreInst(l, AI, bib--);
  234. } else if (isa<InvokeInst>(bib)) {
  235. LoadInst* l = new LoadInst(AI, "counter", bib);
  236. new StoreInst(l, Counter, bib);
  237. BasicBlock* bb = cast<InvokeInst>(bib)->getNormalDest();
  238. BasicBlock::iterator i = bb->getFirstNonPHI();
  239. l = new LoadInst(Counter, "counter", i);
  240. bb = cast<InvokeInst>(bib)->getUnwindDest();
  241. i = bb->getFirstNonPHI();
  242. l = new LoadInst(Counter, "counter", i);
  243. new StoreInst(l, AI, i);
  244. } else if (isa<UnwindInst>(&*bib) || isa<ReturnInst>(&*bib)) {
  245. LoadInst* l = new LoadInst(AI, "counter", bib);
  246. new StoreInst(l, Counter, bib);
  247. }
  248. }
  249. void GlobalRandomCounterOpt::ProcessChoicePoint(BasicBlock* bb) {
  250. BranchInst* t = cast<BranchInst>(bb->getTerminator());
  251. //decrement counter
  252. LoadInst* l = new LoadInst(AI, "counter", t);
  253. ICmpInst* s = new ICmpInst(t, ICmpInst::ICMP_EQ, l,
  254. ConstantInt::get(T, 0),
  255. "countercc");
  256. Value* nv = BinaryOperator::CreateSub(l, ConstantInt::get(T, 1),
  257. "counternew", t);
  258. new StoreInst(nv, AI, t);
  259. t->setCondition(s);
  260. //reset counter
  261. BasicBlock* oldnext = t->getSuccessor(0);
  262. BasicBlock* resetblock = BasicBlock::Create(bb->getContext(),
  263. "reset", oldnext->getParent(),
  264. oldnext);
  265. TerminatorInst* t2 = BranchInst::Create(oldnext, resetblock);
  266. t->setSuccessor(0, resetblock);
  267. new StoreInst(ResetValue, AI, t2);
  268. ReplacePhiPred(oldnext, bb, resetblock);
  269. }
  270. CycleCounter::CycleCounter(Module& m, uint64_t resetmask) : rm(resetmask) {
  271. F = Intrinsic::getDeclaration(&m, Intrinsic::readcyclecounter);
  272. }
  273. CycleCounter::~CycleCounter() {}
  274. void CycleCounter::PrepFunction(Function* F) {}
  275. void CycleCounter::ProcessChoicePoint(BasicBlock* bb) {
  276. BranchInst* t = cast<BranchInst>(bb->getTerminator());
  277. CallInst* c = CallInst::Create(F, "rdcc", t);
  278. BinaryOperator* b =
  279. BinaryOperator::CreateAnd(c,
  280. ConstantInt::get(Type::getInt64Ty(bb->getContext()), rm),
  281. "mrdcc", t);
  282. ICmpInst *s = new ICmpInst(t, ICmpInst::ICMP_EQ, b,
  283. ConstantInt::get(Type::getInt64Ty(bb->getContext()), 0),
  284. "mrdccc");
  285. t->setCondition(s);
  286. }
  287. ///////////////////////////////////////
  288. // Profiling:
  289. ///////////////////////////////////////
  290. bool RSProfilers_std::isProfiling(Value* v) {
  291. if (profcode.find(v) != profcode.end())
  292. return true;
  293. //else
  294. RSProfilers& LI = getAnalysis<RSProfilers>();
  295. return LI.isProfiling(v);
  296. }
  297. void RSProfilers_std::IncrementCounterInBlock(BasicBlock *BB, unsigned CounterNum,
  298. GlobalValue *CounterArray) {
  299. // Insert the increment after any alloca or PHI instructions...
  300. BasicBlock::iterator InsertPos = BB->getFirstNonPHI();
  301. while (isa<AllocaInst>(InsertPos))
  302. ++InsertPos;
  303. // Create the getelementptr constant expression
  304. std::vector<Constant*> Indices(2);
  305. Indices[0] = Constant::getNullValue(Type::getInt32Ty(BB->getContext()));
  306. Indices[1] = ConstantInt::get(Type::getInt32Ty(BB->getContext()), CounterNum);
  307. Constant *ElementPtr =ConstantExpr::getGetElementPtr(CounterArray,
  308. &Indices[0], 2);
  309. // Load, increment and store the value back.
  310. Value *OldVal = new LoadInst(ElementPtr, "OldCounter", InsertPos);
  311. profcode.insert(OldVal);
  312. Value *NewVal = BinaryOperator::CreateAdd(OldVal,
  313. ConstantInt::get(Type::getInt32Ty(BB->getContext()), 1),
  314. "NewCounter", InsertPos);
  315. profcode.insert(NewVal);
  316. profcode.insert(new StoreInst(NewVal, ElementPtr, InsertPos));
  317. }
  318. void RSProfilers_std::getAnalysisUsage(AnalysisUsage &AU) const {
  319. //grab any outstanding profiler, or get the null one
  320. AU.addRequired<RSProfilers>();
  321. }
  322. ///////////////////////////////////////
  323. // RS Framework
  324. ///////////////////////////////////////
  325. Value* ProfilerRS::Translate(Value* v) {
  326. if(TransCache[v])
  327. return TransCache[v];
  328. if (BasicBlock* bb = dyn_cast<BasicBlock>(v)) {
  329. if (bb == &bb->getParent()->getEntryBlock())
  330. TransCache[bb] = bb; //don't translate entry block
  331. else
  332. TransCache[bb] = BasicBlock::Create(v->getContext(),
  333. "dup_" + bb->getName(),
  334. bb->getParent(), NULL);
  335. return TransCache[bb];
  336. } else if (Instruction* i = dyn_cast<Instruction>(v)) {
  337. //we have already translated this
  338. //do not translate entry block allocas
  339. if(&i->getParent()->getParent()->getEntryBlock() == i->getParent()) {
  340. TransCache[i] = i;
  341. return i;
  342. } else {
  343. //translate this
  344. Instruction* i2 = i->clone();
  345. if (i->hasName())
  346. i2->setName("dup_" + i->getName());
  347. TransCache[i] = i2;
  348. //NumNewInst++;
  349. for (unsigned x = 0; x < i2->getNumOperands(); ++x)
  350. i2->setOperand(x, Translate(i2->getOperand(x)));
  351. return i2;
  352. }
  353. } else if (isa<Function>(v) || isa<Constant>(v) || isa<Argument>(v)) {
  354. TransCache[v] = v;
  355. return v;
  356. }
  357. llvm_unreachable("Value not handled");
  358. return 0;
  359. }
  360. void ProfilerRS::Duplicate(Function& F, RSProfilers& LI)
  361. {
  362. //perform a breadth first search, building up a duplicate of the code
  363. std::queue<BasicBlock*> worklist;
  364. std::set<BasicBlock*> seen;
  365. //This loop ensures proper BB order, to help performance
  366. for (Function::iterator fib = F.begin(), fie = F.end(); fib != fie; ++fib)
  367. worklist.push(fib);
  368. while (!worklist.empty()) {
  369. Translate(worklist.front());
  370. worklist.pop();
  371. }
  372. //remember than reg2mem created a new entry block we don't want to duplicate
  373. worklist.push(F.getEntryBlock().getTerminator()->getSuccessor(0));
  374. seen.insert(&F.getEntryBlock());
  375. while (!worklist.empty()) {
  376. BasicBlock* bb = worklist.front();
  377. worklist.pop();
  378. if(seen.find(bb) == seen.end()) {
  379. BasicBlock* bbtarget = cast<BasicBlock>(Translate(bb));
  380. BasicBlock::InstListType& instlist = bbtarget->getInstList();
  381. for (BasicBlock::iterator iib = bb->begin(), iie = bb->end();
  382. iib != iie; ++iib) {
  383. //NumOldInst++;
  384. if (!LI.isProfiling(&*iib)) {
  385. Instruction* i = cast<Instruction>(Translate(iib));
  386. instlist.insert(bbtarget->end(), i);
  387. }
  388. }
  389. //updated search state;
  390. seen.insert(bb);
  391. TerminatorInst* ti = bb->getTerminator();
  392. for (unsigned x = 0; x < ti->getNumSuccessors(); ++x) {
  393. BasicBlock* bbs = ti->getSuccessor(x);
  394. if (seen.find(bbs) == seen.end()) {
  395. worklist.push(bbs);
  396. }
  397. }
  398. }
  399. }
  400. }
  401. void ProfilerRS::ProcessBackEdge(BasicBlock* src, BasicBlock* dst, Function& F) {
  402. //given a backedge from B -> A, and translations A' and B',
  403. //a: insert C and C'
  404. //b: add branches in C to A and A' and in C' to A and A'
  405. //c: mod terminators@B, replace A with C
  406. //d: mod terminators@B', replace A' with C'
  407. //e: mod phis@A for pred B to be pred C
  408. // if multiple entries, simplify to one
  409. //f: mod phis@A' for pred B' to be pred C'
  410. // if multiple entries, simplify to one
  411. //g: for all phis@A with pred C using x
  412. // add in edge from C' using x'
  413. // add in edge from C using x in A'
  414. //a:
  415. Function::iterator BBN = src; ++BBN;
  416. BasicBlock* bbC = BasicBlock::Create(F.getContext(), "choice", &F, BBN);
  417. //ChoicePoints.insert(bbC);
  418. BBN = cast<BasicBlock>(Translate(src));
  419. BasicBlock* bbCp = BasicBlock::Create(F.getContext(), "choice", &F, ++BBN);
  420. ChoicePoints.insert(bbCp);
  421. //b:
  422. BranchInst::Create(cast<BasicBlock>(Translate(dst)), bbC);
  423. BranchInst::Create(dst, cast<BasicBlock>(Translate(dst)),
  424. ConstantInt::get(Type::getInt1Ty(src->getContext()), true), bbCp);
  425. //c:
  426. {
  427. TerminatorInst* iB = src->getTerminator();
  428. for (unsigned x = 0; x < iB->getNumSuccessors(); ++x)
  429. if (iB->getSuccessor(x) == dst)
  430. iB->setSuccessor(x, bbC);
  431. }
  432. //d:
  433. {
  434. TerminatorInst* iBp = cast<TerminatorInst>(Translate(src->getTerminator()));
  435. for (unsigned x = 0; x < iBp->getNumSuccessors(); ++x)
  436. if (iBp->getSuccessor(x) == cast<BasicBlock>(Translate(dst)))
  437. iBp->setSuccessor(x, bbCp);
  438. }
  439. //e:
  440. ReplacePhiPred(dst, src, bbC);
  441. //src could be a switch, in which case we are replacing several edges with one
  442. //thus collapse those edges int the Phi
  443. CollapsePhi(dst, bbC);
  444. //f:
  445. ReplacePhiPred(cast<BasicBlock>(Translate(dst)),
  446. cast<BasicBlock>(Translate(src)),bbCp);
  447. CollapsePhi(cast<BasicBlock>(Translate(dst)), bbCp);
  448. //g:
  449. for(BasicBlock::iterator ib = dst->begin(), ie = dst->end(); ib != ie;
  450. ++ib)
  451. if (PHINode* phi = dyn_cast<PHINode>(&*ib)) {
  452. for(unsigned x = 0; x < phi->getNumIncomingValues(); ++x)
  453. if(bbC == phi->getIncomingBlock(x)) {
  454. phi->addIncoming(Translate(phi->getIncomingValue(x)), bbCp);
  455. cast<PHINode>(Translate(phi))->addIncoming(phi->getIncomingValue(x),
  456. bbC);
  457. }
  458. phi->removeIncomingValue(bbC);
  459. }
  460. }
  461. bool ProfilerRS::runOnFunction(Function& F) {
  462. if (!F.isDeclaration()) {
  463. std::set<std::pair<BasicBlock*, BasicBlock*> > BackEdges;
  464. RSProfilers& LI = getAnalysis<RSProfilers>();
  465. getBackEdges(F, BackEdges);
  466. Duplicate(F, LI);
  467. //assume that stuff worked. now connect the duplicated basic blocks
  468. //with the originals in such a way as to preserve ssa. yuk!
  469. for (std::set<std::pair<BasicBlock*, BasicBlock*> >::iterator
  470. ib = BackEdges.begin(), ie = BackEdges.end(); ib != ie; ++ib)
  471. ProcessBackEdge(ib->first, ib->second, F);
  472. //oh, and add the edge from the reg2mem created entry node to the
  473. //duplicated second node
  474. TerminatorInst* T = F.getEntryBlock().getTerminator();
  475. ReplaceInstWithInst(T, BranchInst::Create(T->getSuccessor(0),
  476. cast<BasicBlock>(
  477. Translate(T->getSuccessor(0))),
  478. ConstantInt::get(Type::getInt1Ty(F.getContext()), true)));
  479. //do whatever is needed now that the function is duplicated
  480. c->PrepFunction(&F);
  481. //add entry node to choice points
  482. ChoicePoints.insert(&F.getEntryBlock());
  483. for (std::set<BasicBlock*>::iterator
  484. ii = ChoicePoints.begin(), ie = ChoicePoints.end(); ii != ie; ++ii)
  485. c->ProcessChoicePoint(*ii);
  486. ChoicePoints.clear();
  487. TransCache.clear();
  488. return true;
  489. }
  490. return false;
  491. }
  492. bool ProfilerRS::doInitialization(Module &M) {
  493. switch (RandomMethod) {
  494. case GBV:
  495. c = new GlobalRandomCounter(M, Type::getInt32Ty(M.getContext()),
  496. (1 << 14) - 1);
  497. break;
  498. case GBVO:
  499. c = new GlobalRandomCounterOpt(M, Type::getInt32Ty(M.getContext()),
  500. (1 << 14) - 1);
  501. break;
  502. case HOSTCC:
  503. c = new CycleCounter(M, (1 << 14) - 1);
  504. break;
  505. };
  506. return true;
  507. }
  508. void ProfilerRS::getAnalysisUsage(AnalysisUsage &AU) const {
  509. AU.addRequired<RSProfilers>();
  510. AU.addRequiredID(DemoteRegisterToMemoryID);
  511. }
  512. ///////////////////////////////////////
  513. // Utilities:
  514. ///////////////////////////////////////
  515. static void ReplacePhiPred(BasicBlock* btarget,
  516. BasicBlock* bold, BasicBlock* bnew) {
  517. for(BasicBlock::iterator ib = btarget->begin(), ie = btarget->end();
  518. ib != ie; ++ib)
  519. if (PHINode* phi = dyn_cast<PHINode>(&*ib)) {
  520. for(unsigned x = 0; x < phi->getNumIncomingValues(); ++x)
  521. if(bold == phi->getIncomingBlock(x))
  522. phi->setIncomingBlock(x, bnew);
  523. }
  524. }
  525. static void CollapsePhi(BasicBlock* btarget, BasicBlock* bsrc) {
  526. for(BasicBlock::iterator ib = btarget->begin(), ie = btarget->end();
  527. ib != ie; ++ib)
  528. if (PHINode* phi = dyn_cast<PHINode>(&*ib)) {
  529. std::map<BasicBlock*, Value*> counter;
  530. for(unsigned i = 0; i < phi->getNumIncomingValues(); ) {
  531. if (counter[phi->getIncomingBlock(i)]) {
  532. assert(phi->getIncomingValue(i) == counter[phi->getIncomingBlock(i)]);
  533. phi->removeIncomingValue(i, false);
  534. } else {
  535. counter[phi->getIncomingBlock(i)] = phi->getIncomingValue(i);
  536. ++i;
  537. }
  538. }
  539. }
  540. }
  541. template<class T>
  542. static void recBackEdge(BasicBlock* bb, T& BackEdges,
  543. std::map<BasicBlock*, int>& color,
  544. std::map<BasicBlock*, int>& depth,
  545. std::map<BasicBlock*, int>& finish,
  546. int& time)
  547. {
  548. color[bb] = 1;
  549. ++time;
  550. depth[bb] = time;
  551. TerminatorInst* t= bb->getTerminator();
  552. for(unsigned i = 0; i < t->getNumSuccessors(); ++i) {
  553. BasicBlock* bbnew = t->getSuccessor(i);
  554. if (color[bbnew] == 0)
  555. recBackEdge(bbnew, BackEdges, color, depth, finish, time);
  556. else if (color[bbnew] == 1) {
  557. BackEdges.insert(std::make_pair(bb, bbnew));
  558. //NumBackEdges++;
  559. }
  560. }
  561. color[bb] = 2;
  562. ++time;
  563. finish[bb] = time;
  564. }
  565. //find the back edges and where they go to
  566. template<class T>
  567. static void getBackEdges(Function& F, T& BackEdges) {
  568. std::map<BasicBlock*, int> color;
  569. std::map<BasicBlock*, int> depth;
  570. std::map<BasicBlock*, int> finish;
  571. int time = 0;
  572. recBackEdge(&F.getEntryBlock(), BackEdges, color, depth, finish, time);
  573. DEBUG(errs() << F.getName() << " " << BackEdges.size() << "\n");
  574. }
  575. //Creation functions
  576. ModulePass* llvm::createNullProfilerRSPass() {
  577. return new NullProfilerRS();
  578. }
  579. FunctionPass* llvm::createRSProfilingPass() {
  580. return new ProfilerRS();
  581. }