mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Re-apply r124518 with fix. Watch out for invalidated iterator.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124526 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -509,7 +509,32 @@ void llvm::FindFunctionBackedges(const Function &F,
|
||||
// Go up one level.
|
||||
InStack.erase(VisitStack.pop_back_val().first);
|
||||
}
|
||||
} while (!VisitStack.empty());
|
||||
|
||||
|
||||
} while (!VisitStack.empty());
|
||||
}
|
||||
|
||||
/// FoldReturnIntoUncondBranch - This method duplicates the specified return
|
||||
/// instruction into a predecessor which ends in an unconditional branch. If
|
||||
/// the return instruction returns a value defined by a PHI, propagate the
|
||||
/// right value into the return. It returns the new return instruction in the
|
||||
/// predecessor.
|
||||
ReturnInst *llvm::FoldReturnIntoUncondBranch(ReturnInst *RI, BasicBlock *BB,
|
||||
BasicBlock *Pred) {
|
||||
Instruction *UncondBranch = Pred->getTerminator();
|
||||
// Clone the return and add it to the end of the predecessor.
|
||||
Instruction *NewRet = RI->clone();
|
||||
Pred->getInstList().push_back(NewRet);
|
||||
|
||||
// If the return instruction returns a value, and if the value was a
|
||||
// PHI node in "BB", propagate the right value into the return.
|
||||
for (User::op_iterator i = NewRet->op_begin(), e = NewRet->op_end();
|
||||
i != e; ++i)
|
||||
if (PHINode *PN = dyn_cast<PHINode>(*i))
|
||||
if (PN->getParent() == BB)
|
||||
*i = PN->getIncomingValueForBlock(Pred);
|
||||
|
||||
// Update any PHI nodes in the returning block to realize that we no
|
||||
// longer branch to them.
|
||||
BB->removePredecessor(Pred);
|
||||
UncondBranch->eraseFromParent();
|
||||
return cast<ReturnInst>(NewRet);
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ConstantRange.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@@ -36,6 +37,10 @@
|
||||
#include <map>
|
||||
using namespace llvm;
|
||||
|
||||
static cl::opt<bool>
|
||||
DupRet("simplifycfg-dup-ret", cl::Hidden, cl::init(false),
|
||||
cl::desc("Duplicate return instructions into unconditional branches"));
|
||||
|
||||
STATISTIC(NumSpeculations, "Number of speculative executed instructions");
|
||||
|
||||
namespace {
|
||||
@@ -2027,28 +2032,12 @@ bool SimplifyCFGOpt::SimplifyReturn(ReturnInst *RI) {
|
||||
}
|
||||
|
||||
// If we found some, do the transformation!
|
||||
if (!UncondBranchPreds.empty()) {
|
||||
if (!UncondBranchPreds.empty() && DupRet) {
|
||||
while (!UncondBranchPreds.empty()) {
|
||||
BasicBlock *Pred = UncondBranchPreds.pop_back_val();
|
||||
DEBUG(dbgs() << "FOLDING: " << *BB
|
||||
<< "INTO UNCOND BRANCH PRED: " << *Pred);
|
||||
Instruction *UncondBranch = Pred->getTerminator();
|
||||
// Clone the return and add it to the end of the predecessor.
|
||||
Instruction *NewRet = RI->clone();
|
||||
Pred->getInstList().push_back(NewRet);
|
||||
|
||||
// If the return instruction returns a value, and if the value was a
|
||||
// PHI node in "BB", propagate the right value into the return.
|
||||
for (User::op_iterator i = NewRet->op_begin(), e = NewRet->op_end();
|
||||
i != e; ++i)
|
||||
if (PHINode *PN = dyn_cast<PHINode>(*i))
|
||||
if (PN->getParent() == BB)
|
||||
*i = PN->getIncomingValueForBlock(Pred);
|
||||
|
||||
// Update any PHI nodes in the returning block to realize that we no
|
||||
// longer branch to them.
|
||||
BB->removePredecessor(Pred);
|
||||
UncondBranch->eraseFromParent();
|
||||
(void)FoldReturnIntoUncondBranch(RI, BB, Pred);
|
||||
}
|
||||
|
||||
// If we eliminated all predecessors of the block, delete the block now.
|
||||
|
Reference in New Issue
Block a user