From: Arthur Eubanks Date: Tue, 11 Oct 2022 18:14:53 +0000 (-0700) Subject: [PrintPipeline] Handle CoroConditionalWrapper and add more verification X-Git-Tag: upstream/17.0.6~30813 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f59e1bcc22717b9cce22848e5b2defb0bfd51b7c;p=platform%2Fupstream%2Fllvm.git [PrintPipeline] Handle CoroConditionalWrapper and add more verification Add a check (can be disabled via a flag) that the pipeline we generate is actually parsable. Can be disabled because we don't expect to handle every pass in -print-pipeline-passes. Fixes #58280. Reviewed By: ChuanqiXu Differential Revision: https://reviews.llvm.org/D135703 --- diff --git a/llvm/include/llvm/Transforms/Coroutines/CoroConditionalWrapper.h b/llvm/include/llvm/Transforms/Coroutines/CoroConditionalWrapper.h index ea19ec5..86b0449 100644 --- a/llvm/include/llvm/Transforms/Coroutines/CoroConditionalWrapper.h +++ b/llvm/include/llvm/Transforms/Coroutines/CoroConditionalWrapper.h @@ -21,6 +21,8 @@ struct CoroConditionalWrapper : PassInfoMixin { CoroConditionalWrapper(ModulePassManager &&); PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); static bool isRequired() { return true; } + void printPipeline(raw_ostream &OS, + function_ref MapClassName2PassName); private: ModulePassManager PM; diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index bd79dc2..1a4e7ef 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -86,6 +86,7 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h" #include "llvm/Transforms/Coroutines/CoroCleanup.h" +#include "llvm/Transforms/Coroutines/CoroConditionalWrapper.h" #include "llvm/Transforms/Coroutines/CoroEarly.h" #include "llvm/Transforms/Coroutines/CoroElide.h" #include "llvm/Transforms/Coroutines/CoroSplit.h" @@ -897,6 +898,8 @@ static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) { return true; if (Name == "function" || Name == "function") return true; + if (Name == "coro-cond") + return true; // Explicitly handle custom-parsed pass names. if (parseRepeatPassName(Name)) @@ -1091,6 +1094,13 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM, MPM.addPass(std::move(NestedMPM)); return Error::success(); } + if (Name == "coro-cond") { + ModulePassManager NestedMPM; + if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline)) + return Err; + MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM))); + return Error::success(); + } if (Name == "cgscc") { CGSCCPassManager CGPM; if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline)) diff --git a/llvm/lib/Transforms/Coroutines/CoroConditionalWrapper.cpp b/llvm/lib/Transforms/Coroutines/CoroConditionalWrapper.cpp index 3d26a43..974123f 100644 --- a/llvm/lib/Transforms/Coroutines/CoroConditionalWrapper.cpp +++ b/llvm/lib/Transforms/Coroutines/CoroConditionalWrapper.cpp @@ -22,3 +22,11 @@ PreservedAnalyses CoroConditionalWrapper::run(Module &M, return PM.run(M, AM); } + +void CoroConditionalWrapper::printPipeline( + raw_ostream &OS, function_ref MapClassName2PassName) { + OS << "coro-cond"; + OS << "("; + PM.printPipeline(OS, MapClassName2PassName); + OS << ")"; +} diff --git a/llvm/test/Other/new-pm-print-pipeline.ll b/llvm/test/Other/new-pm-print-pipeline.ll index fc63cbd..85029d5 100644 --- a/llvm/test/Other/new-pm-print-pipeline.ll +++ b/llvm/test/Other/new-pm-print-pipeline.ll @@ -10,7 +10,7 @@ ; CHECK-2: repeat<5>(function(mem2reg)),invalidate ;; Test that we get ClassName printed when there is no ClassName to pass-name mapping (as is the case for the BitcodeWriterPass). -; RUN: opt -o /dev/null -disable-verify -print-pipeline-passes -passes='function(mem2reg)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-3 +; RUN: opt -o /dev/null -disable-verify -print-pipeline-passes -passes='function(mem2reg)' < %s -disable-pipeline-verification | FileCheck %s --match-full-lines --check-prefixes=CHECK-3 ; CHECK-3: function(mem2reg),BitcodeWriterPass ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop-mssa(indvars))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-4 @@ -79,3 +79,13 @@ ;; Test that LICM & LNICM with options. ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='function(loop-mssa(licm,licm,lnicm,lnicm))' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-25 ; CHECK-25: function(loop-mssa(licm,licm,lnicm,lnicm)) + +;; Test coro-cond. +; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='coro-cond(no-op-module)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-26 +; CHECK-26: coro-cond(no-op-module) + +;; Test that -print-pipeline-passes is parsable (implicitly done with -print-pipeline-passes) for various default pipelines. +; RUN: opt -disable-output -passes='default' < %s +; RUN: opt -disable-output -passes='default' < %s +; RUN: opt -disable-output -passes='default' < %s +; RUN: opt -disable-output -passes='default' < %s diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp index efaa7ff..d4bf250 100644 --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -31,6 +31,7 @@ #include "llvm/Passes/StandardInstrumentations.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/Instrumentation/AddressSanitizer.h" @@ -153,6 +154,13 @@ static cl::opt FullLinkTimeOptimizationLastEPPipeline( "pipelines"), cl::Hidden); +static cl::opt DisablePipelineVerification( + "disable-pipeline-verification", + cl::desc("Only has an effect when specified with -print-pipeline-passes. " + "Disables verifying that the textual pipeline generated by " + "-print-pipeline-passes can be used to create a pipeline."), + cl::Hidden); + // Individual pipeline tuning options. extern cl::opt DisableLoopUnrolling; @@ -462,11 +470,26 @@ bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, // Print a textual, '-passes=' compatible, representation of pipeline if // requested. if (PrintPipelinePasses) { - MPM.printPipeline(outs(), [&PIC](StringRef ClassName) { + std::string Pipeline; + raw_string_ostream SOS(Pipeline); + MPM.printPipeline(SOS, [&PIC](StringRef ClassName) { auto PassName = PIC.getPassNameForClassName(ClassName); return PassName.empty() ? ClassName : PassName; }); + outs() << Pipeline; outs() << "\n"; + + if (!DisablePipelineVerification) { + // Check that we can parse the returned pipeline string as an actual + // pipeline. + ModulePassManager TempPM; + if (auto Err = PB.parsePassPipeline(TempPM, Pipeline)) { + errs() << "Could not parse dumped pass pipeline: " + << toString(std::move(Err)) << "\n"; + return false; + } + } + return true; }