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