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         } else if (Name == "asan-function-pipeline") {
366           MPM.addPass(
367               RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
368           MPM.addPass(
369               createModuleToFunctionPassAdaptor(AddressSanitizerPass(Opts)));
370           return true;
371         }
372         return false;
373       });
374 
375 #define HANDLE_EXTENSION(Ext)                                                  \
376   get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
377 #include "llvm/Support/Extension.def"
378 
379   // Specially handle the alias analysis manager so that we can register
380   // a custom pipeline of AA passes with it.
381   AAManager AA;
382   if (Passes.empty()) {
383     if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) {
384       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
385       return false;
386     }
387   }
388 
389   // For compatibility with the legacy PM AA pipeline.
390   // AAResultsWrapperPass by default provides basic-aa in the legacy PM
391   // unless -disable-basic-aa is specified.
392   // TODO: remove this once tests implicitly requiring basic-aa use -passes= and
393   // -aa-pipeline=basic-aa.
394   if (!Passes.empty() && !DisableBasicAA) {
395     if (auto Err = PB.parseAAPipeline(AA, "basic-aa")) {
396       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
397       return false;
398     }
399   }
400 
401   // For compatibility with legacy pass manager.
402   // Alias analyses are not specially specified when using the legacy PM.
403   for (auto PassName : Passes) {
404     if (PB.isAAPassName(PassName)) {
405       if (auto Err = PB.parseAAPipeline(AA, PassName)) {
406         errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
407         return false;
408       }
409     }
410   }
411 
412   // Register the AA manager first so that our version is the one used.
413   FAM.registerPass([&] { return std::move(AA); });
414   // Register our TargetLibraryInfoImpl.
415   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
416 
417   // Register all the basic analyses with the managers.
418   PB.registerModuleAnalyses(MAM);
419   PB.registerCGSCCAnalyses(CGAM);
420   PB.registerFunctionAnalyses(FAM);
421   PB.registerLoopAnalyses(LAM);
422   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
423 
424   ModulePassManager MPM;
425   if (VK > VK_NoVerifier)
426     MPM.addPass(VerifierPass());
427   if (EnableDebugify)
428     MPM.addPass(NewPMDebugifyPass());
429 
430   // Add passes according to the -passes options.
431   if (!PassPipeline.empty()) {
432     assert(Passes.empty() &&
433            "PassPipeline and Passes should not both contain passes");
434     if (auto Err = PB.parsePassPipeline(MPM, PassPipeline)) {
435       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
436       return false;
437     }
438   }
439   // Add passes specified using the legacy PM syntax (i.e. not using
440   // -passes). This should be removed later when such support has been
441   // deprecated, i.e. when all lit tests running opt (and not using
442   // -enable-new-pm=0) have been updated to use -passes.
443   for (auto PassName : Passes) {
444     std::string ModifiedPassName(PassName.begin(), PassName.end());
445     if (PB.isAnalysisPassName(PassName))
446       ModifiedPassName = "require<" + ModifiedPassName + ">";
447     // FIXME: These translations are supposed to be removed when lit tests that
448     // use these names have been updated to use the -passes syntax (and when the
449     // support for using the old syntax to specify passes is considered as
450     // deprecated for the new PM).
451     if (ModifiedPassName == "early-cse-memssa")
452       ModifiedPassName = "early-cse<memssa>";
453     else if (ModifiedPassName == "post-inline-ee-instrument")
454       ModifiedPassName = "ee-instrument<post-inline>";
455     else if (ModifiedPassName == "loop-extract-single")
456       ModifiedPassName = "loop-extract<single>";
457     else if (ModifiedPassName == "lower-matrix-intrinsics-minimal")
458       ModifiedPassName = "lower-matrix-intrinsics<minimal>";
459     if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName)) {
460       errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
461       return false;
462     }
463   }
464 
465   if (VK > VK_NoVerifier)
466     MPM.addPass(VerifierPass());
467   if (EnableDebugify)
468     MPM.addPass(NewPMCheckDebugifyPass());
469 
470   // Add any relevant output pass at the end of the pipeline.
471   switch (OK) {
472   case OK_NoOutput:
473     break; // No output pass needed.
474   case OK_OutputAssembly:
475     MPM.addPass(
476         PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder));
477     break;
478   case OK_OutputBitcode:
479     MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
480                                   EmitSummaryIndex, EmitModuleHash));
481     break;
482   case OK_OutputThinLTOBitcode:
483     MPM.addPass(ThinLTOBitcodeWriterPass(
484         Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr));
485     break;
486   }
487 
488   // Before executing passes, print the final values of the LLVM options.
489   cl::PrintOptionValues();
490 
491   // Print a textual, '-passes=' compatible, representation of pipeline if
492   // requested.
493   if (PrintPipelinePasses) {
494     MPM.printPipeline(outs(), [&PIC](StringRef ClassName) {
495       auto PassName = PIC.getPassNameForClassName(ClassName);
496       return PassName.empty() ? ClassName : PassName;
497     });
498     outs() << "\n";
499     return true;
500   }
501 
502   // Now that we have all of the passes ready, run them.
503   MPM.run(M, MAM);
504 
505   // Declare success.
506   if (OK != OK_NoOutput) {
507     Out->keep();
508     if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut)
509       ThinLTOLinkOut->keep();
510   }
511 
512   if (OptRemarkFile)
513     OptRemarkFile->keep();
514 
515   if (DebugifyEach && !DebugifyExport.empty())
516     exportDebugifyStats(DebugifyExport, Debugify.StatsMap);
517 
518   return true;
519 }
520 
521 void llvm::printPasses(raw_ostream &OS) {
522   PassBuilder PB;
523   PB.printPassNames(OS);
524 }
525