summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Analysis/LoopPass.h9
-rw-r--r--llvm/lib/Analysis/LoopPass.cpp11
-rw-r--r--llvm/lib/Transforms/Scalar/LICM.cpp13
-rw-r--r--llvm/test/Transforms/LICM/2014-09-10-doFinalizationAssert.ll30
4 files changed, 63 insertions, 0 deletions
diff --git a/llvm/include/llvm/Analysis/LoopPass.h b/llvm/include/llvm/Analysis/LoopPass.h
index 726e28636ac..8650000fcfb 100644
--- a/llvm/include/llvm/Analysis/LoopPass.h
+++ b/llvm/include/llvm/Analysis/LoopPass.h
@@ -82,6 +82,11 @@ public:
/// deleteAnalysisValue - Delete analysis info associated with value V.
virtual void deleteAnalysisValue(Value *V, Loop *L) {}
+ /// Delete analysis info associated with Loop L.
+ /// Called to notify a Pass that a loop has been deleted and any
+ /// associated analysis values can be deleted.
+ virtual void deleteAnalysisLoop(Loop *L) {}
+
protected:
/// skipOptnoneFunction - Containing function has Attribute::OptimizeNone
/// and most transformation passes should skip it.
@@ -152,6 +157,10 @@ public:
/// that implement simple analysis interface.
void deleteSimpleAnalysisValue(Value *V, Loop *L);
+ /// Invoke deleteAnalysisLoop hook for all passes that implement simple
+ /// analysis interface.
+ void deleteSimpleAnalysisLoop(Loop *L);
+
private:
std::deque<Loop *> LQ;
bool skipThisLoop;
diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp
index 7bd866e73e1..190abc73fbb 100644
--- a/llvm/lib/Analysis/LoopPass.cpp
+++ b/llvm/lib/Analysis/LoopPass.cpp
@@ -76,6 +76,9 @@ void LPPassManager::deleteLoopFromQueue(Loop *L) {
LI->updateUnloop(L);
+ // Notify passes that the loop is being deleted.
+ deleteSimpleAnalysisLoop(L);
+
// If L is current loop then skip rest of the passes and let
// runOnFunction remove L from LQ. Otherwise, remove L from LQ now
// and continue applying other passes on CurrentLoop.
@@ -164,6 +167,14 @@ void LPPassManager::deleteSimpleAnalysisValue(Value *V, Loop *L) {
}
}
+/// Invoke deleteAnalysisLoop hook for all passes.
+void LPPassManager::deleteSimpleAnalysisLoop(Loop *L) {
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ LoopPass *LP = getContainedPass(Index);
+ LP->deleteAnalysisLoop(L);
+ }
+}
+
// Recurse through all subloops and all loops into LQ.
static void addLoopIntoQueue(Loop *L, std::deque<Loop *> &LQ) {
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index d387b56689a..4952a644ff2 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -130,6 +130,9 @@ namespace {
/// set.
void deleteAnalysisValue(Value *V, Loop *L) override;
+ /// Simple Analysis hook. Delete loop L from alias set map.
+ void deleteAnalysisLoop(Loop *L) override;
+
/// SinkRegion - Walk the specified region of the CFG (defined by all blocks
/// dominated by the specified block, and that are in the current loop) in
/// reverse depth first order w.r.t the DominatorTree. This allows us to
@@ -943,3 +946,13 @@ void LICM::deleteAnalysisValue(Value *V, Loop *L) {
AST->deleteValue(V);
}
+
+/// Simple Analysis hook. Delete value L from alias set map.
+void LICM::deleteAnalysisLoop(Loop *L) {
+ AliasSetTracker *AST = LoopToAliasSetMap.lookup(L);
+ if (!AST)
+ return;
+
+ delete AST;
+ LoopToAliasSetMap.erase(L);
+}
diff --git a/llvm/test/Transforms/LICM/2014-09-10-doFinalizationAssert.ll b/llvm/test/Transforms/LICM/2014-09-10-doFinalizationAssert.ll
new file mode 100644
index 00000000000..17ae716dd47
--- /dev/null
+++ b/llvm/test/Transforms/LICM/2014-09-10-doFinalizationAssert.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -scalar-evolution -licm -loop-unroll -disable-output
+; Test triggered an assertion in doFinalization() because loop unroll was deleting
+; the inner loop which caused the loop to not get removed from the
+; LoopToAliasSetMap.
+; Test case taken from test/Transforms/LoopUnroll/unloop.ll.
+
+declare i1 @check() nounwind
+define void @skiplevelexit() nounwind {
+entry:
+ br label %outer
+
+outer:
+ br label %inner
+
+inner:
+ %iv = phi i32 [ 0, %outer ], [ %inc, %tail ]
+ %inc = add i32 %iv, 1
+ call zeroext i1 @check()
+ br i1 true, label %outer.backedge, label %tail
+
+tail:
+ br i1 false, label %inner, label %exit
+
+outer.backedge:
+ br label %outer
+
+exit:
+ ret void
+}
+
OpenPOWER on IntegriCloud