mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
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
This commit is contained in:
parent
366669c860
commit
a5bb9b49d3
@ -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
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user