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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29966 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2006-08-29 22:29:16 +00:00
parent c9676deb23
commit 4b8f36f106
3 changed files with 63 additions and 10 deletions

View File

@ -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

View File

@ -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

View File

@ -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());