[llvm] r292241 - [PM] Teach the LoopPassManager to automatically canonicalize loops by

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 17 11:18:13 PST 2017


Author: chandlerc
Date: Tue Jan 17 13:18:12 2017
New Revision: 292241

URL: http://llvm.org/viewvc/llvm-project?rev=292241&view=rev
Log:
[PM] Teach the LoopPassManager to automatically canonicalize loops by
runnig LCSSA over them prior to running the loop pipeline.

This also teaches the loop PM to verify that LCSSA form is preserved
throughout the pipeline's run across the loop nest.

Most of the test updates just leverage this new functionality. One has to be
relaxed with the new PM as IVUsers is less powerful when it sees LCSSA input.

Differential Revision: https://reviews.llvm.org/D28743

Modified:
    llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h
    llvm/trunk/test/Analysis/IVUsers/quadradic-exit-value.ll
    llvm/trunk/test/Other/new-pass-manager.ll
    llvm/trunk/test/Transforms/LICM/atomics.ll
    llvm/trunk/test/Transforms/LICM/constexpr.ll
    llvm/trunk/test/Transforms/LICM/hoist-nounwind.ll
    llvm/trunk/test/Transforms/LICM/hoisting.ll

Modified: llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h?rev=292241&r1=292240&r2=292241&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar/LoopPassManager.h Tue Jan 17 13:18:12 2017
@@ -51,6 +51,7 @@
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/IR/Dominators.h"
 #include "llvm/IR/PassManager.h"
+#include "llvm/Transforms/Utils/LCSSA.h"
 
 namespace llvm {
 
@@ -248,10 +249,18 @@ template <typename LoopPassT>
 class FunctionToLoopPassAdaptor
     : public PassInfoMixin<FunctionToLoopPassAdaptor<LoopPassT>> {
 public:
-  explicit FunctionToLoopPassAdaptor(LoopPassT Pass) : Pass(std::move(Pass)) {}
+  explicit FunctionToLoopPassAdaptor(LoopPassT Pass) : Pass(std::move(Pass)) {
+    LoopCanonicalizationFPM.addPass(LCSSAPass());
+  }
 
   /// \brief Runs the loop passes across every loop in the function.
   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM) {
+    // Before we even compute any loop analyses, first run a miniature function
+    // pass pipeline to put loops into their canonical form. Note that we can
+    // directly build up function analyses after this as the function pass
+    // manager handles all the invalidation at that layer.
+    PreservedAnalyses PA = LoopCanonicalizationFPM.run(F, AM);
+
     // Setup the loop analysis manager from its proxy.
     LoopAnalysisManager &LAM =
         AM.getResult<LoopAnalysisManagerFunctionProxy>(F).getManager();
@@ -260,7 +269,7 @@ public:
 
     // If there are no loops, there is nothing to do here.
     if (LI.empty())
-      return PreservedAnalyses::all();
+      return PA;
 
     // Get the analysis results needed by loop passes.
     LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
@@ -271,8 +280,6 @@ public:
                                        AM.getResult<TargetLibraryAnalysis>(F),
                                        AM.getResult<TargetIRAnalysis>(F)};
 
-    PreservedAnalyses PA = PreservedAnalyses::all();
-
     // A postorder worklist of loops to process.
     SmallPriorityWorklist<Loop *, 4> Worklist;
 
@@ -294,8 +301,15 @@ public:
       // Reset the update structure for this loop.
       Updater.CurrentL = L;
       Updater.SkipCurrentLoop = false;
+
 #ifndef NDEBUG
+      // Save a parent loop pointer for asserts.
       Updater.ParentL = L->getParentLoop();
+
+      // Verify the loop structure and LCSSA form before visiting the loop.
+      L->verifyLoop();
+      assert(L->isRecursivelyLCSSAForm(LAR.DT, LI) &&
+             "Loops must remain in LCSSA form!");
 #endif
 
       PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater);
@@ -335,6 +349,8 @@ public:
 
 private:
   LoopPassT Pass;
+
+  FunctionPassManager LoopCanonicalizationFPM;
 };
 
 /// \brief A function to deduce a loop pass type and wrap it in the templated

Modified: llvm/trunk/test/Analysis/IVUsers/quadradic-exit-value.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/IVUsers/quadradic-exit-value.ll?rev=292241&r1=292240&r2=292241&view=diff
==============================================================================
--- llvm/trunk/test/Analysis/IVUsers/quadradic-exit-value.ll (original)
+++ llvm/trunk/test/Analysis/IVUsers/quadradic-exit-value.ll Tue Jan 17 13:18:12 2017
@@ -5,7 +5,7 @@
 ; passes *always* work on LCSSA. This should stop using a different set of
 ; checks at that point.
 
-; RUN: opt < %s -analyze -iv-users | FileCheck %s
+; RUN: opt < %s -analyze -iv-users | FileCheck %s --check-prefixes=CHECK,CHECK-NO-LCSSA
 ; RUN: opt < %s -disable-output -passes='print<ivusers>' 2>&1 | FileCheck %s
 
 ; Provide legal integer types.
@@ -14,7 +14,7 @@ target datalayout = "n8:16:32:64"
 ; The value of %r is dependent on a polynomial iteration expression.
 ;
 ; CHECK-LABEL: IV Users for loop %foo.loop
-; CHECK: {1,+,3,+,2}<%foo.loop>
+; CHECK-NO-LCSSA: {1,+,3,+,2}<%foo.loop>
 define i64 @foo(i64 %n) {
 entry:
   br label %foo.loop
@@ -36,7 +36,7 @@ exit:
 ; sure they aren't marked as post-inc users.
 ;
 ; CHECK-LABEL: IV Users for loop %test2.loop
-; CHECK: %sext.us = {0,+,(16777216 + (-16777216 * %sub.us))<nuw><nsw>,+,33554432}<%test2.loop> in %f = ashr i32 %sext.us, 24
+; CHECK-NO-LCSSA: %sext.us = {0,+,(16777216 + (-16777216 * %sub.us))<nuw><nsw>,+,33554432}<%test2.loop> in %f = ashr i32 %sext.us, 24
 define i32 @test2() {
 entry:
   br label %test2.loop

Modified: llvm/trunk/test/Other/new-pass-manager.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=292241&r1=292240&r2=292241&view=diff
==============================================================================
--- llvm/trunk/test/Other/new-pass-manager.ll (original)
+++ llvm/trunk/test/Other/new-pass-manager.ll Tue Jan 17 13:18:12 2017
@@ -539,9 +539,9 @@
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass manager run
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: FunctionToLoopPassAdaptor
-; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: LoopAnalysis
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: DominatorTreeAnalysis
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: AAManager
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: TargetLibraryAnalysis
 ; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: AssumptionAnalysis

Modified: llvm/trunk/test/Transforms/LICM/atomics.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/atomics.ll?rev=292241&r1=292240&r2=292241&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LICM/atomics.ll (original)
+++ llvm/trunk/test/Transforms/LICM/atomics.ll Tue Jan 17 13:18:12 2017
@@ -1,5 +1,5 @@
 ; RUN: opt < %s -S -basicaa -licm | FileCheck %s
-; RUN: opt -aa-pipeline=basic-aa -passes='lcssa,require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
+; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
 
 ; Check that we can hoist unordered loads
 define i32 @test1(i32* nocapture %y) nounwind uwtable ssp {

Modified: llvm/trunk/test/Transforms/LICM/constexpr.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/constexpr.ll?rev=292241&r1=292240&r2=292241&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LICM/constexpr.ll (original)
+++ llvm/trunk/test/Transforms/LICM/constexpr.ll Tue Jan 17 13:18:12 2017
@@ -1,5 +1,5 @@
 ; RUN: opt < %s -S -basicaa -licm | FileCheck %s
-; RUN: opt -aa-pipeline=basic-aa -passes='lcssa,require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
+; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' < %s -S | FileCheck %s
 ; This fixes PR22460
 
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"

Modified: llvm/trunk/test/Transforms/LICM/hoist-nounwind.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/hoist-nounwind.ll?rev=292241&r1=292240&r2=292241&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LICM/hoist-nounwind.ll (original)
+++ llvm/trunk/test/Transforms/LICM/hoist-nounwind.ll Tue Jan 17 13:18:12 2017
@@ -1,5 +1,5 @@
 ; RUN: opt -S -basicaa -licm < %s | FileCheck %s
-; RUN: opt -aa-pipeline=basic-aa -passes='lcssa,require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
+; RUN: opt -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -S %s | FileCheck %s
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 

Modified: llvm/trunk/test/Transforms/LICM/hoisting.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LICM/hoisting.ll?rev=292241&r1=292240&r2=292241&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LICM/hoisting.ll (original)
+++ llvm/trunk/test/Transforms/LICM/hoisting.ll Tue Jan 17 13:18:12 2017
@@ -1,5 +1,5 @@
 ; RUN: opt < %s -licm -S | FileCheck %s
-; RUN: opt -lcssa %s | opt -aa-pipeline=basic-aa -passes='require<aa>,require<targetir>,require<scalar-evolution>,require<opt-remark-emit>,loop(licm)' -S | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa -passes='require<opt-remark-emit>,loop(licm)' -S | FileCheck %s
 
 @X = global i32 0		; <i32*> [#uses=1]
 




More information about the llvm-commits mailing list