Mercurial > hg > Members > tobaru > cbc > CbC_llvm
comparison lib/Transforms/Scalar/StructurizeCFG.cpp @ 83:60c9769439b8
LLVM 3.7
author | Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 18 Feb 2015 14:55:36 +0900 |
parents | 54457678186b |
children | afa8332a0e37 |
comparison
equal
deleted
inserted
replaced
78:af83660cff7b | 83:60c9769439b8 |
---|---|
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 | 9 |
10 #include "llvm/Transforms/Scalar.h" | 10 #include "llvm/Transforms/Scalar.h" |
11 #include "llvm/ADT/MapVector.h" | 11 #include "llvm/ADT/MapVector.h" |
12 #include "llvm/ADT/SCCIterator.h" | 12 #include "llvm/ADT/SCCIterator.h" |
13 #include "llvm/ADT/PostOrderIterator.h" | |
14 #include "llvm/Analysis/LoopInfo.h" | |
13 #include "llvm/Analysis/RegionInfo.h" | 15 #include "llvm/Analysis/RegionInfo.h" |
14 #include "llvm/Analysis/RegionIterator.h" | 16 #include "llvm/Analysis/RegionIterator.h" |
15 #include "llvm/Analysis/RegionPass.h" | 17 #include "llvm/Analysis/RegionPass.h" |
16 #include "llvm/IR/Module.h" | 18 #include "llvm/IR/Module.h" |
17 #include "llvm/IR/PatternMatch.h" | 19 #include "llvm/IR/PatternMatch.h" |
20 #include "llvm/Support/Debug.h" | |
18 #include "llvm/Transforms/Utils/SSAUpdater.h" | 21 #include "llvm/Transforms/Utils/SSAUpdater.h" |
19 | 22 |
20 using namespace llvm; | 23 using namespace llvm; |
21 using namespace llvm::PatternMatch; | 24 using namespace llvm::PatternMatch; |
22 | 25 |
164 | 167 |
165 Function *Func; | 168 Function *Func; |
166 Region *ParentRegion; | 169 Region *ParentRegion; |
167 | 170 |
168 DominatorTree *DT; | 171 DominatorTree *DT; |
172 LoopInfo *LI; | |
169 | 173 |
170 RNVector Order; | 174 RNVector Order; |
171 BBSet Visited; | 175 BBSet Visited; |
172 | 176 |
173 BBPhiMap DeletedPhis; | 177 BBPhiMap DeletedPhis; |
245 } | 249 } |
246 | 250 |
247 void getAnalysisUsage(AnalysisUsage &AU) const override { | 251 void getAnalysisUsage(AnalysisUsage &AU) const override { |
248 AU.addRequiredID(LowerSwitchID); | 252 AU.addRequiredID(LowerSwitchID); |
249 AU.addRequired<DominatorTreeWrapperPass>(); | 253 AU.addRequired<DominatorTreeWrapperPass>(); |
254 AU.addRequired<LoopInfoWrapperPass>(); | |
250 AU.addPreserved<DominatorTreeWrapperPass>(); | 255 AU.addPreserved<DominatorTreeWrapperPass>(); |
251 RegionPass::getAnalysisUsage(AU); | 256 RegionPass::getAnalysisUsage(AU); |
252 } | 257 } |
253 }; | 258 }; |
254 | 259 |
276 return false; | 281 return false; |
277 } | 282 } |
278 | 283 |
279 /// \brief Build up the general order of nodes | 284 /// \brief Build up the general order of nodes |
280 void StructurizeCFG::orderNodes() { | 285 void StructurizeCFG::orderNodes() { |
281 scc_iterator<Region *> I = scc_begin(ParentRegion); | 286 RNVector TempOrder; |
282 for (Order.clear(); !I.isAtEnd(); ++I) { | 287 ReversePostOrderTraversal<Region*> RPOT(ParentRegion); |
283 const std::vector<RegionNode *> &Nodes = *I; | 288 TempOrder.append(RPOT.begin(), RPOT.end()); |
284 Order.append(Nodes.begin(), Nodes.end()); | 289 |
285 } | 290 std::map<Loop*, unsigned> LoopBlocks; |
291 | |
292 | |
293 // The reverse post-order traversal of the list gives us an ordering close | |
294 // to what we want. The only problem with it is that sometimes backedges | |
295 // for outer loops will be visited before backedges for inner loops. | |
296 for (RegionNode *RN : TempOrder) { | |
297 BasicBlock *BB = RN->getEntry(); | |
298 Loop *Loop = LI->getLoopFor(BB); | |
299 if (!LoopBlocks.count(Loop)) { | |
300 LoopBlocks[Loop] = 1; | |
301 continue; | |
302 } | |
303 LoopBlocks[Loop]++; | |
304 } | |
305 | |
306 unsigned CurrentLoopDepth = 0; | |
307 Loop *CurrentLoop = nullptr; | |
308 BBSet TempVisited; | |
309 for (RNVector::iterator I = TempOrder.begin(), E = TempOrder.end(); I != E; ++I) { | |
310 BasicBlock *BB = (*I)->getEntry(); | |
311 unsigned LoopDepth = LI->getLoopDepth(BB); | |
312 | |
313 if (std::find(Order.begin(), Order.end(), *I) != Order.end()) | |
314 continue; | |
315 | |
316 if (LoopDepth < CurrentLoopDepth) { | |
317 // Make sure we have visited all blocks in this loop before moving back to | |
318 // the outer loop. | |
319 | |
320 RNVector::iterator LoopI = I; | |
321 while(LoopBlocks[CurrentLoop]) { | |
322 LoopI++; | |
323 BasicBlock *LoopBB = (*LoopI)->getEntry(); | |
324 if (LI->getLoopFor(LoopBB) == CurrentLoop) { | |
325 LoopBlocks[CurrentLoop]--; | |
326 Order.push_back(*LoopI); | |
327 } | |
328 } | |
329 } | |
330 | |
331 CurrentLoop = LI->getLoopFor(BB); | |
332 if (CurrentLoop) { | |
333 LoopBlocks[CurrentLoop]--; | |
334 } | |
335 | |
336 CurrentLoopDepth = LoopDepth; | |
337 Order.push_back(*I); | |
338 } | |
339 | |
340 // This pass originally used a post-order traversal and then operated on | |
341 // the list in reverse. Now that we are using a reverse post-order traversal | |
342 // rather than re-working the whole pass to operate on the list in order, | |
343 // we just reverse the list and continue to operate on it in reverse. | |
344 std::reverse(Order.begin(), Order.end()); | |
286 } | 345 } |
287 | 346 |
288 /// \brief Determine the end of the loops | 347 /// \brief Determine the end of the loops |
289 void StructurizeCFG::analyzeLoops(RegionNode *N) { | 348 void StructurizeCFG::analyzeLoops(RegionNode *N) { |
290 if (N->isSubRegion()) { | 349 if (N->isSubRegion()) { |
299 BranchInst *Term = cast<BranchInst>(BB->getTerminator()); | 358 BranchInst *Term = cast<BranchInst>(BB->getTerminator()); |
300 | 359 |
301 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) { | 360 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) { |
302 BasicBlock *Succ = Term->getSuccessor(i); | 361 BasicBlock *Succ = Term->getSuccessor(i); |
303 | 362 |
304 if (Visited.count(Succ)) | 363 if (Visited.count(Succ)) { |
305 Loops[Succ] = BB; | 364 Loops[Succ] = BB; |
365 } | |
306 } | 366 } |
307 } | 367 } |
308 } | 368 } |
309 | 369 |
310 /// \brief Invert the given condition | 370 /// \brief Invert the given condition |
434 // Reset the visited nodes | 494 // Reset the visited nodes |
435 Visited.clear(); | 495 Visited.clear(); |
436 | 496 |
437 for (RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend(); | 497 for (RNVector::reverse_iterator OI = Order.rbegin(), OE = Order.rend(); |
438 OI != OE; ++OI) { | 498 OI != OE; ++OI) { |
499 | |
500 DEBUG(dbgs() << "Visiting: " << | |
501 ((*OI)->isSubRegion() ? "SubRegion with entry: " : "") << | |
502 (*OI)->getEntry()->getName() << " Loop Depth: " << LI->getLoopDepth((*OI)->getEntry()) << "\n"); | |
439 | 503 |
440 // Analyze all the conditions leading to a node | 504 // Analyze all the conditions leading to a node |
441 gatherPredicates(*OI); | 505 gatherPredicates(*OI); |
442 | 506 |
443 // Remember that we've seen this node | 507 // Remember that we've seen this node |
860 | 924 |
861 Func = R->getEntry()->getParent(); | 925 Func = R->getEntry()->getParent(); |
862 ParentRegion = R; | 926 ParentRegion = R; |
863 | 927 |
864 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); | 928 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); |
929 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo(); | |
865 | 930 |
866 orderNodes(); | 931 orderNodes(); |
867 collectInfos(); | 932 collectInfos(); |
868 createFlow(); | 933 createFlow(); |
869 insertConditions(false); | 934 insertConditions(false); |