1//===- optdriver.cpp - The LLVM Modular Optimizer -------------------------===//
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//
9// Optimizations may be specified an arbitrary number of times on the command
10// line, They are run in the order specified. Common driver library for re-use
11// by potential downstream opt-variants.
12//
13//===----------------------------------------------------------------------===//
14
15#include "NewPMDriver.h"
16#include "llvm/Analysis/CallGraph.h"
17#include "llvm/Analysis/CallGraphSCCPass.h"
18#include "llvm/Analysis/LoopPass.h"
19#include "llvm/Analysis/RegionPass.h"
20#include "llvm/Analysis/TargetLibraryInfo.h"
21#include "llvm/Analysis/TargetTransformInfo.h"
22#include "llvm/AsmParser/Parser.h"
23#include "llvm/CodeGen/CommandFlags.h"
24#include "llvm/CodeGen/TargetPassConfig.h"
25#include "llvm/Config/llvm-config.h"
26#include "llvm/IR/DataLayout.h"
27#include "llvm/IR/DebugInfo.h"
28#include "llvm/IR/LLVMContext.h"
29#include "llvm/IR/LLVMRemarkStreamer.h"
30#include "llvm/IR/LegacyPassManager.h"
31#include "llvm/IR/LegacyPassNameParser.h"
32#include "llvm/IR/Module.h"
33#include "llvm/IR/ModuleSummaryIndex.h"
34#include "llvm/IR/Verifier.h"
35#include "llvm/IRReader/IRReader.h"
36#include "llvm/InitializePasses.h"
37#include "llvm/LinkAllIR.h"
38#include "llvm/LinkAllPasses.h"
39#include "llvm/MC/TargetRegistry.h"
40#include "llvm/Passes/PassPlugin.h"
41#include "llvm/Remarks/HotnessThresholdParser.h"
42#include "llvm/Support/Debug.h"
43#include "llvm/Support/ErrorHandling.h"
44#include "llvm/Support/FileSystem.h"
45#include "llvm/Support/InitLLVM.h"
46#include "llvm/Support/PluginLoader.h"
47#include "llvm/Support/SourceMgr.h"
48#include "llvm/Support/SystemUtils.h"
49#include "llvm/Support/TargetSelect.h"
50#include "llvm/Support/TimeProfiler.h"
51#include "llvm/Support/ToolOutputFile.h"
52#include "llvm/Support/YAMLTraits.h"
53#include "llvm/Target/TargetMachine.h"
54#include "llvm/TargetParser/Host.h"
55#include "llvm/TargetParser/SubtargetFeature.h"
56#include "llvm/TargetParser/Triple.h"
57#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
58#include "llvm/Transforms/Utils/Cloning.h"
59#include "llvm/Transforms/Utils/Debugify.h"
60#include <algorithm>
61#include <memory>
62#include <optional>
63using namespace llvm;
64using namespace opt_tool;
65
66static codegen::RegisterCodeGenFlags CFG;
67
68// The OptimizationList is automatically populated with registered Passes by the
69// PassNameParser.
70static cl::list<const PassInfo *, bool, PassNameParser> PassList(cl::desc(
71 "Optimizations available (use \"-passes=\" for the new pass manager)"));
72
73static cl::opt<bool> EnableLegacyPassManager(
74 "bugpoint-enable-legacy-pm",
75 cl::desc(
76 "Enable the legacy pass manager. This is strictly for bugpoint "
77 "due to it not working with the new PM, please do not use otherwise."),
78 cl::init(Val: false));
79
80// This flag specifies a textual description of the optimization pass pipeline
81// to run over the module. This flag switches opt to use the new pass manager
82// infrastructure, completely disabling all of the flags specific to the old
83// pass management.
84static cl::opt<std::string> PassPipeline(
85 "passes",
86 cl::desc(
87 "A textual description of the pass pipeline. To have analysis passes "
88 "available before a certain pass, add \"require<foo-analysis>\"."));
89static cl::alias PassPipeline2("p", cl::aliasopt(PassPipeline),
90 cl::desc("Alias for -passes"));
91
92static cl::opt<bool> PrintPasses("print-passes",
93 cl::desc("Print available passes that can be "
94 "specified in -passes=foo and exit"));
95
96static cl::opt<std::string> InputFilename(cl::Positional,
97 cl::desc("<input bitcode file>"),
98 cl::init(Val: "-"),
99 cl::value_desc("filename"));
100
101static cl::opt<std::string> OutputFilename("o",
102 cl::desc("Override output filename"),
103 cl::value_desc("filename"));
104
105static cl::opt<bool> Force("f", cl::desc("Enable binary output on terminals"));
106
107static cl::opt<bool> NoOutput("disable-output",
108 cl::desc("Do not write result bitcode file"),
109 cl::Hidden);
110
111static cl::opt<bool> OutputAssembly("S",
112 cl::desc("Write output as LLVM assembly"));
113
114static cl::opt<bool>
115 OutputThinLTOBC("thinlto-bc",
116 cl::desc("Write output as ThinLTO-ready bitcode"));
117
118static cl::opt<bool>
119 SplitLTOUnit("thinlto-split-lto-unit",
120 cl::desc("Enable splitting of a ThinLTO LTOUnit"));
121
122static cl::opt<bool>
123 UnifiedLTO("unified-lto",
124 cl::desc("Use unified LTO piplines. Ignored unless -thinlto-bc "
125 "is also specified."),
126 cl::Hidden, cl::init(Val: false));
127
128static cl::opt<std::string> ThinLinkBitcodeFile(
129 "thin-link-bitcode-file", cl::value_desc("filename"),
130 cl::desc(
131 "A file in which to write minimized bitcode for the thin link only"));
132
133static cl::opt<bool> NoVerify("disable-verify",
134 cl::desc("Do not run the verifier"), cl::Hidden);
135
136static cl::opt<bool> NoUpgradeDebugInfo("disable-upgrade-debug-info",
137 cl::desc("Generate invalid output"),
138 cl::ReallyHidden);
139
140static cl::opt<bool> VerifyEach("verify-each",
141 cl::desc("Verify after each transform"));
142
143static cl::opt<bool>
144 DisableDITypeMap("disable-debug-info-type-map",
145 cl::desc("Don't use a uniquing type map for debug info"));
146
147static cl::opt<bool>
148 StripDebug("strip-debug",
149 cl::desc("Strip debugger symbol info from translation unit"));
150
151static cl::opt<bool>
152 StripNamedMetadata("strip-named-metadata",
153 cl::desc("Strip module-level named metadata"));
154
155static cl::opt<bool>
156 OptLevelO0("O0", cl::desc("Optimization level 0. Similar to clang -O0. "
157 "Same as -passes=\"default<O0>\""));
158
159static cl::opt<bool>
160 OptLevelO1("O1", cl::desc("Optimization level 1. Similar to clang -O1. "
161 "Same as -passes=\"default<O1>\""));
162
163static cl::opt<bool>
164 OptLevelO2("O2", cl::desc("Optimization level 2. Similar to clang -O2. "
165 "Same as -passes=\"default<O2>\""));
166
167static cl::opt<bool>
168 OptLevelOs("Os", cl::desc("Like -O2 but size-conscious. Similar to clang "
169 "-Os. Same as -passes=\"default<Os>\""));
170
171static cl::opt<bool> OptLevelOz(
172 "Oz",
173 cl::desc("Like -O2 but optimize for code size above all else. Similar to "
174 "clang -Oz. Same as -passes=\"default<Oz>\""));
175
176static cl::opt<bool>
177 OptLevelO3("O3", cl::desc("Optimization level 3. Similar to clang -O3. "
178 "Same as -passes=\"default<O3>\""));
179
180static cl::opt<unsigned> CodeGenOptLevelCL(
181 "codegen-opt-level",
182 cl::desc("Override optimization level for codegen hooks, legacy PM only"));
183
184static cl::opt<std::string>
185 TargetTriple("mtriple", cl::desc("Override target triple for module"));
186
187static cl::opt<bool> EmitSummaryIndex("module-summary",
188 cl::desc("Emit module summary index"),
189 cl::init(Val: false));
190
191static cl::opt<bool> EmitModuleHash("module-hash", cl::desc("Emit module hash"),
192 cl::init(Val: false));
193
194static cl::opt<bool>
195 DisableSimplifyLibCalls("disable-simplify-libcalls",
196 cl::desc("Disable simplify-libcalls"));
197
198static cl::list<std::string> DisableBuiltins(
199 "disable-builtin",
200 cl::desc("Disable specific target library builtin function"));
201
202static cl::opt<bool> EnableDebugify(
203 "enable-debugify",
204 cl::desc(
205 "Start the pipeline with debugify and end it with check-debugify"));
206
207static cl::opt<bool> VerifyDebugInfoPreserve(
208 "verify-debuginfo-preserve",
209 cl::desc("Start the pipeline with collecting and end it with checking of "
210 "debug info preservation."));
211
212static cl::opt<std::string> ClDataLayout("data-layout",
213 cl::desc("data layout string to use"),
214 cl::value_desc("layout-string"),
215 cl::init(Val: ""));
216
217static cl::opt<bool> PreserveBitcodeUseListOrder(
218 "preserve-bc-uselistorder",
219 cl::desc("Preserve use-list order when writing LLVM bitcode."),
220 cl::init(Val: true), cl::Hidden);
221
222static cl::opt<bool> PreserveAssemblyUseListOrder(
223 "preserve-ll-uselistorder",
224 cl::desc("Preserve use-list order when writing LLVM assembly."),
225 cl::init(Val: false), cl::Hidden);
226
227static cl::opt<bool> RunTwice("run-twice",
228 cl::desc("Run all passes twice, re-using the "
229 "same pass manager (legacy PM only)."),
230 cl::init(Val: false), cl::Hidden);
231
232static cl::opt<bool> DiscardValueNames(
233 "discard-value-names",
234 cl::desc("Discard names from Value (other than GlobalValue)."),
235 cl::init(Val: false), cl::Hidden);
236
237static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));
238
239static cl::opt<unsigned> TimeTraceGranularity(
240 "time-trace-granularity",
241 cl::desc(
242 "Minimum time granularity (in microseconds) traced by time profiler"),
243 cl::init(Val: 500), cl::Hidden);
244
245static cl::opt<std::string>
246 TimeTraceFile("time-trace-file",
247 cl::desc("Specify time trace file destination"),
248 cl::value_desc("filename"));
249
250static cl::opt<bool> RemarksWithHotness(
251 "pass-remarks-with-hotness",
252 cl::desc("With PGO, include profile count in optimization remarks"),
253 cl::Hidden);
254
255static cl::opt<std::optional<uint64_t>, false, remarks::HotnessThresholdParser>
256 RemarksHotnessThreshold(
257 "pass-remarks-hotness-threshold",
258 cl::desc("Minimum profile count required for "
259 "an optimization remark to be output. "
260 "Use 'auto' to apply the threshold from profile summary"),
261 cl::value_desc("N or 'auto'"), cl::init(Val: 0), cl::Hidden);
262
263static cl::opt<std::string>
264 RemarksFilename("pass-remarks-output",
265 cl::desc("Output filename for pass remarks"),
266 cl::value_desc("filename"));
267
268static cl::opt<std::string>
269 RemarksPasses("pass-remarks-filter",
270 cl::desc("Only record optimization remarks from passes whose "
271 "names match the given regular expression"),
272 cl::value_desc("regex"));
273
274static cl::opt<std::string> RemarksFormat(
275 "pass-remarks-format",
276 cl::desc("The format used for serializing remarks (default: YAML)"),
277 cl::value_desc("format"), cl::init(Val: "yaml"));
278
279static cl::list<std::string>
280 PassPlugins("load-pass-plugin",
281 cl::desc("Load passes from plugin library"));
282
283static cl::opt<bool> TryUseNewDbgInfoFormat(
284 "try-experimental-debuginfo-iterators",
285 cl::desc("Enable debuginfo iterator positions, if they're built in"),
286 cl::init(Val: false), cl::Hidden);
287
288extern cl::opt<bool> UseNewDbgInfoFormat;
289
290//===----------------------------------------------------------------------===//
291// CodeGen-related helper functions.
292//
293
294static CodeGenOptLevel GetCodeGenOptLevel() {
295 return static_cast<CodeGenOptLevel>(unsigned(CodeGenOptLevelCL));
296}
297
298struct TimeTracerRAII {
299 TimeTracerRAII(StringRef ProgramName) {
300 if (TimeTrace)
301 timeTraceProfilerInitialize(TimeTraceGranularity, ProcName: ProgramName);
302 }
303 ~TimeTracerRAII() {
304 if (TimeTrace) {
305 if (auto E = timeTraceProfilerWrite(PreferredFileName: TimeTraceFile, FallbackFileName: OutputFilename)) {
306 handleAllErrors(E: std::move(E), Handlers: [&](const StringError &SE) {
307 errs() << SE.getMessage() << "\n";
308 });
309 return;
310 }
311 timeTraceProfilerCleanup();
312 }
313 }
314};
315
316// For use in NPM transition. Currently this contains most codegen-specific
317// passes. Remove passes from here when porting to the NPM.
318// TODO: use a codegen version of PassRegistry.def/PassBuilder::is*Pass() once
319// it exists.
320static bool shouldPinPassToLegacyPM(StringRef Pass) {
321 static constexpr StringLiteral PassNameExactToIgnore[] = {
322 "nvvm-reflect",
323 "nvvm-intr-range",
324 "amdgpu-simplifylib",
325 "amdgpu-image-intrinsic-opt",
326 "amdgpu-usenative",
327 "amdgpu-promote-alloca",
328 "amdgpu-promote-alloca-to-vector",
329 "amdgpu-lower-kernel-attributes",
330 "amdgpu-propagate-attributes-early",
331 "amdgpu-propagate-attributes-late",
332 "amdgpu-unify-metadata",
333 "amdgpu-printf-runtime-binding",
334 "amdgpu-always-inline"};
335 if (llvm::is_contained(Range: PassNameExactToIgnore, Element: Pass))
336 return false;
337
338 static constexpr StringLiteral PassNamePrefix[] = {
339 "x86-", "xcore-", "wasm-", "systemz-", "ppc-", "nvvm-",
340 "nvptx-", "mips-", "lanai-", "hexagon-", "bpf-", "avr-",
341 "thumb2-", "arm-", "si-", "gcn-", "amdgpu-", "aarch64-",
342 "amdgcn-", "polly-", "riscv-", "dxil-"};
343 static constexpr StringLiteral PassNameContain[] = {"-eh-prepare"};
344 static constexpr StringLiteral PassNameExact[] = {
345 "safe-stack",
346 "cost-model",
347 "codegenprepare",
348 "interleaved-load-combine",
349 "unreachableblockelim",
350 "verify-safepoint-ir",
351 "atomic-expand",
352 "expandvp",
353 "mve-tail-predication",
354 "interleaved-access",
355 "global-merge",
356 "pre-isel-intrinsic-lowering",
357 "expand-reductions",
358 "indirectbr-expand",
359 "generic-to-nvvm",
360 "expand-memcmp",
361 "loop-reduce",
362 "lower-amx-type",
363 "lower-amx-intrinsics",
364 "polyhedral-info",
365 "print-polyhedral-info",
366 "replace-with-veclib",
367 "jmc-instrumenter",
368 "dot-regions",
369 "dot-regions-only",
370 "view-regions",
371 "view-regions-only",
372 "select-optimize",
373 "expand-large-div-rem",
374 "structurizecfg",
375 "fix-irreducible",
376 "expand-large-fp-convert",
377 "callbrprepare",
378 };
379 for (const auto &P : PassNamePrefix)
380 if (Pass.starts_with(Prefix: P))
381 return true;
382 for (const auto &P : PassNameContain)
383 if (Pass.contains(Other: P))
384 return true;
385 return llvm::is_contained(Range: PassNameExact, Element: Pass);
386}
387
388// For use in NPM transition.
389static bool shouldForceLegacyPM() {
390 for (const auto &P : PassList) {
391 StringRef Arg = P->getPassArgument();
392 if (shouldPinPassToLegacyPM(Pass: Arg))
393 return true;
394 }
395 return false;
396}
397
398//===----------------------------------------------------------------------===//
399// main for opt
400//
401extern "C" int optMain(
402 int argc, char **argv,
403 ArrayRef<std::function<void(llvm::PassBuilder &)>> PassBuilderCallbacks) {
404 InitLLVM X(argc, argv);
405
406 // Enable debug stream buffering.
407 EnableDebugBuffering = true;
408
409 InitializeAllTargets();
410 InitializeAllTargetMCs();
411 InitializeAllAsmPrinters();
412 InitializeAllAsmParsers();
413
414 // Initialize passes
415 PassRegistry &Registry = *PassRegistry::getPassRegistry();
416 initializeCore(Registry);
417 initializeScalarOpts(Registry);
418 initializeVectorization(Registry);
419 initializeIPO(Registry);
420 initializeAnalysis(Registry);
421 initializeTransformUtils(Registry);
422 initializeInstCombine(Registry);
423 initializeTarget(Registry);
424 // For codegen passes, only passes that do IR to IR transformation are
425 // supported.
426 initializeExpandLargeDivRemLegacyPassPass(Registry);
427 initializeExpandLargeFpConvertLegacyPassPass(Registry);
428 initializeExpandMemCmpLegacyPassPass(Registry);
429 initializeScalarizeMaskedMemIntrinLegacyPassPass(Registry);
430 initializeSelectOptimizePass(Registry);
431 initializeCallBrPreparePass(Registry);
432 initializeCodeGenPrepareLegacyPassPass(Registry);
433 initializeAtomicExpandLegacyPass(Registry);
434 initializeWinEHPreparePass(Registry);
435 initializeDwarfEHPrepareLegacyPassPass(Registry);
436 initializeSafeStackLegacyPassPass(Registry);
437 initializeSjLjEHPreparePass(Registry);
438 initializePreISelIntrinsicLoweringLegacyPassPass(Registry);
439 initializeGlobalMergePass(Registry);
440 initializeIndirectBrExpandLegacyPassPass(Registry);
441 initializeInterleavedLoadCombinePass(Registry);
442 initializeInterleavedAccessPass(Registry);
443 initializePostInlineEntryExitInstrumenterPass(Registry);
444 initializeUnreachableBlockElimLegacyPassPass(Registry);
445 initializeExpandReductionsPass(Registry);
446 initializeExpandVectorPredicationPass(Registry);
447 initializeWasmEHPreparePass(Registry);
448 initializeWriteBitcodePassPass(Registry);
449 initializeReplaceWithVeclibLegacyPass(Registry);
450 initializeJMCInstrumenterPass(Registry);
451
452 SmallVector<PassPlugin, 1> PluginList;
453 PassPlugins.setCallback([&](const std::string &PluginPath) {
454 auto Plugin = PassPlugin::Load(Filename: PluginPath);
455 if (!Plugin)
456 report_fatal_error(Err: Plugin.takeError(), /*gen_crash_diag=*/false);
457 PluginList.emplace_back(Args&: Plugin.get());
458 });
459
460 // Register the Target and CPU printer for --version.
461 cl::AddExtraVersionPrinter(func: sys::printDefaultTargetAndDetectedCPU);
462
463 cl::ParseCommandLineOptions(
464 argc, argv, Overview: "llvm .bc -> .bc modular optimizer and analysis printer\n");
465
466 // RemoveDIs debug-info transition: tests may request that we /try/ to use the
467 // new debug-info format.
468 if (TryUseNewDbgInfoFormat) {
469 // Turn the new debug-info format on.
470 UseNewDbgInfoFormat = true;
471 }
472
473 LLVMContext Context;
474
475 // TODO: remove shouldForceLegacyPM().
476 const bool UseNPM = (!EnableLegacyPassManager && !shouldForceLegacyPM()) ||
477 PassPipeline.getNumOccurrences() > 0;
478
479 if (UseNPM && !PassList.empty()) {
480 errs() << "The `opt -passname` syntax for the new pass manager is "
481 "not supported, please use `opt -passes=<pipeline>` (or the `-p` "
482 "alias for a more concise version).\n";
483 errs() << "See https://llvm.org/docs/NewPassManager.html#invoking-opt "
484 "for more details on the pass pipeline syntax.\n\n";
485 return 1;
486 }
487
488 if (!UseNPM && PluginList.size()) {
489 errs() << argv[0] << ": " << PassPlugins.ArgStr
490 << " specified with legacy PM.\n";
491 return 1;
492 }
493
494 // FIXME: once the legacy PM code is deleted, move runPassPipeline() here and
495 // construct the PassBuilder before parsing IR so we can reuse the same
496 // PassBuilder for print passes.
497 if (PrintPasses) {
498 printPasses(OS&: outs());
499 return 0;
500 }
501
502 TimeTracerRAII TimeTracer(argv[0]);
503
504 SMDiagnostic Err;
505
506 Context.setDiscardValueNames(DiscardValueNames);
507 if (!DisableDITypeMap)
508 Context.enableDebugTypeODRUniquing();
509
510 Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
511 setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
512 RemarksFormat, RemarksWithHotness,
513 RemarksHotnessThreshold);
514 if (Error E = RemarksFileOrErr.takeError()) {
515 errs() << toString(E: std::move(E)) << '\n';
516 return 1;
517 }
518 std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr);
519
520 // Load the input module...
521 auto SetDataLayout = [&](StringRef IRTriple,
522 StringRef IRLayout) -> std::optional<std::string> {
523 // Data layout specified on the command line has the highest priority.
524 if (!ClDataLayout.empty())
525 return ClDataLayout;
526 // If an explicit data layout is already defined in the IR, don't infer.
527 if (!IRLayout.empty())
528 return std::nullopt;
529
530 // If an explicit triple was specified (either in the IR or on the
531 // command line), use that to infer the default data layout. However, the
532 // command line target triple should override the IR file target triple.
533 std::string TripleStr =
534 TargetTriple.empty() ? IRTriple.str() : Triple::normalize(Str: TargetTriple);
535 // If the triple string is still empty, we don't fall back to
536 // sys::getDefaultTargetTriple() since we do not want to have differing
537 // behaviour dependent on the configured default triple. Therefore, if the
538 // user did not pass -mtriple or define an explicit triple/datalayout in
539 // the IR, we should default to an empty (default) DataLayout.
540 if (TripleStr.empty())
541 return std::nullopt;
542 // Otherwise we infer the DataLayout from the target machine.
543 Expected<std::unique_ptr<TargetMachine>> ExpectedTM =
544 codegen::createTargetMachineForTriple(TargetTriple: TripleStr, OptLevel: GetCodeGenOptLevel());
545 if (!ExpectedTM) {
546 errs() << argv[0] << ": warning: failed to infer data layout: "
547 << toString(E: ExpectedTM.takeError()) << "\n";
548 return std::nullopt;
549 }
550 return (*ExpectedTM)->createDataLayout().getStringRepresentation();
551 };
552 std::unique_ptr<Module> M;
553 if (NoUpgradeDebugInfo)
554 M = parseAssemblyFileWithIndexNoUpgradeDebugInfo(
555 Filename: InputFilename, Err, Context, Slots: nullptr, DataLayoutCallback: SetDataLayout)
556 .Mod;
557 else
558 M = parseIRFile(Filename: InputFilename, Err, Context,
559 Callbacks: ParserCallbacks(SetDataLayout));
560
561 if (!M) {
562 Err.print(ProgName: argv[0], S&: errs());
563 return 1;
564 }
565
566 // Strip debug info before running the verifier.
567 if (StripDebug)
568 StripDebugInfo(M&: *M);
569
570 // Erase module-level named metadata, if requested.
571 if (StripNamedMetadata) {
572 while (!M->named_metadata_empty()) {
573 NamedMDNode *NMD = &*M->named_metadata_begin();
574 M->eraseNamedMetadata(NMD);
575 }
576 }
577
578 // If we are supposed to override the target triple, do so now.
579 if (!TargetTriple.empty())
580 M->setTargetTriple(Triple::normalize(Str: TargetTriple));
581
582 // Immediately run the verifier to catch any problems before starting up the
583 // pass pipelines. Otherwise we can crash on broken code during
584 // doInitialization().
585 if (!NoVerify && verifyModule(M: *M, OS: &errs())) {
586 errs() << argv[0] << ": " << InputFilename
587 << ": error: input module is broken!\n";
588 return 1;
589 }
590
591 // Enable testing of whole program devirtualization on this module by invoking
592 // the facility for updating public visibility to linkage unit visibility when
593 // specified by an internal option. This is normally done during LTO which is
594 // not performed via opt.
595 updateVCallVisibilityInModule(
596 M&: *M,
597 /*WholeProgramVisibilityEnabledInLTO=*/false,
598 // FIXME: These need linker information via a
599 // TBD new interface.
600 /*DynamicExportSymbols=*/{},
601 /*ValidateAllVtablesHaveTypeInfos=*/false,
602 /*IsVisibleToRegularObj=*/[](StringRef) { return true; });
603
604 // Figure out what stream we are supposed to write to...
605 std::unique_ptr<ToolOutputFile> Out;
606 std::unique_ptr<ToolOutputFile> ThinLinkOut;
607 if (NoOutput) {
608 if (!OutputFilename.empty())
609 errs() << "WARNING: The -o (output filename) option is ignored when\n"
610 "the --disable-output option is used.\n";
611 } else {
612 // Default to standard output.
613 if (OutputFilename.empty())
614 OutputFilename = "-";
615
616 std::error_code EC;
617 sys::fs::OpenFlags Flags =
618 OutputAssembly ? sys::fs::OF_TextWithCRLF : sys::fs::OF_None;
619 Out.reset(p: new ToolOutputFile(OutputFilename, EC, Flags));
620 if (EC) {
621 errs() << EC.message() << '\n';
622 return 1;
623 }
624
625 if (!ThinLinkBitcodeFile.empty()) {
626 ThinLinkOut.reset(
627 p: new ToolOutputFile(ThinLinkBitcodeFile, EC, sys::fs::OF_None));
628 if (EC) {
629 errs() << EC.message() << '\n';
630 return 1;
631 }
632 }
633 }
634
635 Triple ModuleTriple(M->getTargetTriple());
636 std::string CPUStr, FeaturesStr;
637 std::unique_ptr<TargetMachine> TM;
638 if (ModuleTriple.getArch()) {
639 CPUStr = codegen::getCPUStr();
640 FeaturesStr = codegen::getFeaturesStr();
641 Expected<std::unique_ptr<TargetMachine>> ExpectedTM =
642 codegen::createTargetMachineForTriple(TargetTriple: ModuleTriple.str(),
643 OptLevel: GetCodeGenOptLevel());
644 if (auto E = ExpectedTM.takeError()) {
645 errs() << argv[0] << ": WARNING: failed to create target machine for '"
646 << ModuleTriple.str() << "': " << toString(E: std::move(E)) << "\n";
647 } else {
648 TM = std::move(*ExpectedTM);
649 }
650 } else if (ModuleTriple.getArchName() != "unknown" &&
651 ModuleTriple.getArchName() != "") {
652 errs() << argv[0] << ": unrecognized architecture '"
653 << ModuleTriple.getArchName() << "' provided.\n";
654 return 1;
655 }
656
657 // Override function attributes based on CPUStr, FeaturesStr, and command line
658 // flags.
659 codegen::setFunctionAttributes(CPU: CPUStr, Features: FeaturesStr, M&: *M);
660
661 // If the output is set to be emitted to standard out, and standard out is a
662 // console, print out a warning message and refuse to do it. We don't
663 // impress anyone by spewing tons of binary goo to a terminal.
664 if (!Force && !NoOutput && !OutputAssembly)
665 if (CheckBitcodeOutputToConsole(stream_to_check&: Out->os()))
666 NoOutput = true;
667
668 if (OutputThinLTOBC) {
669 M->addModuleFlag(Behavior: Module::Error, Key: "EnableSplitLTOUnit", Val: SplitLTOUnit);
670 if (UnifiedLTO)
671 M->addModuleFlag(Behavior: Module::Error, Key: "UnifiedLTO", Val: 1);
672 }
673
674 // Add an appropriate TargetLibraryInfo pass for the module's triple.
675 TargetLibraryInfoImpl TLII(ModuleTriple);
676
677 // The -disable-simplify-libcalls flag actually disables all builtin optzns.
678 if (DisableSimplifyLibCalls)
679 TLII.disableAllFunctions();
680 else {
681 // Disable individual builtin functions in TargetLibraryInfo.
682 LibFunc F;
683 for (auto &FuncName : DisableBuiltins)
684 if (TLII.getLibFunc(funcName: FuncName, F))
685 TLII.setUnavailable(F);
686 else {
687 errs() << argv[0] << ": cannot disable nonexistent builtin function "
688 << FuncName << '\n';
689 return 1;
690 }
691 }
692
693 if (UseNPM) {
694 if (legacy::debugPassSpecified()) {
695 errs() << "-debug-pass does not work with the new PM, either use "
696 "-debug-pass-manager, or use the legacy PM\n";
697 return 1;
698 }
699 auto NumOLevel = OptLevelO0 + OptLevelO1 + OptLevelO2 + OptLevelO3 +
700 OptLevelOs + OptLevelOz;
701 if (NumOLevel > 1) {
702 errs() << "Cannot specify multiple -O#\n";
703 return 1;
704 }
705 if (NumOLevel > 0 && (PassPipeline.getNumOccurrences() > 0)) {
706 errs() << "Cannot specify -O# and --passes=/--foo-pass, use "
707 "-passes='default<O#>,other-pass'\n";
708 return 1;
709 }
710 std::string Pipeline = PassPipeline;
711
712 if (OptLevelO0)
713 Pipeline = "default<O0>";
714 if (OptLevelO1)
715 Pipeline = "default<O1>";
716 if (OptLevelO2)
717 Pipeline = "default<O2>";
718 if (OptLevelO3)
719 Pipeline = "default<O3>";
720 if (OptLevelOs)
721 Pipeline = "default<Os>";
722 if (OptLevelOz)
723 Pipeline = "default<Oz>";
724 OutputKind OK = OK_NoOutput;
725 if (!NoOutput)
726 OK = OutputAssembly
727 ? OK_OutputAssembly
728 : (OutputThinLTOBC ? OK_OutputThinLTOBitcode : OK_OutputBitcode);
729
730 VerifierKind VK = VK_VerifyOut;
731 if (NoVerify)
732 VK = VK_NoVerifier;
733 else if (VerifyEach)
734 VK = VK_VerifyEachPass;
735
736 // The user has asked to use the new pass manager and provided a pipeline
737 // string. Hand off the rest of the functionality to the new code for that
738 // layer.
739 return runPassPipeline(
740 Arg0: argv[0], M&: *M, TM: TM.get(), TLII: &TLII, Out: Out.get(), ThinLinkOut: ThinLinkOut.get(),
741 OptRemarkFile: RemarksFile.get(), PassPipeline: Pipeline, PassPlugins: PluginList, PassBuilderCallbacks,
742 OK, VK, ShouldPreserveAssemblyUseListOrder: PreserveAssemblyUseListOrder,
743 ShouldPreserveBitcodeUseListOrder: PreserveBitcodeUseListOrder, EmitSummaryIndex, EmitModuleHash,
744 EnableDebugify, VerifyDIPreserve: VerifyDebugInfoPreserve, UnifiedLTO)
745 ? 0
746 : 1;
747 }
748
749 if (OptLevelO0 || OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz ||
750 OptLevelO3) {
751 errs() << "Cannot use -O# with legacy PM.\n";
752 return 1;
753 }
754 if (EmitSummaryIndex) {
755 errs() << "Cannot use -module-summary with legacy PM.\n";
756 return 1;
757 }
758 if (EmitModuleHash) {
759 errs() << "Cannot use -module-hash with legacy PM.\n";
760 return 1;
761 }
762 if (OutputThinLTOBC) {
763 errs() << "Cannot use -thinlto-bc with legacy PM.\n";
764 return 1;
765 }
766 // Create a PassManager to hold and optimize the collection of passes we are
767 // about to build. If the -debugify-each option is set, wrap each pass with
768 // the (-check)-debugify passes.
769 DebugifyCustomPassManager Passes;
770 DebugifyStatsMap DIStatsMap;
771 DebugInfoPerPass DebugInfoBeforePass;
772 if (DebugifyEach) {
773 Passes.setDebugifyMode(DebugifyMode::SyntheticDebugInfo);
774 Passes.setDIStatsMap(DIStatsMap);
775 } else if (VerifyEachDebugInfoPreserve) {
776 Passes.setDebugifyMode(DebugifyMode::OriginalDebugInfo);
777 Passes.setDebugInfoBeforePass(DebugInfoBeforePass);
778 if (!VerifyDIPreserveExport.empty())
779 Passes.setOrigDIVerifyBugsReportFilePath(VerifyDIPreserveExport);
780 }
781
782 bool AddOneTimeDebugifyPasses =
783 (EnableDebugify && !DebugifyEach) ||
784 (VerifyDebugInfoPreserve && !VerifyEachDebugInfoPreserve);
785
786 Passes.add(P: new TargetLibraryInfoWrapperPass(TLII));
787
788 // Add internal analysis passes from the target machine.
789 Passes.add(P: createTargetTransformInfoWrapperPass(TIRA: TM ? TM->getTargetIRAnalysis()
790 : TargetIRAnalysis()));
791
792 if (AddOneTimeDebugifyPasses) {
793 if (EnableDebugify) {
794 Passes.setDIStatsMap(DIStatsMap);
795 Passes.add(P: createDebugifyModulePass());
796 } else if (VerifyDebugInfoPreserve) {
797 Passes.setDebugInfoBeforePass(DebugInfoBeforePass);
798 Passes.add(P: createDebugifyModulePass(Mode: DebugifyMode::OriginalDebugInfo, NameOfWrappedPass: "",
799 DebugInfoBeforePass: &(Passes.getDebugInfoPerPass())));
800 }
801 }
802
803 if (TM) {
804 // FIXME: We should dyn_cast this when supported.
805 auto &LTM = static_cast<LLVMTargetMachine &>(*TM);
806 Pass *TPC = LTM.createPassConfig(PM&: Passes);
807 Passes.add(P: TPC);
808 }
809
810 // Create a new optimization pass for each one specified on the command line
811 for (unsigned i = 0; i < PassList.size(); ++i) {
812 const PassInfo *PassInf = PassList[i];
813 if (PassInf->getNormalCtor()) {
814 Pass *P = PassInf->getNormalCtor()();
815 if (P) {
816 // Add the pass to the pass manager.
817 Passes.add(P);
818 // If we are verifying all of the intermediate steps, add the verifier.
819 if (VerifyEach)
820 Passes.add(P: createVerifierPass());
821 }
822 } else
823 errs() << argv[0] << ": cannot create pass: " << PassInf->getPassName()
824 << "\n";
825 }
826
827 // Check that the module is well formed on completion of optimization
828 if (!NoVerify && !VerifyEach)
829 Passes.add(P: createVerifierPass());
830
831 if (AddOneTimeDebugifyPasses) {
832 if (EnableDebugify)
833 Passes.add(P: createCheckDebugifyModulePass(Strip: false));
834 else if (VerifyDebugInfoPreserve) {
835 if (!VerifyDIPreserveExport.empty())
836 Passes.setOrigDIVerifyBugsReportFilePath(VerifyDIPreserveExport);
837 Passes.add(P: createCheckDebugifyModulePass(
838 Strip: false, NameOfWrappedPass: "", StatsMap: nullptr, Mode: DebugifyMode::OriginalDebugInfo,
839 DebugInfoBeforePass: &(Passes.getDebugInfoPerPass()), OrigDIVerifyBugsReportFilePath: VerifyDIPreserveExport));
840 }
841 }
842
843 // In run twice mode, we want to make sure the output is bit-by-bit
844 // equivalent if we run the pass manager again, so setup two buffers and
845 // a stream to write to them. Note that llc does something similar and it
846 // may be worth to abstract this out in the future.
847 SmallVector<char, 0> Buffer;
848 SmallVector<char, 0> FirstRunBuffer;
849 std::unique_ptr<raw_svector_ostream> BOS;
850 raw_ostream *OS = nullptr;
851
852 const bool ShouldEmitOutput = !NoOutput;
853
854 // Write bitcode or assembly to the output as the last step...
855 if (ShouldEmitOutput || RunTwice) {
856 assert(Out);
857 OS = &Out->os();
858 if (RunTwice) {
859 BOS = std::make_unique<raw_svector_ostream>(args&: Buffer);
860 OS = BOS.get();
861 }
862 if (OutputAssembly)
863 Passes.add(P: createPrintModulePass(OS&: *OS, Banner: "", ShouldPreserveUseListOrder: PreserveAssemblyUseListOrder));
864 else
865 Passes.add(P: createBitcodeWriterPass(Str&: *OS, ShouldPreserveUseListOrder: PreserveBitcodeUseListOrder));
866 }
867
868 // Before executing passes, print the final values of the LLVM options.
869 cl::PrintOptionValues();
870
871 if (!RunTwice) {
872 // Now that we have all of the passes ready, run them.
873 Passes.run(M&: *M);
874 } else {
875 // If requested, run all passes twice with the same pass manager to catch
876 // bugs caused by persistent state in the passes.
877 std::unique_ptr<Module> M2(CloneModule(M: *M));
878 // Run all passes on the original module first, so the second run processes
879 // the clone to catch CloneModule bugs.
880 Passes.run(M&: *M);
881 FirstRunBuffer = Buffer;
882 Buffer.clear();
883
884 Passes.run(M&: *M2);
885
886 // Compare the two outputs and make sure they're the same
887 assert(Out);
888 if (Buffer.size() != FirstRunBuffer.size() ||
889 (memcmp(s1: Buffer.data(), s2: FirstRunBuffer.data(), n: Buffer.size()) != 0)) {
890 errs()
891 << "Running the pass manager twice changed the output.\n"
892 "Writing the result of the second run to the specified output.\n"
893 "To generate the one-run comparison binary, just run without\n"
894 "the compile-twice option\n";
895 if (ShouldEmitOutput) {
896 Out->os() << BOS->str();
897 Out->keep();
898 }
899 if (RemarksFile)
900 RemarksFile->keep();
901 return 1;
902 }
903 if (ShouldEmitOutput)
904 Out->os() << BOS->str();
905 }
906
907 if (DebugifyEach && !DebugifyExport.empty())
908 exportDebugifyStats(Path: DebugifyExport, Map: Passes.getDebugifyStatsMap());
909
910 // Declare success.
911 if (!NoOutput)
912 Out->keep();
913
914 if (RemarksFile)
915 RemarksFile->keep();
916
917 if (ThinLinkOut)
918 ThinLinkOut->keep();
919
920 return 0;
921}
922