aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/LoopUtils.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUtils.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUtils.cpp34
1 files changed, 20 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp
index 8dc7709..4cd59af 100644
--- a/llvm/lib/Transforms/Utils/LoopUtils.cpp
+++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp
@@ -63,6 +63,7 @@ static cl::opt<bool> ForceReductionIntrinsic(
static const char *LLVMLoopDisableNonforced = "llvm.loop.disable_nonforced";
static const char *LLVMLoopDisableLICM = "llvm.licm.disable";
+static const char *LLVMLoopMustProgress = "llvm.loop.mustprogress";
bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI,
MemorySSAUpdater *MSSAU,
@@ -419,6 +420,10 @@ bool llvm::hasDisableLICMTransformsHint(const Loop *L) {
return getBooleanLoopAttribute(L, LLVMLoopDisableLICM);
}
+bool llvm::hasMustProgress(const Loop *L) {
+ return getBooleanLoopAttribute(L, LLVMLoopMustProgress);
+}
+
TransformationMode llvm::hasUnrollTransformation(Loop *L) {
if (getBooleanLoopAttribute(L, "llvm.loop.unroll.disable"))
return TM_SuppressedByUser;
@@ -589,6 +594,7 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
IRBuilder<> Builder(OldBr);
auto *ExitBlock = L->getUniqueExitBlock();
+ DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
if (ExitBlock) {
assert(ExitBlock && "Should have a unique exit block!");
assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
@@ -620,7 +626,6 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
"Should have exactly one value and that's from the preheader!");
}
- DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
if (DT) {
DTU.applyUpdates({{DominatorTree::Insert, Preheader, ExitBlock}});
if (MSSA) {
@@ -636,27 +641,28 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
Builder.CreateBr(ExitBlock);
// Remove the old branch.
Preheader->getTerminator()->eraseFromParent();
-
- if (DT) {
- DTU.applyUpdates({{DominatorTree::Delete, Preheader, L->getHeader()}});
- if (MSSA) {
- MSSAU->applyUpdates(
- {{DominatorTree::Delete, Preheader, L->getHeader()}}, *DT);
- SmallSetVector<BasicBlock *, 8> DeadBlockSet(L->block_begin(),
- L->block_end());
- MSSAU->removeBlocks(DeadBlockSet);
- if (VerifyMemorySSA)
- MSSA->verifyMemorySSA();
- }
- }
} else {
assert(L->hasNoExitBlocks() &&
"Loop should have either zero or one exit blocks.");
+
Builder.SetInsertPoint(OldBr);
Builder.CreateUnreachable();
Preheader->getTerminator()->eraseFromParent();
}
+ if (DT) {
+ DTU.applyUpdates({{DominatorTree::Delete, Preheader, L->getHeader()}});
+ if (MSSA) {
+ MSSAU->applyUpdates({{DominatorTree::Delete, Preheader, L->getHeader()}},
+ *DT);
+ SmallSetVector<BasicBlock *, 8> DeadBlockSet(L->block_begin(),
+ L->block_end());
+ MSSAU->removeBlocks(DeadBlockSet);
+ if (VerifyMemorySSA)
+ MSSA->verifyMemorySSA();
+ }
+ }
+
// Use a map to unique and a vector to guarantee deterministic ordering.
llvm::SmallDenseSet<std::pair<DIVariable *, DIExpression *>, 4> DeadDebugSet;
llvm::SmallVector<DbgVariableIntrinsic *, 4> DeadDebugInst;