PM: Implement a basic loop pass manager

This creates the new-style LoopPassManager and wires it up with dummy
and print passes.

This version doesn't support modifying the loop nest at all. It will
be far easier to discuss and evaluate the approaches to that with this
in place so that the boilerplate is out of the way.

llvm-svn: 261831
diff --git a/llvm/test/Other/loop-pass-ordering.ll b/llvm/test/Other/loop-pass-ordering.ll
new file mode 100644
index 0000000..ceda0d3
--- /dev/null
+++ b/llvm/test/Other/loop-pass-ordering.ll
@@ -0,0 +1,35 @@
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN:     -passes='no-op-loop' %s 2>&1 \
+; RUN:     | FileCheck %s
+
+;            @f()
+;           /    \
+;       loop.0   loop.1
+;      /      \        \
+; loop.0.0  loop.0.1  loop.1.0
+;
+; CHECK: Running pass: NoOpLoopPass on loop.1.0
+; CHECK: Running pass: NoOpLoopPass on loop.1
+; CHECK: Running pass: NoOpLoopPass on loop.0.0
+; CHECK: Running pass: NoOpLoopPass on loop.0.1
+; CHECK: Running pass: NoOpLoopPass on loop.0
+define void @f() {
+entry:
+  br label %loop.0
+loop.0:
+  br i1 undef, label %loop.0.0, label %loop.1
+loop.0.0:
+  br i1 undef, label %loop.0.0, label %loop.0.1
+loop.0.1:
+  br i1 undef, label %loop.0.1, label %loop.0
+loop.1:
+  br i1 undef, label %loop.1, label %loop.1.bb1
+loop.1.bb1:
+  br i1 undef, label %loop.1, label %loop.1.bb2
+loop.1.bb2:
+  br i1 undef, label %end, label %loop.1.0
+loop.1.0:
+  br i1 undef, label %loop.1.0, label %loop.1
+end:
+  ret void
+}
diff --git a/llvm/test/Other/pass-pipeline-parsing.ll b/llvm/test/Other/pass-pipeline-parsing.ll
index da0e760..3c09b01 100644
--- a/llvm/test/Other/pass-pipeline-parsing.ll
+++ b/llvm/test/Other/pass-pipeline-parsing.ll
@@ -137,6 +137,46 @@
 ; CHECK-NESTED-MP-CG-FP: Finished pass manager
 ; CHECK-NESTED-MP-CG-FP: Finished pass manager
 
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN:     -passes='no-op-loop,no-op-loop' %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-TWO-NOOP-LOOP
+; CHECK-TWO-NOOP-LOOP: Starting pass manager
+; CHECK-TWO-NOOP-LOOP: Running pass: ModuleToFunctionPassAdaptor
+; CHECK-TWO-NOOP-LOOP: Starting pass manager
+; CHECK-TWO-NOOP-LOOP: Running pass: FunctionToLoopPassAdaptor
+; CHECK-TWO-NOOP-LOOP: Starting pass manager
+; CHECK-TWO-NOOP-LOOP: Running pass: NoOpLoopPass
+; CHECK-TWO-NOOP-LOOP: Running pass: NoOpLoopPass
+; CHECK-TWO-NOOP-LOOP: Finished pass manager
+; CHECK-TWO-NOOP-LOOP: Finished pass manager
+; CHECK-TWO-NOOP-LOOP: Finished pass manager
+
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN:     -passes='module(function(loop(no-op-loop)))' %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-NESTED-FP-LP
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN:     -passes='function(loop(no-op-loop))' %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-NESTED-FP-LP
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN:     -passes='loop(no-op-loop)' %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-NESTED-FP-LP
+; RUN: opt -disable-output -debug-pass-manager \
+; RUN:     -passes='no-op-loop' %s 2>&1 \
+; RUN:     | FileCheck %s --check-prefix=CHECK-NESTED-FP-LP
+; CHECK-NESTED-FP-LP: Starting pass manager
+; CHECK-NESTED-FP-LP: Running pass: ModuleToFunctionPassAdaptor
+; CHECK-NESTED-FP-LP: Starting pass manager
+; CHECK-NESTED-FP-LP: Running pass: FunctionToLoopPassAdaptor
+; CHECK-NESTED-FP-LP: Starting pass manager
+; CHECK-NESTED-FP-LP: Running pass: NoOpLoopPass
+; CHECK-NESTED-FP-LP: Finished pass manager
+; CHECK-NESTED-FP-LP: Finished pass manager
+; CHECK-NESTED-FP-LP: Finished pass manager
+
+
 define void @f() {
- ret void
+entry:
+ br label %loop
+loop:
+ br label %loop
 }