Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / tools / llc / llc.cpp
blob0b174afc22ddced0ffac3394974d8bd56a4834a7
1 //===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
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 // This is the llc code generator driver. It provides a convenient
10 // command-line interface for generating native assembly-language code
11 // or C code, given LLVM bitcode.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/ScopeExit.h"
17 #include "llvm/Analysis/TargetLibraryInfo.h"
18 #include "llvm/CodeGen/CommandFlags.h"
19 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
20 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
21 #include "llvm/CodeGen/MIRParser/MIRParser.h"
22 #include "llvm/CodeGen/MachineFunctionPass.h"
23 #include "llvm/CodeGen/MachineModuleInfo.h"
24 #include "llvm/CodeGen/TargetPassConfig.h"
25 #include "llvm/CodeGen/TargetSubtargetInfo.h"
26 #include "llvm/IR/AutoUpgrade.h"
27 #include "llvm/IR/DataLayout.h"
28 #include "llvm/IR/DiagnosticInfo.h"
29 #include "llvm/IR/DiagnosticPrinter.h"
30 #include "llvm/IR/LLVMContext.h"
31 #include "llvm/IR/LLVMRemarkStreamer.h"
32 #include "llvm/IR/LegacyPassManager.h"
33 #include "llvm/IR/Module.h"
34 #include "llvm/IR/Verifier.h"
35 #include "llvm/IRReader/IRReader.h"
36 #include "llvm/InitializePasses.h"
37 #include "llvm/MC/MCTargetOptionsCommandFlags.h"
38 #include "llvm/MC/TargetRegistry.h"
39 #include "llvm/Pass.h"
40 #include "llvm/Remarks/HotnessThresholdParser.h"
41 #include "llvm/Support/CommandLine.h"
42 #include "llvm/Support/Debug.h"
43 #include "llvm/Support/FileSystem.h"
44 #include "llvm/Support/FormattedStream.h"
45 #include "llvm/Support/InitLLVM.h"
46 #include "llvm/Support/PluginLoader.h"
47 #include "llvm/Support/SourceMgr.h"
48 #include "llvm/Support/TargetSelect.h"
49 #include "llvm/Support/TimeProfiler.h"
50 #include "llvm/Support/ToolOutputFile.h"
51 #include "llvm/Support/WithColor.h"
52 #include "llvm/Target/TargetLoweringObjectFile.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/Utils/Cloning.h"
58 #include <memory>
59 #include <optional>
60 using namespace llvm;
62 static codegen::RegisterCodeGenFlags CGF;
64 // General options for llc. Other pass-specific options are specified
65 // within the corresponding llc passes, and target-specific options
66 // and back-end code generation options are specified with the target machine.
68 static cl::opt<std::string>
69 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
71 static cl::opt<std::string>
72 InputLanguage("x", cl::desc("Input language ('ir' or 'mir')"));
74 static cl::opt<std::string>
75 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
77 static cl::opt<std::string>
78 SplitDwarfOutputFile("split-dwarf-output",
79 cl::desc(".dwo output filename"),
80 cl::value_desc("filename"));
82 static cl::opt<unsigned>
83 TimeCompilations("time-compilations", cl::Hidden, cl::init(1u),
84 cl::value_desc("N"),
85 cl::desc("Repeat compilation N times for timing"));
87 static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));
89 static cl::opt<unsigned> TimeTraceGranularity(
90 "time-trace-granularity",
91 cl::desc(
92 "Minimum time granularity (in microseconds) traced by time profiler"),
93 cl::init(500), cl::Hidden);
95 static cl::opt<std::string>
96 TimeTraceFile("time-trace-file",
97 cl::desc("Specify time trace file destination"),
98 cl::value_desc("filename"));
100 static cl::opt<std::string>
101 BinutilsVersion("binutils-version", cl::Hidden,
102 cl::desc("Produced object files can use all ELF features "
103 "supported by this binutils version and newer."
104 "If -no-integrated-as is specified, the generated "
105 "assembly will consider GNU as support."
106 "'none' means that all ELF features can be used, "
107 "regardless of binutils support"));
109 static cl::opt<bool>
110 PreserveComments("preserve-as-comments", cl::Hidden,
111 cl::desc("Preserve Comments in outputted assembly"),
112 cl::init(true));
114 // Determine optimization level.
115 static cl::opt<char>
116 OptLevel("O",
117 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
118 "(default = '-O2')"),
119 cl::Prefix, cl::init('2'));
121 static cl::opt<std::string>
122 TargetTriple("mtriple", cl::desc("Override target triple for module"));
124 static cl::opt<std::string> SplitDwarfFile(
125 "split-dwarf-file",
126 cl::desc(
127 "Specify the name of the .dwo file to encode in the DWARF output"));
129 static cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
130 cl::desc("Do not verify input module"));
132 static cl::opt<bool> DisableSimplifyLibCalls("disable-simplify-libcalls",
133 cl::desc("Disable simplify-libcalls"));
135 static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden,
136 cl::desc("Show encoding in .s output"));
138 static cl::opt<bool>
139 DwarfDirectory("dwarf-directory", cl::Hidden,
140 cl::desc("Use .file directives with an explicit directory"),
141 cl::init(true));
143 static cl::opt<bool> AsmVerbose("asm-verbose",
144 cl::desc("Add comments to directives."),
145 cl::init(true));
147 static cl::opt<bool>
148 CompileTwice("compile-twice", cl::Hidden,
149 cl::desc("Run everything twice, re-using the same pass "
150 "manager and verify the result is the same."),
151 cl::init(false));
153 static cl::opt<bool> DiscardValueNames(
154 "discard-value-names",
155 cl::desc("Discard names from Value (other than GlobalValue)."),
156 cl::init(false), cl::Hidden);
158 static cl::list<std::string> IncludeDirs("I", cl::desc("include search path"));
160 static cl::opt<bool> RemarksWithHotness(
161 "pass-remarks-with-hotness",
162 cl::desc("With PGO, include profile count in optimization remarks"),
163 cl::Hidden);
165 static cl::opt<std::optional<uint64_t>, false, remarks::HotnessThresholdParser>
166 RemarksHotnessThreshold(
167 "pass-remarks-hotness-threshold",
168 cl::desc("Minimum profile count required for "
169 "an optimization remark to be output. "
170 "Use 'auto' to apply the threshold from profile summary."),
171 cl::value_desc("N or 'auto'"), cl::init(0), cl::Hidden);
173 static cl::opt<std::string>
174 RemarksFilename("pass-remarks-output",
175 cl::desc("Output filename for pass remarks"),
176 cl::value_desc("filename"));
178 static cl::opt<std::string>
179 RemarksPasses("pass-remarks-filter",
180 cl::desc("Only record optimization remarks from passes whose "
181 "names match the given regular expression"),
182 cl::value_desc("regex"));
184 static cl::opt<std::string> RemarksFormat(
185 "pass-remarks-format",
186 cl::desc("The format used for serializing remarks (default: YAML)"),
187 cl::value_desc("format"), cl::init("yaml"));
189 namespace {
191 std::vector<std::string> &getRunPassNames() {
192 static std::vector<std::string> RunPassNames;
193 return RunPassNames;
196 struct RunPassOption {
197 void operator=(const std::string &Val) const {
198 if (Val.empty())
199 return;
200 SmallVector<StringRef, 8> PassNames;
201 StringRef(Val).split(PassNames, ',', -1, false);
202 for (auto PassName : PassNames)
203 getRunPassNames().push_back(std::string(PassName));
208 static RunPassOption RunPassOpt;
210 static cl::opt<RunPassOption, true, cl::parser<std::string>> RunPass(
211 "run-pass",
212 cl::desc("Run compiler only for specified passes (comma separated list)"),
213 cl::value_desc("pass-name"), cl::location(RunPassOpt));
215 static int compileModule(char **, LLVMContext &);
217 [[noreturn]] static void reportError(Twine Msg, StringRef Filename = "") {
218 SmallString<256> Prefix;
219 if (!Filename.empty()) {
220 if (Filename == "-")
221 Filename = "<stdin>";
222 ("'" + Twine(Filename) + "': ").toStringRef(Prefix);
224 WithColor::error(errs(), "llc") << Prefix << Msg << "\n";
225 exit(1);
228 [[noreturn]] static void reportError(Error Err, StringRef Filename) {
229 assert(Err);
230 handleAllErrors(createFileError(Filename, std::move(Err)),
231 [&](const ErrorInfoBase &EI) { reportError(EI.message()); });
232 llvm_unreachable("reportError() should not return");
235 static std::unique_ptr<ToolOutputFile> GetOutputStream(const char *TargetName,
236 Triple::OSType OS,
237 const char *ProgName) {
238 // If we don't yet have an output filename, make one.
239 if (OutputFilename.empty()) {
240 if (InputFilename == "-")
241 OutputFilename = "-";
242 else {
243 // If InputFilename ends in .bc or .ll, remove it.
244 StringRef IFN = InputFilename;
245 if (IFN.endswith(".bc") || IFN.endswith(".ll"))
246 OutputFilename = std::string(IFN.drop_back(3));
247 else if (IFN.endswith(".mir"))
248 OutputFilename = std::string(IFN.drop_back(4));
249 else
250 OutputFilename = std::string(IFN);
252 switch (codegen::getFileType()) {
253 case CodeGenFileType::AssemblyFile:
254 if (TargetName[0] == 'c') {
255 if (TargetName[1] == 0)
256 OutputFilename += ".cbe.c";
257 else if (TargetName[1] == 'p' && TargetName[2] == 'p')
258 OutputFilename += ".cpp";
259 else
260 OutputFilename += ".s";
261 } else
262 OutputFilename += ".s";
263 break;
264 case CodeGenFileType::ObjectFile:
265 if (OS == Triple::Win32)
266 OutputFilename += ".obj";
267 else
268 OutputFilename += ".o";
269 break;
270 case CodeGenFileType::Null:
271 OutputFilename = "-";
272 break;
277 // Decide if we need "binary" output.
278 bool Binary = false;
279 switch (codegen::getFileType()) {
280 case CodeGenFileType::AssemblyFile:
281 break;
282 case CodeGenFileType::ObjectFile:
283 case CodeGenFileType::Null:
284 Binary = true;
285 break;
288 // Open the file.
289 std::error_code EC;
290 sys::fs::OpenFlags OpenFlags = sys::fs::OF_None;
291 if (!Binary)
292 OpenFlags |= sys::fs::OF_TextWithCRLF;
293 auto FDOut = std::make_unique<ToolOutputFile>(OutputFilename, EC, OpenFlags);
294 if (EC) {
295 reportError(EC.message());
296 return nullptr;
299 return FDOut;
302 struct LLCDiagnosticHandler : public DiagnosticHandler {
303 bool *HasError;
304 LLCDiagnosticHandler(bool *HasErrorPtr) : HasError(HasErrorPtr) {}
305 bool handleDiagnostics(const DiagnosticInfo &DI) override {
306 if (DI.getKind() == llvm::DK_SrcMgr) {
307 const auto &DISM = cast<DiagnosticInfoSrcMgr>(DI);
308 const SMDiagnostic &SMD = DISM.getSMDiag();
310 if (SMD.getKind() == SourceMgr::DK_Error)
311 *HasError = true;
313 SMD.print(nullptr, errs());
315 // For testing purposes, we print the LocCookie here.
316 if (DISM.isInlineAsmDiag() && DISM.getLocCookie())
317 WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";
319 return true;
322 if (DI.getSeverity() == DS_Error)
323 *HasError = true;
325 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
326 if (!Remark->isEnabled())
327 return true;
329 DiagnosticPrinterRawOStream DP(errs());
330 errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
331 DI.print(DP);
332 errs() << "\n";
333 return true;
337 // main - Entry point for the llc compiler.
339 int main(int argc, char **argv) {
340 InitLLVM X(argc, argv);
342 // Enable debug stream buffering.
343 EnableDebugBuffering = true;
345 // Initialize targets first, so that --version shows registered targets.
346 InitializeAllTargets();
347 InitializeAllTargetMCs();
348 InitializeAllAsmPrinters();
349 InitializeAllAsmParsers();
351 // Initialize codegen and IR passes used by llc so that the -print-after,
352 // -print-before, and -stop-after options work.
353 PassRegistry *Registry = PassRegistry::getPassRegistry();
354 initializeCore(*Registry);
355 initializeCodeGen(*Registry);
356 initializeLoopStrengthReducePass(*Registry);
357 initializeLowerIntrinsicsPass(*Registry);
358 initializeUnreachableBlockElimLegacyPassPass(*Registry);
359 initializeConstantHoistingLegacyPassPass(*Registry);
360 initializeScalarOpts(*Registry);
361 initializeVectorization(*Registry);
362 initializeScalarizeMaskedMemIntrinLegacyPassPass(*Registry);
363 initializeExpandReductionsPass(*Registry);
364 initializeExpandVectorPredicationPass(*Registry);
365 initializeHardwareLoopsLegacyPass(*Registry);
366 initializeTransformUtils(*Registry);
367 initializeReplaceWithVeclibLegacyPass(*Registry);
368 initializeTLSVariableHoistLegacyPassPass(*Registry);
370 // Initialize debugging passes.
371 initializeScavengerTestPass(*Registry);
373 // Register the Target and CPU printer for --version.
374 cl::AddExtraVersionPrinter(sys::printDefaultTargetAndDetectedCPU);
375 // Register the target printer for --version.
376 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
378 cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
380 if (TimeTrace)
381 timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]);
382 auto TimeTraceScopeExit = make_scope_exit([]() {
383 if (TimeTrace) {
384 if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
385 handleAllErrors(std::move(E), [&](const StringError &SE) {
386 errs() << SE.getMessage() << "\n";
388 return;
390 timeTraceProfilerCleanup();
394 LLVMContext Context;
395 Context.setDiscardValueNames(DiscardValueNames);
397 // Set a diagnostic handler that doesn't exit on the first error
398 bool HasError = false;
399 Context.setDiagnosticHandler(
400 std::make_unique<LLCDiagnosticHandler>(&HasError));
402 Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =
403 setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,
404 RemarksFormat, RemarksWithHotness,
405 RemarksHotnessThreshold);
406 if (Error E = RemarksFileOrErr.takeError())
407 reportError(std::move(E), RemarksFilename);
408 std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr);
410 if (InputLanguage != "" && InputLanguage != "ir" && InputLanguage != "mir")
411 reportError("input language must be '', 'IR' or 'MIR'");
413 // Compile the module TimeCompilations times to give better compile time
414 // metrics.
415 for (unsigned I = TimeCompilations; I; --I)
416 if (int RetVal = compileModule(argv, Context))
417 return RetVal;
419 if (RemarksFile)
420 RemarksFile->keep();
421 return 0;
424 static bool addPass(PassManagerBase &PM, const char *argv0,
425 StringRef PassName, TargetPassConfig &TPC) {
426 if (PassName == "none")
427 return false;
429 const PassRegistry *PR = PassRegistry::getPassRegistry();
430 const PassInfo *PI = PR->getPassInfo(PassName);
431 if (!PI) {
432 WithColor::error(errs(), argv0)
433 << "run-pass " << PassName << " is not registered.\n";
434 return true;
437 Pass *P;
438 if (PI->getNormalCtor())
439 P = PI->getNormalCtor()();
440 else {
441 WithColor::error(errs(), argv0)
442 << "cannot create pass: " << PI->getPassName() << "\n";
443 return true;
445 std::string Banner = std::string("After ") + std::string(P->getPassName());
446 TPC.addMachinePrePasses();
447 PM.add(P);
448 TPC.addMachinePostPasses(Banner);
450 return false;
453 static int compileModule(char **argv, LLVMContext &Context) {
454 // Load the module to be compiled...
455 SMDiagnostic Err;
456 std::unique_ptr<Module> M;
457 std::unique_ptr<MIRParser> MIR;
458 Triple TheTriple;
459 std::string CPUStr = codegen::getCPUStr(),
460 FeaturesStr = codegen::getFeaturesStr();
462 // Set attributes on functions as loaded from MIR from command line arguments.
463 auto setMIRFunctionAttributes = [&CPUStr, &FeaturesStr](Function &F) {
464 codegen::setFunctionAttributes(CPUStr, FeaturesStr, F);
467 auto MAttrs = codegen::getMAttrs();
468 bool SkipModule =
469 CPUStr == "help" || (!MAttrs.empty() && MAttrs.front() == "help");
471 CodeGenOptLevel OLvl;
472 if (auto Level = CodeGenOpt::parseLevel(OptLevel)) {
473 OLvl = *Level;
474 } else {
475 WithColor::error(errs(), argv[0]) << "invalid optimization level.\n";
476 return 1;
479 // Parse 'none' or '$major.$minor'. Disallow -binutils-version=0 because we
480 // use that to indicate the MC default.
481 if (!BinutilsVersion.empty() && BinutilsVersion != "none") {
482 StringRef V = BinutilsVersion.getValue();
483 unsigned Num;
484 if (V.consumeInteger(10, Num) || Num == 0 ||
485 !(V.empty() ||
486 (V.consume_front(".") && !V.consumeInteger(10, Num) && V.empty()))) {
487 WithColor::error(errs(), argv[0])
488 << "invalid -binutils-version, accepting 'none' or major.minor\n";
489 return 1;
492 TargetOptions Options;
493 auto InitializeOptions = [&](const Triple &TheTriple) {
494 Options = codegen::InitTargetOptionsFromCodeGenFlags(TheTriple);
496 if (Options.XCOFFReadOnlyPointers) {
497 if (!TheTriple.isOSAIX())
498 reportError("-mxcoff-roptr option is only supported on AIX",
499 InputFilename);
501 // Since the storage mapping class is specified per csect,
502 // without using data sections, it is less effective to use read-only
503 // pointers. Using read-only pointers may cause other RO variables in the
504 // same csect to become RW when the linker acts upon `-bforceimprw`;
505 // therefore, we require that separate data sections are used in the
506 // presence of ReadOnlyPointers. We respect the setting of data-sections
507 // since we have not found reasons to do otherwise that overcome the user
508 // surprise of not respecting the setting.
509 if (!Options.DataSections)
510 reportError("-mxcoff-roptr option must be used with -data-sections",
511 InputFilename);
514 Options.BinutilsVersion =
515 TargetMachine::parseBinutilsVersion(BinutilsVersion);
516 Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
517 Options.MCOptions.AsmVerbose = AsmVerbose;
518 Options.MCOptions.PreserveAsmComments = PreserveComments;
519 Options.MCOptions.IASSearchPaths = IncludeDirs;
520 Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
521 if (DwarfDirectory.getPosition()) {
522 Options.MCOptions.MCUseDwarfDirectory =
523 DwarfDirectory ? MCTargetOptions::EnableDwarfDirectory
524 : MCTargetOptions::DisableDwarfDirectory;
525 } else {
526 // -dwarf-directory is not set explicitly. Some assemblers
527 // (e.g. GNU as or ptxas) do not support `.file directory'
528 // syntax prior to DWARFv5. Let the target decide the default
529 // value.
530 Options.MCOptions.MCUseDwarfDirectory =
531 MCTargetOptions::DefaultDwarfDirectory;
535 std::optional<Reloc::Model> RM = codegen::getExplicitRelocModel();
536 std::optional<CodeModel::Model> CM = codegen::getExplicitCodeModel();
538 const Target *TheTarget = nullptr;
539 std::unique_ptr<TargetMachine> Target;
541 // If user just wants to list available options, skip module loading
542 if (!SkipModule) {
543 auto SetDataLayout = [&](StringRef DataLayoutTargetTriple,
544 StringRef OldDLStr) -> std::optional<std::string> {
545 // If we are supposed to override the target triple, do so now.
546 std::string IRTargetTriple = DataLayoutTargetTriple.str();
547 if (!TargetTriple.empty())
548 IRTargetTriple = Triple::normalize(TargetTriple);
549 TheTriple = Triple(IRTargetTriple);
550 if (TheTriple.getTriple().empty())
551 TheTriple.setTriple(sys::getDefaultTargetTriple());
553 std::string Error;
554 TheTarget =
555 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
556 if (!TheTarget) {
557 WithColor::error(errs(), argv[0]) << Error;
558 exit(1);
561 InitializeOptions(TheTriple);
562 Target = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
563 TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, CM, OLvl));
564 assert(Target && "Could not allocate target machine!");
566 return Target->createDataLayout().getStringRepresentation();
568 if (InputLanguage == "mir" ||
569 (InputLanguage == "" && StringRef(InputFilename).endswith(".mir"))) {
570 MIR = createMIRParserFromFile(InputFilename, Err, Context,
571 setMIRFunctionAttributes);
572 if (MIR)
573 M = MIR->parseIRModule(SetDataLayout);
574 } else {
575 M = parseIRFile(InputFilename, Err, Context,
576 ParserCallbacks(SetDataLayout));
578 if (!M) {
579 Err.print(argv[0], WithColor::error(errs(), argv[0]));
580 return 1;
582 if (!TargetTriple.empty())
583 M->setTargetTriple(Triple::normalize(TargetTriple));
585 std::optional<CodeModel::Model> CM_IR = M->getCodeModel();
586 if (!CM && CM_IR)
587 Target->setCodeModel(*CM_IR);
588 if (std::optional<uint64_t> LDT = codegen::getExplicitLargeDataThreshold())
589 Target->setLargeDataThreshold(*LDT);
590 } else {
591 TheTriple = Triple(Triple::normalize(TargetTriple));
592 if (TheTriple.getTriple().empty())
593 TheTriple.setTriple(sys::getDefaultTargetTriple());
595 // Get the target specific parser.
596 std::string Error;
597 TheTarget =
598 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error);
599 if (!TheTarget) {
600 WithColor::error(errs(), argv[0]) << Error;
601 return 1;
604 InitializeOptions(TheTriple);
605 Target = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine(
606 TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, CM, OLvl));
607 assert(Target && "Could not allocate target machine!");
609 // If we don't have a module then just exit now. We do this down
610 // here since the CPU/Feature help is underneath the target machine
611 // creation.
612 return 0;
615 assert(M && "Should have exited if we didn't have a module!");
616 if (codegen::getFloatABIForCalls() != FloatABI::Default)
617 Options.FloatABIType = codegen::getFloatABIForCalls();
619 // Figure out where we are going to send the output.
620 std::unique_ptr<ToolOutputFile> Out =
621 GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]);
622 if (!Out) return 1;
624 // Ensure the filename is passed down to CodeViewDebug.
625 Target->Options.ObjectFilenameForDebug = Out->outputFilename();
627 std::unique_ptr<ToolOutputFile> DwoOut;
628 if (!SplitDwarfOutputFile.empty()) {
629 std::error_code EC;
630 DwoOut = std::make_unique<ToolOutputFile>(SplitDwarfOutputFile, EC,
631 sys::fs::OF_None);
632 if (EC)
633 reportError(EC.message(), SplitDwarfOutputFile);
636 // Build up all of the passes that we want to do to the module.
637 legacy::PassManager PM;
639 // Add an appropriate TargetLibraryInfo pass for the module's triple.
640 TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple()));
642 // The -disable-simplify-libcalls flag actually disables all builtin optzns.
643 if (DisableSimplifyLibCalls)
644 TLII.disableAllFunctions();
645 PM.add(new TargetLibraryInfoWrapperPass(TLII));
647 // Verify module immediately to catch problems before doInitialization() is
648 // called on any passes.
649 if (!NoVerify && verifyModule(*M, &errs()))
650 reportError("input module cannot be verified", InputFilename);
652 // Override function attributes based on CPUStr, FeaturesStr, and command line
653 // flags.
654 codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M);
656 if (mc::getExplicitRelaxAll() &&
657 codegen::getFileType() != CodeGenFileType::ObjectFile)
658 WithColor::warning(errs(), argv[0])
659 << ": warning: ignoring -mc-relax-all because filetype != obj";
662 raw_pwrite_stream *OS = &Out->os();
664 // Manually do the buffering rather than using buffer_ostream,
665 // so we can memcmp the contents in CompileTwice mode
666 SmallVector<char, 0> Buffer;
667 std::unique_ptr<raw_svector_ostream> BOS;
668 if ((codegen::getFileType() != CodeGenFileType::AssemblyFile &&
669 !Out->os().supportsSeeking()) ||
670 CompileTwice) {
671 BOS = std::make_unique<raw_svector_ostream>(Buffer);
672 OS = BOS.get();
675 const char *argv0 = argv[0];
676 LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine &>(*Target);
677 MachineModuleInfoWrapperPass *MMIWP =
678 new MachineModuleInfoWrapperPass(&LLVMTM);
680 // Construct a custom pass pipeline that starts after instruction
681 // selection.
682 if (!getRunPassNames().empty()) {
683 if (!MIR) {
684 WithColor::warning(errs(), argv[0])
685 << "run-pass is for .mir file only.\n";
686 delete MMIWP;
687 return 1;
689 TargetPassConfig *PTPC = LLVMTM.createPassConfig(PM);
690 TargetPassConfig &TPC = *PTPC;
691 if (TPC.hasLimitedCodeGenPipeline()) {
692 WithColor::warning(errs(), argv[0])
693 << "run-pass cannot be used with "
694 << TPC.getLimitedCodeGenPipelineReason(" and ") << ".\n";
695 delete PTPC;
696 delete MMIWP;
697 return 1;
700 TPC.setDisableVerify(NoVerify);
701 PM.add(&TPC);
702 PM.add(MMIWP);
703 TPC.printAndVerify("");
704 for (const std::string &RunPassName : getRunPassNames()) {
705 if (addPass(PM, argv0, RunPassName, TPC))
706 return 1;
708 TPC.setInitialized();
709 PM.add(createPrintMIRPass(*OS));
710 PM.add(createFreeMachineFunctionPass());
711 } else if (Target->addPassesToEmitFile(
712 PM, *OS, DwoOut ? &DwoOut->os() : nullptr,
713 codegen::getFileType(), NoVerify, MMIWP)) {
714 reportError("target does not support generation of this file type");
717 const_cast<TargetLoweringObjectFile *>(LLVMTM.getObjFileLowering())
718 ->Initialize(MMIWP->getMMI().getContext(), *Target);
719 if (MIR) {
720 assert(MMIWP && "Forgot to create MMIWP?");
721 if (MIR->parseMachineFunctions(*M, MMIWP->getMMI()))
722 return 1;
725 // Before executing passes, print the final values of the LLVM options.
726 cl::PrintOptionValues();
728 // If requested, run the pass manager over the same module again,
729 // to catch any bugs due to persistent state in the passes. Note that
730 // opt has the same functionality, so it may be worth abstracting this out
731 // in the future.
732 SmallVector<char, 0> CompileTwiceBuffer;
733 if (CompileTwice) {
734 std::unique_ptr<Module> M2(llvm::CloneModule(*M));
735 PM.run(*M2);
736 CompileTwiceBuffer = Buffer;
737 Buffer.clear();
740 PM.run(*M);
742 auto HasError =
743 ((const LLCDiagnosticHandler *)(Context.getDiagHandlerPtr()))->HasError;
744 if (*HasError)
745 return 1;
747 // Compare the two outputs and make sure they're the same
748 if (CompileTwice) {
749 if (Buffer.size() != CompileTwiceBuffer.size() ||
750 (memcmp(Buffer.data(), CompileTwiceBuffer.data(), Buffer.size()) !=
751 0)) {
752 errs()
753 << "Running the pass manager twice changed the output.\n"
754 "Writing the result of the second run to the specified output\n"
755 "To generate the one-run comparison binary, just run without\n"
756 "the compile-twice option\n";
757 Out->os() << Buffer;
758 Out->keep();
759 return 1;
763 if (BOS) {
764 Out->os() << Buffer;
768 // Declare success.
769 Out->keep();
770 if (DwoOut)
771 DwoOut->keep();
773 return 0;