1 //===- NewPMDriver.cpp - Driver for opt with new PM -----------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file is just a split of the code that logically belongs in opt.cpp but
11 /// that includes the new pass manager headers.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "NewPMDriver.h"
16 #include "PassPrinters.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Analysis/AliasAnalysis.h"
20 #include "llvm/Analysis/CGSCCPassManager.h"
21 #include "llvm/Analysis/TargetLibraryInfo.h"
22 #include "llvm/Bitcode/BitcodeWriterPass.h"
23 #include "llvm/Config/llvm-config.h"
24 #include "llvm/IR/Dominators.h"
25 #include "llvm/IR/IRPrintingPasses.h"
26 #include "llvm/IR/LLVMContext.h"
27 #include "llvm/IR/Module.h"
28 #include "llvm/IR/PassManager.h"
29 #include "llvm/IR/Verifier.h"
30 #include "llvm/Passes/PassBuilder.h"
31 #include "llvm/Passes/PassPlugin.h"
32 #include "llvm/Passes/StandardInstrumentations.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/ToolOutputFile.h"
35 #include "llvm/Target/TargetMachine.h"
36 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
37 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
38 #include "llvm/Transforms/Scalar/LoopPassManager.h"
39 #include "llvm/Transforms/Utils/Debugify.h"
40 
41 using namespace llvm;
42 using namespace opt_tool;
43 
44 namespace llvm {
45 cl::opt<bool> DebugifyEach(
46     "debugify-each",
47     cl::desc("Start each pass with debugify and end it with check-debugify"));
48 
49 cl::opt<std::string>
50     DebugifyExport("debugify-export",
51                    cl::desc("Export per-pass debugify statistics to this file"),
52                    cl::value_desc("filename"));
53 } // namespace llvm
54 
55 static cl::opt<bool>
56     DebugPM("debug-pass-manager", cl::Hidden,
57             cl::desc("Print pass management debugging information"));
58 
59 static cl::list<std::string>
60     PassPlugins("load-pass-plugin",
61                 cl::desc("Load passes from plugin library"));
62 
63 // This flag specifies a textual description of the alias analysis pipeline to
64 // use when querying for aliasing information. It only works in concert with
65 // the "passes" flag above.
66 static cl::opt<std::string>
67     AAPipeline("aa-pipeline",
68                cl::desc("A textual description of the alias analysis "
69                         "pipeline for handling managed aliasing queries"),
70                cl::Hidden, cl::init("default"));
71 
72 /// {{@ These options accept textual pipeline descriptions which will be
73 /// inserted into default pipelines at the respective extension points
74 static cl::opt<std::string> PeepholeEPPipeline(
75     "passes-ep-peephole",
76     cl::desc("A textual description of the function pass pipeline inserted at "
77              "the Peephole extension points into default pipelines"),
78     cl::Hidden);
79 static cl::opt<std::string> LateLoopOptimizationsEPPipeline(
80     "passes-ep-late-loop-optimizations",
81     cl::desc(
82         "A textual description of the loop pass pipeline inserted at "
83         "the LateLoopOptimizations extension point into default pipelines"),
84     cl::Hidden);
85 static cl::opt<std::string> LoopOptimizerEndEPPipeline(
86     "passes-ep-loop-optimizer-end",
87     cl::desc("A textual description of the loop pass pipeline inserted at "
88              "the LoopOptimizerEnd extension point into default pipelines"),
89     cl::Hidden);
90 static cl::opt<std::string> ScalarOptimizerLateEPPipeline(
91     "passes-ep-scalar-optimizer-late",
92     cl::desc("A textual description of the function pass pipeline inserted at "
93              "the ScalarOptimizerLate extension point into default pipelines"),
94     cl::Hidden);
95 static cl::opt<std::string> CGSCCOptimizerLateEPPipeline(
96     "passes-ep-cgscc-optimizer-late",
97     cl::desc("A textual description of the cgscc pass pipeline inserted at "
98              "the CGSCCOptimizerLate extension point into default pipelines"),
99     cl::Hidden);
100 static cl::opt<std::string> VectorizerStartEPPipeline(
101     "passes-ep-vectorizer-start",
102     cl::desc("A textual description of the function pass pipeline inserted at "
103              "the VectorizerStart extension point into default pipelines"),
104     cl::Hidden);
105 static cl::opt<std::string> PipelineStartEPPipeline(
106     "passes-ep-pipeline-start",
107     cl::desc("A textual description of the module pass pipeline inserted at "
108              "the PipelineStart extension point into default pipelines"),
109     cl::Hidden);
110 static cl::opt<std::string> PipelineEarlySimplificationEPPipeline(
111     "passes-ep-pipeline-early-simplification",
112     cl::desc("A textual description of the module pass pipeline inserted at "
113              "the EarlySimplification extension point into default pipelines"),
114     cl::Hidden);
115 static cl::opt<std::string> OptimizerLastEPPipeline(
116     "passes-ep-optimizer-last",
117     cl::desc("A textual description of the module pass pipeline inserted at "
118              "the OptimizerLast extension point into default pipelines"),
119     cl::Hidden);
120 
121 // Individual pipeline tuning options.
122 extern cl::opt<bool> DisableLoopUnrolling;
123 
124 namespace llvm {
125 extern cl::opt<PGOKind> PGOKindFlag;
126 extern cl::opt<std::string> ProfileFile;
127 extern cl::opt<CSPGOKind> CSPGOKindFlag;
128 extern cl::opt<std::string> CSProfileGenFile;
129 extern cl::opt<bool> DisableBasicAA;
130 } // namespace llvm
131 
132 static cl::opt<std::string>
133     ProfileRemappingFile("profile-remapping-file",
134                          cl::desc("Path to the profile remapping file."),
135                          cl::Hidden);
136 static cl::opt<bool> DebugInfoForProfiling(
137     "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden,
138     cl::desc("Emit special debug info to enable PGO profile generation."));
139 static cl::opt<bool> PseudoProbeForProfiling(
140     "new-pm-pseudo-probe-for-profiling", cl::init(false), cl::Hidden,
141     cl::desc("Emit pseudo probes to enable PGO profile generation."));
142 /// @}}
143 
144 template <typename PassManagerT>
145 bool tryParsePipelineText(PassBuilder &PB,
146                           const cl::opt<std::string> &PipelineOpt) {
147   if (PipelineOpt.empty())
148     return false;
149 
150   // Verify the pipeline is parseable:
151   PassManagerT PM;
152   if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) {
153     errs() << "Could not parse -" << PipelineOpt.ArgStr
154            << " pipeline: " << toString(std::move(Err))
155            << "... I'm going to ignore it.\n";
156     return false;
157   }
158   return true;
159 }
160 
161 /// If one of the EPPipeline command line options was given, register callbacks
162 /// for parsing and inserting the given pipeline
163 static void registerEPCallbacks(PassBuilder &PB) {
164   if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline))
165     PB.registerPeepholeEPCallback(
166         [&PB](FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
167           ExitOnError Err("Unable to parse PeepholeEP pipeline: ");
168           Err(PB.parsePassPipeline(PM, PeepholeEPPipeline));
169         });
170   if (tryParsePipelineText<LoopPassManager>(PB,
171                                             LateLoopOptimizationsEPPipeline))
172     PB.registerLateLoopOptimizationsEPCallback(
173         [&PB](LoopPassManager &PM, PassBuilder::OptimizationLevel Level) {
174           ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: ");
175           Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline));
176         });
177   if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline))
178     PB.registerLoopOptimizerEndEPCallback(
179         [&PB](LoopPassManager &PM, PassBuilder::OptimizationLevel Level) {
180           ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: ");
181           Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline));
182         });
183   if (tryParsePipelineText<FunctionPassManager>(PB,
184                                                 ScalarOptimizerLateEPPipeline))
185     PB.registerScalarOptimizerLateEPCallback(
186         [&PB](FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
187           ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: ");
188           Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline));
189         });
190   if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline))
191     PB.registerCGSCCOptimizerLateEPCallback(
192         [&PB](CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) {
193           ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: ");
194           Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline));
195         });
196   if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline))
197     PB.registerVectorizerStartEPCallback(
198         [&PB](FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
199           ExitOnError Err("Unable to parse VectorizerStartEP pipeline: ");
200           Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline));
201         });
202   if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline))
203     PB.registerPipelineStartEPCallback(
204         [&PB](ModulePassManager &PM, PassBuilder::OptimizationLevel) {
205           ExitOnError Err("Unable to parse PipelineStartEP pipeline: ");
206           Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline));
207         });
208   if (tryParsePipelineText<ModulePassManager>(
209           PB, PipelineEarlySimplificationEPPipeline))
210     PB.registerPipelineEarlySimplificationEPCallback(
211         [&PB](ModulePassManager &PM, PassBuilder::OptimizationLevel) {
212           ExitOnError Err("Unable to parse EarlySimplification pipeline: ");
213           Err(PB.parsePassPipeline(PM, PipelineEarlySimplificationEPPipeline));
214         });
215   if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline))
216     PB.registerOptimizerLastEPCallback(
217         [&PB](ModulePassManager &PM, PassBuilder::OptimizationLevel) {
218           ExitOnError Err("Unable to parse OptimizerLastEP pipeline: ");
219           Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline));
220         });
221 }
222 
223 #define HANDLE_EXTENSION(Ext)                                                  \
224   llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
225 #include "llvm/Support/Extension.def"
226 
227 bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
228                            TargetLibraryInfoImpl *TLII, ToolOutputFile *Out,
229                            ToolOutputFile *ThinLTOLinkOut,
230                            ToolOutputFile *OptRemarkFile,
231                            StringRef PassPipeline, ArrayRef<StringRef> Passes,
232                            OutputKind OK, VerifierKind VK,
233                            bool ShouldPreserveAssemblyUseListOrder,
234                            bool ShouldPreserveBitcodeUseListOrder,
235                            bool EmitSummaryIndex, bool EmitModuleHash,
236                            bool EnableDebugify, bool Coroutines) {
237   bool VerifyEachPass = VK == VK_VerifyEachPass;
238 
239   Optional<PGOOptions> P;
240   switch (PGOKindFlag) {
241   case InstrGen:
242     P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr);
243     break;
244   case InstrUse:
245     P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse);
246     break;
247   case SampleUse:
248     P = PGOOptions(ProfileFile, "", ProfileRemappingFile,
249                    PGOOptions::SampleUse);
250     break;
251   case NoPGO:
252     if (DebugInfoForProfiling)
253       P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
254                      true);
255     else if (PseudoProbeForProfiling)
256       P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
257                      false, true);
258     else
259       P = None;
260   }
261   if (CSPGOKindFlag != NoCSPGO) {
262     if (P && (P->Action == PGOOptions::IRInstr ||
263               P->Action == PGOOptions::SampleUse))
264       errs() << "CSPGOKind cannot be used with IRInstr or SampleUse";
265     if (CSPGOKindFlag == CSInstrGen) {
266       if (CSProfileGenFile.empty())
267         errs() << "CSInstrGen needs to specify CSProfileGenFile";
268       if (P) {
269         P->CSAction = PGOOptions::CSIRInstr;
270         P->CSProfileGenFile = CSProfileGenFile;
271       } else
272         P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
273                        PGOOptions::NoAction, PGOOptions::CSIRInstr);
274     } else /* CSPGOKindFlag == CSInstrUse */ {
275       if (!P)
276         errs() << "CSInstrUse needs to be together with InstrUse";
277       P->CSAction = PGOOptions::CSIRUse;
278     }
279   }
280   LoopAnalysisManager LAM;
281   FunctionAnalysisManager FAM;
282   CGSCCAnalysisManager CGAM;
283   ModuleAnalysisManager MAM;
284 
285   PassInstrumentationCallbacks PIC;
286   StandardInstrumentations SI(DebugPM, VerifyEachPass);
287   SI.registerCallbacks(PIC, &FAM);
288   DebugifyEachInstrumentation Debugify;
289   if (DebugifyEach)
290     Debugify.registerCallbacks(PIC);
291 
292   PipelineTuningOptions PTO;
293   // LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized
294   // to false above so we shouldn't necessarily need to check whether or not the
295   // option has been enabled.
296   PTO.LoopUnrolling = !DisableLoopUnrolling;
297   PTO.Coroutines = Coroutines;
298   PassBuilder PB(TM, PTO, P, &PIC);
299   registerEPCallbacks(PB);
300 
301   // Load requested pass plugins and let them register pass builder callbacks
302   for (auto &PluginFN : PassPlugins) {
303     auto PassPlugin = PassPlugin::Load(PluginFN);
304     if (!PassPlugin) {
305       errs() << "Failed to load passes from '" << PluginFN
306              << "'. Request ignored.\n";
307       continue;
308     }
309 
310     PassPlugin->registerPassBuilderCallbacks(PB);
311   }
312 
313   // Register a callback that creates the debugify passes as needed.
314   PB.registerPipelineParsingCallback(
315       [](StringRef Name, ModulePassManager &MPM,
316          ArrayRef<PassBuilder::PipelineElement>) {
317         if (Name == "debugify") {
318           MPM.addPass(NewPMDebugifyPass());
319           return true;
320         } else if (Name == "check-debugify") {
321           MPM.addPass(NewPMCheckDebugifyPass());
322           return true;
323         }
324         return false;
325       });
326   PB.registerPipelineParsingCallback(
327       [](StringRef Name, ModulePassManager &MPM,
328          ArrayRef<PassBuilder::PipelineElement>) {
329         if (Name == "asan-pipeline") {
330           MPM.addPass(
331               RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
332           MPM.addPass(
333               createModuleToFunctionPassAdaptor(AddressSanitizerPass()));
334           MPM.addPass(ModuleAddressSanitizerPass());
335           return true;
336         } else if (Name == "asan-function-pipeline") {
337           MPM.addPass(
338               RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
339           MPM.addPass(
340               createModuleToFunctionPassAdaptor(AddressSanitizerPass()));
341           return true;
342         }
343         return false;
344       });
345 
346 #define HANDLE_EXTENSION(Ext)                                                  \
347   get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
348 #include "llvm/Support/Extension.def"
349 
350   // Specially handle the alias analysis manager so that we can register
351   // a custom pipeline of AA passes with it.
352   AAManager AA;
353   if (Passes.empty()) {
354     if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) {
355       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
356       return false;
357     }
358   }
359 
360   // For compatibility with the legacy PM AA pipeline.
361   // AAResultsWrapperPass by default provides basic-aa in the legacy PM
362   // unless -disable-basic-aa is specified.
363   // TODO: remove this once tests implicitly requiring basic-aa use -passes= and
364   // -aa-pipeline=basic-aa.
365   if (!Passes.empty() && !DisableBasicAA) {
366     if (auto Err = PB.parseAAPipeline(AA, "basic-aa")) {
367       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
368       return false;
369     }
370   }
371 
372   // For compatibility with legacy pass manager.
373   // Alias analyses are not specially specified when using the legacy PM.
374   for (auto PassName : Passes) {
375     if (PB.isAAPassName(PassName)) {
376       if (auto Err = PB.parseAAPipeline(AA, PassName)) {
377         errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
378         return false;
379       }
380     }
381   }
382 
383   // Register the AA manager first so that our version is the one used.
384   FAM.registerPass([&] { return std::move(AA); });
385   // Register our TargetLibraryInfoImpl.
386   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
387 
388   // Register all the basic analyses with the managers.
389   PB.registerModuleAnalyses(MAM);
390   PB.registerCGSCCAnalyses(CGAM);
391   PB.registerFunctionAnalyses(FAM);
392   PB.registerLoopAnalyses(LAM);
393   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
394 
395   ModulePassManager MPM;
396   if (VK > VK_NoVerifier)
397     MPM.addPass(VerifierPass());
398   if (EnableDebugify)
399     MPM.addPass(NewPMDebugifyPass());
400 
401   if (!PassPipeline.empty()) {
402     assert(Passes.empty() &&
403            "PassPipeline and Passes should not both contain passes");
404     if (auto Err = PB.parsePassPipeline(MPM, PassPipeline)) {
405       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
406       return false;
407     }
408   }
409   for (auto PassName : Passes) {
410     std::string ModifiedPassName(PassName.begin(), PassName.end());
411     if (PB.isAnalysisPassName(PassName))
412       ModifiedPassName = "require<" + ModifiedPassName + ">";
413     if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName)) {
414       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
415       return false;
416     }
417   }
418 
419   if (VK > VK_NoVerifier)
420     MPM.addPass(VerifierPass());
421   if (EnableDebugify)
422     MPM.addPass(NewPMCheckDebugifyPass());
423 
424   // Add any relevant output pass at the end of the pipeline.
425   switch (OK) {
426   case OK_NoOutput:
427     break; // No output pass needed.
428   case OK_OutputAssembly:
429     MPM.addPass(
430         PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder));
431     break;
432   case OK_OutputBitcode:
433     MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
434                                   EmitSummaryIndex, EmitModuleHash));
435     break;
436   case OK_OutputThinLTOBitcode:
437     MPM.addPass(ThinLTOBitcodeWriterPass(
438         Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr));
439     break;
440   }
441 
442   // Before executing passes, print the final values of the LLVM options.
443   cl::PrintOptionValues();
444 
445   // Now that we have all of the passes ready, run them.
446   MPM.run(M, MAM);
447 
448   // Declare success.
449   if (OK != OK_NoOutput) {
450     Out->keep();
451     if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut)
452       ThinLTOLinkOut->keep();
453   }
454 
455   if (OptRemarkFile)
456     OptRemarkFile->keep();
457 
458   if (DebugifyEach && !DebugifyExport.empty())
459     exportDebugifyStats(DebugifyExport, Debugify.StatsMap);
460 
461   return true;
462 }
463 
464 void llvm::printPasses(raw_ostream &OS) {
465   PassBuilder PB;
466   PB.printPassNames(OS);
467 }
468