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