1*0b57cec5SDimitry Andric //===- NewPMDriver.cpp - Driver for opt with new PM -----------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric /// \file 9*0b57cec5SDimitry Andric /// 10*0b57cec5SDimitry Andric /// This file is just a split of the code that logically belongs in opt.cpp but 11*0b57cec5SDimitry Andric /// that includes the new pass manager headers. 12*0b57cec5SDimitry Andric /// 13*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 14*0b57cec5SDimitry Andric 15*0b57cec5SDimitry Andric #include "NewPMDriver.h" 16*0b57cec5SDimitry Andric #include "Debugify.h" 17*0b57cec5SDimitry Andric #include "PassPrinters.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 19*0b57cec5SDimitry Andric #include "llvm/Analysis/AliasAnalysis.h" 20*0b57cec5SDimitry Andric #include "llvm/Analysis/CGSCCPassManager.h" 21*0b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeWriterPass.h" 22*0b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h" 23*0b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 24*0b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h" 25*0b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 26*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 27*0b57cec5SDimitry Andric #include "llvm/IR/PassManager.h" 28*0b57cec5SDimitry Andric #include "llvm/IR/Verifier.h" 29*0b57cec5SDimitry Andric #include "llvm/Passes/PassBuilder.h" 30*0b57cec5SDimitry Andric #include "llvm/Passes/PassPlugin.h" 31*0b57cec5SDimitry Andric #include "llvm/Passes/StandardInstrumentations.h" 32*0b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 33*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 34*0b57cec5SDimitry Andric #include "llvm/Support/ToolOutputFile.h" 35*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 36*0b57cec5SDimitry Andric #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" 37*0b57cec5SDimitry Andric #include "llvm/Transforms/Scalar/LoopPassManager.h" 38*0b57cec5SDimitry Andric 39*0b57cec5SDimitry Andric using namespace llvm; 40*0b57cec5SDimitry Andric using namespace opt_tool; 41*0b57cec5SDimitry Andric 42*0b57cec5SDimitry Andric static cl::opt<bool> 43*0b57cec5SDimitry Andric DebugPM("debug-pass-manager", cl::Hidden, 44*0b57cec5SDimitry Andric cl::desc("Print pass management debugging information")); 45*0b57cec5SDimitry Andric 46*0b57cec5SDimitry Andric static cl::list<std::string> 47*0b57cec5SDimitry Andric PassPlugins("load-pass-plugin", 48*0b57cec5SDimitry Andric cl::desc("Load passes from plugin library")); 49*0b57cec5SDimitry Andric 50*0b57cec5SDimitry Andric // This flag specifies a textual description of the alias analysis pipeline to 51*0b57cec5SDimitry Andric // use when querying for aliasing information. It only works in concert with 52*0b57cec5SDimitry Andric // the "passes" flag above. 53*0b57cec5SDimitry Andric static cl::opt<std::string> 54*0b57cec5SDimitry Andric AAPipeline("aa-pipeline", 55*0b57cec5SDimitry Andric cl::desc("A textual description of the alias analysis " 56*0b57cec5SDimitry Andric "pipeline for handling managed aliasing queries"), 57*0b57cec5SDimitry Andric cl::Hidden); 58*0b57cec5SDimitry Andric 59*0b57cec5SDimitry Andric /// {{@ These options accept textual pipeline descriptions which will be 60*0b57cec5SDimitry Andric /// inserted into default pipelines at the respective extension points 61*0b57cec5SDimitry Andric static cl::opt<std::string> PeepholeEPPipeline( 62*0b57cec5SDimitry Andric "passes-ep-peephole", 63*0b57cec5SDimitry Andric cl::desc("A textual description of the function pass pipeline inserted at " 64*0b57cec5SDimitry Andric "the Peephole extension points into default pipelines"), 65*0b57cec5SDimitry Andric cl::Hidden); 66*0b57cec5SDimitry Andric static cl::opt<std::string> LateLoopOptimizationsEPPipeline( 67*0b57cec5SDimitry Andric "passes-ep-late-loop-optimizations", 68*0b57cec5SDimitry Andric cl::desc( 69*0b57cec5SDimitry Andric "A textual description of the loop pass pipeline inserted at " 70*0b57cec5SDimitry Andric "the LateLoopOptimizations extension point into default pipelines"), 71*0b57cec5SDimitry Andric cl::Hidden); 72*0b57cec5SDimitry Andric static cl::opt<std::string> LoopOptimizerEndEPPipeline( 73*0b57cec5SDimitry Andric "passes-ep-loop-optimizer-end", 74*0b57cec5SDimitry Andric cl::desc("A textual description of the loop pass pipeline inserted at " 75*0b57cec5SDimitry Andric "the LoopOptimizerEnd extension point into default pipelines"), 76*0b57cec5SDimitry Andric cl::Hidden); 77*0b57cec5SDimitry Andric static cl::opt<std::string> ScalarOptimizerLateEPPipeline( 78*0b57cec5SDimitry Andric "passes-ep-scalar-optimizer-late", 79*0b57cec5SDimitry Andric cl::desc("A textual description of the function pass pipeline inserted at " 80*0b57cec5SDimitry Andric "the ScalarOptimizerLate extension point into default pipelines"), 81*0b57cec5SDimitry Andric cl::Hidden); 82*0b57cec5SDimitry Andric static cl::opt<std::string> CGSCCOptimizerLateEPPipeline( 83*0b57cec5SDimitry Andric "passes-ep-cgscc-optimizer-late", 84*0b57cec5SDimitry Andric cl::desc("A textual description of the cgscc pass pipeline inserted at " 85*0b57cec5SDimitry Andric "the CGSCCOptimizerLate extension point into default pipelines"), 86*0b57cec5SDimitry Andric cl::Hidden); 87*0b57cec5SDimitry Andric static cl::opt<std::string> VectorizerStartEPPipeline( 88*0b57cec5SDimitry Andric "passes-ep-vectorizer-start", 89*0b57cec5SDimitry Andric cl::desc("A textual description of the function pass pipeline inserted at " 90*0b57cec5SDimitry Andric "the VectorizerStart extension point into default pipelines"), 91*0b57cec5SDimitry Andric cl::Hidden); 92*0b57cec5SDimitry Andric static cl::opt<std::string> PipelineStartEPPipeline( 93*0b57cec5SDimitry Andric "passes-ep-pipeline-start", 94*0b57cec5SDimitry Andric cl::desc("A textual description of the function pass pipeline inserted at " 95*0b57cec5SDimitry Andric "the PipelineStart extension point into default pipelines"), 96*0b57cec5SDimitry Andric cl::Hidden); 97*0b57cec5SDimitry Andric static cl::opt<std::string> OptimizerLastEPPipeline( 98*0b57cec5SDimitry Andric "passes-ep-optimizer-last", 99*0b57cec5SDimitry Andric cl::desc("A textual description of the function pass pipeline inserted at " 100*0b57cec5SDimitry Andric "the OptimizerLast extension point into default pipelines"), 101*0b57cec5SDimitry Andric cl::Hidden); 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric extern cl::opt<PGOKind> PGOKindFlag; 104*0b57cec5SDimitry Andric extern cl::opt<std::string> ProfileFile; 105*0b57cec5SDimitry Andric extern cl::opt<CSPGOKind> CSPGOKindFlag; 106*0b57cec5SDimitry Andric extern cl::opt<std::string> CSProfileGenFile; 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric static cl::opt<std::string> 109*0b57cec5SDimitry Andric ProfileRemappingFile("profile-remapping-file", 110*0b57cec5SDimitry Andric cl::desc("Path to the profile remapping file."), 111*0b57cec5SDimitry Andric cl::Hidden); 112*0b57cec5SDimitry Andric static cl::opt<bool> DebugInfoForProfiling( 113*0b57cec5SDimitry Andric "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden, 114*0b57cec5SDimitry Andric cl::desc("Emit special debug info to enable PGO profile generation.")); 115*0b57cec5SDimitry Andric /// @}} 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric template <typename PassManagerT> 118*0b57cec5SDimitry Andric bool tryParsePipelineText(PassBuilder &PB, 119*0b57cec5SDimitry Andric const cl::opt<std::string> &PipelineOpt) { 120*0b57cec5SDimitry Andric if (PipelineOpt.empty()) 121*0b57cec5SDimitry Andric return false; 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric // Verify the pipeline is parseable: 124*0b57cec5SDimitry Andric PassManagerT PM; 125*0b57cec5SDimitry Andric if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) { 126*0b57cec5SDimitry Andric errs() << "Could not parse -" << PipelineOpt.ArgStr 127*0b57cec5SDimitry Andric << " pipeline: " << toString(std::move(Err)) 128*0b57cec5SDimitry Andric << "... I'm going to ignore it.\n"; 129*0b57cec5SDimitry Andric return false; 130*0b57cec5SDimitry Andric } 131*0b57cec5SDimitry Andric return true; 132*0b57cec5SDimitry Andric } 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric /// If one of the EPPipeline command line options was given, register callbacks 135*0b57cec5SDimitry Andric /// for parsing and inserting the given pipeline 136*0b57cec5SDimitry Andric static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass, 137*0b57cec5SDimitry Andric bool DebugLogging) { 138*0b57cec5SDimitry Andric if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline)) 139*0b57cec5SDimitry Andric PB.registerPeepholeEPCallback( 140*0b57cec5SDimitry Andric [&PB, VerifyEachPass, DebugLogging]( 141*0b57cec5SDimitry Andric FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 142*0b57cec5SDimitry Andric ExitOnError Err("Unable to parse PeepholeEP pipeline: "); 143*0b57cec5SDimitry Andric Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass, 144*0b57cec5SDimitry Andric DebugLogging)); 145*0b57cec5SDimitry Andric }); 146*0b57cec5SDimitry Andric if (tryParsePipelineText<LoopPassManager>(PB, 147*0b57cec5SDimitry Andric LateLoopOptimizationsEPPipeline)) 148*0b57cec5SDimitry Andric PB.registerLateLoopOptimizationsEPCallback( 149*0b57cec5SDimitry Andric [&PB, VerifyEachPass, DebugLogging]( 150*0b57cec5SDimitry Andric LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 151*0b57cec5SDimitry Andric ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: "); 152*0b57cec5SDimitry Andric Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline, 153*0b57cec5SDimitry Andric VerifyEachPass, DebugLogging)); 154*0b57cec5SDimitry Andric }); 155*0b57cec5SDimitry Andric if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline)) 156*0b57cec5SDimitry Andric PB.registerLoopOptimizerEndEPCallback( 157*0b57cec5SDimitry Andric [&PB, VerifyEachPass, DebugLogging]( 158*0b57cec5SDimitry Andric LoopPassManager &PM, PassBuilder::OptimizationLevel Level) { 159*0b57cec5SDimitry Andric ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: "); 160*0b57cec5SDimitry Andric Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline, 161*0b57cec5SDimitry Andric VerifyEachPass, DebugLogging)); 162*0b57cec5SDimitry Andric }); 163*0b57cec5SDimitry Andric if (tryParsePipelineText<FunctionPassManager>(PB, 164*0b57cec5SDimitry Andric ScalarOptimizerLateEPPipeline)) 165*0b57cec5SDimitry Andric PB.registerScalarOptimizerLateEPCallback( 166*0b57cec5SDimitry Andric [&PB, VerifyEachPass, DebugLogging]( 167*0b57cec5SDimitry Andric FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 168*0b57cec5SDimitry Andric ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: "); 169*0b57cec5SDimitry Andric Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline, 170*0b57cec5SDimitry Andric VerifyEachPass, DebugLogging)); 171*0b57cec5SDimitry Andric }); 172*0b57cec5SDimitry Andric if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline)) 173*0b57cec5SDimitry Andric PB.registerCGSCCOptimizerLateEPCallback( 174*0b57cec5SDimitry Andric [&PB, VerifyEachPass, DebugLogging]( 175*0b57cec5SDimitry Andric CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) { 176*0b57cec5SDimitry Andric ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: "); 177*0b57cec5SDimitry Andric Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline, 178*0b57cec5SDimitry Andric VerifyEachPass, DebugLogging)); 179*0b57cec5SDimitry Andric }); 180*0b57cec5SDimitry Andric if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline)) 181*0b57cec5SDimitry Andric PB.registerVectorizerStartEPCallback( 182*0b57cec5SDimitry Andric [&PB, VerifyEachPass, DebugLogging]( 183*0b57cec5SDimitry Andric FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) { 184*0b57cec5SDimitry Andric ExitOnError Err("Unable to parse VectorizerStartEP pipeline: "); 185*0b57cec5SDimitry Andric Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline, 186*0b57cec5SDimitry Andric VerifyEachPass, DebugLogging)); 187*0b57cec5SDimitry Andric }); 188*0b57cec5SDimitry Andric if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline)) 189*0b57cec5SDimitry Andric PB.registerPipelineStartEPCallback( 190*0b57cec5SDimitry Andric [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM) { 191*0b57cec5SDimitry Andric ExitOnError Err("Unable to parse PipelineStartEP pipeline: "); 192*0b57cec5SDimitry Andric Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline, VerifyEachPass, 193*0b57cec5SDimitry Andric DebugLogging)); 194*0b57cec5SDimitry Andric }); 195*0b57cec5SDimitry Andric if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline)) 196*0b57cec5SDimitry Andric PB.registerOptimizerLastEPCallback( 197*0b57cec5SDimitry Andric [&PB, VerifyEachPass, DebugLogging](FunctionPassManager &PM, 198*0b57cec5SDimitry Andric PassBuilder::OptimizationLevel) { 199*0b57cec5SDimitry Andric ExitOnError Err("Unable to parse OptimizerLastEP pipeline: "); 200*0b57cec5SDimitry Andric Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, VerifyEachPass, 201*0b57cec5SDimitry Andric DebugLogging)); 202*0b57cec5SDimitry Andric }); 203*0b57cec5SDimitry Andric } 204*0b57cec5SDimitry Andric 205*0b57cec5SDimitry Andric #ifdef LINK_POLLY_INTO_TOOLS 206*0b57cec5SDimitry Andric namespace polly { 207*0b57cec5SDimitry Andric void RegisterPollyPasses(PassBuilder &); 208*0b57cec5SDimitry Andric } 209*0b57cec5SDimitry Andric #endif 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, 212*0b57cec5SDimitry Andric ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut, 213*0b57cec5SDimitry Andric ToolOutputFile *OptRemarkFile, 214*0b57cec5SDimitry Andric StringRef PassPipeline, OutputKind OK, 215*0b57cec5SDimitry Andric VerifierKind VK, 216*0b57cec5SDimitry Andric bool ShouldPreserveAssemblyUseListOrder, 217*0b57cec5SDimitry Andric bool ShouldPreserveBitcodeUseListOrder, 218*0b57cec5SDimitry Andric bool EmitSummaryIndex, bool EmitModuleHash, 219*0b57cec5SDimitry Andric bool EnableDebugify) { 220*0b57cec5SDimitry Andric bool VerifyEachPass = VK == VK_VerifyEachPass; 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric Optional<PGOOptions> P; 223*0b57cec5SDimitry Andric switch (PGOKindFlag) { 224*0b57cec5SDimitry Andric case InstrGen: 225*0b57cec5SDimitry Andric P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr); 226*0b57cec5SDimitry Andric break; 227*0b57cec5SDimitry Andric case InstrUse: 228*0b57cec5SDimitry Andric P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse); 229*0b57cec5SDimitry Andric break; 230*0b57cec5SDimitry Andric case SampleUse: 231*0b57cec5SDimitry Andric P = PGOOptions(ProfileFile, "", ProfileRemappingFile, 232*0b57cec5SDimitry Andric PGOOptions::SampleUse); 233*0b57cec5SDimitry Andric break; 234*0b57cec5SDimitry Andric case NoPGO: 235*0b57cec5SDimitry Andric if (DebugInfoForProfiling) 236*0b57cec5SDimitry Andric P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction, 237*0b57cec5SDimitry Andric true); 238*0b57cec5SDimitry Andric else 239*0b57cec5SDimitry Andric P = None; 240*0b57cec5SDimitry Andric } 241*0b57cec5SDimitry Andric if (CSPGOKindFlag != NoCSPGO) { 242*0b57cec5SDimitry Andric if (P && (P->Action == PGOOptions::IRInstr || 243*0b57cec5SDimitry Andric P->Action == PGOOptions::SampleUse)) 244*0b57cec5SDimitry Andric errs() << "CSPGOKind cannot be used with IRInstr or SampleUse"; 245*0b57cec5SDimitry Andric if (CSPGOKindFlag == CSInstrGen) { 246*0b57cec5SDimitry Andric if (CSProfileGenFile.empty()) 247*0b57cec5SDimitry Andric errs() << "CSInstrGen needs to specify CSProfileGenFile"; 248*0b57cec5SDimitry Andric if (P) { 249*0b57cec5SDimitry Andric P->CSAction = PGOOptions::CSIRInstr; 250*0b57cec5SDimitry Andric P->CSProfileGenFile = CSProfileGenFile; 251*0b57cec5SDimitry Andric } else 252*0b57cec5SDimitry Andric P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile, 253*0b57cec5SDimitry Andric PGOOptions::NoAction, PGOOptions::CSIRInstr); 254*0b57cec5SDimitry Andric } else /* CSPGOKindFlag == CSInstrUse */ { 255*0b57cec5SDimitry Andric if (!P) 256*0b57cec5SDimitry Andric errs() << "CSInstrUse needs to be together with InstrUse"; 257*0b57cec5SDimitry Andric P->CSAction = PGOOptions::CSIRUse; 258*0b57cec5SDimitry Andric } 259*0b57cec5SDimitry Andric } 260*0b57cec5SDimitry Andric PassInstrumentationCallbacks PIC; 261*0b57cec5SDimitry Andric StandardInstrumentations SI; 262*0b57cec5SDimitry Andric SI.registerCallbacks(PIC); 263*0b57cec5SDimitry Andric 264*0b57cec5SDimitry Andric PassBuilder PB(TM, PipelineTuningOptions(), P, &PIC); 265*0b57cec5SDimitry Andric registerEPCallbacks(PB, VerifyEachPass, DebugPM); 266*0b57cec5SDimitry Andric 267*0b57cec5SDimitry Andric // Load requested pass plugins and let them register pass builder callbacks 268*0b57cec5SDimitry Andric for (auto &PluginFN : PassPlugins) { 269*0b57cec5SDimitry Andric auto PassPlugin = PassPlugin::Load(PluginFN); 270*0b57cec5SDimitry Andric if (!PassPlugin) { 271*0b57cec5SDimitry Andric errs() << "Failed to load passes from '" << PluginFN 272*0b57cec5SDimitry Andric << "'. Request ignored.\n"; 273*0b57cec5SDimitry Andric continue; 274*0b57cec5SDimitry Andric } 275*0b57cec5SDimitry Andric 276*0b57cec5SDimitry Andric PassPlugin->registerPassBuilderCallbacks(PB); 277*0b57cec5SDimitry Andric } 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric // Register a callback that creates the debugify passes as needed. 280*0b57cec5SDimitry Andric PB.registerPipelineParsingCallback( 281*0b57cec5SDimitry Andric [](StringRef Name, ModulePassManager &MPM, 282*0b57cec5SDimitry Andric ArrayRef<PassBuilder::PipelineElement>) { 283*0b57cec5SDimitry Andric if (Name == "debugify") { 284*0b57cec5SDimitry Andric MPM.addPass(NewPMDebugifyPass()); 285*0b57cec5SDimitry Andric return true; 286*0b57cec5SDimitry Andric } else if (Name == "check-debugify") { 287*0b57cec5SDimitry Andric MPM.addPass(NewPMCheckDebugifyPass()); 288*0b57cec5SDimitry Andric return true; 289*0b57cec5SDimitry Andric } 290*0b57cec5SDimitry Andric return false; 291*0b57cec5SDimitry Andric }); 292*0b57cec5SDimitry Andric 293*0b57cec5SDimitry Andric #ifdef LINK_POLLY_INTO_TOOLS 294*0b57cec5SDimitry Andric polly::RegisterPollyPasses(PB); 295*0b57cec5SDimitry Andric #endif 296*0b57cec5SDimitry Andric 297*0b57cec5SDimitry Andric // Specially handle the alias analysis manager so that we can register 298*0b57cec5SDimitry Andric // a custom pipeline of AA passes with it. 299*0b57cec5SDimitry Andric AAManager AA; 300*0b57cec5SDimitry Andric if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) { 301*0b57cec5SDimitry Andric errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 302*0b57cec5SDimitry Andric return false; 303*0b57cec5SDimitry Andric } 304*0b57cec5SDimitry Andric 305*0b57cec5SDimitry Andric LoopAnalysisManager LAM(DebugPM); 306*0b57cec5SDimitry Andric FunctionAnalysisManager FAM(DebugPM); 307*0b57cec5SDimitry Andric CGSCCAnalysisManager CGAM(DebugPM); 308*0b57cec5SDimitry Andric ModuleAnalysisManager MAM(DebugPM); 309*0b57cec5SDimitry Andric 310*0b57cec5SDimitry Andric // Register the AA manager first so that our version is the one used. 311*0b57cec5SDimitry Andric FAM.registerPass([&] { return std::move(AA); }); 312*0b57cec5SDimitry Andric 313*0b57cec5SDimitry Andric // Register all the basic analyses with the managers. 314*0b57cec5SDimitry Andric PB.registerModuleAnalyses(MAM); 315*0b57cec5SDimitry Andric PB.registerCGSCCAnalyses(CGAM); 316*0b57cec5SDimitry Andric PB.registerFunctionAnalyses(FAM); 317*0b57cec5SDimitry Andric PB.registerLoopAnalyses(LAM); 318*0b57cec5SDimitry Andric PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); 319*0b57cec5SDimitry Andric 320*0b57cec5SDimitry Andric ModulePassManager MPM(DebugPM); 321*0b57cec5SDimitry Andric if (VK > VK_NoVerifier) 322*0b57cec5SDimitry Andric MPM.addPass(VerifierPass()); 323*0b57cec5SDimitry Andric if (EnableDebugify) 324*0b57cec5SDimitry Andric MPM.addPass(NewPMDebugifyPass()); 325*0b57cec5SDimitry Andric 326*0b57cec5SDimitry Andric if (auto Err = 327*0b57cec5SDimitry Andric PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) { 328*0b57cec5SDimitry Andric errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; 329*0b57cec5SDimitry Andric return false; 330*0b57cec5SDimitry Andric } 331*0b57cec5SDimitry Andric 332*0b57cec5SDimitry Andric if (VK > VK_NoVerifier) 333*0b57cec5SDimitry Andric MPM.addPass(VerifierPass()); 334*0b57cec5SDimitry Andric if (EnableDebugify) 335*0b57cec5SDimitry Andric MPM.addPass(NewPMCheckDebugifyPass()); 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric // Add any relevant output pass at the end of the pipeline. 338*0b57cec5SDimitry Andric switch (OK) { 339*0b57cec5SDimitry Andric case OK_NoOutput: 340*0b57cec5SDimitry Andric break; // No output pass needed. 341*0b57cec5SDimitry Andric case OK_OutputAssembly: 342*0b57cec5SDimitry Andric MPM.addPass( 343*0b57cec5SDimitry Andric PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder)); 344*0b57cec5SDimitry Andric break; 345*0b57cec5SDimitry Andric case OK_OutputBitcode: 346*0b57cec5SDimitry Andric MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder, 347*0b57cec5SDimitry Andric EmitSummaryIndex, EmitModuleHash)); 348*0b57cec5SDimitry Andric break; 349*0b57cec5SDimitry Andric case OK_OutputThinLTOBitcode: 350*0b57cec5SDimitry Andric MPM.addPass(ThinLTOBitcodeWriterPass( 351*0b57cec5SDimitry Andric Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr)); 352*0b57cec5SDimitry Andric break; 353*0b57cec5SDimitry Andric } 354*0b57cec5SDimitry Andric 355*0b57cec5SDimitry Andric // Before executing passes, print the final values of the LLVM options. 356*0b57cec5SDimitry Andric cl::PrintOptionValues(); 357*0b57cec5SDimitry Andric 358*0b57cec5SDimitry Andric // Now that we have all of the passes ready, run them. 359*0b57cec5SDimitry Andric MPM.run(M, MAM); 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric // Declare success. 362*0b57cec5SDimitry Andric if (OK != OK_NoOutput) { 363*0b57cec5SDimitry Andric Out->keep(); 364*0b57cec5SDimitry Andric if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut) 365*0b57cec5SDimitry Andric ThinLTOLinkOut->keep(); 366*0b57cec5SDimitry Andric } 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric if (OptRemarkFile) 369*0b57cec5SDimitry Andric OptRemarkFile->keep(); 370*0b57cec5SDimitry Andric 371*0b57cec5SDimitry Andric return true; 372*0b57cec5SDimitry Andric } 373