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 enum class DebugLogging { None, Normal, Verbose, Quiet };
56 
57 static cl::opt<DebugLogging> DebugPM(
58     "debug-pass-manager", cl::Hidden, cl::ValueOptional,
59     cl::desc("Print pass management debugging information"),
60     cl::init(DebugLogging::None),
61     cl::values(
62         clEnumValN(DebugLogging::Normal, "", ""),
63         clEnumValN(DebugLogging::Quiet, "quiet",
64                    "Skip printing info about analyses"),
65         clEnumValN(
66             DebugLogging::Verbose, "verbose",
67             "Print extra information about adaptors and pass managers")));
68 
69 static cl::list<std::string>
70     PassPlugins("load-pass-plugin",
71                 cl::desc("Load passes from plugin library"));
72 
73 // This flag specifies a textual description of the alias analysis pipeline to
74 // use when querying for aliasing information. It only works in concert with
75 // the "passes" flag above.
76 static cl::opt<std::string>
77     AAPipeline("aa-pipeline",
78                cl::desc("A textual description of the alias analysis "
79                         "pipeline for handling managed aliasing queries"),
80                cl::Hidden, cl::init("default"));
81 
82 /// {{@ These options accept textual pipeline descriptions which will be
83 /// inserted into default pipelines at the respective extension points
84 static cl::opt<std::string> PeepholeEPPipeline(
85     "passes-ep-peephole",
86     cl::desc("A textual description of the function pass pipeline inserted at "
87              "the Peephole extension points into default pipelines"),
88     cl::Hidden);
89 static cl::opt<std::string> LateLoopOptimizationsEPPipeline(
90     "passes-ep-late-loop-optimizations",
91     cl::desc(
92         "A textual description of the loop pass pipeline inserted at "
93         "the LateLoopOptimizations extension point into default pipelines"),
94     cl::Hidden);
95 static cl::opt<std::string> LoopOptimizerEndEPPipeline(
96     "passes-ep-loop-optimizer-end",
97     cl::desc("A textual description of the loop pass pipeline inserted at "
98              "the LoopOptimizerEnd extension point into default pipelines"),
99     cl::Hidden);
100 static cl::opt<std::string> ScalarOptimizerLateEPPipeline(
101     "passes-ep-scalar-optimizer-late",
102     cl::desc("A textual description of the function pass pipeline inserted at "
103              "the ScalarOptimizerLate extension point into default pipelines"),
104     cl::Hidden);
105 static cl::opt<std::string> CGSCCOptimizerLateEPPipeline(
106     "passes-ep-cgscc-optimizer-late",
107     cl::desc("A textual description of the cgscc pass pipeline inserted at "
108              "the CGSCCOptimizerLate extension point into default pipelines"),
109     cl::Hidden);
110 static cl::opt<std::string> VectorizerStartEPPipeline(
111     "passes-ep-vectorizer-start",
112     cl::desc("A textual description of the function pass pipeline inserted at "
113              "the VectorizerStart extension point into default pipelines"),
114     cl::Hidden);
115 static cl::opt<std::string> PipelineStartEPPipeline(
116     "passes-ep-pipeline-start",
117     cl::desc("A textual description of the module pass pipeline inserted at "
118              "the PipelineStart extension point into default pipelines"),
119     cl::Hidden);
120 static cl::opt<std::string> PipelineEarlySimplificationEPPipeline(
121     "passes-ep-pipeline-early-simplification",
122     cl::desc("A textual description of the module pass pipeline inserted at "
123              "the EarlySimplification extension point into default pipelines"),
124     cl::Hidden);
125 static cl::opt<std::string> OptimizerLastEPPipeline(
126     "passes-ep-optimizer-last",
127     cl::desc("A textual description of the module pass pipeline inserted at "
128              "the OptimizerLast extension point into default pipelines"),
129     cl::Hidden);
130 static cl::opt<std::string> FullLinkTimeOptimizationEarlyEPPipeline(
131     "passes-ep-full-link-time-optimization-early",
132     cl::desc("A textual description of the module pass pipeline inserted at "
133              "the FullLinkTimeOptimizationEarly extension point into default "
134              "pipelines"),
135     cl::Hidden);
136 static cl::opt<std::string> FullLinkTimeOptimizationLastEPPipeline(
137     "passes-ep-full-link-time-optimization-last",
138     cl::desc("A textual description of the module pass pipeline inserted at "
139              "the FullLinkTimeOptimizationLast extension point into default "
140              "pipelines"),
141     cl::Hidden);
142 
143 // Individual pipeline tuning options.
144 extern cl::opt<bool> DisableLoopUnrolling;
145 
146 namespace llvm {
147 extern cl::opt<PGOKind> PGOKindFlag;
148 extern cl::opt<std::string> ProfileFile;
149 extern cl::opt<CSPGOKind> CSPGOKindFlag;
150 extern cl::opt<std::string> CSProfileGenFile;
151 extern cl::opt<bool> DisableBasicAA;
152 extern cl::opt<bool> PrintPipelinePasses;
153 } // namespace llvm
154 
155 static cl::opt<std::string>
156     ProfileRemappingFile("profile-remapping-file",
157                          cl::desc("Path to the profile remapping file."),
158                          cl::Hidden);
159 static cl::opt<bool> DebugInfoForProfiling(
160     "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden,
161     cl::desc("Emit special debug info to enable PGO profile generation."));
162 static cl::opt<bool> PseudoProbeForProfiling(
163     "new-pm-pseudo-probe-for-profiling", cl::init(false), cl::Hidden,
164     cl::desc("Emit pseudo probes to enable PGO profile generation."));
165 /// @}}
166 
167 template <typename PassManagerT>
168 bool tryParsePipelineText(PassBuilder &PB,
169                           const cl::opt<std::string> &PipelineOpt) {
170   if (PipelineOpt.empty())
171     return false;
172 
173   // Verify the pipeline is parseable:
174   PassManagerT PM;
175   if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) {
176     errs() << "Could not parse -" << PipelineOpt.ArgStr
177            << " pipeline: " << toString(std::move(Err))
178            << "... I'm going to ignore it.\n";
179     return false;
180   }
181   return true;
182 }
183 
184 /// If one of the EPPipeline command line options was given, register callbacks
185 /// for parsing and inserting the given pipeline
186 static void registerEPCallbacks(PassBuilder &PB) {
187   if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline))
188     PB.registerPeepholeEPCallback(
189         [&PB](FunctionPassManager &PM, OptimizationLevel Level) {
190           ExitOnError Err("Unable to parse PeepholeEP pipeline: ");
191           Err(PB.parsePassPipeline(PM, PeepholeEPPipeline));
192         });
193   if (tryParsePipelineText<LoopPassManager>(PB,
194                                             LateLoopOptimizationsEPPipeline))
195     PB.registerLateLoopOptimizationsEPCallback(
196         [&PB](LoopPassManager &PM, OptimizationLevel Level) {
197           ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: ");
198           Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline));
199         });
200   if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline))
201     PB.registerLoopOptimizerEndEPCallback(
202         [&PB](LoopPassManager &PM, OptimizationLevel Level) {
203           ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: ");
204           Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline));
205         });
206   if (tryParsePipelineText<FunctionPassManager>(PB,
207                                                 ScalarOptimizerLateEPPipeline))
208     PB.registerScalarOptimizerLateEPCallback(
209         [&PB](FunctionPassManager &PM, OptimizationLevel Level) {
210           ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: ");
211           Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline));
212         });
213   if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline))
214     PB.registerCGSCCOptimizerLateEPCallback(
215         [&PB](CGSCCPassManager &PM, OptimizationLevel Level) {
216           ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: ");
217           Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline));
218         });
219   if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline))
220     PB.registerVectorizerStartEPCallback(
221         [&PB](FunctionPassManager &PM, OptimizationLevel Level) {
222           ExitOnError Err("Unable to parse VectorizerStartEP pipeline: ");
223           Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline));
224         });
225   if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline))
226     PB.registerPipelineStartEPCallback(
227         [&PB](ModulePassManager &PM, OptimizationLevel) {
228           ExitOnError Err("Unable to parse PipelineStartEP pipeline: ");
229           Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline));
230         });
231   if (tryParsePipelineText<ModulePassManager>(
232           PB, PipelineEarlySimplificationEPPipeline))
233     PB.registerPipelineEarlySimplificationEPCallback(
234         [&PB](ModulePassManager &PM, OptimizationLevel) {
235           ExitOnError Err("Unable to parse EarlySimplification pipeline: ");
236           Err(PB.parsePassPipeline(PM, PipelineEarlySimplificationEPPipeline));
237         });
238   if (tryParsePipelineText<ModulePassManager>(PB, OptimizerLastEPPipeline))
239     PB.registerOptimizerLastEPCallback(
240         [&PB](ModulePassManager &PM, OptimizationLevel) {
241           ExitOnError Err("Unable to parse OptimizerLastEP pipeline: ");
242           Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline));
243         });
244   if (tryParsePipelineText<ModulePassManager>(
245           PB, FullLinkTimeOptimizationEarlyEPPipeline))
246     PB.registerFullLinkTimeOptimizationEarlyEPCallback(
247         [&PB](ModulePassManager &PM, OptimizationLevel) {
248           ExitOnError Err(
249               "Unable to parse FullLinkTimeOptimizationEarlyEP pipeline: ");
250           Err(PB.parsePassPipeline(PM,
251                                    FullLinkTimeOptimizationEarlyEPPipeline));
252         });
253   if (tryParsePipelineText<ModulePassManager>(
254           PB, FullLinkTimeOptimizationLastEPPipeline))
255     PB.registerFullLinkTimeOptimizationLastEPCallback(
256         [&PB](ModulePassManager &PM, OptimizationLevel) {
257           ExitOnError Err(
258               "Unable to parse FullLinkTimeOptimizationLastEP pipeline: ");
259           Err(PB.parsePassPipeline(PM, FullLinkTimeOptimizationLastEPPipeline));
260         });
261 }
262 
263 #define HANDLE_EXTENSION(Ext)                                                  \
264   llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
265 #include "llvm/Support/Extension.def"
266 
267 bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
268                            TargetLibraryInfoImpl *TLII, ToolOutputFile *Out,
269                            ToolOutputFile *ThinLTOLinkOut,
270                            ToolOutputFile *OptRemarkFile,
271                            StringRef PassPipeline, ArrayRef<StringRef> Passes,
272                            OutputKind OK, VerifierKind VK,
273                            bool ShouldPreserveAssemblyUseListOrder,
274                            bool ShouldPreserveBitcodeUseListOrder,
275                            bool EmitSummaryIndex, bool EmitModuleHash,
276                            bool EnableDebugify) {
277   bool VerifyEachPass = VK == VK_VerifyEachPass;
278 
279   Optional<PGOOptions> P;
280   switch (PGOKindFlag) {
281   case InstrGen:
282     P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr);
283     break;
284   case InstrUse:
285     P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse);
286     break;
287   case SampleUse:
288     P = PGOOptions(ProfileFile, "", ProfileRemappingFile,
289                    PGOOptions::SampleUse);
290     break;
291   case NoPGO:
292     if (DebugInfoForProfiling || PseudoProbeForProfiling)
293       P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
294                      DebugInfoForProfiling, PseudoProbeForProfiling);
295     else
296       P = None;
297   }
298   if (CSPGOKindFlag != NoCSPGO) {
299     if (P && (P->Action == PGOOptions::IRInstr ||
300               P->Action == PGOOptions::SampleUse))
301       errs() << "CSPGOKind cannot be used with IRInstr or SampleUse";
302     if (CSPGOKindFlag == CSInstrGen) {
303       if (CSProfileGenFile.empty())
304         errs() << "CSInstrGen needs to specify CSProfileGenFile";
305       if (P) {
306         P->CSAction = PGOOptions::CSIRInstr;
307         P->CSProfileGenFile = CSProfileGenFile;
308       } else
309         P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
310                        PGOOptions::NoAction, PGOOptions::CSIRInstr);
311     } else /* CSPGOKindFlag == CSInstrUse */ {
312       if (!P)
313         errs() << "CSInstrUse needs to be together with InstrUse";
314       P->CSAction = PGOOptions::CSIRUse;
315     }
316   }
317   if (TM)
318     TM->setPGOOption(P);
319 
320   LoopAnalysisManager LAM;
321   FunctionAnalysisManager FAM;
322   CGSCCAnalysisManager CGAM;
323   ModuleAnalysisManager MAM;
324 
325   PassInstrumentationCallbacks PIC;
326   PrintPassOptions PrintPassOpts;
327   PrintPassOpts.Verbose = DebugPM == DebugLogging::Verbose;
328   PrintPassOpts.SkipAnalyses = DebugPM == DebugLogging::Quiet;
329   StandardInstrumentations SI(DebugPM != DebugLogging::None, VerifyEachPass,
330                               PrintPassOpts);
331   SI.registerCallbacks(PIC, &FAM);
332   DebugifyEachInstrumentation Debugify;
333   if (DebugifyEach)
334     Debugify.registerCallbacks(PIC);
335 
336   PipelineTuningOptions PTO;
337   // LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized
338   // to false above so we shouldn't necessarily need to check whether or not the
339   // option has been enabled.
340   PTO.LoopUnrolling = !DisableLoopUnrolling;
341   PassBuilder PB(TM, PTO, P, &PIC);
342   registerEPCallbacks(PB);
343 
344   // Load requested pass plugins and let them register pass builder callbacks
345   for (auto &PluginFN : PassPlugins) {
346     auto PassPlugin = PassPlugin::Load(PluginFN);
347     if (!PassPlugin) {
348       errs() << "Failed to load passes from '" << PluginFN
349              << "'. Request ignored.\n";
350       continue;
351     }
352 
353     PassPlugin->registerPassBuilderCallbacks(PB);
354   }
355 
356   PB.registerPipelineParsingCallback(
357       [](StringRef Name, ModulePassManager &MPM,
358          ArrayRef<PassBuilder::PipelineElement>) {
359         AddressSanitizerOptions Opts;
360         if (Name == "asan-pipeline") {
361           MPM.addPass(
362               RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
363           MPM.addPass(ModuleAddressSanitizerPass(Opts));
364           return true;
365         }
366         return false;
367       });
368 
369 #define HANDLE_EXTENSION(Ext)                                                  \
370   get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
371 #include "llvm/Support/Extension.def"
372 
373   // Specially handle the alias analysis manager so that we can register
374   // a custom pipeline of AA passes with it.
375   AAManager AA;
376   if (Passes.empty()) {
377     if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) {
378       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
379       return false;
380     }
381   }
382 
383   // For compatibility with the legacy PM AA pipeline.
384   // AAResultsWrapperPass by default provides basic-aa in the legacy PM
385   // unless -disable-basic-aa is specified.
386   // TODO: remove this once tests implicitly requiring basic-aa use -passes= and
387   // -aa-pipeline=basic-aa.
388   if (!Passes.empty() && !DisableBasicAA) {
389     if (auto Err = PB.parseAAPipeline(AA, "basic-aa")) {
390       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
391       return false;
392     }
393   }
394 
395   // For compatibility with legacy pass manager.
396   // Alias analyses are not specially specified when using the legacy PM.
397   for (auto PassName : Passes) {
398     if (PB.isAAPassName(PassName)) {
399       if (auto Err = PB.parseAAPipeline(AA, PassName)) {
400         errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
401         return false;
402       }
403     }
404   }
405 
406   // Register the AA manager first so that our version is the one used.
407   FAM.registerPass([&] { return std::move(AA); });
408   // Register our TargetLibraryInfoImpl.
409   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
410 
411   // Register all the basic analyses with the managers.
412   PB.registerModuleAnalyses(MAM);
413   PB.registerCGSCCAnalyses(CGAM);
414   PB.registerFunctionAnalyses(FAM);
415   PB.registerLoopAnalyses(LAM);
416   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
417 
418   ModulePassManager MPM;
419   if (VK > VK_NoVerifier)
420     MPM.addPass(VerifierPass());
421   if (EnableDebugify)
422     MPM.addPass(NewPMDebugifyPass());
423 
424   // Add passes according to the -passes options.
425   if (!PassPipeline.empty()) {
426     assert(Passes.empty() &&
427            "PassPipeline and Passes should not both contain passes");
428     if (auto Err = PB.parsePassPipeline(MPM, PassPipeline)) {
429       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
430       return false;
431     }
432   }
433   // Add passes specified using the legacy PM syntax (i.e. not using
434   // -passes). This should be removed later when such support has been
435   // deprecated, i.e. when all lit tests running opt (and not using
436   // -enable-new-pm=0) have been updated to use -passes.
437   for (auto PassName : Passes) {
438     std::string ModifiedPassName(PassName.begin(), PassName.end());
439     if (PB.isAnalysisPassName(PassName))
440       ModifiedPassName = "require<" + ModifiedPassName + ">";
441     // FIXME: These translations are supposed to be removed when lit tests that
442     // use these names have been updated to use the -passes syntax (and when the
443     // support for using the old syntax to specify passes is considered as
444     // deprecated for the new PM).
445     if (ModifiedPassName == "early-cse-memssa")
446       ModifiedPassName = "early-cse<memssa>";
447     else if (ModifiedPassName == "post-inline-ee-instrument")
448       ModifiedPassName = "ee-instrument<post-inline>";
449     else if (ModifiedPassName == "loop-extract-single")
450       ModifiedPassName = "loop-extract<single>";
451     else if (ModifiedPassName == "lower-matrix-intrinsics-minimal")
452       ModifiedPassName = "lower-matrix-intrinsics<minimal>";
453     if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName)) {
454       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
455       return false;
456     }
457   }
458 
459   if (VK > VK_NoVerifier)
460     MPM.addPass(VerifierPass());
461   if (EnableDebugify)
462     MPM.addPass(NewPMCheckDebugifyPass());
463 
464   // Add any relevant output pass at the end of the pipeline.
465   switch (OK) {
466   case OK_NoOutput:
467     break; // No output pass needed.
468   case OK_OutputAssembly:
469     MPM.addPass(
470         PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder));
471     break;
472   case OK_OutputBitcode:
473     MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
474                                   EmitSummaryIndex, EmitModuleHash));
475     break;
476   case OK_OutputThinLTOBitcode:
477     MPM.addPass(ThinLTOBitcodeWriterPass(
478         Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr));
479     break;
480   }
481 
482   // Before executing passes, print the final values of the LLVM options.
483   cl::PrintOptionValues();
484 
485   // Print a textual, '-passes=' compatible, representation of pipeline if
486   // requested.
487   if (PrintPipelinePasses) {
488     MPM.printPipeline(outs(), [&PIC](StringRef ClassName) {
489       auto PassName = PIC.getPassNameForClassName(ClassName);
490       return PassName.empty() ? ClassName : PassName;
491     });
492     outs() << "\n";
493     return true;
494   }
495 
496   // Now that we have all of the passes ready, run them.
497   MPM.run(M, MAM);
498 
499   // Declare success.
500   if (OK != OK_NoOutput) {
501     Out->keep();
502     if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut)
503       ThinLTOLinkOut->keep();
504   }
505 
506   if (OptRemarkFile)
507     OptRemarkFile->keep();
508 
509   if (DebugifyEach && !DebugifyExport.empty())
510     exportDebugifyStats(DebugifyExport, Debugify.StatsMap);
511 
512   return true;
513 }
514 
515 void llvm::printPasses(raw_ostream &OS) {
516   PassBuilder PB;
517   PB.printPassNames(OS);
518 }
519