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 "llvm/ADT/SmallVector.h"
17#include "llvm/ADT/Statistic.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Analysis/AliasAnalysis.h"
20#include "llvm/Analysis/CGSCCPassManager.h"
21#include "llvm/Analysis/RuntimeLibcallInfo.h"
22#include "llvm/Analysis/TargetLibraryInfo.h"
23#include "llvm/Bitcode/BitcodeWriterPass.h"
24#include "llvm/CodeGen/LibcallLoweringInfo.h"
25#include "llvm/Config/llvm-config.h"
26#include "llvm/IR/Dominators.h"
27#include "llvm/IR/LLVMContext.h"
28#include "llvm/IR/Module.h"
29#include "llvm/IR/PassManager.h"
30#include "llvm/IR/Verifier.h"
31#include "llvm/IRPrinter/IRPrintingPasses.h"
32#include "llvm/Passes/PassBuilder.h"
33#include "llvm/Passes/StandardInstrumentations.h"
34#include "llvm/Plugins/PassPlugin.h"
35#include "llvm/Support/ErrorHandling.h"
36#include "llvm/Support/Timer.h"
37#include "llvm/Support/ToolOutputFile.h"
38#include "llvm/Support/VirtualFileSystem.h"
39#include "llvm/Support/raw_ostream.h"
40#include "llvm/Target/TargetMachine.h"
41#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
42#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
43#include "llvm/Transforms/Scalar/LoopPassManager.h"
44#include "llvm/Transforms/Utils/Debugify.h"
45#include "llvm/Transforms/Utils/ProfileVerify.h"
46
47using namespace llvm;
48using namespace opt_tool;
49
50cl::opt<bool> llvm::DebugifyEach(
51 "debugify-each",
52 cl::desc("Start each pass with debugify and end it with check-debugify"));
53
54cl::opt<std::string> llvm::DebugifyExport(
55 "debugify-export",
56 cl::desc("Export per-pass debugify statistics to this file"),
57 cl::value_desc("filename"));
58
59cl::opt<bool> llvm::VerifyEachDebugInfoPreserve(
60 "verify-each-debuginfo-preserve",
61 cl::desc("Start each pass with collecting and end it with checking of "
62 "debug info preservation."));
63
64cl::opt<std::string> llvm::VerifyDIPreserveExport(
65 "verify-di-preserve-export",
66 cl::desc("Export debug info preservation failures into "
67 "specified (JSON) file (should be abs path as we use"
68 " append mode to insert new JSON objects)"),
69 cl::value_desc("filename"), cl::init(Val: ""));
70
71static cl::opt<bool> EnableLoopFusion("enable-loopfusion", cl::init(Val: false),
72 cl::Hidden,
73 cl::desc("Enable the LoopFuse Pass"));
74
75enum class DebugLogging { None, Normal, Verbose, Quiet };
76
77static cl::opt<DebugLogging> DebugPM(
78 "debug-pass-manager", cl::Hidden, cl::ValueOptional,
79 cl::desc("Print pass management debugging information"),
80 cl::init(Val: DebugLogging::None),
81 cl::values(
82 clEnumValN(DebugLogging::Normal, "", ""),
83 clEnumValN(DebugLogging::Quiet, "quiet",
84 "Skip printing info about analyses"),
85 clEnumValN(
86 DebugLogging::Verbose, "verbose",
87 "Print extra information about adaptors and pass managers")));
88
89// This flag specifies a textual description of the alias analysis pipeline to
90// use when querying for aliasing information. It only works in concert with
91// the "passes" flag above.
92static cl::opt<std::string>
93 AAPipeline("aa-pipeline",
94 cl::desc("A textual description of the alias analysis "
95 "pipeline for handling managed aliasing queries"),
96 cl::Hidden, cl::init(Val: "default"));
97
98/// {{@ These options accept textual pipeline descriptions which will be
99/// inserted into default pipelines at the respective extension points
100static cl::opt<std::string> PeepholeEPPipeline(
101 "passes-ep-peephole",
102 cl::desc("A textual description of the function pass pipeline inserted at "
103 "the Peephole extension points into default pipelines"),
104 cl::Hidden);
105static cl::opt<std::string> LateLoopOptimizationsEPPipeline(
106 "passes-ep-late-loop-optimizations",
107 cl::desc(
108 "A textual description of the loop pass pipeline inserted at "
109 "the LateLoopOptimizations extension point into default pipelines"),
110 cl::Hidden);
111static cl::opt<std::string> LoopOptimizerEndEPPipeline(
112 "passes-ep-loop-optimizer-end",
113 cl::desc("A textual description of the loop pass pipeline inserted at "
114 "the LoopOptimizerEnd extension point into default pipelines"),
115 cl::Hidden);
116static cl::opt<std::string> ScalarOptimizerLateEPPipeline(
117 "passes-ep-scalar-optimizer-late",
118 cl::desc("A textual description of the function pass pipeline inserted at "
119 "the ScalarOptimizerLate extension point into default pipelines"),
120 cl::Hidden);
121static cl::opt<std::string> CGSCCOptimizerLateEPPipeline(
122 "passes-ep-cgscc-optimizer-late",
123 cl::desc("A textual description of the cgscc pass pipeline inserted at "
124 "the CGSCCOptimizerLate extension point into default pipelines"),
125 cl::Hidden);
126static cl::opt<std::string> VectorizerStartEPPipeline(
127 "passes-ep-vectorizer-start",
128 cl::desc("A textual description of the function pass pipeline inserted at "
129 "the VectorizerStart extension point into default pipelines"),
130 cl::Hidden);
131static cl::opt<std::string> VectorizerEndEPPipeline(
132 "passes-ep-vectorizer-end",
133 cl::desc("A textual description of the function pass pipeline inserted at "
134 "the VectorizerEnd extension point into default pipelines"),
135 cl::Hidden);
136static cl::opt<std::string> PipelineStartEPPipeline(
137 "passes-ep-pipeline-start",
138 cl::desc("A textual description of the module pass pipeline inserted at "
139 "the PipelineStart extension point into default pipelines"),
140 cl::Hidden);
141static cl::opt<std::string> PipelineEarlySimplificationEPPipeline(
142 "passes-ep-pipeline-early-simplification",
143 cl::desc("A textual description of the module pass pipeline inserted at "
144 "the EarlySimplification extension point into default pipelines"),
145 cl::Hidden);
146static cl::opt<std::string> OptimizerEarlyEPPipeline(
147 "passes-ep-optimizer-early",
148 cl::desc("A textual description of the module pass pipeline inserted at "
149 "the OptimizerEarly extension point into default pipelines"),
150 cl::Hidden);
151static cl::opt<std::string> OptimizerLastEPPipeline(
152 "passes-ep-optimizer-last",
153 cl::desc("A textual description of the module pass pipeline inserted at "
154 "the OptimizerLast extension point into default pipelines"),
155 cl::Hidden);
156static cl::opt<std::string> FullLinkTimeOptimizationEarlyEPPipeline(
157 "passes-ep-full-link-time-optimization-early",
158 cl::desc("A textual description of the module pass pipeline inserted at "
159 "the FullLinkTimeOptimizationEarly extension point into default "
160 "pipelines"),
161 cl::Hidden);
162static cl::opt<std::string> FullLinkTimeOptimizationLastEPPipeline(
163 "passes-ep-full-link-time-optimization-last",
164 cl::desc("A textual description of the module pass pipeline inserted at "
165 "the FullLinkTimeOptimizationLast extension point into default "
166 "pipelines"),
167 cl::Hidden);
168/// @}}
169
170static cl::opt<bool> DisablePipelineVerification(
171 "disable-pipeline-verification",
172 cl::desc("Only has an effect when specified with -print-pipeline-passes. "
173 "Disables verifying that the textual pipeline generated by "
174 "-print-pipeline-passes can be used to create a pipeline."),
175 cl::Hidden);
176
177
178static cl::opt<PGOKind>
179 PGOKindFlag("pgo-kind", cl::init(Val: NoPGO), cl::Hidden,
180 cl::desc("The kind of profile guided optimization"),
181 cl::values(clEnumValN(NoPGO, "nopgo", "Do not use PGO."),
182 clEnumValN(InstrGen, "pgo-instr-gen-pipeline",
183 "Instrument the IR to generate profile."),
184 clEnumValN(InstrUse, "pgo-instr-use-pipeline",
185 "Use instrumented profile to guide PGO."),
186 clEnumValN(SampleUse, "pgo-sample-use-pipeline",
187 "Use sampled profile to guide PGO.")));
188static cl::opt<std::string> ProfileFile("profile-file",
189 cl::desc("Path to the profile."), cl::Hidden);
190static cl::opt<std::string>
191 MemoryProfileFile("memory-profile-file",
192 cl::desc("Path to the memory profile."), cl::Hidden);
193
194static cl::opt<CSPGOKind> CSPGOKindFlag(
195 "cspgo-kind", cl::init(Val: NoCSPGO), cl::Hidden,
196 cl::desc("The kind of context sensitive profile guided optimization"),
197 cl::values(
198 clEnumValN(NoCSPGO, "nocspgo", "Do not use CSPGO."),
199 clEnumValN(
200 CSInstrGen, "cspgo-instr-gen-pipeline",
201 "Instrument (context sensitive) the IR to generate profile."),
202 clEnumValN(
203 CSInstrUse, "cspgo-instr-use-pipeline",
204 "Use instrumented (context sensitive) profile to guide PGO.")));
205
206static cl::opt<std::string> CSProfileGenFile(
207 "cs-profilegen-file",
208 cl::desc("Path to the instrumented context sensitive profile."),
209 cl::Hidden);
210
211static cl::opt<std::string>
212 ProfileRemappingFile("profile-remapping-file",
213 cl::desc("Path to the profile remapping file."),
214 cl::Hidden);
215
216static cl::opt<PGOOptions::ColdFuncOpt> PGOColdFuncAttr(
217 "pgo-cold-func-opt", cl::init(Val: PGOOptions::ColdFuncOpt::Default), cl::Hidden,
218 cl::desc(
219 "Function attribute to apply to cold functions as determined by PGO"),
220 cl::values(clEnumValN(PGOOptions::ColdFuncOpt::Default, "default",
221 "Default (no attribute)"),
222 clEnumValN(PGOOptions::ColdFuncOpt::OptSize, "optsize",
223 "Mark cold functions with optsize."),
224 clEnumValN(PGOOptions::ColdFuncOpt::MinSize, "minsize",
225 "Mark cold functions with minsize."),
226 clEnumValN(PGOOptions::ColdFuncOpt::OptNone, "optnone",
227 "Mark cold functions with optnone.")));
228
229static cl::opt<bool> DebugInfoForProfiling(
230 "debug-info-for-profiling", cl::init(Val: false), cl::Hidden,
231 cl::desc("Emit special debug info to enable PGO profile generation."));
232
233static cl::opt<bool> PseudoProbeForProfiling(
234 "pseudo-probe-for-profiling", cl::init(Val: false), cl::Hidden,
235 cl::desc("Emit pseudo probes to enable PGO profile generation."));
236
237static cl::opt<bool> DisableLoopUnrolling(
238 "disable-loop-unrolling",
239 cl::desc("Disable loop unrolling in all relevant passes"), cl::init(Val: false));
240
241template <typename PassManagerT>
242bool tryParsePipelineText(PassBuilder &PB,
243 const cl::opt<std::string> &PipelineOpt) {
244 if (PipelineOpt.empty())
245 return false;
246
247 // Verify the pipeline is parseable:
248 PassManagerT PM;
249 if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) {
250 errs() << "Could not parse -" << PipelineOpt.ArgStr
251 << " pipeline: " << toString(std::move(Err))
252 << "... I'm going to ignore it.\n";
253 return false;
254 }
255 return true;
256}
257
258/// If one of the EPPipeline command line options was given, register callbacks
259/// for parsing and inserting the given pipeline
260static void registerEPCallbacks(PassBuilder &PB) {
261 if (tryParsePipelineText<FunctionPassManager>(PB, PipelineOpt: PeepholeEPPipeline))
262 PB.registerPeepholeEPCallback(
263 C: [&PB](FunctionPassManager &PM, OptimizationLevel Level) {
264 ExitOnError Err("Unable to parse PeepholeEP pipeline: ");
265 Err(PB.parsePassPipeline(FPM&: PM, PipelineText: PeepholeEPPipeline));
266 });
267 if (tryParsePipelineText<LoopPassManager>(PB,
268 PipelineOpt: LateLoopOptimizationsEPPipeline))
269 PB.registerLateLoopOptimizationsEPCallback(
270 C: [&PB](LoopPassManager &PM, OptimizationLevel Level) {
271 ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: ");
272 Err(PB.parsePassPipeline(LPM&: PM, PipelineText: LateLoopOptimizationsEPPipeline));
273 });
274 if (tryParsePipelineText<LoopPassManager>(PB, PipelineOpt: LoopOptimizerEndEPPipeline))
275 PB.registerLoopOptimizerEndEPCallback(
276 C: [&PB](LoopPassManager &PM, OptimizationLevel Level) {
277 ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: ");
278 Err(PB.parsePassPipeline(LPM&: PM, PipelineText: LoopOptimizerEndEPPipeline));
279 });
280 if (tryParsePipelineText<FunctionPassManager>(PB,
281 PipelineOpt: ScalarOptimizerLateEPPipeline))
282 PB.registerScalarOptimizerLateEPCallback(
283 C: [&PB](FunctionPassManager &PM, OptimizationLevel Level) {
284 ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: ");
285 Err(PB.parsePassPipeline(FPM&: PM, PipelineText: ScalarOptimizerLateEPPipeline));
286 });
287 if (tryParsePipelineText<CGSCCPassManager>(PB, PipelineOpt: CGSCCOptimizerLateEPPipeline))
288 PB.registerCGSCCOptimizerLateEPCallback(
289 C: [&PB](CGSCCPassManager &PM, OptimizationLevel Level) {
290 ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: ");
291 Err(PB.parsePassPipeline(CGPM&: PM, PipelineText: CGSCCOptimizerLateEPPipeline));
292 });
293 if (tryParsePipelineText<FunctionPassManager>(PB, PipelineOpt: VectorizerStartEPPipeline))
294 PB.registerVectorizerStartEPCallback(
295 C: [&PB](FunctionPassManager &PM, OptimizationLevel Level) {
296 ExitOnError Err("Unable to parse VectorizerStartEP pipeline: ");
297 Err(PB.parsePassPipeline(FPM&: PM, PipelineText: VectorizerStartEPPipeline));
298 });
299 if (tryParsePipelineText<FunctionPassManager>(PB, PipelineOpt: VectorizerEndEPPipeline))
300 PB.registerVectorizerEndEPCallback(
301 C: [&PB](FunctionPassManager &PM, OptimizationLevel Level) {
302 ExitOnError Err("Unable to parse VectorizerEndEP pipeline: ");
303 Err(PB.parsePassPipeline(FPM&: PM, PipelineText: VectorizerEndEPPipeline));
304 });
305 if (tryParsePipelineText<ModulePassManager>(PB, PipelineOpt: PipelineStartEPPipeline))
306 PB.registerPipelineStartEPCallback(
307 C: [&PB](ModulePassManager &PM, OptimizationLevel) {
308 ExitOnError Err("Unable to parse PipelineStartEP pipeline: ");
309 Err(PB.parsePassPipeline(MPM&: PM, PipelineText: PipelineStartEPPipeline));
310 });
311 if (tryParsePipelineText<ModulePassManager>(
312 PB, PipelineOpt: PipelineEarlySimplificationEPPipeline))
313 PB.registerPipelineEarlySimplificationEPCallback(
314 C: [&PB](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) {
315 ExitOnError Err("Unable to parse EarlySimplification pipeline: ");
316 Err(PB.parsePassPipeline(MPM&: PM, PipelineText: PipelineEarlySimplificationEPPipeline));
317 });
318 if (tryParsePipelineText<ModulePassManager>(PB, PipelineOpt: OptimizerEarlyEPPipeline))
319 PB.registerOptimizerEarlyEPCallback(
320 C: [&PB](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) {
321 ExitOnError Err("Unable to parse OptimizerEarlyEP pipeline: ");
322 Err(PB.parsePassPipeline(MPM&: PM, PipelineText: OptimizerEarlyEPPipeline));
323 });
324 if (tryParsePipelineText<ModulePassManager>(PB, PipelineOpt: OptimizerLastEPPipeline))
325 PB.registerOptimizerLastEPCallback(
326 C: [&PB](ModulePassManager &PM, OptimizationLevel, ThinOrFullLTOPhase) {
327 ExitOnError Err("Unable to parse OptimizerLastEP pipeline: ");
328 Err(PB.parsePassPipeline(MPM&: PM, PipelineText: OptimizerLastEPPipeline));
329 });
330 if (tryParsePipelineText<ModulePassManager>(
331 PB, PipelineOpt: FullLinkTimeOptimizationEarlyEPPipeline))
332 PB.registerFullLinkTimeOptimizationEarlyEPCallback(
333 C: [&PB](ModulePassManager &PM, OptimizationLevel) {
334 ExitOnError Err(
335 "Unable to parse FullLinkTimeOptimizationEarlyEP pipeline: ");
336 Err(PB.parsePassPipeline(MPM&: PM,
337 PipelineText: FullLinkTimeOptimizationEarlyEPPipeline));
338 });
339 if (tryParsePipelineText<ModulePassManager>(
340 PB, PipelineOpt: FullLinkTimeOptimizationLastEPPipeline))
341 PB.registerFullLinkTimeOptimizationLastEPCallback(
342 C: [&PB](ModulePassManager &PM, OptimizationLevel) {
343 ExitOnError Err(
344 "Unable to parse FullLinkTimeOptimizationLastEP pipeline: ");
345 Err(PB.parsePassPipeline(MPM&: PM, PipelineText: FullLinkTimeOptimizationLastEPPipeline));
346 });
347}
348
349#define HANDLE_EXTENSION(Ext) \
350 llvm::PassPluginLibraryInfo get##Ext##PluginInfo();
351#include "llvm/Support/Extension.def"
352#undef HANDLE_EXTENSION
353
354bool llvm::runPassPipeline(
355 StringRef Arg0, Module &M, TargetMachine *TM, TargetLibraryInfoImpl *TLII,
356 ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut,
357 ToolOutputFile *OptRemarkFile, StringRef PassPipeline,
358 ArrayRef<PassPlugin> PassPlugins,
359 ArrayRef<std::function<void(PassBuilder &)>> PassBuilderCallbacks,
360 OutputKind OK, VerifierKind VK, bool ShouldPreserveAssemblyUseListOrder,
361 bool ShouldPreserveBitcodeUseListOrder, bool EmitSummaryIndex,
362 bool EmitModuleHash, bool EnableDebugify, bool VerifyDIPreserve,
363 bool EnableProfcheck, bool UnifiedLTO) {
364 std::optional<PGOOptions> P;
365 switch (PGOKindFlag) {
366 case InstrGen:
367 P = PGOOptions(ProfileFile, "", "", MemoryProfileFile, PGOOptions::IRInstr,
368 PGOOptions::NoCSAction, PGOColdFuncAttr);
369 break;
370 case InstrUse:
371 P = PGOOptions(ProfileFile, "", ProfileRemappingFile, MemoryProfileFile,
372 PGOOptions::IRUse, PGOOptions::NoCSAction, PGOColdFuncAttr);
373 break;
374 case SampleUse:
375 P = PGOOptions(ProfileFile, "", ProfileRemappingFile, MemoryProfileFile,
376 PGOOptions::SampleUse, PGOOptions::NoCSAction,
377 PGOColdFuncAttr);
378 break;
379 case NoPGO:
380 if (DebugInfoForProfiling || PseudoProbeForProfiling ||
381 !MemoryProfileFile.empty())
382 P = PGOOptions("", "", "", MemoryProfileFile, PGOOptions::NoAction,
383 PGOOptions::NoCSAction, PGOColdFuncAttr,
384 DebugInfoForProfiling, PseudoProbeForProfiling);
385 else
386 P = std::nullopt;
387 }
388 if (CSPGOKindFlag != NoCSPGO) {
389 if (P && (P->Action == PGOOptions::IRInstr ||
390 P->Action == PGOOptions::SampleUse)) {
391 errs() << "CSPGOKind cannot be used with IRInstr or SampleUse";
392 return false;
393 }
394 if (CSPGOKindFlag == CSInstrGen) {
395 if (CSProfileGenFile.empty()) {
396 errs() << "CSInstrGen needs to specify CSProfileGenFile";
397 return false;
398 }
399 if (P) {
400 P->CSAction = PGOOptions::CSIRInstr;
401 P->CSProfileGenFile = CSProfileGenFile;
402 } else
403 P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
404 /*MemoryProfile=*/"", PGOOptions::NoAction,
405 PGOOptions::CSIRInstr);
406 } else /* CSPGOKindFlag == CSInstrUse */ {
407 if (!P) {
408 errs() << "CSInstrUse needs to be together with InstrUse";
409 return false;
410 }
411 P->CSAction = PGOOptions::CSIRUse;
412 }
413 }
414
415 LoopAnalysisManager LAM;
416 FunctionAnalysisManager FAM;
417 CGSCCAnalysisManager CGAM;
418 ModuleAnalysisManager MAM;
419
420 if (TM) {
421 TM->setPGOOption(P);
422
423 MAM.registerPass(PassBuilder: [&] {
424 const TargetOptions &Options = TM->Options;
425 return RuntimeLibraryAnalysis(M.getTargetTriple(), Options.ExceptionModel,
426 Options.FloatABIType, Options.EABIVersion,
427 Options.MCOptions.ABIName, Options.VecLib);
428 });
429
430 MAM.registerPass(PassBuilder: [&] { return LibcallLoweringModuleAnalysis(); });
431 }
432
433 PassInstrumentationCallbacks PIC;
434 PrintPassOptions PrintPassOpts;
435 PrintPassOpts.Verbose = DebugPM == DebugLogging::Verbose;
436 PrintPassOpts.SkipAnalyses = DebugPM == DebugLogging::Quiet;
437 StandardInstrumentations SI(M.getContext(), DebugPM != DebugLogging::None,
438 VK == VerifierKind::EachPass, PrintPassOpts);
439 SI.registerCallbacks(PIC, MAM: &MAM);
440 DebugifyEachInstrumentation Debugify;
441 DebugifyStatsMap DIStatsMap;
442 DebugInfoPerPass DebugInfoBeforePass;
443 if (DebugifyEach) {
444 Debugify.setDIStatsMap(DIStatsMap);
445 Debugify.setDebugifyMode(DebugifyMode::SyntheticDebugInfo);
446 Debugify.registerCallbacks(PIC, MAM);
447 } else if (VerifyEachDebugInfoPreserve) {
448 Debugify.setDebugInfoBeforePass(DebugInfoBeforePass);
449 Debugify.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
450 Debugify.setOrigDIVerifyBugsReportFilePath(
451 VerifyDIPreserveExport);
452 Debugify.registerCallbacks(PIC, MAM);
453 }
454
455 PipelineTuningOptions PTO;
456 // LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized
457 // to false above so we shouldn't necessarily need to check whether or not the
458 // option has been enabled.
459 PTO.LoopUnrolling = !DisableLoopUnrolling;
460 PTO.UnifiedLTO = UnifiedLTO;
461 PTO.LoopFusion = EnableLoopFusion;
462 PassBuilder PB(TM, PTO, P, &PIC);
463 registerEPCallbacks(PB);
464
465 // For any loaded plugins, let them register pass builder callbacks.
466 for (auto &PassPlugin : PassPlugins)
467 PassPlugin.registerPassBuilderCallbacks(PB);
468
469 // Load any explicitly specified plugins.
470 for (auto &PassCallback : PassBuilderCallbacks)
471 PassCallback(PB);
472
473#define HANDLE_EXTENSION(Ext) \
474 get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB);
475#include "llvm/Support/Extension.def"
476#undef HANDLE_EXTENSION
477
478 // Specially handle the alias analysis manager so that we can register
479 // a custom pipeline of AA passes with it.
480 AAManager AA;
481 if (auto Err = PB.parseAAPipeline(AA, PipelineText: AAPipeline)) {
482 errs() << Arg0 << ": " << toString(E: std::move(Err)) << "\n";
483 return false;
484 }
485
486 // Register the AA manager first so that our version is the one used.
487 FAM.registerPass(PassBuilder: [&] { return std::move(AA); });
488 // Register our TargetLibraryInfoImpl.
489 FAM.registerPass(PassBuilder: [&] { return TargetLibraryAnalysis(*TLII); });
490
491 // Register all the basic analyses with the managers.
492 PB.registerModuleAnalyses(MAM);
493 PB.registerCGSCCAnalyses(CGAM);
494 PB.registerFunctionAnalyses(FAM);
495 PB.registerLoopAnalyses(LAM);
496 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
497
498 ModulePassManager MPM;
499 if (EnableDebugify)
500 MPM.addPass(Pass: NewPMDebugifyPass());
501 if (VerifyDIPreserve)
502 MPM.addPass(Pass: NewPMDebugifyPass(DebugifyMode::OriginalDebugInfo, "",
503 &DebugInfoBeforePass));
504 if (EnableProfcheck)
505 MPM.addPass(Pass: createModuleToFunctionPassAdaptor(Pass: ProfileInjectorPass()));
506 // Add passes according to the -passes options.
507 if (!PassPipeline.empty()) {
508 if (auto Err = PB.parsePassPipeline(MPM, PipelineText: PassPipeline)) {
509 errs() << Arg0 << ": " << toString(E: std::move(Err)) << "\n";
510 return false;
511 }
512 }
513
514 if (VK != VerifierKind::None)
515 MPM.addPass(Pass: VerifierPass());
516 if (EnableDebugify)
517 MPM.addPass(Pass: NewPMCheckDebugifyPass(false, "", &DIStatsMap));
518 if (VerifyDIPreserve)
519 MPM.addPass(Pass: NewPMCheckDebugifyPass(
520 false, "", nullptr, DebugifyMode::OriginalDebugInfo,
521 &DebugInfoBeforePass, VerifyDIPreserveExport));
522 if (EnableProfcheck)
523 MPM.addPass(Pass: ProfileVerifierPass());
524
525 // Add any relevant output pass at the end of the pipeline.
526 switch (OK) {
527 case OK_NoOutput:
528 break; // No output pass needed.
529 case OK_OutputAssembly:
530 MPM.addPass(Pass: PrintModulePass(
531 Out->os(), "", ShouldPreserveAssemblyUseListOrder, EmitSummaryIndex));
532 break;
533 case OK_OutputBitcode:
534 MPM.addPass(Pass: BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
535 EmitSummaryIndex, EmitModuleHash));
536 break;
537 case OK_OutputThinLTOBitcode:
538 MPM.addPass(Pass: ThinLTOBitcodeWriterPass(
539 Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr,
540 ShouldPreserveBitcodeUseListOrder));
541 break;
542 }
543
544 // Before executing passes, print the final values of the LLVM options.
545 cl::PrintOptionValues();
546
547 // Print a textual, '-passes=' compatible, representation of pipeline if
548 // requested.
549 if (PrintPipelinePasses) {
550 std::string Pipeline;
551 raw_string_ostream SOS(Pipeline);
552 MPM.printPipeline(OS&: SOS, MapClassName2PassName: [&PIC](StringRef ClassName) {
553 auto PassName = PIC.getPassNameForClassName(ClassName);
554 return PassName.empty() ? ClassName : PassName;
555 });
556 outs() << Pipeline;
557 outs() << "\n";
558
559 if (!DisablePipelineVerification) {
560 // Check that we can parse the returned pipeline string as an actual
561 // pipeline.
562 ModulePassManager TempPM;
563 if (auto Err = PB.parsePassPipeline(MPM&: TempPM, PipelineText: Pipeline)) {
564 errs() << "Could not parse dumped pass pipeline: "
565 << toString(E: std::move(Err)) << "\n";
566 return false;
567 }
568 }
569
570 return true;
571 }
572
573 // Now that we have all of the passes ready, run them.
574 MPM.run(IR&: M, AM&: MAM);
575
576 // Declare success.
577 if (OK != OK_NoOutput) {
578 Out->keep();
579 if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut)
580 ThinLTOLinkOut->keep();
581 }
582
583 if (OptRemarkFile)
584 OptRemarkFile->keep();
585
586 if (DebugifyEach && !DebugifyExport.empty())
587 exportDebugifyStats(Path: DebugifyExport, Map: Debugify.getDebugifyStatsMap());
588
589 TimerGroup::printAll(OS&: *CreateInfoOutputFile());
590 TimerGroup::clearAll();
591
592 return true;
593}
594
595void llvm::printPasses(raw_ostream &OS) {
596 PassBuilder PB;
597 PB.printPassNames(OS);
598}
599