Index: llvm/include/llvm/IR/PassManagerImpl.h =================================================================== --- llvm/include/llvm/IR/PassManagerImpl.h +++ llvm/include/llvm/IR/PassManagerImpl.h @@ -74,7 +74,8 @@ AnalysisResultListT &ResultList = AnalysisResultLists[&IR]; ResultList.emplace_back(ID, P.run(IR, *this, ExtraArgs...)); - PI.runAfterAnalysis(P, IR); + if (ID != PassInstrumentationAnalysis::ID()) + PI.runAfterAnalysis(P, IR); // P.run may have inserted elements into AnalysisResults and invalidated // RI. Index: llvm/include/llvm/Passes/StandardInstrumentations.h =================================================================== --- llvm/include/llvm/Passes/StandardInstrumentations.h +++ llvm/include/llvm/Passes/StandardInstrumentations.h @@ -82,12 +82,25 @@ // Debug logging for transformation and analysis passes. class PrintPassInstrumentation { + void printWithIdent(bool Expand, const Twine &Msg); + public: PrintPassInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {} void registerCallbacks(PassInstrumentationCallbacks &PIC); private: bool DebugLogging; + int Ident = 0; +}; + +// Pass structure dumper +class PassStructurePrinter { + int Ident = 0; + void printWithIdent(bool Expand, const Twine &Msg); + +public: + PassStructurePrinter() {} + void registerCallbacks(PassInstrumentationCallbacks &PIC); }; class PreservedCFGCheckerInstrumentation { @@ -398,6 +411,7 @@ class StandardInstrumentations { PrintIRInstrumentation PrintIR; PrintPassInstrumentation PrintPass; + PassStructurePrinter StructurePrinter; TimePassesHandler TimePasses; OptNoneInstrumentation OptNone; OptBisectInstrumentation OptBisect; Index: llvm/lib/Passes/StandardInstrumentations.cpp =================================================================== --- llvm/lib/Passes/StandardInstrumentations.cpp +++ llvm/lib/Passes/StandardInstrumentations.cpp @@ -20,6 +20,7 @@ #include "llvm/Analysis/LazyCallGraph.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/IR/Function.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/PassInstrumentation.h" #include "llvm/IR/PrintPasses.h" @@ -50,6 +51,10 @@ cl::desc("Print all pass management debugging information. " "`-debug-pass-manager` must also be specified")); +static cl::opt + DebugPassStructure("debug-pass-structure", cl::Hidden, cl::init(false), + cl::desc("Print pass structure information.")); + // An option that prints out the IR after passes, similar to // -print-after-all except that it only prints the IR after passes that // change the IR. Those passes that do not make changes to the IR are @@ -913,6 +918,43 @@ }); } +void PassStructurePrinter::printWithIdent(bool Expand, const Twine &Msg) { + if (!Msg.isTriviallyEmpty()) { + for (int I = 0; I < Ident; ++I) + dbgs() << " "; + dbgs() << Msg; + } + Ident = Expand ? Ident + 2 : Ident - 2; + assert(Ident >= 0); +} + +void PassStructurePrinter::registerCallbacks( + PassInstrumentationCallbacks &PIC) { + if (!DebugPassStructure) + return; + + PIC.registerBeforeNonSkippedPassCallback([this](StringRef PassID, Any IR) { + printWithIdent(true, PassID + " on "); + unwrapAndPrint(dbgs(), IR, "", false, true); + }); + PIC.registerAfterPassCallback( + [this](StringRef PassID, Any IR, const PreservedAnalyses &) { + printWithIdent(false, Twine()); + }); + + PIC.registerAfterPassInvalidatedCallback( + [this](StringRef PassID, const PreservedAnalyses &) { + printWithIdent(false, Twine()); + }); + + PIC.registerBeforeAnalysisCallback([this](StringRef PassID, Any IR) { + printWithIdent(true, PassID + " analysis on "); + unwrapAndPrint(dbgs(), IR, "", false, true); + }); + PIC.registerAfterAnalysisCallback( + [this](StringRef PassID, Any IR) { printWithIdent(false, Twine()); }); +} + PreservedCFGCheckerInstrumentation::CFG::CFG(const Function *F, bool TrackBBLifetime) { if (TrackBBLifetime) @@ -1172,6 +1214,7 @@ PassInstrumentationCallbacks &PIC) { PrintIR.registerCallbacks(PIC); PrintPass.registerCallbacks(PIC); + StructurePrinter.registerCallbacks(PIC); TimePasses.registerCallbacks(PIC); OptNone.registerCallbacks(PIC); OptBisect.registerCallbacks(PIC); Index: llvm/test/Other/opt-O3-pipeline.ll =================================================================== --- llvm/test/Other/opt-O3-pipeline.ll +++ llvm/test/Other/opt-O3-pipeline.ll @@ -1,4 +1,5 @@ ; RUN: opt -enable-new-pm=0 -mtriple=x86_64-- -O3 -debug-pass=Structure < %s -o /dev/null 2>&1 | FileCheck --check-prefixes=CHECK,%llvmcheckext %s +; RUN: opt -enable-new-pm=1 -mtriple=x86_64-- -O3 -debug-pass-structure < %s -o /dev/null 2>&1 | FileCheck --check-prefixes=NEWPM %s ; REQUIRES: asserts @@ -335,6 +336,172 @@ ; CHECK-NEXT: Branch Probability Analysis ; CHECK-NEXT: Block Frequency Analysis +; NEWPM: VerifierPass on +; NEWPM-NEXT: VerifierAnalysis analysis on +; NEWPM-NEXT: Annotation2MetadataPass on +; NEWPM-NEXT: ForceFunctionAttrsPass on +; NEWPM-NEXT: InferFunctionAttrsPass on +; NEWPM-NEXT: InnerAnalysisManagerProxy<{{.*}}> analysis on +; NEWPM-NEXT: ModuleToFunctionPassAdaptor on +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: SimplifyCFGPass on f +; NEWPM-NEXT: TargetIRAnalysis analysis on f +; NEWPM-NEXT: AssumptionAnalysis analysis on f +; NEWPM-NEXT: SROA on f +; NEWPM-NEXT: DominatorTreeAnalysis analysis on f +; NEWPM-NEXT: EarlyCSEPass on f +; NEWPM-NEXT: TargetLibraryAnalysis analysis on f +; NEWPM-NEXT: LowerExpectIntrinsicPass on f +; NEWPM-NEXT: CallSiteSplittingPass on f +; NEWPM-NEXT: IPSCCPPass on +; NEWPM-NEXT: CalledValuePropagationPass on +; NEWPM-NEXT: GlobalOptPass on +; NEWPM-NEXT: ModuleToFunctionPassAdaptor on +; NEWPM-NEXT: InnerAnalysisManagerProxy<{{.*}}> analysis on +; NEWPM-NEXT: PromotePass on f +; NEWPM-NEXT: DominatorTreeAnalysis analysis on f +; NEWPM-NEXT: AssumptionAnalysis analysis on f +; NEWPM-NEXT: DeadArgumentEliminationPass on +; NEWPM-NEXT: ModuleToFunctionPassAdaptor on +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: InstCombinePass on f +; NEWPM-NEXT: TargetLibraryAnalysis analysis on f +; NEWPM-NEXT: OptimizationRemarkEmitterAnalysis analysis on f +; NEWPM-NEXT: TargetIRAnalysis analysis on f +; NEWPM-NEXT: AAManager analysis on f +; NEWPM-NEXT: BasicAA analysis on f +; NEWPM-NEXT: OuterAnalysisManagerProxy<{{.*}}> analysis on f +; NEWPM-NEXT: SimplifyCFGPass on f +; NEWPM-NEXT: ModuleInlinerWrapperPass on +; NEWPM-NEXT: InlineAdvisorAnalysis analysis on +; NEWPM-NEXT: RequireAnalysisPass<{{.*}}> on +; NEWPM-NEXT: GlobalsAA analysis on +; NEWPM-NEXT: CallGraphAnalysis analysis on +; NEWPM-NEXT: RequireAnalysisPass<{{.*}}> on +; NEWPM-NEXT: ProfileSummaryAnalysis analysis on +; NEWPM-NEXT: ModuleToPostOrderCGSCCPassAdaptor on +; NEWPM-NEXT: InnerAnalysisManagerProxy<{{.*}}> analysis on +; NEWPM-NEXT: LazyCallGraphAnalysis analysis on +; NEWPM-NEXT: FunctionAnalysisManagerCGSCCProxy analysis on (f) +; NEWPM-NEXT: OuterAnalysisManagerProxy{{.*}}> analysis on (f) +; NEWPM-NEXT: DevirtSCCRepeatedPass on (f) +; NEWPM-NEXT: PassManager<{{.*}}> on (f) +; NEWPM-NEXT: InlinerPass on (f) +; NEWPM-NEXT: InlinerPass on (f) +; NEWPM-NEXT: PostOrderFunctionAttrsPass on (f) +; NEWPM-NEXT: ArgumentPromotionPass on (f) +; NEWPM-NEXT: OpenMPOptPass on (f) +; NEWPM-NEXT: CGSCCToFunctionPassAdaptor on (f) +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: SROA on f +; NEWPM-NEXT: DominatorTreeAnalysis analysis on f +; NEWPM-NEXT: EarlyCSEPass on f +; NEWPM-NEXT: MemorySSAAnalysis analysis on f +; NEWPM-NEXT: AAManager analysis on f +; NEWPM-NEXT: BasicAA analysis on f +; NEWPM-NEXT: SpeculativeExecutionPass on f +; NEWPM-NEXT: JumpThreadingPass on f +; NEWPM-NEXT: LazyValueAnalysis analysis on f +; NEWPM-NEXT: CorrelatedValuePropagationPass on f +; NEWPM-NEXT: SimplifyCFGPass on f +; NEWPM-NEXT: AggressiveInstCombinePass on f +; NEWPM-NEXT: InstCombinePass on f +; NEWPM-NEXT: LibCallsShrinkWrapPass on f +; NEWPM-NEXT: TailCallElimPass on f +; NEWPM-NEXT: SimplifyCFGPass on f +; NEWPM-NEXT: ReassociatePass on f +; NEWPM-NEXT: RequireAnalysisPass<{{.*}}> on f +; NEWPM-NEXT: FunctionToLoopPassAdaptor on f +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: LoopSimplifyPass on f +; NEWPM-NEXT: LoopAnalysis analysis on f +; NEWPM-NEXT: LCSSAPass on f +; NEWPM-NEXT: SimplifyCFGPass on f +; NEWPM-NEXT: InstCombinePass on f +; NEWPM-NEXT: FunctionToLoopPassAdaptor on f +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: LoopSimplifyPass on f +; NEWPM-NEXT: LCSSAPass on f +; NEWPM-NEXT: SROA on f +; NEWPM-NEXT: MergedLoadStoreMotionPass on f +; NEWPM-NEXT: GVN on f +; NEWPM-NEXT: MemoryDependenceAnalysis analysis on f +; NEWPM-NEXT: PhiValuesAnalysis analysis on f +; NEWPM-NEXT: SCCPPass on f +; NEWPM-NEXT: BDCEPass on f +; NEWPM-NEXT: DemandedBitsAnalysis analysis on f +; NEWPM-NEXT: InstCombinePass on f +; NEWPM-NEXT: JumpThreadingPass on f +; NEWPM-NEXT: LazyValueAnalysis analysis on f +; NEWPM-NEXT: CorrelatedValuePropagationPass on f +; NEWPM-NEXT: ADCEPass on f +; NEWPM-NEXT: PostDominatorTreeAnalysis analysis on f +; NEWPM-NEXT: MemCpyOptPass on f +; NEWPM-NEXT: DSEPass on f +; NEWPM-NEXT: FunctionToLoopPassAdaptor on f +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: LoopSimplifyPass on f +; NEWPM-NEXT: LCSSAPass on f +; NEWPM-NEXT: SimplifyCFGPass on f +; NEWPM-NEXT: InstCombinePass on f +; NEWPM-NEXT: GlobalOptPass on +; NEWPM-NEXT: GlobalDCEPass on +; NEWPM-NEXT: EliminateAvailableExternallyPass on +; NEWPM-NEXT: ReversePostOrderFunctionAttrsPass on +; NEWPM-NEXT: CallGraphAnalysis analysis on +; NEWPM-NEXT: RequireAnalysisPass<{{.*}}> on +; NEWPM-NEXT: ModuleToFunctionPassAdaptor on +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: Float2IntPass on f +; NEWPM-NEXT: DominatorTreeAnalysis analysis on f +; NEWPM-NEXT: LowerConstantIntrinsicsPass on f +; NEWPM-NEXT: FunctionToLoopPassAdaptor on f +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: LoopSimplifyPass on f +; NEWPM-NEXT: LoopAnalysis analysis on f +; NEWPM-NEXT: LCSSAPass on f +; NEWPM-NEXT: LoopDistributePass on f +; NEWPM-NEXT: ScalarEvolutionAnalysis analysis on f +; NEWPM-NEXT: AAManager analysis on f +; NEWPM-NEXT: BasicAA analysis on f +; NEWPM-NEXT: InnerAnalysisManagerProxy<{{.*}}> analysis on f +; NEWPM-NEXT: InjectTLIMappings on f +; NEWPM-NEXT: LoopVectorizePass on f +; NEWPM-NEXT: BlockFrequencyAnalysis analysis on f +; NEWPM-NEXT: BranchProbabilityAnalysis analysis on f +; NEWPM-NEXT: PostDominatorTreeAnalysis analysis on f +; NEWPM-NEXT: DemandedBitsAnalysis analysis on f +; NEWPM-NEXT: MemorySSAAnalysis analysis on f +; NEWPM-NEXT: LoopLoadEliminationPass on f +; NEWPM-NEXT: InstCombinePass on f +; NEWPM-NEXT: SimplifyCFGPass on f +; NEWPM-NEXT: SLPVectorizerPass on f +; NEWPM-NEXT: VectorCombinePass on f +; NEWPM-NEXT: InstCombinePass on f +; NEWPM-NEXT: LoopUnrollPass on f +; NEWPM-NEXT: WarnMissedTransformationsPass on f +; NEWPM-NEXT: InstCombinePass on f +; NEWPM-NEXT: RequireAnalysisPass<{{.*}}> on f +; NEWPM-NEXT: FunctionToLoopPassAdaptor on f +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: LoopSimplifyPass on f +; NEWPM-NEXT: LCSSAPass on f +; NEWPM-NEXT: AlignmentFromAssumptionsPass on f +; NEWPM-NEXT: LoopSinkPass on f +; NEWPM-NEXT: InstSimplifyPass on f +; NEWPM-NEXT: DivRemPairsPass on f +; NEWPM-NEXT: SimplifyCFGPass on f +; NEWPM-NEXT: SpeculateAroundPHIsPass on f +; NEWPM-NEXT: CGProfilePass on +; NEWPM-NEXT: GlobalDCEPass on +; NEWPM-NEXT: ConstantMergePass on +; NEWPM-NEXT: ModuleToFunctionPassAdaptor on +; NEWPM-NEXT: PassManager<{{.*}}> on f +; NEWPM-NEXT: AnnotationRemarksPass on f +; NEWPM-NEXT: VerifierPass on +; NEWPM-NEXT: VerifierAnalysis analysis on +; NEWPM-NEXT: BitcodeWriterPass on + define void @f() { ret void }