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. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/ADT/STLExtras.h" 16 #include "llvm/ADT/Triple.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/IRPrintingPasses.h" 31 #include "llvm/IR/LLVMContext.h" 32 #include "llvm/IR/LLVMRemarkStreamer.h" 33 #include "llvm/IR/LegacyPassManager.h" 34 #include "llvm/IR/Module.h" 35 #include "llvm/IR/Verifier.h" 36 #include "llvm/IRReader/IRReader.h" 37 #include "llvm/InitializePasses.h" 38 #include "llvm/MC/SubtargetFeature.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/Host.h" 46 #include "llvm/Support/InitLLVM.h" 47 #include "llvm/Support/ManagedStatic.h" 48 #include "llvm/Support/PluginLoader.h" 49 #include "llvm/Support/SourceMgr.h" 50 #include "llvm/Support/TargetRegistry.h" 51 #include "llvm/Support/TargetSelect.h" 52 #include "llvm/Support/ToolOutputFile.h" 53 #include "llvm/Support/WithColor.h" 54 #include "llvm/Target/TargetLoweringObjectFile.h" 55 #include "llvm/Target/TargetMachine.h" 56 #include "llvm/Transforms/Utils/Cloning.h" 57 #include <memory> 58 using namespace llvm; 59 60 static codegen::RegisterCodeGenFlags CGF; 61 62 // General options for llc. Other pass-specific options are specified 63 // within the corresponding llc passes, and target-specific options 64 // and back-end code generation options are specified with the target machine. 65 // 66 static cl::opt<std::string> 67 InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 68 69 static cl::opt<std::string> 70 InputLanguage("x", cl::desc("Input language ('ir' or 'mir')")); 71 72 static cl::opt<std::string> 73 OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); 74 75 static cl::opt<std::string> 76 SplitDwarfOutputFile("split-dwarf-output", 77 cl::desc(".dwo output filename"), 78 cl::value_desc("filename")); 79 80 static cl::opt<unsigned> 81 TimeCompilations("time-compilations", cl::Hidden, cl::init(1u), 82 cl::value_desc("N"), 83 cl::desc("Repeat compilation N times for timing")); 84 85 static cl::opt<bool> 86 NoIntegratedAssembler("no-integrated-as", cl::Hidden, 87 cl::desc("Disable integrated assembler")); 88 89 static cl::opt<bool> 90 PreserveComments("preserve-as-comments", cl::Hidden, 91 cl::desc("Preserve Comments in outputted assembly"), 92 cl::init(true)); 93 94 // Determine optimization level. 95 static cl::opt<char> 96 OptLevel("O", 97 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " 98 "(default = '-O2')"), 99 cl::Prefix, 100 cl::ZeroOrMore, 101 cl::init(' ')); 102 103 static cl::opt<std::string> 104 TargetTriple("mtriple", cl::desc("Override target triple for module")); 105 106 static cl::opt<std::string> SplitDwarfFile( 107 "split-dwarf-file", 108 cl::desc( 109 "Specify the name of the .dwo file to encode in the DWARF output")); 110 111 static cl::opt<bool> NoVerify("disable-verify", cl::Hidden, 112 cl::desc("Do not verify input module")); 113 114 static cl::opt<bool> DisableSimplifyLibCalls("disable-simplify-libcalls", 115 cl::desc("Disable simplify-libcalls")); 116 117 static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden, 118 cl::desc("Show encoding in .s output")); 119 120 static cl::opt<bool> EnableDwarfDirectory( 121 "enable-dwarf-directory", cl::Hidden, 122 cl::desc("Use .file directives with an explicit directory.")); 123 124 static cl::opt<bool> AsmVerbose("asm-verbose", 125 cl::desc("Add comments to directives."), 126 cl::init(true)); 127 128 static cl::opt<bool> 129 CompileTwice("compile-twice", cl::Hidden, 130 cl::desc("Run everything twice, re-using the same pass " 131 "manager and verify the result is the same."), 132 cl::init(false)); 133 134 static cl::opt<bool> DiscardValueNames( 135 "discard-value-names", 136 cl::desc("Discard names from Value (other than GlobalValue)."), 137 cl::init(false), cl::Hidden); 138 139 static cl::list<std::string> IncludeDirs("I", cl::desc("include search path")); 140 141 static cl::opt<bool> RemarksWithHotness( 142 "pass-remarks-with-hotness", 143 cl::desc("With PGO, include profile count in optimization remarks"), 144 cl::Hidden); 145 146 static cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser> 147 RemarksHotnessThreshold( 148 "pass-remarks-hotness-threshold", 149 cl::desc("Minimum profile count required for " 150 "an optimization remark to be output. " 151 "Use 'auto' to apply the threshold from profile summary."), 152 cl::value_desc("N or 'auto'"), cl::init(0), cl::Hidden); 153 154 static cl::opt<std::string> 155 RemarksFilename("pass-remarks-output", 156 cl::desc("Output filename for pass remarks"), 157 cl::value_desc("filename")); 158 159 static cl::opt<std::string> 160 RemarksPasses("pass-remarks-filter", 161 cl::desc("Only record optimization remarks from passes whose " 162 "names match the given regular expression"), 163 cl::value_desc("regex")); 164 165 static cl::opt<std::string> RemarksFormat( 166 "pass-remarks-format", 167 cl::desc("The format used for serializing remarks (default: YAML)"), 168 cl::value_desc("format"), cl::init("yaml")); 169 170 namespace { 171 static ManagedStatic<std::vector<std::string>> RunPassNames; 172 173 struct RunPassOption { 174 void operator=(const std::string &Val) const { 175 if (Val.empty()) 176 return; 177 SmallVector<StringRef, 8> PassNames; 178 StringRef(Val).split(PassNames, ',', -1, false); 179 for (auto PassName : PassNames) 180 RunPassNames->push_back(std::string(PassName)); 181 } 182 }; 183 } 184 185 static RunPassOption RunPassOpt; 186 187 static cl::opt<RunPassOption, true, cl::parser<std::string>> RunPass( 188 "run-pass", 189 cl::desc("Run compiler only for specified passes (comma separated list)"), 190 cl::value_desc("pass-name"), cl::ZeroOrMore, cl::location(RunPassOpt)); 191 192 static int compileModule(char **, LLVMContext &); 193 194 static std::unique_ptr<ToolOutputFile> GetOutputStream(const char *TargetName, 195 Triple::OSType OS, 196 const char *ProgName) { 197 // If we don't yet have an output filename, make one. 198 if (OutputFilename.empty()) { 199 if (InputFilename == "-") 200 OutputFilename = "-"; 201 else { 202 // If InputFilename ends in .bc or .ll, remove it. 203 StringRef IFN = InputFilename; 204 if (IFN.endswith(".bc") || IFN.endswith(".ll")) 205 OutputFilename = std::string(IFN.drop_back(3)); 206 else if (IFN.endswith(".mir")) 207 OutputFilename = std::string(IFN.drop_back(4)); 208 else 209 OutputFilename = std::string(IFN); 210 211 switch (codegen::getFileType()) { 212 case CGFT_AssemblyFile: 213 if (TargetName[0] == 'c') { 214 if (TargetName[1] == 0) 215 OutputFilename += ".cbe.c"; 216 else if (TargetName[1] == 'p' && TargetName[2] == 'p') 217 OutputFilename += ".cpp"; 218 else 219 OutputFilename += ".s"; 220 } else 221 OutputFilename += ".s"; 222 break; 223 case CGFT_ObjectFile: 224 if (OS == Triple::Win32) 225 OutputFilename += ".obj"; 226 else 227 OutputFilename += ".o"; 228 break; 229 case CGFT_Null: 230 OutputFilename = "-"; 231 break; 232 } 233 } 234 } 235 236 // Decide if we need "binary" output. 237 bool Binary = false; 238 switch (codegen::getFileType()) { 239 case CGFT_AssemblyFile: 240 break; 241 case CGFT_ObjectFile: 242 case CGFT_Null: 243 Binary = true; 244 break; 245 } 246 247 // Open the file. 248 std::error_code EC; 249 sys::fs::OpenFlags OpenFlags = sys::fs::OF_None; 250 if (!Binary) 251 OpenFlags |= sys::fs::OF_Text; 252 auto FDOut = std::make_unique<ToolOutputFile>(OutputFilename, EC, OpenFlags); 253 if (EC) { 254 WithColor::error() << EC.message() << '\n'; 255 return nullptr; 256 } 257 258 return FDOut; 259 } 260 261 struct LLCDiagnosticHandler : public DiagnosticHandler { 262 bool *HasError; 263 LLCDiagnosticHandler(bool *HasErrorPtr) : HasError(HasErrorPtr) {} 264 bool handleDiagnostics(const DiagnosticInfo &DI) override { 265 if (DI.getSeverity() == DS_Error) 266 *HasError = true; 267 268 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 269 if (!Remark->isEnabled()) 270 return true; 271 272 DiagnosticPrinterRawOStream DP(errs()); 273 errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; 274 DI.print(DP); 275 errs() << "\n"; 276 return true; 277 } 278 }; 279 280 static void InlineAsmDiagHandler(const SMDiagnostic &SMD, void *Context, 281 unsigned LocCookie) { 282 bool *HasError = static_cast<bool *>(Context); 283 if (SMD.getKind() == SourceMgr::DK_Error) 284 *HasError = true; 285 286 SMD.print(nullptr, errs()); 287 288 // For testing purposes, we print the LocCookie here. 289 if (LocCookie) 290 WithColor::note() << "!srcloc = " << LocCookie << "\n"; 291 } 292 293 // main - Entry point for the llc compiler. 294 // 295 int main(int argc, char **argv) { 296 InitLLVM X(argc, argv); 297 298 // Enable debug stream buffering. 299 EnableDebugBuffering = true; 300 301 LLVMContext Context; 302 303 // Initialize targets first, so that --version shows registered targets. 304 InitializeAllTargets(); 305 InitializeAllTargetMCs(); 306 InitializeAllAsmPrinters(); 307 InitializeAllAsmParsers(); 308 309 // Initialize codegen and IR passes used by llc so that the -print-after, 310 // -print-before, and -stop-after options work. 311 PassRegistry *Registry = PassRegistry::getPassRegistry(); 312 initializeCore(*Registry); 313 initializeCodeGen(*Registry); 314 initializeLoopStrengthReducePass(*Registry); 315 initializeLowerIntrinsicsPass(*Registry); 316 initializeEntryExitInstrumenterPass(*Registry); 317 initializePostInlineEntryExitInstrumenterPass(*Registry); 318 initializeUnreachableBlockElimLegacyPassPass(*Registry); 319 initializeConstantHoistingLegacyPassPass(*Registry); 320 initializeScalarOpts(*Registry); 321 initializeVectorization(*Registry); 322 initializeScalarizeMaskedMemIntrinLegacyPassPass(*Registry); 323 initializeExpandReductionsPass(*Registry); 324 initializeHardwareLoopsPass(*Registry); 325 initializeTransformUtils(*Registry); 326 327 // Initialize debugging passes. 328 initializeScavengerTestPass(*Registry); 329 330 // Register the target printer for --version. 331 cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); 332 333 cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); 334 335 Context.setDiscardValueNames(DiscardValueNames); 336 337 // Set a diagnostic handler that doesn't exit on the first error 338 bool HasError = false; 339 Context.setDiagnosticHandler( 340 std::make_unique<LLCDiagnosticHandler>(&HasError)); 341 Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError); 342 343 Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr = 344 setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses, 345 RemarksFormat, RemarksWithHotness, 346 RemarksHotnessThreshold); 347 if (Error E = RemarksFileOrErr.takeError()) { 348 WithColor::error(errs(), argv[0]) << toString(std::move(E)) << '\n'; 349 return 1; 350 } 351 std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr); 352 353 if (InputLanguage != "" && InputLanguage != "ir" && 354 InputLanguage != "mir") { 355 WithColor::error(errs(), argv[0]) 356 << "input language must be '', 'IR' or 'MIR'\n"; 357 return 1; 358 } 359 360 // Compile the module TimeCompilations times to give better compile time 361 // metrics. 362 for (unsigned I = TimeCompilations; I; --I) 363 if (int RetVal = compileModule(argv, Context)) 364 return RetVal; 365 366 if (RemarksFile) 367 RemarksFile->keep(); 368 return 0; 369 } 370 371 static bool addPass(PassManagerBase &PM, const char *argv0, 372 StringRef PassName, TargetPassConfig &TPC) { 373 if (PassName == "none") 374 return false; 375 376 const PassRegistry *PR = PassRegistry::getPassRegistry(); 377 const PassInfo *PI = PR->getPassInfo(PassName); 378 if (!PI) { 379 WithColor::error(errs(), argv0) 380 << "run-pass " << PassName << " is not registered.\n"; 381 return true; 382 } 383 384 Pass *P; 385 if (PI->getNormalCtor()) 386 P = PI->getNormalCtor()(); 387 else { 388 WithColor::error(errs(), argv0) 389 << "cannot create pass: " << PI->getPassName() << "\n"; 390 return true; 391 } 392 std::string Banner = std::string("After ") + std::string(P->getPassName()); 393 TPC.addMachinePrePasses(); 394 PM.add(P); 395 TPC.addMachinePostPasses(Banner); 396 397 return false; 398 } 399 400 static int compileModule(char **argv, LLVMContext &Context) { 401 // Load the module to be compiled... 402 SMDiagnostic Err; 403 std::unique_ptr<Module> M; 404 std::unique_ptr<MIRParser> MIR; 405 Triple TheTriple; 406 std::string CPUStr = codegen::getCPUStr(), 407 FeaturesStr = codegen::getFeaturesStr(); 408 409 // Set attributes on functions as loaded from MIR from command line arguments. 410 auto setMIRFunctionAttributes = [&CPUStr, &FeaturesStr](Function &F) { 411 codegen::setFunctionAttributes(CPUStr, FeaturesStr, F); 412 }; 413 414 auto MAttrs = codegen::getMAttrs(); 415 bool SkipModule = codegen::getMCPU() == "help" || 416 (!MAttrs.empty() && MAttrs.front() == "help"); 417 418 CodeGenOpt::Level OLvl = CodeGenOpt::Default; 419 switch (OptLevel) { 420 default: 421 WithColor::error(errs(), argv[0]) << "invalid optimization level.\n"; 422 return 1; 423 case ' ': break; 424 case '0': OLvl = CodeGenOpt::None; break; 425 case '1': OLvl = CodeGenOpt::Less; break; 426 case '2': OLvl = CodeGenOpt::Default; break; 427 case '3': OLvl = CodeGenOpt::Aggressive; break; 428 } 429 430 TargetOptions Options; 431 auto InitializeOptions = [&](const Triple &TheTriple) { 432 Options = codegen::InitTargetOptionsFromCodeGenFlags(TheTriple); 433 Options.DisableIntegratedAS = NoIntegratedAssembler; 434 Options.MCOptions.ShowMCEncoding = ShowMCEncoding; 435 Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory; 436 Options.MCOptions.AsmVerbose = AsmVerbose; 437 Options.MCOptions.PreserveAsmComments = PreserveComments; 438 Options.MCOptions.IASSearchPaths = IncludeDirs; 439 Options.MCOptions.SplitDwarfFile = SplitDwarfFile; 440 }; 441 442 Optional<Reloc::Model> RM = codegen::getExplicitRelocModel(); 443 444 const Target *TheTarget = nullptr; 445 std::unique_ptr<TargetMachine> Target; 446 447 // If user just wants to list available options, skip module loading 448 if (!SkipModule) { 449 auto SetDataLayout = 450 [&](StringRef DataLayoutTargetTriple) -> Optional<std::string> { 451 // If we are supposed to override the target triple, do so now. 452 std::string IRTargetTriple = DataLayoutTargetTriple.str(); 453 if (!TargetTriple.empty()) 454 IRTargetTriple = Triple::normalize(TargetTriple); 455 TheTriple = Triple(IRTargetTriple); 456 if (TheTriple.getTriple().empty()) 457 TheTriple.setTriple(sys::getDefaultTargetTriple()); 458 459 std::string Error; 460 TheTarget = 461 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); 462 if (!TheTarget) { 463 WithColor::error(errs(), argv[0]) << Error; 464 exit(1); 465 } 466 467 // On AIX, setting the relocation model to anything other than PIC is 468 // considered a user error. 469 if (TheTriple.isOSAIX() && RM.hasValue() && *RM != Reloc::PIC_) { 470 WithColor::error(errs(), argv[0]) 471 << "invalid relocation model, AIX only supports PIC.\n"; 472 exit(1); 473 } 474 475 InitializeOptions(TheTriple); 476 Target = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine( 477 TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, 478 codegen::getExplicitCodeModel(), OLvl)); 479 assert(Target && "Could not allocate target machine!"); 480 481 return Target->createDataLayout().getStringRepresentation(); 482 }; 483 if (InputLanguage == "mir" || 484 (InputLanguage == "" && StringRef(InputFilename).endswith(".mir"))) { 485 MIR = createMIRParserFromFile(InputFilename, Err, Context, 486 setMIRFunctionAttributes); 487 if (MIR) 488 M = MIR->parseIRModule(SetDataLayout); 489 } else { 490 M = parseIRFile(InputFilename, Err, Context, SetDataLayout); 491 } 492 if (!M) { 493 Err.print(argv[0], WithColor::error(errs(), argv[0])); 494 return 1; 495 } 496 if (!TargetTriple.empty()) 497 M->setTargetTriple(Triple::normalize(TargetTriple)); 498 } else { 499 TheTriple = Triple(Triple::normalize(TargetTriple)); 500 if (TheTriple.getTriple().empty()) 501 TheTriple.setTriple(sys::getDefaultTargetTriple()); 502 503 // Get the target specific parser. 504 std::string Error; 505 TheTarget = 506 TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); 507 if (!TheTarget) { 508 WithColor::error(errs(), argv[0]) << Error; 509 return 1; 510 } 511 512 // On AIX, setting the relocation model to anything other than PIC is 513 // considered a user error. 514 if (TheTriple.isOSAIX() && RM.hasValue() && *RM != Reloc::PIC_) { 515 WithColor::error(errs(), argv[0]) 516 << "invalid relocation model, AIX only supports PIC.\n"; 517 return 1; 518 } 519 520 InitializeOptions(TheTriple); 521 Target = std::unique_ptr<TargetMachine>(TheTarget->createTargetMachine( 522 TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, 523 codegen::getExplicitCodeModel(), OLvl)); 524 assert(Target && "Could not allocate target machine!"); 525 526 // If we don't have a module then just exit now. We do this down 527 // here since the CPU/Feature help is underneath the target machine 528 // creation. 529 return 0; 530 } 531 532 assert(M && "Should have exited if we didn't have a module!"); 533 if (codegen::getFloatABIForCalls() != FloatABI::Default) 534 Options.FloatABIType = codegen::getFloatABIForCalls(); 535 536 // Figure out where we are going to send the output. 537 std::unique_ptr<ToolOutputFile> Out = 538 GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]); 539 if (!Out) return 1; 540 541 std::unique_ptr<ToolOutputFile> DwoOut; 542 if (!SplitDwarfOutputFile.empty()) { 543 std::error_code EC; 544 DwoOut = std::make_unique<ToolOutputFile>(SplitDwarfOutputFile, EC, 545 sys::fs::OF_None); 546 if (EC) { 547 WithColor::error(errs(), argv[0]) << EC.message() << '\n'; 548 return 1; 549 } 550 } 551 552 // Build up all of the passes that we want to do to the module. 553 legacy::PassManager PM; 554 555 // Add an appropriate TargetLibraryInfo pass for the module's triple. 556 TargetLibraryInfoImpl TLII(Triple(M->getTargetTriple())); 557 558 // The -disable-simplify-libcalls flag actually disables all builtin optzns. 559 if (DisableSimplifyLibCalls) 560 TLII.disableAllFunctions(); 561 PM.add(new TargetLibraryInfoWrapperPass(TLII)); 562 563 // Verify module immediately to catch problems before doInitialization() is 564 // called on any passes. 565 if (!NoVerify && verifyModule(*M, &errs())) { 566 std::string Prefix = 567 (Twine(argv[0]) + Twine(": ") + Twine(InputFilename)).str(); 568 WithColor::error(errs(), Prefix) << "input module is broken!\n"; 569 return 1; 570 } 571 572 // Override function attributes based on CPUStr, FeaturesStr, and command line 573 // flags. 574 codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M); 575 576 if (mc::getExplicitRelaxAll() && codegen::getFileType() != CGFT_ObjectFile) 577 WithColor::warning(errs(), argv[0]) 578 << ": warning: ignoring -mc-relax-all because filetype != obj"; 579 580 { 581 raw_pwrite_stream *OS = &Out->os(); 582 583 // Manually do the buffering rather than using buffer_ostream, 584 // so we can memcmp the contents in CompileTwice mode 585 SmallVector<char, 0> Buffer; 586 std::unique_ptr<raw_svector_ostream> BOS; 587 if ((codegen::getFileType() != CGFT_AssemblyFile && 588 !Out->os().supportsSeeking()) || 589 CompileTwice) { 590 BOS = std::make_unique<raw_svector_ostream>(Buffer); 591 OS = BOS.get(); 592 } 593 594 const char *argv0 = argv[0]; 595 LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine &>(*Target); 596 MachineModuleInfoWrapperPass *MMIWP = 597 new MachineModuleInfoWrapperPass(&LLVMTM); 598 599 // Construct a custom pass pipeline that starts after instruction 600 // selection. 601 if (!RunPassNames->empty()) { 602 if (!MIR) { 603 WithColor::warning(errs(), argv[0]) 604 << "run-pass is for .mir file only.\n"; 605 return 1; 606 } 607 TargetPassConfig &TPC = *LLVMTM.createPassConfig(PM); 608 if (TPC.hasLimitedCodeGenPipeline()) { 609 WithColor::warning(errs(), argv[0]) 610 << "run-pass cannot be used with " 611 << TPC.getLimitedCodeGenPipelineReason(" and ") << ".\n"; 612 return 1; 613 } 614 615 TPC.setDisableVerify(NoVerify); 616 PM.add(&TPC); 617 PM.add(MMIWP); 618 TPC.printAndVerify(""); 619 for (const std::string &RunPassName : *RunPassNames) { 620 if (addPass(PM, argv0, RunPassName, TPC)) 621 return 1; 622 } 623 TPC.setInitialized(); 624 PM.add(createPrintMIRPass(*OS)); 625 PM.add(createFreeMachineFunctionPass()); 626 } else if (Target->addPassesToEmitFile( 627 PM, *OS, DwoOut ? &DwoOut->os() : nullptr, 628 codegen::getFileType(), NoVerify, MMIWP)) { 629 WithColor::warning(errs(), argv[0]) 630 << "target does not support generation of this" 631 << " file type!\n"; 632 return 1; 633 } 634 635 const_cast<TargetLoweringObjectFile *>(LLVMTM.getObjFileLowering()) 636 ->Initialize(MMIWP->getMMI().getContext(), *Target); 637 if (MIR) { 638 assert(MMIWP && "Forgot to create MMIWP?"); 639 if (MIR->parseMachineFunctions(*M, MMIWP->getMMI())) 640 return 1; 641 } 642 643 // Before executing passes, print the final values of the LLVM options. 644 cl::PrintOptionValues(); 645 646 // If requested, run the pass manager over the same module again, 647 // to catch any bugs due to persistent state in the passes. Note that 648 // opt has the same functionality, so it may be worth abstracting this out 649 // in the future. 650 SmallVector<char, 0> CompileTwiceBuffer; 651 if (CompileTwice) { 652 std::unique_ptr<Module> M2(llvm::CloneModule(*M)); 653 PM.run(*M2); 654 CompileTwiceBuffer = Buffer; 655 Buffer.clear(); 656 } 657 658 PM.run(*M); 659 660 auto HasError = 661 ((const LLCDiagnosticHandler *)(Context.getDiagHandlerPtr()))->HasError; 662 if (*HasError) 663 return 1; 664 665 // Compare the two outputs and make sure they're the same 666 if (CompileTwice) { 667 if (Buffer.size() != CompileTwiceBuffer.size() || 668 (memcmp(Buffer.data(), CompileTwiceBuffer.data(), Buffer.size()) != 669 0)) { 670 errs() 671 << "Running the pass manager twice changed the output.\n" 672 "Writing the result of the second run to the specified output\n" 673 "To generate the one-run comparison binary, just run without\n" 674 "the compile-twice option\n"; 675 Out->os() << Buffer; 676 Out->keep(); 677 return 1; 678 } 679 } 680 681 if (BOS) { 682 Out->os() << Buffer; 683 } 684 } 685 686 // Declare success. 687 Out->keep(); 688 if (DwoOut) 689 DwoOut->keep(); 690 691 return 0; 692 } 693