diff options
author | Devang Patel <dpatel@apple.com> | 2006-08-29 22:29:16 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2006-08-29 22:29:16 +0000 |
commit | f489d0f85c4a90769df6cd6cf86173a5f1826ddc (patch) | |
tree | 6b49b902995eb081b8f9e287a486dc99f5782f34 /llvm | |
parent | 6d464146d0c545d339b49124828be92b51fc648f (diff) | |
download | bcm5719-llvm-f489d0f85c4a90769df6cd6cf86173a5f1826ddc.tar.gz bcm5719-llvm-f489d0f85c4a90769df6cd6cf86173a5f1826ddc.zip |
Do not rely on std::sort and std::erase to get list of unique
exit blocks. The output is dependent on addresses of basic block.
Add and use Loop::getUniqueExitBlocks.
llvm-svn: 29966
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/include/llvm/Analysis/LoopInfo.h | 6 | ||||
-rw-r--r-- | llvm/lib/Analysis/LoopInfo.cpp | 53 | ||||
-rw-r--r-- | llvm/lib/Transforms/Scalar/LoopUnswitch.cpp | 14 |
3 files changed, 63 insertions, 10 deletions
diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h index 17363df3957..a81b674fba5 100644 --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/include/llvm/Analysis/LoopInfo.h @@ -112,6 +112,12 @@ public: /// void getExitBlocks(std::vector<BasicBlock*> &Blocks) const; + /// getUniqueExitBlocks - Return all unique successor blocks of this loop. + /// These are the blocks _outside of the current loop_ which are branched to. + /// This assumes that loop is in canonical form. + /// + void getUniqueExitBlocks(std::vector<BasicBlock*> &ExitBlocks) const; + /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop /// from outside of the loop. If this is the case, the block branching to the diff --git a/llvm/lib/Analysis/LoopInfo.cpp b/llvm/lib/Analysis/LoopInfo.cpp index 907cf5f4fe6..6483de4b0a3 100644 --- a/llvm/lib/Analysis/LoopInfo.cpp +++ b/llvm/lib/Analysis/LoopInfo.cpp @@ -349,6 +349,59 @@ void Loop::getExitBlocks(std::vector<BasicBlock*> &ExitBlocks) const { ExitBlocks.push_back(*I); } +/// getUniqueExitBlocks - Return all unique successor blocks of this loop. These +/// are the blocks _outside of the current loop_ which are branched to. This +/// assumes that loop is in canonical form. +// +void Loop::getUniqueExitBlocks(std::vector<BasicBlock*> &ExitBlocks) const { + // Sort the blocks vector so that we can use binary search to do quick + // lookups. + std::vector<BasicBlock*> LoopBBs(block_begin(), block_end()); + std::sort(LoopBBs.begin(), LoopBBs.end()); + + std::vector<BasicBlock*> switchExitBlocks; + + for (std::vector<BasicBlock*>::const_iterator BI = Blocks.begin(), + BE = Blocks.end(); BI != BE; ++BI) { + + BasicBlock *current = *BI; + switchExitBlocks.clear(); + + for (succ_iterator I = succ_begin(*BI), E = succ_end(*BI); I != E; ++I) { + if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) + // If block is inside the loop then it is not a exit block. + continue; + + pred_iterator PI = pred_begin(*I); + BasicBlock *firstPred = *PI; + + // If current basic block is this exit block's first predecessor + // then only insert exit block in to the output ExitBlocks vector. + // This ensures that same exit block is not inserted twice into + // ExitBlocks vector. + if (current != firstPred) + continue; + + // If a terminator has more then two successors, for example SwitchInst, + // then it is possible that there are multiple edges from current block + // to one exit block. + if (current->getTerminator()->getNumSuccessors() <= 2) { + ExitBlocks.push_back(*I); + continue; + } + + // In case of multiple edges from current block to exit block, collect + // only one edge in ExitBlocks. Use switchExitBlocks to keep track of + // duplicate edges. + if (std::find(switchExitBlocks.begin(), switchExitBlocks.end(), *I) + == switchExitBlocks.end()) { + switchExitBlocks.push_back(*I); + ExitBlocks.push_back(*I); + } + } + } +} + /// getLoopPreheader - If there is a preheader for this loop, return it. A /// loop has a preheader if there is only one edge to the header of the loop diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp index 9c3655205b5..ea643b698ed 100644 --- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp +++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp @@ -570,11 +570,8 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val, LoopBlocks.insert(LoopBlocks.end(), L->block_begin(), L->block_end()); std::vector<BasicBlock*> ExitBlocks; - L->getExitBlocks(ExitBlocks); - std::sort(ExitBlocks.begin(), ExitBlocks.end()); - ExitBlocks.erase(std::unique(ExitBlocks.begin(), ExitBlocks.end()), - ExitBlocks.end()); - + L->getUniqueExitBlocks(ExitBlocks); + // Split all of the edges from inside the loop to their exit blocks. Update // the appropriate Phi nodes as we do so. unsigned NumBlocks = L->getBlocks().size(); @@ -626,11 +623,8 @@ void LoopUnswitch::UnswitchNontrivialCondition(Value *LIC, Constant *Val, // The exit blocks may have been changed due to edge splitting, recompute. ExitBlocks.clear(); - L->getExitBlocks(ExitBlocks); - std::sort(ExitBlocks.begin(), ExitBlocks.end()); - ExitBlocks.erase(std::unique(ExitBlocks.begin(), ExitBlocks.end()), - ExitBlocks.end()); - + L->getUniqueExitBlocks(ExitBlocks); + // Add exit blocks to the loop blocks. LoopBlocks.insert(LoopBlocks.end(), ExitBlocks.begin(), ExitBlocks.end()); |