MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM)));
}
+static Optional<int> parseRepeatPassName(StringRef Name) {
+ if (!Name.consume_front("repeat<") || !Name.consume_back(">"))
+ return None;
+ int Count;
+ if (Name.getAsInteger(0, Count) || Count <= 0)
+ return None;
+ return Count;
+}
+
static bool isModulePassName(StringRef Name) {
// Manually handle aliases for pre-configured pipeline fragments.
if (Name.startswith("default") || Name.startswith("lto"))
if (Name == "function")
return true;
+ // Explicitly handle custom-parsed pass names.
+ if (parseRepeatPassName(Name))
+ return true;
+
#define MODULE_PASS(NAME, CREATE_PASS) \
if (Name == NAME) \
return true;
if (Name == "function")
return true;
+ // Explicitly handle custom-parsed pass names.
+ if (parseRepeatPassName(Name))
+ return true;
+
#define CGSCC_PASS(NAME, CREATE_PASS) \
if (Name == NAME) \
return true;
if (Name == "loop")
return true;
+ // Explicitly handle custom-parsed pass names.
+ if (parseRepeatPassName(Name))
+ return true;
+
#define FUNCTION_PASS(NAME, CREATE_PASS) \
if (Name == NAME) \
return true;
if (Name == "loop")
return true;
+ // Explicitly handle custom-parsed pass names.
+ if (parseRepeatPassName(Name))
+ return true;
+
#define LOOP_PASS(NAME, CREATE_PASS) \
if (Name == NAME) \
return true;
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
return true;
}
+ if (auto Count = parseRepeatPassName(Name)) {
+ ModulePassManager NestedMPM(DebugLogging);
+ if (!parseModulePassPipeline(NestedMPM, InnerPipeline, VerifyEachPass,
+ DebugLogging))
+ return false;
+ MPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedMPM)));
+ return true;
+ }
// Normal passes can't have pipelines.
return false;
}
createCGSCCToFunctionPassAdaptor(std::move(FPM), DebugLogging));
return true;
}
+ if (auto Count = parseRepeatPassName(Name)) {
+ CGSCCPassManager NestedCGPM(DebugLogging);
+ if (!parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, VerifyEachPass,
+ DebugLogging))
+ return false;
+ CGPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedCGPM)));
+ return true;
+ }
// Normal passes can't have pipelines.
return false;
}
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
return true;
}
+ if (auto Count = parseRepeatPassName(Name)) {
+ FunctionPassManager NestedFPM(DebugLogging);
+ if (!parseFunctionPassPipeline(NestedFPM, InnerPipeline, VerifyEachPass,
+ DebugLogging))
+ return false;
+ FPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedFPM)));
+ return true;
+ }
// Normal passes can't have pipelines.
return false;
}
bool PassBuilder::parseLoopPass(LoopPassManager &FPM, const PipelineElement &E,
bool VerifyEachPass, bool DebugLogging) {
- auto &Name = E.Name;
+ StringRef Name = E.Name;
auto &InnerPipeline = E.InnerPipeline;
// First handle complex passes like the pass managers which carry pipelines.
FPM.addPass(std::move(NestedLPM));
return true;
}
+ if (auto Count = parseRepeatPassName(Name)) {
+ LoopPassManager NestedLPM(DebugLogging);
+ if (!parseLoopPassPipeline(NestedLPM, InnerPipeline, VerifyEachPass,
+ DebugLogging))
+ return false;
+ FPM.addPass(createRepeatingPassWrapper(*Count, std::move(NestedLPM)));
+ return true;
+ }
// Normal passes can't have pipelines.
return false;
}
; CHECK-MODULE-PRINT: Running pass: VerifierPass
; CHECK-MODULE-PRINT: Running pass: PrintModulePass
; CHECK-MODULE-PRINT: ModuleID
-; CHECK-MODULE-PRINT: define void @foo()
+; CHECK-MODULE-PRINT: define void @foo(i1 %x)
; CHECK-MODULE-PRINT: Running pass: VerifierPass
; CHECK-MODULE-PRINT: Finished llvm::Module pass manager run
; CHECK-MODULE-VERIFY: Starting llvm::Module pass manager run
; CHECK-MODULE-VERIFY: Running pass: PrintModulePass
; CHECK-MODULE-VERIFY: ModuleID
-; CHECK-MODULE-VERIFY: define void @foo()
+; CHECK-MODULE-VERIFY: define void @foo(i1 %x)
; CHECK-MODULE-VERIFY: Running pass: VerifierPass
; CHECK-MODULE-VERIFY: Finished llvm::Module pass manager run
; CHECK-FUNCTION-PRINT: Starting llvm::Function pass manager run
; CHECK-FUNCTION-PRINT: Running pass: PrintFunctionPass
; CHECK-FUNCTION-PRINT-NOT: ModuleID
-; CHECK-FUNCTION-PRINT: define void @foo()
+; CHECK-FUNCTION-PRINT: define void @foo(i1 %x)
; CHECK-FUNCTION-PRINT: Finished llvm::Function pass manager run
; CHECK-FUNCTION-PRINT: Running pass: VerifierPass
; CHECK-FUNCTION-PRINT: Finished llvm::Module pass manager run
; CHECK-FUNCTION-VERIFY: Starting llvm::Function pass manager run
; CHECK-FUNCTION-VERIFY: Running pass: PrintFunctionPass
; CHECK-FUNCTION-VERIFY-NOT: ModuleID
-; CHECK-FUNCTION-VERIFY: define void @foo()
+; CHECK-FUNCTION-VERIFY: define void @foo(i1 %x)
; CHECK-FUNCTION-VERIFY: Running pass: VerifierPass
; CHECK-FUNCTION-VERIFY: Finished llvm::Function pass manager run
; CHECK-FUNCTION-VERIFY: Finished llvm::Module pass manager run
; RUN: opt -S -o - -passes='no-op-module,no-op-module' %s \
; RUN: | FileCheck %s --check-prefix=CHECK-NOOP
-; CHECK-NOOP: define void @foo() {
+; CHECK-NOOP: define void @foo(i1 %x) {
+; CHECK-NOOP: entry:
+; CHECK-NOOP: br i1 %x, label %loop, label %exit
+; CHECK-NOOP: loop:
+; CHECK-NOOP: br label %loop
+; CHECK-NOOP: exit:
; CHECK-NOOP: ret void
; CHECK-NOOP: }
; CHECK-LTO-O2: Running pass: InstCombinePass
; CHECK-LTO-O2: Running pass: SimplifyCFGPass
-define void @foo() {
+; RUN: opt -disable-output -disable-verify -debug-pass-manager \
+; RUN: -passes='repeat<3>(no-op-module)' %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-REPEAT-MODULE-PASS
+; CHECK-REPEAT-MODULE-PASS: Starting llvm::Module pass manager run
+; CHECK-REPEAT-MODULE-PASS-NEXT: Running pass: RepeatingPassWrapper
+; CHECK-REPEAT-MODULE-PASS-NEXT: Starting llvm::Module pass manager run
+; CHECK-REPEAT-MODULE-PASS-NEXT: Running pass: NoOpModulePass
+; CHECK-REPEAT-MODULE-PASS-NEXT: Finished llvm::Module pass manager run
+; CHECK-REPEAT-MODULE-PASS-NEXT: Starting llvm::Module pass manager run
+; CHECK-REPEAT-MODULE-PASS-NEXT: Running pass: NoOpModulePass
+; CHECK-REPEAT-MODULE-PASS-NEXT: Finished llvm::Module pass manager run
+; CHECK-REPEAT-MODULE-PASS-NEXT: Starting llvm::Module pass manager run
+; CHECK-REPEAT-MODULE-PASS-NEXT: Running pass: NoOpModulePass
+; CHECK-REPEAT-MODULE-PASS-NEXT: Finished llvm::Module pass manager run
+; CHECK-REPEAT-MODULE-PASS-NEXT: Finished llvm::Module pass manager run
+
+; RUN: opt -disable-output -disable-verify -debug-pass-manager \
+; RUN: -passes='cgscc(repeat<3>(no-op-cgscc))' %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-REPEAT-CGSCC-PASS
+; CHECK-REPEAT-CGSCC-PASS: Starting llvm::Module pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running an SCC pass across the RefSCC: [(foo)]
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: RepeatingPassWrapper
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting llvm::LazyCallGraph::SCC pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::LazyCallGraph::SCC pass manager run
+; CHECK-REPEAT-CGSCC-PASS-NEXT: Finished llvm::Module pass manager run
+
+; RUN: opt -disable-output -disable-verify -debug-pass-manager \
+; RUN: -passes='function(repeat<3>(no-op-function))' %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-REPEAT-FUNCTION-PASS
+; CHECK-REPEAT-FUNCTION-PASS: Starting llvm::Module pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*}}>
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: RepeatingPassWrapper
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Starting llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Running pass: NoOpFunctionPass
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Function pass manager run
+; CHECK-REPEAT-FUNCTION-PASS-NEXT: Finished llvm::Module pass manager run
+
+; RUN: opt -disable-output -disable-verify -debug-pass-manager \
+; RUN: -passes='loop(repeat<3>(no-op-loop))' %s 2>&1 \
+; RUN: | FileCheck %s --check-prefix=CHECK-REPEAT-LOOP-PASS
+; CHECK-REPEAT-LOOP-PASS: Starting llvm::Module pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: ModuleToFunctionPassAdaptor
+; 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: Starting llvm::Loop pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: RepeatingPassWrapper
+; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Loop pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Loop pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Loop pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Loop pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Starting llvm::Loop pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Running pass: NoOpLoopPass
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Loop pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Loop pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Function pass manager run
+; CHECK-REPEAT-LOOP-PASS-NEXT: Finished llvm::Module pass manager run
+
+define void @foo(i1 %x) {
+entry:
+ br i1 %x, label %loop, label %exit
+
+loop:
+ br label %loop
+
+exit:
ret void
}