brintos

brintos / llvm-project-archived public Read only

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