Index: llvm/trunk/include/llvm/Passes/PassBuilder.h =================================================================== --- llvm/trunk/include/llvm/Passes/PassBuilder.h +++ llvm/trunk/include/llvm/Passes/PassBuilder.h @@ -192,6 +192,39 @@ buildFunctionSimplificationPipeline(OptimizationLevel Level, bool DebugLogging = false); + /// Construct the core LLVM module canonicalization and simplification + /// pipeline. + /// + /// This pipeline focuses on canonicalizing and simplifying the entire module + /// of IR. Much like the function simplification pipeline above, it is + /// suitable to run repeatedly over the IR and is not expected to destroy + /// important information. It does, however, perform inlining and other + /// heuristic based simplifications that are not strictly reversible. + /// + /// Note that \p Level cannot be `O0` here. The pipelines produced are + /// only intended for use when attempting to optimize code. If frontends + /// require some transformations for semantic reasons, they should explicitly + /// build them. + ModulePassManager + buildModuleSimplificationPipeline(OptimizationLevel Level, + bool DebugLogging = false); + + /// Construct the core LLVM module optimization pipeline. + /// + /// This pipeline focuses on optimizing the execution speed of the IR. It + /// uses cost modeling and thresholds to balance code growth against runtime + /// improvements. It includes vectorization and other information destroying + /// transformations. It also cannot generally be run repeatedly on a module + /// without potentially seriously regressing either runtime performance of + /// the code or serious code size growth. + /// + /// Note that \p Level cannot be `O0` here. The pipelines produced are + /// only intended for use when attempting to optimize code. If frontends + /// require some transformations for semantic reasons, they should explicitly + /// build them. + ModulePassManager buildModuleOptimizationPipeline(OptimizationLevel Level, + bool DebugLogging = false); + /// Build a per-module default optimization pipeline. /// /// This provides a good default optimization pipeline for per-module @@ -206,6 +239,36 @@ ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level, bool DebugLogging = false); + /// Build a pre-link, ThinLTO-targeting default optimization pipeline to + /// a pass manager. + /// + /// This adds the pre-link optimizations tuned to prepare a module for + /// a ThinLTO run. It works to minimize the IR which needs to be analyzed + /// without making irreversible decisions which could be made better during + /// the LTO run. + /// + /// Note that \p Level cannot be `O0` here. The pipelines produced are + /// only intended for use when attempting to optimize code. If frontends + /// require some transformations for semantic reasons, they should explicitly + /// build them. + ModulePassManager + buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level, + bool DebugLogging = false); + + /// Build an ThinLTO default optimization pipeline to a pass manager. + /// + /// This provides a good default optimization pipeline for link-time + /// optimization and code generation. It is particularly tuned to fit well + /// when IR coming into the LTO phase was first run through \c + /// addPreLinkLTODefaultPipeline, and the two coordinate closely. + /// + /// Note that \p Level cannot be `O0` here. The pipelines produced are + /// only intended for use when attempting to optimize code. If frontends + /// require some transformations for semantic reasons, they should explicitly + /// build them. + ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level, + bool DebugLogging = false); + /// Build a pre-link, LTO-targeting default optimization pipeline to a pass /// manager. /// Index: llvm/trunk/lib/LTO/LTOBackend.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOBackend.cpp +++ llvm/trunk/lib/LTO/LTOBackend.cpp @@ -136,7 +136,8 @@ Conf.CodeModel, Conf.CGOptLevel)); } -static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel) { +static void runNewPMPasses(Module &Mod, TargetMachine *TM, unsigned OptLevel, + bool IsThinLTO) { PassBuilder PB(TM); AAManager AA; @@ -180,7 +181,10 @@ break; } - MPM = PB.buildLTODefaultPipeline(OL, false /* DebugLogging */); + if (IsThinLTO) + MPM = PB.buildThinLTODefaultPipeline(OL, false /* DebugLogging */); + else + MPM = PB.buildLTODefaultPipeline(OL, false /* DebugLogging */); MPM.run(Mod, MAM); // FIXME (davide): verify the output. @@ -258,17 +262,12 @@ bool opt(Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, bool IsThinLTO, ModuleSummaryIndex *ExportSummary, const ModuleSummaryIndex *ImportSummary) { - // There's still no ThinLTO pipeline hooked up in the new pass manager, - // once there is one, we can just remove this. - if (LTOUseNewPM && IsThinLTO) - report_fatal_error("ThinLTO not supported with the new PM yet!"); - // FIXME: Plumb the combined index into the new pass manager. if (!Conf.OptPipeline.empty()) runNewPMCustomPasses(Mod, TM, Conf.OptPipeline, Conf.AAPipeline, Conf.DisableVerify); else if (LTOUseNewPM) - runNewPMPasses(Mod, TM, Conf.OptLevel); + runNewPMPasses(Mod, TM, Conf.OptLevel, IsThinLTO); else runOldPMPasses(Conf, Mod, TM, IsThinLTO, ExportSummary, ImportSummary); return !Conf.PostOptModuleHook || Conf.PostOptModuleHook(Task, Mod); Index: llvm/trunk/lib/Passes/PassBuilder.cpp =================================================================== --- llvm/trunk/lib/Passes/PassBuilder.cpp +++ llvm/trunk/lib/Passes/PassBuilder.cpp @@ -164,7 +164,8 @@ "enable-npm-gvn-hoist", cl::init(false), cl::Hidden, cl::desc("Enable the GVN hoisting pass for the new PM (default = off)")); -static Regex DefaultAliasRegex("^(default|lto-pre-link|lto)<(O[0123sz])>$"); +static Regex DefaultAliasRegex( + "^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$"); static bool isOptimizingForSize(PassBuilder::OptimizationLevel Level) { switch (Level) { @@ -345,6 +346,9 @@ LPM2.addPass(IndVarSimplifyPass()); LPM2.addPass(LoopIdiomRecognizePass()); LPM2.addPass(LoopDeletionPass()); + // FIXME: The old pass manager has a hack to disable loop unrolling during + // ThinLTO when using sample PGO. Need to either fix it or port some + // workaround. LPM2.addPass(LoopUnrollPass::createFull(Level)); // We provide the opt remark emitter pass for LICM to use. We only need to do @@ -454,14 +458,10 @@ } ModulePassManager -PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level, - bool DebugLogging) { - assert(Level != O0 && "Must request optimizations for the default pipeline!"); +PassBuilder::buildModuleSimplificationPipeline(OptimizationLevel Level, + bool DebugLogging) { ModulePassManager MPM(DebugLogging); - // Force any function attributes we want the rest of the pipeline te observe. - MPM.addPass(ForceFunctionAttrsPass()); - // Do basic inference of function attributes from known properties of system // libraries and other oracles. MPM.addPass(InferFunctionAttrsPass()); @@ -504,16 +504,16 @@ GlobalCleanupPM.addPass(SimplifyCFGPass()); MPM.addPass(createModuleToFunctionPassAdaptor(std::move(GlobalCleanupPM))); - // Add all the requested passes for PGO Instrumentation, if requested. + // Add all the requested passes for PGO, if requested. if (PGOOpt) { assert(PGOOpt->RunProfileGen || PGOOpt->SamplePGO || !PGOOpt->ProfileUseFile.empty()); addPGOInstrPasses(MPM, DebugLogging, Level, PGOOpt->RunProfileGen, PGOOpt->ProfileGenFile, PGOOpt->ProfileUseFile); - } - // Indirect call promotion that promotes intra-module targes only. - MPM.addPass(PGOIndirectCallPromotion(false, PGOOpt && PGOOpt->SamplePGO)); + // Indirect call promotion that promotes intra-module targes only. + MPM.addPass(PGOIndirectCallPromotion(false, PGOOpt && PGOOpt->SamplePGO)); + } // Require the GlobalsAA analysis for the module so we can query it within // the CGSCC pipeline. @@ -562,17 +562,30 @@ createModuleToPostOrderCGSCCPassAdaptor(createDevirtSCCRepeatedPass( std::move(MainCGPipeline), MaxDevirtIterations, DebugLogging))); - // This ends the canonicalization and simplification phase of the pipeline. - // At this point, we expect to have canonical and simple IR which we begin - // *optimizing* for efficient execution going forward. + return MPM; +} + +ModulePassManager +PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level, + bool DebugLogging) { + ModulePassManager MPM(DebugLogging); + + // Optimize globals now that the module is fully simplified. + MPM.addPass(GlobalOptPass()); // Run partial inlining pass to partially inline functions that have // large bodies. if (RunPartialInlining) MPM.addPass(PartialInlinerPass()); - // Eliminate externally available functions now that inlining is over -- we - // won't emit these anyways. + // Remove avail extern fns and globals definitions since we aren't compiling + // an object file for later LTO. For LTO we want to preserve these so they + // are eligible for inlining at link-time. Note if they are unreferenced they + // will be removed by GlobalDCE later, so this only impacts referenced + // available externally globals. Eventually they will be suppressed during + // codegen, but eliminating here enables more opportunity for GlobalDCE as it + // may make globals referenced by available external functions dead and saves + // running remaining passes on the eliminated functions. MPM.addPass(EliminateAvailableExternallyPass()); // Do RPO function attribute inference across the module to forward-propagate @@ -671,6 +684,87 @@ } ModulePassManager +PassBuilder::buildPerModuleDefaultPipeline(OptimizationLevel Level, + bool DebugLogging) { + assert(Level != O0 && "Must request optimizations for the default pipeline!"); + + ModulePassManager MPM(DebugLogging); + + // Force any function attributes we want the rest of the pipeline to observe. + MPM.addPass(ForceFunctionAttrsPass()); + + // Add the core simplification pipeline. + MPM.addPass(buildModuleSimplificationPipeline(Level, DebugLogging)); + + // Now add the optimization pipeline. + MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging)); + + return MPM; +} + +ModulePassManager +PassBuilder::buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level, + bool DebugLogging) { + assert(Level != O0 && "Must request optimizations for the default pipeline!"); + + ModulePassManager MPM(DebugLogging); + + // Force any function attributes we want the rest of the pipeline to observe. + MPM.addPass(ForceFunctionAttrsPass()); + + // If we are planning to perform ThinLTO later, we don't bloat the code with + // unrolling/vectorization/... now. Just simplify the module as much as we + // can. + MPM.addPass(buildModuleSimplificationPipeline(Level, DebugLogging)); + + // Run partial inlining pass to partially inline functions that have + // large bodies. + // FIXME: It isn't clear whether this is really the right place to run this + // in ThinLTO. Because there is another canonicalization and simplification + // phase that will run after the thin link, running this here ends up with + // less information than will be available later and it may grow functions in + // ways that aren't beneficial. + if (RunPartialInlining) + MPM.addPass(PartialInlinerPass()); + + // Reduce the size of the IR as much as possible. + MPM.addPass(GlobalOptPass()); + + // Rename anon globals to be able to export them in the summary. + MPM.addPass(NameAnonGlobalPass()); + + return MPM; +} + +ModulePassManager +PassBuilder::buildThinLTODefaultPipeline(OptimizationLevel Level, + bool DebugLogging) { + // FIXME: The summary index is not hooked in the new pass manager yet. + // When it's going to be hooked, enable WholeProgramDevirt and LowerTypeTest + // here. + + ModulePassManager MPM(DebugLogging); + + // Force any function attributes we want the rest of the pipeline to observe. + MPM.addPass(ForceFunctionAttrsPass()); + + // During the ThinLTO backend phase we perform early indirect call promotion + // here, before globalopt. Otherwise imported available_externally functions + // look unreferenced and are removed. + MPM.addPass(PGOIndirectCallPromotion(true /* InLTO */, + PGOOpt && PGOOpt->SamplePGO && + !PGOOpt->ProfileUseFile.empty())); + + // Add the core simplification pipeline. + MPM.addPass(buildModuleSimplificationPipeline(Level, DebugLogging)); + + // Now add the optimization pipeline. + MPM.addPass(buildModuleOptimizationPipeline(Level, DebugLogging)); + + return MPM; +} + +ModulePassManager PassBuilder::buildLTOPreLinkDefaultPipeline(OptimizationLevel Level, bool DebugLogging) { assert(Level != O0 && "Must request optimizations for the default pipeline!"); @@ -893,9 +987,16 @@ return Count; } +/// Tests whether a pass name starts with a valid prefix for a default pipeline +/// alias. +static bool startsWithDefaultPipelineAliasPrefix(StringRef Name) { + return Name.startswith("default") || Name.startswith("thinlto") || + Name.startswith("lto"); +} + static bool isModulePassName(StringRef Name) { // Manually handle aliases for pre-configured pipeline fragments. - if (Name.startswith("default") || Name.startswith("lto")) + if (startsWithDefaultPipelineAliasPrefix(Name)) return DefaultAliasRegex.match(Name); // Explicitly handle pass manager names. @@ -1090,7 +1191,7 @@ } // Manually handle aliases for pre-configured pipeline fragments. - if (Name.startswith("default") || Name.startswith("lto")) { + if (startsWithDefaultPipelineAliasPrefix(Name)) { SmallVector Matches; if (!DefaultAliasRegex.match(Name, &Matches)) return false; @@ -1109,6 +1210,10 @@ if (Matches[1] == "default") { MPM.addPass(buildPerModuleDefaultPipeline(L, DebugLogging)); + } else if (Matches[1] == "thinlto-pre-link") { + MPM.addPass(buildThinLTOPreLinkDefaultPipeline(L, DebugLogging)); + } else if (Matches[1] == "thinlto") { + MPM.addPass(buildThinLTODefaultPipeline(L, DebugLogging)); } else if (Matches[1] == "lto-pre-link") { MPM.addPass(buildLTOPreLinkDefaultPipeline(L, DebugLogging)); } else { Index: llvm/trunk/test/Other/new-pm-defaults.ll =================================================================== --- llvm/trunk/test/Other/new-pm-defaults.ll +++ llvm/trunk/test/Other/new-pm-defaults.ll @@ -30,6 +30,8 @@ ; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> ; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass +; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> +; CHECK-O-NEXT: Starting llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass ; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis ; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> @@ -53,7 +55,6 @@ ; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-O-NEXT: Running pass: SimplifyCFGPass ; CHECK-O-NEXT: Finished llvm::Function pass manager run. -; CHECK-O-NEXT: Running pass: PGOIndirectCallPromotion ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA ; CHECK-O-NEXT: Running analysis: GlobalsAA ; CHECK-O-NEXT: Running analysis: CallGraphAnalysis @@ -134,6 +135,10 @@ ; CHECK-O-NEXT: Running pass: InstCombinePass ; CHECK-O-NEXT: Finished llvm::Function pass manager run. ; CHECK-O-NEXT: Finished CGSCC pass manager run. +; CHECK-O-NEXT: Finished llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> +; CHECK-O-NEXT: Starting llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: GlobalOptPass ; CHECK-O-NEXT: Running pass: EliminateAvailableExternallyPass ; CHECK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass ; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA @@ -163,6 +168,7 @@ ; CHECK-O-NEXT: Running pass: GlobalDCEPass ; CHECK-O-NEXT: Running pass: ConstantMergePass ; CHECK-O-NEXT: Finished llvm::Module pass manager run. +; CHECK-O-NEXT: Finished llvm::Module pass manager run. ; CHECK-O-NEXT: Running pass: PrintModulePass ; ; Make sure we get the IR back out without changes when we print the module. Index: llvm/trunk/test/Other/new-pm-thinlto-defaults.ll =================================================================== --- llvm/trunk/test/Other/new-pm-thinlto-defaults.ll +++ llvm/trunk/test/Other/new-pm-thinlto-defaults.ll @@ -0,0 +1,221 @@ +; The IR below was crafted so as: +; 1) To have a loop, so we create a loop pass manager +; 2) To be "immutable" in the sense that no pass in the standard +; pipeline will modify it. +; Since no transformations take place, we don't expect any analyses +; to be invalidated. +; Any invalidation that shows up here is a bug, unless we started modifying +; the IR, in which case we need to make it immutable harder. +; +; Prelink pipelines: +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto-pre-link' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O1,CHECK-PRELINK-O,CHECK-PRELINK-O1 +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto-pre-link' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-PRELINK-O,CHECK-PRELINK-O2 +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto-pre-link' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-PRELINK-O,CHECK-PRELINK-O3 +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto-pre-link' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-Os,CHECK-PRELINK-O,CHECK-PRELINK-Os +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto-pre-link' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-Oz,CHECK-PRELINK-O,CHECK-PRELINK-Oz +; +; Postlink pipelines: +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O1,CHECK-POSTLINK-O,CHECK-POSTLINK-O1 +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O2,CHECK-POSTLINK-O,CHECK-POSTLINK-O2 +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-O3,CHECK-POSTLINK-O,CHECK-POSTLINK-O3 +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-Os,CHECK-POSTLINK-O,CHECK-POSTLINK-Os +; RUN: opt -disable-verify -debug-pass-manager \ +; RUN: -passes='thinlto' -S %s 2>&1 \ +; RUN: | FileCheck %s --check-prefixes=CHECK-O,CHECK-Oz,CHECK-POSTLINK-O,CHECK-POSTLINK-Oz +; +; CHECK-O: Starting llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> +; CHECK-O-NEXT: Starting llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: ForceFunctionAttrsPass +; CHECK-POSTLINK-O-NEXT: Running pass: PGOIndirectCallPromotion +; CHECK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> +; CHECK-O-NEXT: Starting llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: InferFunctionAttrsPass +; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> +; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-O-NEXT: Starting llvm::Function pass manager run. +; CHECK-O-NEXT: Running pass: SimplifyCFGPass +; CHECK-O-NEXT: Running analysis: TargetIRAnalysis +; CHECK-O-NEXT: Running analysis: AssumptionAnalysis +; CHECK-O-NEXT: Running pass: SROA +; CHECK-O-NEXT: Running analysis: DominatorTreeAnalysis +; CHECK-O-NEXT: Running pass: EarlyCSEPass +; CHECK-O-NEXT: Running analysis: TargetLibraryAnalysis +; CHECK-O-NEXT: Running pass: LowerExpectIntrinsicPass +; CHECK-O-NEXT: Finished llvm::Function pass manager run. +; CHECK-O-NEXT: Running pass: IPSCCPPass +; CHECK-O-NEXT: Running pass: GlobalOptPass +; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PromotePass> +; CHECK-O-NEXT: Running pass: DeadArgumentEliminationPass +; CHECK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> +; CHECK-O-NEXT: Starting llvm::Function pass manager run. +; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Running pass: SimplifyCFGPass +; CHECK-O-NEXT: Finished llvm::Function pass manager run. +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA +; CHECK-O-NEXT: Running analysis: GlobalsAA +; CHECK-O-NEXT: Running analysis: CallGraphAnalysis +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}ProfileSummaryAnalysis +; CHECK-O-NEXT: Running analysis: ProfileSummaryAnalysis +; CHECK-O-NEXT: Running pass: ModuleToPostOrderCGSCCPassAdaptor<{{.*}}LazyCallGraph{{.*}}> +; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-O-NEXT: Running analysis: LazyCallGraphAnalysis +; CHECK-O-NEXT: Starting CGSCC pass manager run. +; CHECK-O-NEXT: Running pass: InlinerPass +; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy<{{.*}}LazyCallGraph{{.*}}> +; CHECK-O-NEXT: Running pass: PostOrderFunctionAttrsPass +; CHECK-O-NEXT: Running analysis: FunctionAnalysisManagerCGSCCProxy +; CHECK-O-NEXT: Running analysis: AAManager +; CHECK-O3-NEXT: Running pass: ArgumentPromotionPass +; CHECK-O-NEXT: Running pass: CGSCCToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> +; CHECK-O-NEXT: Starting llvm::Function pass manager run. +; CHECK-O-NEXT: Running pass: SROA +; CHECK-O-NEXT: Running pass: EarlyCSEPass +; CHECK-O-NEXT: Running pass: SpeculativeExecutionPass +; CHECK-O-NEXT: Running pass: JumpThreadingPass +; CHECK-O-NEXT: Running analysis: LazyValueAnalysis +; CHECK-O-NEXT: Running pass: CorrelatedValuePropagationPass +; CHECK-O-NEXT: Running pass: SimplifyCFGPass +; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O1-NEXT: Running pass: LibCallsShrinkWrapPass +; CHECK-O2-NEXT: Running pass: LibCallsShrinkWrapPass +; CHECK-O3-NEXT: Running pass: LibCallsShrinkWrapPass +; CHECK-O-NEXT: Running pass: TailCallElimPass +; CHECK-O-NEXT: Running pass: SimplifyCFGPass +; CHECK-O-NEXT: Running pass: ReassociatePass +; CHECK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}OptimizationRemarkEmitterAnalysis +; CHECK-O-NEXT: Running analysis: OptimizationRemarkEmitterAnalysis +; CHECK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LoopStandardAnalysisResults{{.*}}> +; CHECK-O-NEXT: Running analysis: LoopAnalysis +; CHECK-O-NEXT: Running analysis: ScalarEvolutionAnalysis +; CHECK-O-NEXT: Running analysis: InnerAnalysisManagerProxy +; CHECK-O-NEXT: Starting Loop pass manager run. +; CHECK-O-NEXT: Running pass: LoopRotatePass +; CHECK-O-NEXT: Running pass: LICM +; CHECK-O-NEXT: Running analysis: OuterAnalysisManagerProxy +; CHECK-O-NEXT: Running pass: SimpleLoopUnswitchPass +; CHECK-O-NEXT: Finished Loop pass manager run. +; CHECK-O-NEXT: Running pass: SimplifyCFGPass +; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LoopStandardAnalysisResults{{.*}}> +; CHECK-O-NEXT: Starting Loop pass manager run. +; CHECK-O-NEXT: Running pass: IndVarSimplifyPass +; CHECK-O-NEXT: Running pass: LoopIdiomRecognizePass +; CHECK-O-NEXT: Running pass: LoopDeletionPass +; CHECK-O-NEXT: Running pass: LoopUnrollPass +; CHECK-O-NEXT: Finished Loop pass manager run. +; CHECK-Os-NEXT: Running pass: MergedLoadStoreMotionPass +; CHECK-Os-NEXT: Running pass: GVN +; CHECK-Os-NEXT: Running analysis: MemoryDependenceAnalysis +; CHECK-Oz-NEXT: Running pass: MergedLoadStoreMotionPass +; CHECK-Oz-NEXT: Running pass: GVN +; CHECK-Oz-NEXT: Running analysis: MemoryDependenceAnalysis +; CHECK-O2-NEXT: Running pass: MergedLoadStoreMotionPass +; CHECK-O2-NEXT: Running pass: GVN +; CHECK-O2-NEXT: Running analysis: MemoryDependenceAnalysis +; CHECK-O3-NEXT: Running pass: MergedLoadStoreMotionPass +; CHECK-O3-NEXT: Running pass: GVN +; CHECK-O3-NEXT: Running analysis: MemoryDependenceAnalysis +; CHECK-O-NEXT: Running pass: MemCpyOptPass +; CHECK-O1-NEXT: Running analysis: MemoryDependenceAnalysis +; CHECK-O-NEXT: Running pass: SCCPPass +; CHECK-O-NEXT: Running pass: BDCEPass +; CHECK-O-NEXT: Running analysis: DemandedBitsAnalysis +; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Running pass: JumpThreadingPass +; CHECK-O-NEXT: Running pass: CorrelatedValuePropagationPass +; CHECK-O-NEXT: Running pass: DSEPass +; CHECK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LICMPass{{.*}}> +; CHECK-O-NEXT: Running pass: ADCEPass +; CHECK-O-NEXT: Running analysis: PostDominatorTreeAnalysis +; CHECK-O-NEXT: Running pass: SimplifyCFGPass +; CHECK-O-NEXT: Running pass: InstCombinePass +; CHECK-O-NEXT: Finished llvm::Function pass manager run. +; CHECK-O-NEXT: Finished CGSCC pass manager run. +; CHECK-O-NEXT: Finished llvm::Module pass manager run. +; CHECK-PRELINK-O-NEXT: Running pass: GlobalOptPass +; CHECK-PRELINK-O-NEXT: Running pass: NameAnonGlobalPass +; CHECK-POSTLINK-O-NEXT: Running pass: PassManager<{{.*}}Module{{.*}}> +; CHECK-POSTLINK-O-NEXT: Starting llvm::Module pass manager run. +; CHECK-POSTLINK-O-NEXT: Running pass: GlobalOptPass +; CHECK-POSTLINK-O-NEXT: Running pass: EliminateAvailableExternallyPass +; CHECK-POSTLINK-O-NEXT: Running pass: ReversePostOrderFunctionAttrsPass +; CHECK-POSTLINK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}GlobalsAA +; CHECK-POSTLINK-O-NEXT: Running pass: ModuleToFunctionPassAdaptor<{{.*}}PassManager{{.*}}> +; CHECK-POSTLINK-O-NEXT: Starting llvm::Function pass manager run. +; CHECK-POSTLINK-O-NEXT: Running pass: Float2IntPass +; CHECK-POSTLINK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LoopRotatePass +; CHECK-POSTLINK-O-NEXT: Running pass: LoopDistributePass +; CHECK-POSTLINK-O-NEXT: Running pass: LoopVectorizePass +; CHECK-POSTLINK-O-NEXT: Running analysis: BlockFrequencyAnalysis +; CHECK-POSTLINK-O-NEXT: Running analysis: BranchProbabilityAnalysis +; CHECK-POSTLINK-O-NEXT: Running pass: LoopLoadEliminationPass +; CHECK-POSTLINK-O-NEXT: Running analysis: LoopAccessAnalysis +; CHECK-POSTLINK-O-NEXT: Running pass: InstCombinePass +; CHECK-POSTLINK-O-NEXT: Running pass: SLPVectorizerPass +; CHECK-POSTLINK-O-NEXT: Running pass: SimplifyCFGPass +; CHECK-POSTLINK-O-NEXT: Running pass: InstCombinePass +; CHECK-POSTLINK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LoopUnrollPass +; CHECK-POSTLINK-O-NEXT: Running pass: InstCombinePass +; CHECK-POSTLINK-O-NEXT: Running pass: RequireAnalysisPass<{{.*}}OptimizationRemarkEmitterAnalysis +; CHECK-POSTLINK-O-NEXT: Running pass: FunctionToLoopPassAdaptor<{{.*}}LICMPass +; CHECK-POSTLINK-O-NEXT: Running pass: AlignmentFromAssumptionsPass +; CHECK-POSTLINK-O-NEXT: Running pass: LoopSinkPass +; CHECK-POSTLINK-O-NEXT: Running pass: InstSimplifierPass +; CHECK-POSTLINK-O-NEXT: Running pass: SimplifyCFGPass +; CHECK-POSTLINK-O-NEXT: Finished llvm::Function pass manager run. +; CHECK-POSTLINK-O-NEXT: Running pass: GlobalDCEPass +; CHECK-POSTLINK-O-NEXT: Running pass: ConstantMergePass +; CHECK-POSTLINK-O-NEXT: Finished llvm::Module pass manager run. +; CHECK-O-NEXT: Finished llvm::Module pass manager run. +; CHECK-O-NEXT: Running pass: PrintModulePass + +; Make sure we get the IR back out without changes when we print the module. +; CHECK-O-LABEL: define void @foo(i32 %n) local_unnamed_addr { +; CHECK-O-NEXT: entry: +; CHECK-O-NEXT: br label %loop +; CHECK-O: loop: +; CHECK-O-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] +; CHECK-O-NEXT: %iv.next = add i32 %iv, 1 +; CHECK-O-NEXT: tail call void @bar() +; CHECK-O-NEXT: %cmp = icmp eq i32 %iv, %n +; CHECK-O-NEXT: br i1 %cmp, label %exit, label %loop +; CHECK-O: exit: +; CHECK-O-NEXT: ret void +; CHECK-O-NEXT: } +; +; CHECK-O-NEXT: Finished llvm::Module pass manager run. + +declare void @bar() local_unnamed_addr + +define void @foo(i32 %n) local_unnamed_addr { +entry: + br label %loop +loop: + %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop ] + %iv.next = add i32 %iv, 1 + tail call void @bar() + %cmp = icmp eq i32 %iv, %n + br i1 %cmp, label %exit, label %loop +exit: + ret void +} Index: llvm/trunk/test/ThinLTO/X86/error-newpm.ll =================================================================== --- llvm/trunk/test/ThinLTO/X86/error-newpm.ll +++ llvm/trunk/test/ThinLTO/X86/error-newpm.ll @@ -1,13 +0,0 @@ -; RUN: opt -module-summary %s -o %t1.bc -; RUN: not llvm-lto2 run %t1.bc -o %t.o \ -; RUN: -r=%t1.bc,_tinkywinky,pxl \ -; RUN: -lto-use-new-pm 2>&1 | FileCheck %s - -; CHECK: ThinLTO not supported with the new PM yet! - -target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-apple-macosx10.11.0" - -define void @tinkywinky() { - ret void -} Index: llvm/trunk/test/ThinLTO/X86/newpm-basic.ll =================================================================== --- llvm/trunk/test/ThinLTO/X86/newpm-basic.ll +++ llvm/trunk/test/ThinLTO/X86/newpm-basic.ll @@ -0,0 +1,11 @@ +; RUN: opt -module-summary %s -o %t1.bc +; RUN: llvm-lto2 run %t1.bc -o %t.o \ +; RUN: -r=%t1.bc,_tinkywinky,pxl \ +; RUN: -lto-use-new-pm + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.11.0" + +define void @tinkywinky() { + ret void +}