summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Scalar/JumpThreading.cpp5
-rw-r--r--llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp12
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp25
3 files changed, 34 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index c79e756f572..2def0b54c6d 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -245,10 +245,13 @@ bool JumpThreading::runOnFunction(Function &F) {
// Can't thread an unconditional jump, but if the block is "almost
// empty", we can replace uses of it with uses of the successor and make
// this dead.
+ // We should not eliminate the loop header either, because eliminating
+ // a loop header might later prevent LoopSimplify from transforming nested
+ // loops into simplified form.
if (BI && BI->isUnconditional() &&
BB != &BB->getParent()->getEntryBlock() &&
// If the terminator is the only non-phi instruction, try to nuke it.
- BB->getFirstNonPHIOrDbg()->isTerminator()) {
+ BB->getFirstNonPHIOrDbg()->isTerminator() && !LoopHeaders.count(BB)) {
// Since TryToSimplifyUncondBranchFromEmptyBlock may delete the
// block, we have to make sure it isn't in the LoopHeaders set. We
// reinsert afterward if needed.
diff --git a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
index 687d388701e..72ce7693ec0 100644
--- a/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
+++ b/llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
@@ -28,6 +28,7 @@
#include "llvm/Analysis/GlobalsModRef.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Analysis/CFG.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
@@ -130,13 +131,20 @@ static bool iterativelySimplifyCFG(Function &F, const TargetTransformInfo &TTI,
AssumptionCache *AC,
unsigned BonusInstThreshold) {
bool Changed = false;
- bool LocalChange = true;
+ bool LocalChange = true;
+
+ SmallVector<std::pair<const BasicBlock *, const BasicBlock *>, 32> Edges;
+ FindFunctionBackedges(F, Edges);
+ SmallPtrSet<BasicBlock *, 16> LoopHeaders;
+ for (unsigned i = 0, e = Edges.size(); i != e; ++i)
+ LoopHeaders.insert(const_cast<BasicBlock *>(Edges[i].second));
+
while (LocalChange) {
LocalChange = false;
// Loop over all of the basic blocks and remove them if they are unneeded.
for (Function::iterator BBIt = F.begin(); BBIt != F.end(); ) {
- if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC)) {
+ if (SimplifyCFG(&*BBIt++, TTI, BonusInstThreshold, AC, &LoopHeaders)) {
LocalChange = true;
++NumSimpl;
}
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 75d42617a6a..197ac510949 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -135,6 +135,7 @@ class SimplifyCFGOpt {
const DataLayout &DL;
unsigned BonusInstThreshold;
AssumptionCache *AC;
+ SmallPtrSetImpl<BasicBlock *> *LoopHeaders;
Value *isValueEqualityComparison(TerminatorInst *TI);
BasicBlock *GetValueEqualityComparisonCases(TerminatorInst *TI,
std::vector<ValueEqualityComparisonCase> &Cases);
@@ -157,8 +158,10 @@ class SimplifyCFGOpt {
public:
SimplifyCFGOpt(const TargetTransformInfo &TTI, const DataLayout &DL,
- unsigned BonusInstThreshold, AssumptionCache *AC)
- : TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold), AC(AC) {}
+ unsigned BonusInstThreshold, AssumptionCache *AC,
+ SmallPtrSetImpl<BasicBlock *> *LoopHeaders)
+ : TTI(TTI), DL(DL), BonusInstThreshold(BonusInstThreshold), AC(AC),
+ LoopHeaders(LoopHeaders) {}
bool run(BasicBlock *BB);
};
}
@@ -3362,6 +3365,7 @@ bool SimplifyCFGOpt::SimplifySingleResume(ResumeInst *RI) {
// The landingpad is now unreachable. Zap it.
BB->eraseFromParent();
+ if (LoopHeaders) LoopHeaders->erase(BB);
return true;
}
@@ -3480,6 +3484,7 @@ static bool removeEmptyCleanup(CleanupReturnInst *RI) {
// The cleanup pad is now unreachable. Zap it.
BB->eraseFromParent();
+ if (LoopHeaders) LoopHeaders->erase(BB);
return true;
}
@@ -3560,9 +3565,11 @@ bool SimplifyCFGOpt::SimplifyReturn(ReturnInst *RI, IRBuilder<> &Builder) {
}
// If we eliminated all predecessors of the block, delete the block now.
- if (pred_empty(BB))
+ if (pred_empty(BB)) {
// We know there are no successors, so just nuke the block.
BB->eraseFromParent();
+ if (LoopHeaders) LoopHeaders->erase(BB);
+ }
return true;
}
@@ -3719,6 +3726,7 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
BB != &BB->getParent()->getEntryBlock()) {
// We know there are no successors, so just nuke the block.
BB->eraseFromParent();
+ if (LoopHeaders) LoopHeaders->erase(BB);
return true;
}
@@ -5062,8 +5070,14 @@ bool SimplifyCFGOpt::SimplifyUncondBranch(BranchInst *BI, IRBuilder<> &Builder){
return true;
// If the Terminator is the only non-phi instruction, simplify the block.
+ // if LoopHeader is provided, check if the block is a loop header
+ // (This is for early invocations before loop simplify and vectorization
+ // to keep canonical loop forms for nested loops.
+ // These blocks can be eliminated when the pass is invoked later
+ // in the back-end.)
BasicBlock::iterator I = BB->getFirstNonPHIOrDbg()->getIterator();
if (I->isTerminator() && BB != &BB->getParent()->getEntryBlock() &&
+ (!LoopHeaders || (LoopHeaders && !LoopHeaders->count(BB))) &&
TryToSimplifyUncondBranchFromEmptyBlock(BB))
return true;
@@ -5343,7 +5357,8 @@ bool SimplifyCFGOpt::run(BasicBlock *BB) {
/// of the CFG. It returns true if a modification was made.
///
bool llvm::SimplifyCFG(BasicBlock *BB, const TargetTransformInfo &TTI,
- unsigned BonusInstThreshold, AssumptionCache *AC) {
+ unsigned BonusInstThreshold, AssumptionCache *AC,
+ SmallPtrSetImpl<BasicBlock *> *LoopHeaders) {
return SimplifyCFGOpt(TTI, BB->getModule()->getDataLayout(),
- BonusInstThreshold, AC).run(BB);
+ BonusInstThreshold, AC, LoopHeaders).run(BB);
}
OpenPOWER on IntegriCloud