[llvm] r277581 - [PM] Add a generic 'repeat N times' pass wrapper to the new pass
Chandler Carruth via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 3 19:26:30 PDT 2016
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. =]
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.
On Wed, Aug 3, 2016 at 1:20 PM Sean Silva via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> 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)
>
> Same goes for the DevirtIteratingWrapper in
> https://reviews.llvm.org/D23114
>
> These seem to essentially be decorator classes, so "decorator" is probably
> a better name anyway and avoids the confusion.
>
> -- Sean Silva
>
>
> On Wed, Aug 3, 2016 at 12:44 AM, Chandler Carruth via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>> Author: chandlerc
>> Date: Wed Aug 3 02:44:48 2016
>> New Revision: 277581
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=277581&view=rev
>> Log:
>> [PM] Add a generic 'repeat N times' pass wrapper to the new pass
>> manager.
>>
>> While this has some utility for debugging and testing on its own, it is
>> primarily intended to demonstrate the technique for adding custom
>> wrappers that can provide more interesting interation behavior in
>> a nice, orthogonal, and composable layer.
>>
>> Being able to write these kinds of very dynamic and customized controls
>> for running passes was one of the motivating use cases of the new pass
>> manager design, and this gives a hint at how they might look. The actual
>> logic is tiny here, and most of this is just wiring in the pipeline
>> parsing so that this can be widely used.
>>
>> I'm adding this now to show the wiring without a lot of business logic.
>> This is a precursor patch for showing how a "iterate up to N times as
>> long as we devirtualize a call" utility can be added as a separable and
>> composable component along side the CGSCC pass management.
>>
>> Differential Revision: https://reviews.llvm.org/D22405
>>
>> Modified:
>> llvm/trunk/include/llvm/IR/PassManager.h
>> llvm/trunk/lib/Passes/PassBuilder.cpp
>> llvm/trunk/test/Other/new-pass-manager.ll
>>
>> Modified: llvm/trunk/include/llvm/IR/PassManager.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/PassManager.h?rev=277581&r1=277580&r2=277581&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/IR/PassManager.h (original)
>> +++ llvm/trunk/include/llvm/IR/PassManager.h Wed Aug 3 02:44:48 2016
>> @@ -987,6 +987,34 @@ struct InvalidateAllAnalysesPass : PassI
>> }
>> };
>>
>> +/// A utility pass template that simply runs another pass multiple times.
>> +///
>> +/// This can be useful when debugging or testing passes. It also serves
>> as an
>> +/// example of how to extend the pass manager in ways beyond composition.
>> +template <typename PassT>
>> +class RepeatingPassWrapper : public
>> PassInfoMixin<RepeatingPassWrapper<PassT>> {
>> +public:
>> + RepeatingPassWrapper(int Count, PassT P) : Count(Count),
>> P(std::move(P)) {}
>> +
>> + template <typename IRUnitT, typename... Ts>
>> + PreservedAnalyses run(IRUnitT &Arg, AnalysisManager<IRUnitT> &AM,
>> + Ts... Args) {
>> + auto PA = PreservedAnalyses::all();
>> + for (int i = 0; i < Count; ++i)
>> + PA.intersect(P.run(Arg, AM, Args...));
>> + return PA;
>> + }
>> +
>> +private:
>> + const int Count;
>> + PassT P;
>> +};
>> +
>> +template <typename PassT>
>> +RepeatingPassWrapper<PassT> createRepeatingPassWrapper(int Count, PassT
>> P) {
>> + return RepeatingPassWrapper<PassT>(Count, std::move(P));
>> +}
>> +
>> }
>>
>> #endif
>>
>> Modified: llvm/trunk/lib/Passes/PassBuilder.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/PassBuilder.cpp?rev=277581&r1=277580&r2=277581&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/Passes/PassBuilder.cpp (original)
>> +++ llvm/trunk/lib/Passes/PassBuilder.cpp Wed Aug 3 02:44:48 2016
>> @@ -274,6 +274,15 @@ void PassBuilder::addLTODefaultPipeline(
>> 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"))
>> @@ -287,6 +296,10 @@ static bool isModulePassName(StringRef N
>> 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;
>> @@ -305,6 +318,10 @@ static bool isCGSCCPassName(StringRef Na
>> 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;
>> @@ -323,6 +340,10 @@ static bool isFunctionPassName(StringRef
>> 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;
>> @@ -339,6 +360,10 @@ static bool isLoopPassName(StringRef Nam
>> 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;
>> @@ -440,6 +465,14 @@ bool PassBuilder::parseModulePass(Module
>> 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;
>> }
>> @@ -519,6 +552,14 @@ bool PassBuilder::parseCGSCCPass(CGSCCPa
>> 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;
>> }
>> @@ -571,6 +612,14 @@ bool PassBuilder::parseFunctionPass(Func
>> 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;
>> }
>> @@ -599,7 +648,7 @@ bool PassBuilder::parseFunctionPass(Func
>>
>> 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.
>> @@ -613,6 +662,14 @@ bool PassBuilder::parseLoopPass(LoopPass
>> 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;
>> }
>>
>> 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=277581&r1=277580&r2=277581&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/test/Other/new-pass-manager.ll (original)
>> +++ llvm/trunk/test/Other/new-pass-manager.ll Wed Aug 3 02:44:48 2016
>> @@ -48,7 +48,7 @@
>> ; 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
>>
>> @@ -57,7 +57,7 @@
>> ; 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
>>
>> @@ -70,7 +70,7 @@
>> ; 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
>> @@ -81,14 +81,19 @@
>> ; 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: }
>>
>> @@ -363,7 +368,98 @@
>> ; 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
>> }
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160804/36652f84/attachment-0001.html>
More information about the llvm-commits
mailing list