RSProfiling.cpp 23 KB

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