<div dir="ltr">Yea, I completely agree that Wrapper is a bad suffix. Thanks for catching it, I just hadn't gone down that thought process. However, I'm not terribly fond of just using Decorator here because I feel like it isn't conveying much of anything. With the actual place we used "wrapper pass" in the old pass manager it has a reasonably specific meaning, and this doesn't. Ultimately, I think the suffix isn't helping at all and what is needed is a better name. =]<div><br></div><div>After some bikeshedding on IRC, I'm going with RepeatedPass<...> as it is a template to create a repeated pass. =] Happy to keep tweaking this if this name presents more problems.</div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Aug 3, 2016 at 1:20 PM Sean Silva via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Sorry for not mentioning this earlier, but can you please avoid using the term "wrapper" for this? (as it may cause confusion with the "wrapper pass" notion for analyses)<div><div><br></div><div>Same goes for the DevirtIteratingWrapper in <a href="https://reviews.llvm.org/D23114" target="_blank">https://reviews.llvm.org/D23114</a></div><div><br></div><div>These seem to essentially be decorator classes, so "decorator" is probably a better name anyway and avoids the confusion.</div></div></div><div dir="ltr"><div><br></div><div>-- Sean Silva</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Aug 3, 2016 at 12:44 AM, Chandler Carruth via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: chandlerc<br>
Date: Wed Aug  3 02:44:48 2016<br>
New Revision: 277581<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=277581&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=277581&view=rev</a><br>
Log:<br>
[PM] Add a generic 'repeat N times' pass wrapper to the new pass<br>
manager.<br>
<br>
While this has some utility for debugging and testing on its own, it is<br>
primarily intended to demonstrate the technique for adding custom<br>
wrappers that can provide more interesting interation behavior in<br>
a nice, orthogonal, and composable layer.<br>
<br>
Being able to write these kinds of very dynamic and customized controls<br>
for running passes was one of the motivating use cases of the new pass<br>
manager design, and this gives a hint at how they might look. The actual<br>
logic is tiny here, and most of this is just wiring in the pipeline<br>
parsing so that this can be widely used.<br>
<br>
I'm adding this now to show the wiring without a lot of business logic.<br>
This is a precursor patch for showing how a "iterate up to N times as<br>
long as we devirtualize a call" utility can be added as a separable and<br>
composable component along side the CGSCC pass management.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D22405" rel="noreferrer" target="_blank">https://reviews.llvm.org/D22405</a><br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/PassManager.h<br>
    llvm/trunk/lib/Passes/PassBuilder.cpp<br>
    llvm/trunk/test/Other/new-pass-manager.ll<br>
<br>
Modified: llvm/trunk/include/llvm/IR/PassManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=277581&r1=277580&r2=277581&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=277581&r1=277580&r2=277581&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/PassManager.h (original)<br>
+++ llvm/trunk/include/llvm/IR/PassManager.h Wed Aug  3 02:44:48 2016<br>
@@ -987,6 +987,34 @@ struct InvalidateAllAnalysesPass : PassI<br>
   }<br>
 };<br>
<br>
+/// A utility pass template that simply runs another pass multiple times.<br>
+///<br>
+/// This can be useful when debugging or testing passes. It also serves as an<br>
+/// example of how to extend the pass manager in ways beyond composition.<br>
+template <typename PassT><br>
+class RepeatingPassWrapper : public PassInfoMixin<RepeatingPassWrapper<PassT>> {<br>
+public:<br>
+  RepeatingPassWrapper(int Count, PassT P) : Count(Count), P(std::move(P)) {}<br>
+<br>
+  template <typename IRUnitT, typename... Ts><br>
+  PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> &AM,<br>
+                        Ts... Args) {<br>
+    auto PA = PreservedAnalyses::all();<br>
+    for (int i = 0; i < Count; ++i)<br>
+      PA.intersect(P.run(Arg, AM, Args...));<br>
+    return PA;<br>
+  }<br>
+<br>
+private:<br>
+  const int Count;<br>
+  PassT P;<br>
+};<br>
+<br>
+template <typename PassT><br>
+RepeatingPassWrapper<PassT> createRepeatingPassWrapper(int Count, PassT P) {<br>
+  return RepeatingPassWrapper<PassT>(Count, std::move(P));<br>
+}<br>
+<br>
 }<br>
<br>
 #endif<br>
<br>
Modified: llvm/trunk/lib/Passes/PassBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=277581&r1=277580&r2=277581&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=277581&r1=277580&r2=277581&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Passes/PassBuilder.cpp (original)<br>
+++ llvm/trunk/lib/Passes/PassBuilder.cpp Wed Aug  3 02:44:48 2016<br>
@@ -274,6 +274,15 @@ void PassBuilder::addLTODefaultPipeline(<br>
   MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM)));<br>
 }<br>
<br>
+static Optional<int> parseRepeatPassName(StringRef Name) {<br>
+  if (!Name.consume_front("repeat<") || !Name.consume_back(">"))<br>
+    return None;<br>
+  int Count;<br>
+  if (Name.getAsInteger(0, Count) || Count <= 0)<br>
+    return None;<br>
+  return Count;<br>
+}<br>
+<br>
 static bool isModulePassName(StringRef Name) {<br>
   // Manually handle aliases for pre-configured pipeline fragments.<br>
   if (Name.startswith("default") || Name.startswith("lto"))<br>
@@ -287,6 +296,10 @@ static bool isModulePassName(StringRef N<br>
   if (Name == "function")<br>
     return true;<br>
<br>
+  // Explicitly handle custom-parsed pass names.<br>
+  if (parseRepeatPassName(Name))<br>
+    return true;<br>
+<br>
 #define MODULE_PASS(NAME, CREATE_PASS)                                         \<br>
   if (Name == NAME)                                                            \<br>
     return true;<br>
@@ -305,6 +318,10 @@ static bool isCGSCCPassName(StringRef Na<br>
   if (Name == "function")<br>
     return true;<br>
<br>
+  // Explicitly handle custom-parsed pass names.<br>
+  if (parseRepeatPassName(Name))<br>
+    return true;<br>
+<br>
 #define CGSCC_PASS(NAME, CREATE_PASS)                                          \<br>
   if (Name == NAME)                                                            \<br>
     return true;<br>
@@ -323,6 +340,10 @@ static bool isFunctionPassName(StringRef<br>
   if (Name == "loop")<br>
     return true;<br>
<br>
+  // Explicitly handle custom-parsed pass names.<br>
+  if (parseRepeatPassName(Name))<br>
+    return true;<br>
+<br>
 #define FUNCTION_PASS(NAME, CREATE_PASS)                                       \<br>
   if (Name == NAME)                                                            \<br>
     return true;<br>
@@ -339,6 +360,10 @@ static bool isLoopPassName(StringRef Nam<br>
   if (Name == "loop")<br>
     return true;<br>
<br>
+  // Explicitly handle custom-parsed pass names.<br>
+  if (parseRepeatPassName(Name))<br>
+    return true;<br>
+<br>
 #define LOOP_PASS(NAME, CREATE_PASS)                                           \<br>
   if (Name == NAME)                                                            \<br>
     return true;<br>
@@ -440,6 +465,14 @@ bool PassBuilder::parseModulePass(Module<br>
       MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));<br>
       return true;<br>
     }<br>
+    if (auto Count = parseRepeatPassName(Name)) {<br>
+      ModulePassManager NestedMPM(DebugLogging);<br>
+      if (!parseModulePassPipeline(NestedMPM, InnerPipeline, VerifyEachPass,<br>
+                                   DebugLogging))<br>
+        return false;<br>
+      MPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedMPM)));<br>
+      return true;<br>
+    }<br>
     // Normal passes can't have pipelines.<br>
     return false;<br>
   }<br>
@@ -519,6 +552,14 @@ bool PassBuilder::parseCGSCCPass(CGSCCPa<br>
           createCGSCCToFunctionPassAdaptor(std::move(FPM), DebugLogging));<br>
       return true;<br>
     }<br>
+    if (auto Count = parseRepeatPassName(Name)) {<br>
+      CGSCCPassManager NestedCGPM(DebugLogging);<br>
+      if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass,<br>
+                                  DebugLogging))<br>
+        return false;<br>
+      CGPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedCGPM)));<br>
+      return true;<br>
+    }<br>
     // Normal passes can't have pipelines.<br>
     return false;<br>
   }<br>
@@ -571,6 +612,14 @@ bool PassBuilder::parseFunctionPass(Func<br>
       FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));<br>
       return true;<br>
     }<br>
+    if (auto Count = parseRepeatPassName(Name)) {<br>
+      FunctionPassManager NestedFPM(DebugLogging);<br>
+      if (!parseFunctionPassPipeline(NestedFPM, InnerPipeline, VerifyEachPass,<br>
+                                     DebugLogging))<br>
+        return false;<br>
+      FPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedFPM)));<br>
+      return true;<br>
+    }<br>
     // Normal passes can't have pipelines.<br>
     return false;<br>
   }<br>
@@ -599,7 +648,7 @@ bool PassBuilder::parseFunctionPass(Func<br>
<br>
 bool PassBuilder::parseLoopPass(LoopPassManager &FPM, const PipelineElement &E,<br>
                                 bool VerifyEachPass, bool DebugLogging) {<br>
-  auto &Name = E.Name;<br>
+  StringRef Name = E.Name;<br>
   auto &InnerPipeline = E.InnerPipeline;<br>
<br>
   // First handle complex passes like the pass managers which carry pipelines.<br>
@@ -613,6 +662,14 @@ bool PassBuilder::parseLoopPass(LoopPass<br>
       FPM.addPass(std::move(NestedLPM));<br>
       return true;<br>
     }<br>
+    if (auto Count = parseRepeatPassName(Name)) {<br>
+      LoopPassManager NestedLPM(DebugLogging);<br>
+      if (!parseLoopPassPipeline(NestedLPM, InnerPipeline, VerifyEachPass,<br>
+                                 DebugLogging))<br>
+        return false;<br>
+      FPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedLPM)));<br>
+      return true;<br>
+    }<br>
     // Normal passes can't have pipelines.<br>
     return false;<br>
   }<br>
<br>
Modified: llvm/trunk/test/Other/new-pass-manager.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=277581&r1=277580&r2=277581&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/new-pass-manager.ll?rev=277581&r1=277580&r2=277581&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Other/new-pass-manager.ll (original)<br>
+++ llvm/trunk/test/Other/new-pass-manager.ll Wed Aug  3 02:44:48 2016<br>
@@ -48,7 +48,7 @@<br>
 ; CHECK-MODULE-PRINT: Running pass: VerifierPass<br>
 ; CHECK-MODULE-PRINT: Running pass: PrintModulePass<br>
 ; CHECK-MODULE-PRINT: ModuleID<br>
-; CHECK-MODULE-PRINT: define void @foo()<br>
+; CHECK-MODULE-PRINT: define void @foo(i1 %x)<br>
 ; CHECK-MODULE-PRINT: Running pass: VerifierPass<br>
 ; CHECK-MODULE-PRINT: Finished llvm::Module pass manager run<br>
<br>
@@ -57,7 +57,7 @@<br>
 ; CHECK-MODULE-VERIFY: Starting llvm::Module pass manager run<br>
 ; CHECK-MODULE-VERIFY: Running pass: PrintModulePass<br>
 ; CHECK-MODULE-VERIFY: ModuleID<br>
-; CHECK-MODULE-VERIFY: define void @foo()<br>
+; CHECK-MODULE-VERIFY: define void @foo(i1 %x)<br>
 ; CHECK-MODULE-VERIFY: Running pass: VerifierPass<br>
 ; CHECK-MODULE-VERIFY: Finished llvm::Module pass manager run<br>
<br>
@@ -70,7 +70,7 @@<br>
 ; CHECK-FUNCTION-PRINT: Starting llvm::Function pass manager run<br>
 ; CHECK-FUNCTION-PRINT: Running pass: PrintFunctionPass<br>
 ; CHECK-FUNCTION-PRINT-NOT: ModuleID<br>
-; CHECK-FUNCTION-PRINT: define void @foo()<br>
+; CHECK-FUNCTION-PRINT: define void @foo(i1 %x)<br>
 ; CHECK-FUNCTION-PRINT: Finished llvm::Function pass manager run<br>
 ; CHECK-FUNCTION-PRINT: Running pass: VerifierPass<br>
 ; CHECK-FUNCTION-PRINT: Finished llvm::Module pass manager run<br>
@@ -81,14 +81,19 @@<br>
 ; CHECK-FUNCTION-VERIFY: Starting llvm::Function pass manager run<br>
 ; CHECK-FUNCTION-VERIFY: Running pass: PrintFunctionPass<br>
 ; CHECK-FUNCTION-VERIFY-NOT: ModuleID<br>
-; CHECK-FUNCTION-VERIFY: define void @foo()<br>
+; CHECK-FUNCTION-VERIFY: define void @foo(i1 %x)<br>
 ; CHECK-FUNCTION-VERIFY: Running pass: VerifierPass<br>
 ; CHECK-FUNCTION-VERIFY: Finished llvm::Function pass manager run<br>
 ; CHECK-FUNCTION-VERIFY: Finished llvm::Module pass manager run<br>
<br>
 ; RUN: opt -S -o - -passes='no-op-module,no-op-module' %s \<br>
 ; RUN:     | FileCheck %s --check-prefix=CHECK-NOOP<br>
-; CHECK-NOOP: define void @foo() {<br>
+; CHECK-NOOP: define void @foo(i1 %x) {<br>
+; CHECK-NOOP: entry:<br>
+; CHECK-NOOP:   br i1 %x, label %loop, label %exit<br>
+; CHECK-NOOP: loop:<br>
+; CHECK-NOOP:   br label %loop<br>
+; CHECK-NOOP: exit:<br>
 ; CHECK-NOOP:   ret void<br>
 ; CHECK-NOOP: }<br>
<br>
@@ -363,7 +368,98 @@<br>
 ; CHECK-LTO-O2: Running pass: InstCombinePass<br>
 ; CHECK-LTO-O2: Running pass: SimplifyCFGPass<br>
<br>
-define void @foo() {<br>
+; RUN: opt -disable-output -disable-verify -debug-pass-manager \<br>
+; RUN:     -passes='repeat<3>(no-op-module)' %s 2>&1 \<br>
+; RUN:     | FileCheck %s --check-prefix=CHECK-REPEAT-MODULE-PASS<br>
+; CHECK-REPEAT-MODULE-PASS: Starting llvm::Module pass manager run<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Running pass: RepeatingPassWrapper<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Starting llvm::Module pass manager run<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Running pass: NoOpModulePass<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Finished llvm::Module pass manager run<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Starting llvm::Module pass manager run<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Running pass: NoOpModulePass<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Finished llvm::Module pass manager run<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Starting llvm::Module pass manager run<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Running pass: NoOpModulePass<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Finished llvm::Module pass manager run<br>
+; CHECK-REPEAT-MODULE-PASS-NEXT: Finished llvm::Module pass manager run<br>
+<br>
+; RUN: opt -disable-output -disable-verify -debug-pass-manager \<br>
+; RUN:     -passes='cgscc(repeat<3>(no-op-cgscc))' %s 2>&1 \<br>
+; RUN:     | FileCheck %s --check-prefix=CHECK-REPEAT-CGSCC-PASS<br>
+; CHECK-REPEAT-CGSCC-PASS: Starting llvm::Module pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}><br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running an SCC pass across the RefSCC: [(foo)]<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: RepeatingPassWrapper<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run<br>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::Module pass manager run<br>
+<br>
+; RUN: opt -disable-output -disable-verify -debug-pass-manager \<br>
+; RUN:     -passes='function(repeat<3>(no-op-function))' %s 2>&1 \<br>
+; RUN:     | FileCheck %s --check-prefix=CHECK-REPEAT-FUNCTION-PASS<br>
+; CHECK-REPEAT-FUNCTION-PASS: Starting llvm::Module pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}><br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: RepeatingPassWrapper<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run<br>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Module pass manager run<br>
+<br>
+; RUN: opt -disable-output -disable-verify -debug-pass-manager \<br>
+; RUN:     -passes='loop(repeat<3>(no-op-loop))' %s 2>&1 \<br>
+; RUN:     | FileCheck %s --check-prefix=CHECK-REPEAT-LOOP-PASS<br>
+; CHECK-REPEAT-LOOP-PASS: Starting llvm::Module pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}><br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Function pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: FunctionToLoopPassAdaptor<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}><br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: LoopAnalysis<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running analysis: DominatorTreeAnalysis<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Loop pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: RepeatingPassWrapper<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Loop pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Loop pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Loop pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Loop pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Loop pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Loop pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Loop pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Function pass manager run<br>
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Module pass manager run<br>
+<br>
+define void @foo(i1 %x) {<br>
+entry:<br>
+  br i1 %x, label %loop, label %exit<br>
+<br>
+loop:<br>
+  br label %loop<br>
+<br>
+exit:<br>
   ret void<br>
 }<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>