xref: /freebsd/contrib/llvm-project/llvm/tools/opt/NewPMDriver.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
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