diff --git a/llvm/include/llvm/Passes/PassBuilder.h b/llvm/include/llvm/Passes/PassBuilder.h --- a/llvm/include/llvm/Passes/PassBuilder.h +++ b/llvm/include/llvm/Passes/PassBuilder.h @@ -488,7 +488,6 @@ /// preferred when a pipeline is largely of one type, but one or just a few /// passes are of different types(See PassBuilder.cpp for examples). Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, - bool VerifyEachPass = true, bool DebugLogging = false); /// {{@ Parse a textual pass pipeline description into a specific PassManager @@ -499,13 +498,10 @@ /// /// function(lpass) Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText, - bool VerifyEachPass = true, bool DebugLogging = false); Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText, - bool VerifyEachPass = true, bool DebugLogging = false); Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText, - bool VerifyEachPass = true, bool DebugLogging = false); /// @}} @@ -682,7 +678,7 @@ /// PassManagers and populate the passed ModulePassManager. void registerParseTopLevelPipelineCallback( const std::function, - bool VerifyEachPass, bool DebugLogging)> &C); + bool DebugLogging)> &C); /// Add PGOInstrumenation passes for O0 only. void addPGOInstrPassesForO0(ModulePassManager &MPM, bool DebugLogging, @@ -706,27 +702,27 @@ parsePipelineText(StringRef Text); Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E, - bool VerifyEachPass, bool DebugLogging); + bool DebugLogging); Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E, - bool VerifyEachPass, bool DebugLogging); + bool DebugLogging); Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E, - bool VerifyEachPass, bool DebugLogging); + bool DebugLogging); Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E, - bool VerifyEachPass, bool DebugLogging); + bool DebugLogging); bool parseAAPassName(AAManager &AA, StringRef Name); Error parseLoopPassPipeline(LoopPassManager &LPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging); + bool DebugLogging); Error parseFunctionPassPipeline(FunctionPassManager &FPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging); + bool DebugLogging); Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging); + bool DebugLogging); Error parseModulePassPipeline(ModulePassManager &MPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging); + bool DebugLogging); void addPGOInstrPasses(ModulePassManager &MPM, bool DebugLogging, OptimizationLevel Level, bool RunProfileGen, bool IsCS, @@ -759,7 +755,7 @@ 2> ModulePipelineParsingCallbacks; SmallVector, - bool VerifyEachPass, bool DebugLogging)>, + bool DebugLogging)>, 2> TopLevelPipelineParsingCallbacks; // CGSCC callbacks diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h --- a/llvm/include/llvm/Passes/StandardInstrumentations.h +++ b/llvm/include/llvm/Passes/StandardInstrumentations.h @@ -213,6 +213,14 @@ raw_ostream &Out; }; +class VerifyInstrumentation { + bool DebugLogging; + +public: + VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} + void registerCallbacks(PassInstrumentationCallbacks &PIC); +}; + /// This class provides an interface to register all the standard pass /// instrumentations and manages their state (if any). class StandardInstrumentations { @@ -222,9 +230,13 @@ OptNoneInstrumentation OptNone; PreservedCFGCheckerInstrumentation PreservedCFGChecker; IRChangePrinter PrintChangedIR; + VerifyInstrumentation Verify; + + bool VerifyEach; public: - StandardInstrumentations(bool DebugLogging) : PrintPass(DebugLogging) {} + StandardInstrumentations(bool DebugLogging, bool VerifyEach = false) + : PrintPass(DebugLogging), Verify(DebugLogging), VerifyEach(VerifyEach) {} void registerCallbacks(PassInstrumentationCallbacks &PIC); diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -2133,7 +2133,7 @@ Error PassBuilder::parseModulePass(ModulePassManager &MPM, const PipelineElement &E, - bool VerifyEachPass, bool DebugLogging) { + bool DebugLogging) { auto &Name = E.Name; auto &InnerPipeline = E.InnerPipeline; @@ -2141,32 +2141,31 @@ if (!InnerPipeline.empty()) { if (Name == "module") { ModulePassManager NestedMPM(DebugLogging); - if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseModulePassPipeline(NestedMPM, InnerPipeline, DebugLogging)) return Err; MPM.addPass(std::move(NestedMPM)); return Error::success(); } if (Name == "cgscc") { CGSCCPassManager CGPM(DebugLogging); - if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline, VerifyEachPass, - DebugLogging)) + if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline, DebugLogging)) return Err; MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM))); return Error::success(); } if (Name == "function") { FunctionPassManager FPM(DebugLogging); - if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseFunctionPassPipeline(FPM, InnerPipeline, DebugLogging)) return Err; MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); return Error::success(); } if (auto Count = parseRepeatPassName(Name)) { ModulePassManager NestedMPM(DebugLogging); - if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseModulePassPipeline(NestedMPM, InnerPipeline, DebugLogging)) return Err; MPM.addPass(createRepeatedPass(*Count, std::move(NestedMPM))); return Error::success(); @@ -2315,8 +2314,7 @@ } Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM, - const PipelineElement &E, bool VerifyEachPass, - bool DebugLogging) { + const PipelineElement &E, bool DebugLogging) { auto &Name = E.Name; auto &InnerPipeline = E.InnerPipeline; @@ -2324,8 +2322,8 @@ if (!InnerPipeline.empty()) { if (Name == "cgscc") { CGSCCPassManager NestedCGPM(DebugLogging); - if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, DebugLogging)) return Err; // Add the nested pass manager with the appropriate adaptor. CGPM.addPass(std::move(NestedCGPM)); @@ -2333,8 +2331,8 @@ } if (Name == "function") { FunctionPassManager FPM(DebugLogging); - if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseFunctionPassPipeline(FPM, InnerPipeline, DebugLogging)) return Err; // Add the nested pass manager with the appropriate adaptor. CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM))); @@ -2342,16 +2340,16 @@ } if (auto Count = parseRepeatPassName(Name)) { CGSCCPassManager NestedCGPM(DebugLogging); - if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, DebugLogging)) return Err; CGPM.addPass(createRepeatedPass(*Count, std::move(NestedCGPM))); return Error::success(); } if (auto MaxRepetitions = parseDevirtPassName(Name)) { CGSCCPassManager NestedCGPM(DebugLogging); - if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseCGSCCPassPipeline(NestedCGPM, InnerPipeline, DebugLogging)) return Err; CGPM.addPass( createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions)); @@ -2429,7 +2427,7 @@ Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E, - bool VerifyEachPass, bool DebugLogging) { + bool DebugLogging) { auto &Name = E.Name; auto &InnerPipeline = E.InnerPipeline; @@ -2437,8 +2435,8 @@ if (!InnerPipeline.empty()) { if (Name == "function") { FunctionPassManager NestedFPM(DebugLogging); - if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseFunctionPassPipeline(NestedFPM, InnerPipeline, DebugLogging)) return Err; // Add the nested pass manager with the appropriate adaptor. FPM.addPass(std::move(NestedFPM)); @@ -2446,8 +2444,7 @@ } if (Name == "loop" || Name == "loop-mssa") { LoopPassManager LPM(DebugLogging); - if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline, VerifyEachPass, - DebugLogging)) + if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline, DebugLogging)) return Err; // Add the nested pass manager with the appropriate adaptor. bool UseMemorySSA = (Name == "loop-mssa"); @@ -2460,8 +2457,8 @@ } if (auto Count = parseRepeatPassName(Name)) { FunctionPassManager NestedFPM(DebugLogging); - if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseFunctionPassPipeline(NestedFPM, InnerPipeline, DebugLogging)) return Err; FPM.addPass(createRepeatedPass(*Count, std::move(NestedFPM))); return Error::success(); @@ -2533,7 +2530,7 @@ } Error PassBuilder::parseLoopPass(LoopPassManager &LPM, const PipelineElement &E, - bool VerifyEachPass, bool DebugLogging) { + bool DebugLogging) { StringRef Name = E.Name; auto &InnerPipeline = E.InnerPipeline; @@ -2541,8 +2538,8 @@ if (!InnerPipeline.empty()) { if (Name == "loop") { LoopPassManager NestedLPM(DebugLogging); - if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseLoopPassPipeline(NestedLPM, InnerPipeline, DebugLogging)) return Err; // Add the nested pass manager with the appropriate adaptor. LPM.addPass(std::move(NestedLPM)); @@ -2550,8 +2547,8 @@ } if (auto Count = parseRepeatPassName(Name)) { LoopPassManager NestedLPM(DebugLogging); - if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline, - VerifyEachPass, DebugLogging)) + if (auto Err = + parseLoopPassPipeline(NestedLPM, InnerPipeline, DebugLogging)) return Err; LPM.addPass(createRepeatedPass(*Count, std::move(NestedLPM))); return Error::success(); @@ -2626,38 +2623,30 @@ Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging) { for (const auto &Element : Pipeline) { - if (auto Err = parseLoopPass(LPM, Element, VerifyEachPass, DebugLogging)) + if (auto Err = parseLoopPass(LPM, Element, DebugLogging)) return Err; - // FIXME: No verifier support for Loop passes! } return Error::success(); } Error PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging) { for (const auto &Element : Pipeline) { - if (auto Err = - parseFunctionPass(FPM, Element, VerifyEachPass, DebugLogging)) + if (auto Err = parseFunctionPass(FPM, Element, DebugLogging)) return Err; - if (VerifyEachPass) - FPM.addPass(VerifierPass()); } return Error::success(); } Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging) { for (const auto &Element : Pipeline) { - if (auto Err = parseCGSCCPass(CGPM, Element, VerifyEachPass, DebugLogging)) + if (auto Err = parseCGSCCPass(CGPM, Element, DebugLogging)) return Err; - // FIXME: No verifier support for CGSCC passes! } return Error::success(); } @@ -2677,13 +2666,10 @@ Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging) { for (const auto &Element : Pipeline) { - if (auto Err = parseModulePass(MPM, Element, VerifyEachPass, DebugLogging)) + if (auto Err = parseModulePass(MPM, Element, DebugLogging)) return Err; - if (VerifyEachPass) - MPM.addPass(VerifierPass()); } return Error::success(); } @@ -2693,7 +2679,7 @@ // pre-populate the analysis managers with target-specific stuff? Error PassBuilder::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText, - bool VerifyEachPass, bool DebugLogging) { + bool DebugLogging) { auto Pipeline = parsePipelineText(PipelineText); if (!Pipeline || Pipeline->empty()) return make_error( @@ -2714,7 +2700,7 @@ Pipeline = {{"function", {{"loop", std::move(*Pipeline)}}}}; } else { for (auto &C : TopLevelPipelineParsingCallbacks) - if (C(MPM, *Pipeline, VerifyEachPass, DebugLogging)) + if (C(MPM, *Pipeline, DebugLogging)) return Error::success(); // Unknown pass or pipeline name! @@ -2727,8 +2713,7 @@ } } - if (auto Err = - parseModulePassPipeline(MPM, *Pipeline, VerifyEachPass, DebugLogging)) + if (auto Err = parseModulePassPipeline(MPM, *Pipeline, DebugLogging)) return Err; return Error::success(); } @@ -2736,7 +2721,7 @@ // Primary pass pipeline description parsing routine for a \c CGSCCPassManager Error PassBuilder::parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText, - bool VerifyEachPass, bool DebugLogging) { + bool DebugLogging) { auto Pipeline = parsePipelineText(PipelineText); if (!Pipeline || Pipeline->empty()) return make_error( @@ -2751,8 +2736,7 @@ .str(), inconvertibleErrorCode()); - if (auto Err = - parseCGSCCPassPipeline(CGPM, *Pipeline, VerifyEachPass, DebugLogging)) + if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline, DebugLogging)) return Err; return Error::success(); } @@ -2761,7 +2745,7 @@ // FunctionPassManager Error PassBuilder::parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText, - bool VerifyEachPass, bool DebugLogging) { + bool DebugLogging) { auto Pipeline = parsePipelineText(PipelineText); if (!Pipeline || Pipeline->empty()) return make_error( @@ -2776,8 +2760,7 @@ .str(), inconvertibleErrorCode()); - if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline, VerifyEachPass, - DebugLogging)) + if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline, DebugLogging)) return Err; return Error::success(); } @@ -2785,15 +2768,14 @@ // Primary pass pipeline description parsing routine for a \c LoopPassManager Error PassBuilder::parsePassPipeline(LoopPassManager &CGPM, StringRef PipelineText, - bool VerifyEachPass, bool DebugLogging) { + bool DebugLogging) { auto Pipeline = parsePipelineText(PipelineText); if (!Pipeline || Pipeline->empty()) return make_error( formatv("invalid pipeline '{0}'", PipelineText).str(), inconvertibleErrorCode()); - if (auto Err = - parseLoopPassPipeline(CGPM, *Pipeline, VerifyEachPass, DebugLogging)) + if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline, DebugLogging)) return Err; return Error::success(); @@ -2855,6 +2837,6 @@ void PassBuilder::registerParseTopLevelPipelineCallback( const std::function, - bool VerifyEachPass, bool DebugLogging)> &C) { + bool DebugLogging)> &C) { TopLevelPipelineParsingCallbacks.push_back(C); } diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -22,6 +22,7 @@ #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassInstrumentation.h" +#include "llvm/IR/Verifier.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/FormatVariadic.h" @@ -233,19 +234,19 @@ } // Return true when this is a pass for which changes should be ignored -inline bool isIgnored(StringRef PassID) { +bool isIgnored(StringRef PassID) { return isSpecialPass(PassID, {"PassManager", "PassAdaptor", "AnalysisManagerProxy"}); } // Return true when this is a defined function for which printing // of changes is desired. -inline bool isInterestingFunction(const Function &F) { +bool isInterestingFunction(const Function &F) { return llvm::isFunctionInPrintList(F.getName()); } // Return true when this is a pass for which printing of changes is desired. -inline bool isInterestingPass(StringRef PassID) { +bool isInterestingPass(StringRef PassID) { if (isIgnored(PassID)) return false; @@ -724,6 +725,42 @@ }); } +void VerifyInstrumentation::registerCallbacks( + PassInstrumentationCallbacks &PIC) { + PIC.registerAfterPassCallback( + [this](StringRef P, Any IR, const PreservedAnalyses &PassPA) { + if (isIgnored(P) || P == "VerifierPass") + return; + if (any_isa(IR) || any_isa(IR)) { + const Function *F; + if (any_isa(IR)) + F = any_cast(IR)->getHeader()->getParent(); + else + F = any_cast(IR); + if (DebugLogging) + dbgs() << "Verifying function " << F->getName() << "\n"; + + if (verifyFunction(*F)) + report_fatal_error("Broken function found, compilation aborted!"); + } else if (any_isa(IR) || + any_isa(IR)) { + const Module *M; + if (any_isa(IR)) + M = any_cast(IR) + ->begin() + ->getFunction() + .getParent(); + else + M = any_cast(IR); + if (DebugLogging) + dbgs() << "Verifying module " << M->getName() << "\n"; + + if (verifyModule(*M)) + report_fatal_error("Broken module found, compilation aborted!"); + } + }); +} + void StandardInstrumentations::registerCallbacks( PassInstrumentationCallbacks &PIC) { PrintIR.registerCallbacks(PIC); @@ -732,4 +769,6 @@ OptNone.registerCallbacks(PIC); PreservedCFGChecker.registerCallbacks(PIC); PrintChangedIR.registerCallbacks(PIC); + if (VerifyEach) + Verify.registerCallbacks(PIC); } diff --git a/llvm/test/Other/new-pass-manager-verify-each.ll b/llvm/test/Other/new-pass-manager-verify-each.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Other/new-pass-manager-verify-each.ll @@ -0,0 +1,39 @@ +; RUN: opt -disable-output -debug-pass-manager -verify-each -passes='no-op-module,verify,cgscc(no-op-cgscc,function(no-op-function,loop(no-op-loop)))' %s 2>&1 | FileCheck %s + +; Added manually by opt at beginning +; CHECK: Running pass: VerifierPass + +; CHECK: Running pass: NoOpModulePass +; CHECK: Verifying module +; CHECK-NOT: Verifying module +; CHECK: Running pass: NoOpCGSCCPass +; CHECK: Verifying module +; CHECK-NOT: Verifying module +; CHECK: Running pass: NoOpFunctionPass +; CHECK: Verifying function foo +; CHECK: Running pass: LoopSimplifyPass +; CHECK: Verifying function foo +; CHECK: Running pass: LCSSAPass +; CHECK: Verifying function foo +; CHECK: Running pass: NoOpLoopPass +; CHECK: Verifying function foo +; CHECK-NOT: Verifying function +; CHECK-NOT: Verifying module + +; Added manually by opt at end +; CHECK: Running pass: VerifierPass + +define void @foo(i1 %x, i8* %p1, i8* %p2) { +entry: + store i8 42, i8* %p1 + br i1 %x, label %loop, label %exit + +loop: + %tmp1 = load i8, i8* %p2 + br label %loop + +exit: + ret void +} + +declare void @bar() diff --git a/llvm/test/Other/new-pass-manager.ll b/llvm/test/Other/new-pass-manager.ll --- a/llvm/test/Other/new-pass-manager.ll +++ b/llvm/test/Other/new-pass-manager.ll @@ -104,19 +104,6 @@ ; RUN: | llvm-dis \ ; RUN: | FileCheck %s --check-prefix=CHECK-NOOP -; RUN: opt -disable-output -debug-pass-manager -verify-each -passes='no-op-module,function(no-op-function)' %s 2>&1 \ -; RUN: | FileCheck %s --check-prefix=CHECK-VERIFY-EACH -; CHECK-VERIFY-EACH: Starting llvm::Module pass manager run -; CHECK-VERIFY-EACH: Running pass: VerifierPass -; CHECK-VERIFY-EACH: Running pass: NoOpModulePass -; CHECK-VERIFY-EACH: Running pass: VerifierPass -; CHECK-VERIFY-EACH: Starting llvm::Function pass manager run -; CHECK-VERIFY-EACH: Running pass: NoOpFunctionPass -; CHECK-VERIFY-EACH: Running pass: VerifierPass -; CHECK-VERIFY-EACH: Finished llvm::Function pass manager run -; CHECK-VERIFY-EACH: Running pass: VerifierPass -; CHECK-VERIFY-EACH: Finished llvm::Module pass manager run - ; RUN: opt -disable-output -debug-pass-manager -disable-verify -passes='no-op-module,function(no-op-function)' %s 2>&1 \ ; RUN: | FileCheck %s --check-prefix=CHECK-NO-VERIFY ; CHECK-NO-VERIFY: Starting llvm::Module pass manager run diff --git a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp --- a/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp +++ b/llvm/tools/llvm-opt-fuzzer/llvm-opt-fuzzer.cpp @@ -148,7 +148,7 @@ PB.registerLoopAnalyses(LAM); PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); - auto Err = PB.parsePassPipeline(MPM, PassPipeline, false, false); + auto Err = PB.parsePassPipeline(MPM, PassPipeline, false); assert(!Err && "Should have been checked during fuzzer initialization"); // Only fail with assert above, otherwise ignore the parsing error. consumeError(std::move(Err)); @@ -241,7 +241,7 @@ PassBuilder PB(TM.get()); ModulePassManager MPM; - if (auto Err = PB.parsePassPipeline(MPM, PassPipeline, false, false)) { + if (auto Err = PB.parsePassPipeline(MPM, PassPipeline, false)) { errs() << *argv[0] << ": " << toString(std::move(Err)) << "\n"; exit(1); } diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -140,72 +140,68 @@ /// If one of the EPPipeline command line options was given, register callbacks /// for parsing and inserting the given pipeline -static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass, - bool DebugLogging) { +static void registerEPCallbacks(PassBuilder &PB, bool DebugLogging) { if (tryParsePipelineText(PB, PeepholeEPPipeline)) PB.registerPeepholeEPCallback( - [&PB, VerifyEachPass, DebugLogging]( - FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { + [&PB, DebugLogging](FunctionPassManager &PM, + PassBuilder::OptimizationLevel Level) { ExitOnError Err("Unable to parse PeepholeEP pipeline: "); - Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass, - DebugLogging)); + Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, DebugLogging)); }); if (tryParsePipelineText(PB, LateLoopOptimizationsEPPipeline)) PB.registerLateLoopOptimizationsEPCallback( - [&PB, VerifyEachPass, DebugLogging]( - LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { + [&PB, DebugLogging](LoopPassManager &PM, + PassBuilder::OptimizationLevel Level) { ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: "); Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline, - VerifyEachPass, DebugLogging)); + DebugLogging)); }); if (tryParsePipelineText(PB, LoopOptimizerEndEPPipeline)) PB.registerLoopOptimizerEndEPCallback( - [&PB, VerifyEachPass, DebugLogging]( - LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { + [&PB, DebugLogging](LoopPassManager &PM, + PassBuilder::OptimizationLevel Level) { ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: "); Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline, - VerifyEachPass, DebugLogging)); + DebugLogging)); }); if (tryParsePipelineText(PB, ScalarOptimizerLateEPPipeline)) PB.registerScalarOptimizerLateEPCallback( - [&PB, VerifyEachPass, DebugLogging]( - FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { + [&PB, DebugLogging](FunctionPassManager &PM, + PassBuilder::OptimizationLevel Level) { ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: "); Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline, - VerifyEachPass, DebugLogging)); + DebugLogging)); }); if (tryParsePipelineText(PB, CGSCCOptimizerLateEPPipeline)) PB.registerCGSCCOptimizerLateEPCallback( - [&PB, VerifyEachPass, DebugLogging]( - CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) { + [&PB, DebugLogging](CGSCCPassManager &PM, + PassBuilder::OptimizationLevel Level) { ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: "); Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline, - VerifyEachPass, DebugLogging)); + DebugLogging)); }); if (tryParsePipelineText(PB, VectorizerStartEPPipeline)) PB.registerVectorizerStartEPCallback( - [&PB, VerifyEachPass, DebugLogging]( - FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { + [&PB, DebugLogging](FunctionPassManager &PM, + PassBuilder::OptimizationLevel Level) { ExitOnError Err("Unable to parse VectorizerStartEP pipeline: "); Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline, - VerifyEachPass, DebugLogging)); + DebugLogging)); }); if (tryParsePipelineText(PB, PipelineStartEPPipeline)) PB.registerPipelineStartEPCallback( - [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM) { + [&PB, DebugLogging](ModulePassManager &PM) { ExitOnError Err("Unable to parse PipelineStartEP pipeline: "); - Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline, VerifyEachPass, - DebugLogging)); + Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline, DebugLogging)); }); if (tryParsePipelineText(PB, OptimizerLastEPPipeline)) PB.registerOptimizerLastEPCallback( - [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM, - PassBuilder::OptimizationLevel) { + [&PB, DebugLogging](ModulePassManager &PM, + PassBuilder::OptimizationLevel) { ExitOnError Err("Unable to parse OptimizerLastEP pipeline: "); - Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, VerifyEachPass, - DebugLogging)); + Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, DebugLogging)); }); } @@ -264,7 +260,7 @@ } } PassInstrumentationCallbacks PIC; - StandardInstrumentations SI(DebugPM); + StandardInstrumentations SI(DebugPM, VerifyEachPass); SI.registerCallbacks(PIC); PipelineTuningOptions PTO; @@ -274,7 +270,7 @@ PTO.LoopUnrolling = !DisableLoopUnrolling; PTO.Coroutines = Coroutines; PassBuilder PB(TM, PTO, P, &PIC); - registerEPCallbacks(PB, VerifyEachPass, DebugPM); + registerEPCallbacks(PB, DebugPM); // Load requested pass plugins and let them register pass builder callbacks for (auto &PluginFN : PassPlugins) { @@ -387,8 +383,7 @@ if (!PassPipeline.empty()) { assert(Passes.empty() && "PassPipeline and Passes should not both contain passes"); - if (auto Err = - PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) { + if (auto Err = PB.parsePassPipeline(MPM, PassPipeline, DebugPM)) { errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; return false; } @@ -397,8 +392,7 @@ std::string ModifiedPassName(PassName.begin(), PassName.end()); if (PB.isAnalysisPassName(PassName)) ModifiedPassName = "require<" + ModifiedPassName + ">"; - if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName, VerifyEachPass, - DebugPM)) { + if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName, DebugPM)) { errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; return false; } diff --git a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp --- a/llvm/unittests/IR/PassBuilderCallbacksTest.cpp +++ b/llvm/unittests/IR/PassBuilderCallbacksTest.cpp @@ -502,7 +502,7 @@ .WillOnce(Invoke(getAnalysisResult)); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); @@ -547,7 +547,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); @@ -663,7 +663,7 @@ StringRef PipelineText = "test-transform,function(test-transform),cgscc(" "function(loop(test-transform)))"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); @@ -675,7 +675,7 @@ .WillOnce(Invoke(getAnalysisResult)); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -725,7 +725,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -771,7 +771,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -782,7 +782,7 @@ .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult))); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -833,7 +833,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -881,7 +881,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -925,7 +925,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -936,7 +936,7 @@ .WillOnce(WithArgs<0, 1, 2>(Invoke(getAnalysisResult))); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -987,7 +987,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -1035,7 +1035,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -1080,7 +1080,7 @@ .Times(0); StringRef PipelineText = "test-transform"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -1095,7 +1095,7 @@ EXPECT_CALL(AnalysisHandle, invalidate(HasName(""), _, _)); StringRef PipelineText = "require,invalidate"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -1105,7 +1105,7 @@ EXPECT_CALL(AnalysisHandle, invalidate(HasName("(foo)"), _, _)); StringRef PipelineText = "require,invalidate"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -1115,7 +1115,7 @@ EXPECT_CALL(AnalysisHandle, invalidate(HasName("foo"), _, _)); StringRef PipelineText = "require,invalidate"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -1126,7 +1126,7 @@ StringRef PipelineText = "require,invalidate"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); } @@ -1139,25 +1139,27 @@ /// This test parses a pipeline named 'another-pipeline', whose only elements /// may be the test-transform pass or the analysis utilities TEST_F(ModuleCallbacksTest, ParseTopLevelPipeline) { - PB.registerParseTopLevelPipelineCallback([this]( - ModulePassManager &MPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging) { - auto &FirstName = Pipeline.front().Name; - auto &InnerPipeline = Pipeline.front().InnerPipeline; - if (FirstName == "another-pipeline") { - for (auto &E : InnerPipeline) { - if (parseAnalysisUtilityPasses("test-analysis", E.Name, PM)) - continue; - - if (E.Name == "test-transform") { - PM.addPass(PassHandle.getPass()); - continue; + PB.registerParseTopLevelPipelineCallback( + [this](ModulePassManager &MPM, + ArrayRef Pipeline, + bool DebugLogging) { + auto &FirstName = Pipeline.front().Name; + auto &InnerPipeline = Pipeline.front().InnerPipeline; + if (FirstName == "another-pipeline") { + for (auto &E : InnerPipeline) { + if (parseAnalysisUtilityPasses("test-analysis", E.Name, + PM)) + continue; + + if (E.Name == "test-transform") { + PM.addPass(PassHandle.getPass()); + continue; + } + return false; + } } - return false; - } - } - return true; - }); + return true; + }); EXPECT_CALL(AnalysisHandle, run(HasName(""), _)); EXPECT_CALL(PassHandle, run(HasName(""), _)) @@ -1166,13 +1168,13 @@ StringRef PipelineText = "another-pipeline(test-transform,invalidate)"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Succeeded()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Succeeded()) << "Pipeline was: " << PipelineText; PM.run(*M, AM); /// Test the negative case PipelineText = "another-pipeline(instcombine)"; - ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText, true), Failed()) + ASSERT_THAT_ERROR(PB.parsePassPipeline(PM, PipelineText), Failed()) << "Pipeline was: " << PipelineText; } } // end anonymous namespace diff --git a/polly/lib/Support/RegisterPasses.cpp b/polly/lib/Support/RegisterPasses.cpp --- a/polly/lib/Support/RegisterPasses.cpp +++ b/polly/lib/Support/RegisterPasses.cpp @@ -678,7 +678,7 @@ static bool parseTopLevelPipeline(ModulePassManager &MPM, ArrayRef Pipeline, - bool VerifyEachPass, bool DebugLogging) { + bool DebugLogging) { std::vector FullPipeline; StringRef FirstName = Pipeline.front().Name; @@ -698,11 +698,7 @@ } FPM.addPass(createFunctionToScopPassAdaptor(std::move(SPM))); - if (VerifyEachPass) - FPM.addPass(VerifierPass()); MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); - if (VerifyEachPass) - MPM.addPass(VerifierPass()); return true; }