Path: blob/main/contrib/llvm-project/llvm/tools/opt/optdriver.cpp
35231 views
//===- optdriver.cpp - The LLVM Modular Optimizer -------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// Optimizations may be specified an arbitrary number of times on the command9// line, They are run in the order specified. Common driver library for re-use10// by potential downstream opt-variants.11//12//===----------------------------------------------------------------------===//1314#include "NewPMDriver.h"15#include "llvm/Analysis/CallGraph.h"16#include "llvm/Analysis/CallGraphSCCPass.h"17#include "llvm/Analysis/LoopPass.h"18#include "llvm/Analysis/RegionPass.h"19#include "llvm/Analysis/TargetLibraryInfo.h"20#include "llvm/Analysis/TargetTransformInfo.h"21#include "llvm/AsmParser/Parser.h"22#include "llvm/CodeGen/CommandFlags.h"23#include "llvm/CodeGen/TargetPassConfig.h"24#include "llvm/Config/llvm-config.h"25#include "llvm/IR/DataLayout.h"26#include "llvm/IR/DebugInfo.h"27#include "llvm/IR/LLVMContext.h"28#include "llvm/IR/LLVMRemarkStreamer.h"29#include "llvm/IR/LegacyPassManager.h"30#include "llvm/IR/LegacyPassNameParser.h"31#include "llvm/IR/Module.h"32#include "llvm/IR/ModuleSummaryIndex.h"33#include "llvm/IR/Verifier.h"34#include "llvm/IRReader/IRReader.h"35#include "llvm/InitializePasses.h"36#include "llvm/LinkAllIR.h"37#include "llvm/LinkAllPasses.h"38#include "llvm/MC/TargetRegistry.h"39#include "llvm/Passes/PassPlugin.h"40#include "llvm/Remarks/HotnessThresholdParser.h"41#include "llvm/Support/Debug.h"42#include "llvm/Support/ErrorHandling.h"43#include "llvm/Support/FileSystem.h"44#include "llvm/Support/InitLLVM.h"45#include "llvm/Support/PluginLoader.h"46#include "llvm/Support/SourceMgr.h"47#include "llvm/Support/SystemUtils.h"48#include "llvm/Support/TargetSelect.h"49#include "llvm/Support/TimeProfiler.h"50#include "llvm/Support/ToolOutputFile.h"51#include "llvm/Support/YAMLTraits.h"52#include "llvm/Target/TargetMachine.h"53#include "llvm/TargetParser/Host.h"54#include "llvm/TargetParser/SubtargetFeature.h"55#include "llvm/TargetParser/Triple.h"56#include "llvm/Transforms/IPO/WholeProgramDevirt.h"57#include "llvm/Transforms/Utils/Cloning.h"58#include "llvm/Transforms/Utils/Debugify.h"59#include <algorithm>60#include <memory>61#include <optional>62using namespace llvm;63using namespace opt_tool;6465static codegen::RegisterCodeGenFlags CFG;6667// The OptimizationList is automatically populated with registered Passes by the68// PassNameParser.69static cl::list<const PassInfo *, bool, PassNameParser> PassList(cl::desc(70"Optimizations available (use \"-passes=\" for the new pass manager)"));7172static cl::opt<bool> EnableLegacyPassManager(73"bugpoint-enable-legacy-pm",74cl::desc(75"Enable the legacy pass manager. This is strictly for bugpoint "76"due to it not working with the new PM, please do not use otherwise."),77cl::init(false));7879// This flag specifies a textual description of the optimization pass pipeline80// to run over the module. This flag switches opt to use the new pass manager81// infrastructure, completely disabling all of the flags specific to the old82// pass management.83static cl::opt<std::string> PassPipeline(84"passes",85cl::desc(86"A textual description of the pass pipeline. To have analysis passes "87"available before a certain pass, add \"require<foo-analysis>\"."));88static cl::alias PassPipeline2("p", cl::aliasopt(PassPipeline),89cl::desc("Alias for -passes"));9091static cl::opt<bool> PrintPasses("print-passes",92cl::desc("Print available passes that can be "93"specified in -passes=foo and exit"));9495static cl::opt<std::string> InputFilename(cl::Positional,96cl::desc("<input bitcode file>"),97cl::init("-"),98cl::value_desc("filename"));99100static cl::opt<std::string> OutputFilename("o",101cl::desc("Override output filename"),102cl::value_desc("filename"));103104static cl::opt<bool> Force("f", cl::desc("Enable binary output on terminals"));105106static cl::opt<bool> NoOutput("disable-output",107cl::desc("Do not write result bitcode file"),108cl::Hidden);109110static cl::opt<bool> OutputAssembly("S",111cl::desc("Write output as LLVM assembly"));112113static cl::opt<bool>114OutputThinLTOBC("thinlto-bc",115cl::desc("Write output as ThinLTO-ready bitcode"));116117static cl::opt<bool>118SplitLTOUnit("thinlto-split-lto-unit",119cl::desc("Enable splitting of a ThinLTO LTOUnit"));120121static cl::opt<bool>122UnifiedLTO("unified-lto",123cl::desc("Use unified LTO piplines. Ignored unless -thinlto-bc "124"is also specified."),125cl::Hidden, cl::init(false));126127static cl::opt<std::string> ThinLinkBitcodeFile(128"thin-link-bitcode-file", cl::value_desc("filename"),129cl::desc(130"A file in which to write minimized bitcode for the thin link only"));131132static cl::opt<bool> NoVerify("disable-verify",133cl::desc("Do not run the verifier"), cl::Hidden);134135static cl::opt<bool> NoUpgradeDebugInfo("disable-upgrade-debug-info",136cl::desc("Generate invalid output"),137cl::ReallyHidden);138139static cl::opt<bool> VerifyEach("verify-each",140cl::desc("Verify after each transform"));141142static cl::opt<bool>143DisableDITypeMap("disable-debug-info-type-map",144cl::desc("Don't use a uniquing type map for debug info"));145146static cl::opt<bool>147StripDebug("strip-debug",148cl::desc("Strip debugger symbol info from translation unit"));149150static cl::opt<bool>151StripNamedMetadata("strip-named-metadata",152cl::desc("Strip module-level named metadata"));153154static cl::opt<bool>155OptLevelO0("O0", cl::desc("Optimization level 0. Similar to clang -O0. "156"Same as -passes=\"default<O0>\""));157158static cl::opt<bool>159OptLevelO1("O1", cl::desc("Optimization level 1. Similar to clang -O1. "160"Same as -passes=\"default<O1>\""));161162static cl::opt<bool>163OptLevelO2("O2", cl::desc("Optimization level 2. Similar to clang -O2. "164"Same as -passes=\"default<O2>\""));165166static cl::opt<bool>167OptLevelOs("Os", cl::desc("Like -O2 but size-conscious. Similar to clang "168"-Os. Same as -passes=\"default<Os>\""));169170static cl::opt<bool> OptLevelOz(171"Oz",172cl::desc("Like -O2 but optimize for code size above all else. Similar to "173"clang -Oz. Same as -passes=\"default<Oz>\""));174175static cl::opt<bool>176OptLevelO3("O3", cl::desc("Optimization level 3. Similar to clang -O3. "177"Same as -passes=\"default<O3>\""));178179static cl::opt<unsigned> CodeGenOptLevelCL(180"codegen-opt-level",181cl::desc("Override optimization level for codegen hooks, legacy PM only"));182183static cl::opt<std::string>184TargetTriple("mtriple", cl::desc("Override target triple for module"));185186static cl::opt<bool> EmitSummaryIndex("module-summary",187cl::desc("Emit module summary index"),188cl::init(false));189190static cl::opt<bool> EmitModuleHash("module-hash", cl::desc("Emit module hash"),191cl::init(false));192193static cl::opt<bool>194DisableSimplifyLibCalls("disable-simplify-libcalls",195cl::desc("Disable simplify-libcalls"));196197static cl::list<std::string> DisableBuiltins(198"disable-builtin",199cl::desc("Disable specific target library builtin function"));200201static cl::opt<bool> EnableDebugify(202"enable-debugify",203cl::desc(204"Start the pipeline with debugify and end it with check-debugify"));205206static cl::opt<bool> VerifyDebugInfoPreserve(207"verify-debuginfo-preserve",208cl::desc("Start the pipeline with collecting and end it with checking of "209"debug info preservation."));210211static cl::opt<std::string> ClDataLayout("data-layout",212cl::desc("data layout string to use"),213cl::value_desc("layout-string"),214cl::init(""));215216static cl::opt<bool> PreserveBitcodeUseListOrder(217"preserve-bc-uselistorder",218cl::desc("Preserve use-list order when writing LLVM bitcode."),219cl::init(true), cl::Hidden);220221static cl::opt<bool> PreserveAssemblyUseListOrder(222"preserve-ll-uselistorder",223cl::desc("Preserve use-list order when writing LLVM assembly."),224cl::init(false), cl::Hidden);225226static cl::opt<bool> RunTwice("run-twice",227cl::desc("Run all passes twice, re-using the "228"same pass manager (legacy PM only)."),229cl::init(false), cl::Hidden);230231static cl::opt<bool> DiscardValueNames(232"discard-value-names",233cl::desc("Discard names from Value (other than GlobalValue)."),234cl::init(false), cl::Hidden);235236static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));237238static cl::opt<unsigned> TimeTraceGranularity(239"time-trace-granularity",240cl::desc(241"Minimum time granularity (in microseconds) traced by time profiler"),242cl::init(500), cl::Hidden);243244static cl::opt<std::string>245TimeTraceFile("time-trace-file",246cl::desc("Specify time trace file destination"),247cl::value_desc("filename"));248249static cl::opt<bool> RemarksWithHotness(250"pass-remarks-with-hotness",251cl::desc("With PGO, include profile count in optimization remarks"),252cl::Hidden);253254static cl::opt<std::optional<uint64_t>, false, remarks::HotnessThresholdParser>255RemarksHotnessThreshold(256"pass-remarks-hotness-threshold",257cl::desc("Minimum profile count required for "258"an optimization remark to be output. "259"Use 'auto' to apply the threshold from profile summary"),260cl::value_desc("N or 'auto'"), cl::init(0), cl::Hidden);261262static cl::opt<std::string>263RemarksFilename("pass-remarks-output",264cl::desc("Output filename for pass remarks"),265cl::value_desc("filename"));266267static cl::opt<std::string>268RemarksPasses("pass-remarks-filter",269cl::desc("Only record optimization remarks from passes whose "270"names match the given regular expression"),271cl::value_desc("regex"));272273static cl::opt<std::string> RemarksFormat(274"pass-remarks-format",275cl::desc("The format used for serializing remarks (default: YAML)"),276cl::value_desc("format"), cl::init("yaml"));277278static cl::list<std::string>279PassPlugins("load-pass-plugin",280cl::desc("Load passes from plugin library"));281282static cl::opt<bool> TryUseNewDbgInfoFormat(283"try-experimental-debuginfo-iterators",284cl::desc("Enable debuginfo iterator positions, if they're built in"),285cl::init(false), cl::Hidden);286287extern cl::opt<bool> UseNewDbgInfoFormat;288289//===----------------------------------------------------------------------===//290// CodeGen-related helper functions.291//292293static CodeGenOptLevel GetCodeGenOptLevel() {294return static_cast<CodeGenOptLevel>(unsigned(CodeGenOptLevelCL));295}296297struct TimeTracerRAII {298TimeTracerRAII(StringRef ProgramName) {299if (TimeTrace)300timeTraceProfilerInitialize(TimeTraceGranularity, ProgramName);301}302~TimeTracerRAII() {303if (TimeTrace) {304if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {305handleAllErrors(std::move(E), [&](const StringError &SE) {306errs() << SE.getMessage() << "\n";307});308return;309}310timeTraceProfilerCleanup();311}312}313};314315// For use in NPM transition. Currently this contains most codegen-specific316// passes. Remove passes from here when porting to the NPM.317// TODO: use a codegen version of PassRegistry.def/PassBuilder::is*Pass() once318// it exists.319static bool shouldPinPassToLegacyPM(StringRef Pass) {320static constexpr StringLiteral PassNameExactToIgnore[] = {321"nvvm-reflect",322"nvvm-intr-range",323"amdgpu-simplifylib",324"amdgpu-image-intrinsic-opt",325"amdgpu-usenative",326"amdgpu-promote-alloca",327"amdgpu-promote-alloca-to-vector",328"amdgpu-lower-kernel-attributes",329"amdgpu-propagate-attributes-early",330"amdgpu-propagate-attributes-late",331"amdgpu-unify-metadata",332"amdgpu-printf-runtime-binding",333"amdgpu-always-inline"};334if (llvm::is_contained(PassNameExactToIgnore, Pass))335return false;336337static constexpr StringLiteral PassNamePrefix[] = {338"x86-", "xcore-", "wasm-", "systemz-", "ppc-", "nvvm-",339"nvptx-", "mips-", "lanai-", "hexagon-", "bpf-", "avr-",340"thumb2-", "arm-", "si-", "gcn-", "amdgpu-", "aarch64-",341"amdgcn-", "polly-", "riscv-", "dxil-"};342static constexpr StringLiteral PassNameContain[] = {"-eh-prepare"};343static constexpr StringLiteral PassNameExact[] = {344"safe-stack",345"cost-model",346"codegenprepare",347"interleaved-load-combine",348"unreachableblockelim",349"verify-safepoint-ir",350"atomic-expand",351"expandvp",352"mve-tail-predication",353"interleaved-access",354"global-merge",355"pre-isel-intrinsic-lowering",356"expand-reductions",357"indirectbr-expand",358"generic-to-nvvm",359"expand-memcmp",360"loop-reduce",361"lower-amx-type",362"lower-amx-intrinsics",363"polyhedral-info",364"print-polyhedral-info",365"replace-with-veclib",366"jmc-instrumenter",367"dot-regions",368"dot-regions-only",369"view-regions",370"view-regions-only",371"select-optimize",372"expand-large-div-rem",373"structurizecfg",374"fix-irreducible",375"expand-large-fp-convert",376"callbrprepare",377};378for (const auto &P : PassNamePrefix)379if (Pass.starts_with(P))380return true;381for (const auto &P : PassNameContain)382if (Pass.contains(P))383return true;384return llvm::is_contained(PassNameExact, Pass);385}386387// For use in NPM transition.388static bool shouldForceLegacyPM() {389for (const auto &P : PassList) {390StringRef Arg = P->getPassArgument();391if (shouldPinPassToLegacyPM(Arg))392return true;393}394return false;395}396397//===----------------------------------------------------------------------===//398// main for opt399//400extern "C" int optMain(401int argc, char **argv,402ArrayRef<std::function<void(llvm::PassBuilder &)>> PassBuilderCallbacks) {403InitLLVM X(argc, argv);404405// Enable debug stream buffering.406EnableDebugBuffering = true;407408InitializeAllTargets();409InitializeAllTargetMCs();410InitializeAllAsmPrinters();411InitializeAllAsmParsers();412413// Initialize passes414PassRegistry &Registry = *PassRegistry::getPassRegistry();415initializeCore(Registry);416initializeScalarOpts(Registry);417initializeVectorization(Registry);418initializeIPO(Registry);419initializeAnalysis(Registry);420initializeTransformUtils(Registry);421initializeInstCombine(Registry);422initializeTarget(Registry);423// For codegen passes, only passes that do IR to IR transformation are424// supported.425initializeExpandLargeDivRemLegacyPassPass(Registry);426initializeExpandLargeFpConvertLegacyPassPass(Registry);427initializeExpandMemCmpLegacyPassPass(Registry);428initializeScalarizeMaskedMemIntrinLegacyPassPass(Registry);429initializeSelectOptimizePass(Registry);430initializeCallBrPreparePass(Registry);431initializeCodeGenPrepareLegacyPassPass(Registry);432initializeAtomicExpandLegacyPass(Registry);433initializeWinEHPreparePass(Registry);434initializeDwarfEHPrepareLegacyPassPass(Registry);435initializeSafeStackLegacyPassPass(Registry);436initializeSjLjEHPreparePass(Registry);437initializePreISelIntrinsicLoweringLegacyPassPass(Registry);438initializeGlobalMergePass(Registry);439initializeIndirectBrExpandLegacyPassPass(Registry);440initializeInterleavedLoadCombinePass(Registry);441initializeInterleavedAccessPass(Registry);442initializePostInlineEntryExitInstrumenterPass(Registry);443initializeUnreachableBlockElimLegacyPassPass(Registry);444initializeExpandReductionsPass(Registry);445initializeExpandVectorPredicationPass(Registry);446initializeWasmEHPreparePass(Registry);447initializeWriteBitcodePassPass(Registry);448initializeReplaceWithVeclibLegacyPass(Registry);449initializeJMCInstrumenterPass(Registry);450451SmallVector<PassPlugin, 1> PluginList;452PassPlugins.setCallback([&](const std::string &PluginPath) {453auto Plugin = PassPlugin::Load(PluginPath);454if (!Plugin)455report_fatal_error(Plugin.takeError(), /*gen_crash_diag=*/false);456PluginList.emplace_back(Plugin.get());457});458459// Register the Target and CPU printer for --version.460cl::AddExtraVersionPrinter(sys::printDefaultTargetAndDetectedCPU);461462cl::ParseCommandLineOptions(463argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n");464465// RemoveDIs debug-info transition: tests may request that we /try/ to use the466// new debug-info format.467if (TryUseNewDbgInfoFormat) {468// Turn the new debug-info format on.469UseNewDbgInfoFormat = true;470}471472LLVMContext Context;473474// TODO: remove shouldForceLegacyPM().475const bool UseNPM = (!EnableLegacyPassManager && !shouldForceLegacyPM()) ||476PassPipeline.getNumOccurrences() > 0;477478if (UseNPM && !PassList.empty()) {479errs() << "The `opt -passname` syntax for the new pass manager is "480"not supported, please use `opt -passes=<pipeline>` (or the `-p` "481"alias for a more concise version).\n";482errs() << "See https://llvm.org/docs/NewPassManager.html#invoking-opt "483"for more details on the pass pipeline syntax.\n\n";484return 1;485}486487if (!UseNPM && PluginList.size()) {488errs() << argv[0] << ": " << PassPlugins.ArgStr489<< " specified with legacy PM.\n";490return 1;491}492493// FIXME: once the legacy PM code is deleted, move runPassPipeline() here and494// construct the PassBuilder before parsing IR so we can reuse the same495// PassBuilder for print passes.496if (PrintPasses) {497printPasses(outs());498return 0;499}500501TimeTracerRAII TimeTracer(argv[0]);502503SMDiagnostic Err;504505Context.setDiscardValueNames(DiscardValueNames);506if (!DisableDITypeMap)507Context.enableDebugTypeODRUniquing();508509Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr =510setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses,511RemarksFormat, RemarksWithHotness,512RemarksHotnessThreshold);513if (Error E = RemarksFileOrErr.takeError()) {514errs() << toString(std::move(E)) << '\n';515return 1;516}517std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr);518519// Load the input module...520auto SetDataLayout = [&](StringRef IRTriple,521StringRef IRLayout) -> std::optional<std::string> {522// Data layout specified on the command line has the highest priority.523if (!ClDataLayout.empty())524return ClDataLayout;525// If an explicit data layout is already defined in the IR, don't infer.526if (!IRLayout.empty())527return std::nullopt;528529// If an explicit triple was specified (either in the IR or on the530// command line), use that to infer the default data layout. However, the531// command line target triple should override the IR file target triple.532std::string TripleStr =533TargetTriple.empty() ? IRTriple.str() : Triple::normalize(TargetTriple);534// If the triple string is still empty, we don't fall back to535// sys::getDefaultTargetTriple() since we do not want to have differing536// behaviour dependent on the configured default triple. Therefore, if the537// user did not pass -mtriple or define an explicit triple/datalayout in538// the IR, we should default to an empty (default) DataLayout.539if (TripleStr.empty())540return std::nullopt;541// Otherwise we infer the DataLayout from the target machine.542Expected<std::unique_ptr<TargetMachine>> ExpectedTM =543codegen::createTargetMachineForTriple(TripleStr, GetCodeGenOptLevel());544if (!ExpectedTM) {545errs() << argv[0] << ": warning: failed to infer data layout: "546<< toString(ExpectedTM.takeError()) << "\n";547return std::nullopt;548}549return (*ExpectedTM)->createDataLayout().getStringRepresentation();550};551std::unique_ptr<Module> M;552if (NoUpgradeDebugInfo)553M = parseAssemblyFileWithIndexNoUpgradeDebugInfo(554InputFilename, Err, Context, nullptr, SetDataLayout)555.Mod;556else557M = parseIRFile(InputFilename, Err, Context,558ParserCallbacks(SetDataLayout));559560if (!M) {561Err.print(argv[0], errs());562return 1;563}564565// Strip debug info before running the verifier.566if (StripDebug)567StripDebugInfo(*M);568569// Erase module-level named metadata, if requested.570if (StripNamedMetadata) {571while (!M->named_metadata_empty()) {572NamedMDNode *NMD = &*M->named_metadata_begin();573M->eraseNamedMetadata(NMD);574}575}576577// If we are supposed to override the target triple, do so now.578if (!TargetTriple.empty())579M->setTargetTriple(Triple::normalize(TargetTriple));580581// Immediately run the verifier to catch any problems before starting up the582// pass pipelines. Otherwise we can crash on broken code during583// doInitialization().584if (!NoVerify && verifyModule(*M, &errs())) {585errs() << argv[0] << ": " << InputFilename586<< ": error: input module is broken!\n";587return 1;588}589590// Enable testing of whole program devirtualization on this module by invoking591// the facility for updating public visibility to linkage unit visibility when592// specified by an internal option. This is normally done during LTO which is593// not performed via opt.594updateVCallVisibilityInModule(595*M,596/*WholeProgramVisibilityEnabledInLTO=*/false,597// FIXME: These need linker information via a598// TBD new interface.599/*DynamicExportSymbols=*/{},600/*ValidateAllVtablesHaveTypeInfos=*/false,601/*IsVisibleToRegularObj=*/[](StringRef) { return true; });602603// Figure out what stream we are supposed to write to...604std::unique_ptr<ToolOutputFile> Out;605std::unique_ptr<ToolOutputFile> ThinLinkOut;606if (NoOutput) {607if (!OutputFilename.empty())608errs() << "WARNING: The -o (output filename) option is ignored when\n"609"the --disable-output option is used.\n";610} else {611// Default to standard output.612if (OutputFilename.empty())613OutputFilename = "-";614615std::error_code EC;616sys::fs::OpenFlags Flags =617OutputAssembly ? sys::fs::OF_TextWithCRLF : sys::fs::OF_None;618Out.reset(new ToolOutputFile(OutputFilename, EC, Flags));619if (EC) {620errs() << EC.message() << '\n';621return 1;622}623624if (!ThinLinkBitcodeFile.empty()) {625ThinLinkOut.reset(626new ToolOutputFile(ThinLinkBitcodeFile, EC, sys::fs::OF_None));627if (EC) {628errs() << EC.message() << '\n';629return 1;630}631}632}633634Triple ModuleTriple(M->getTargetTriple());635std::string CPUStr, FeaturesStr;636std::unique_ptr<TargetMachine> TM;637if (ModuleTriple.getArch()) {638CPUStr = codegen::getCPUStr();639FeaturesStr = codegen::getFeaturesStr();640Expected<std::unique_ptr<TargetMachine>> ExpectedTM =641codegen::createTargetMachineForTriple(ModuleTriple.str(),642GetCodeGenOptLevel());643if (auto E = ExpectedTM.takeError()) {644errs() << argv[0] << ": WARNING: failed to create target machine for '"645<< ModuleTriple.str() << "': " << toString(std::move(E)) << "\n";646} else {647TM = std::move(*ExpectedTM);648}649} else if (ModuleTriple.getArchName() != "unknown" &&650ModuleTriple.getArchName() != "") {651errs() << argv[0] << ": unrecognized architecture '"652<< ModuleTriple.getArchName() << "' provided.\n";653return 1;654}655656// Override function attributes based on CPUStr, FeaturesStr, and command line657// flags.658codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M);659660// If the output is set to be emitted to standard out, and standard out is a661// console, print out a warning message and refuse to do it. We don't662// impress anyone by spewing tons of binary goo to a terminal.663if (!Force && !NoOutput && !OutputAssembly)664if (CheckBitcodeOutputToConsole(Out->os()))665NoOutput = true;666667if (OutputThinLTOBC) {668M->addModuleFlag(Module::Error, "EnableSplitLTOUnit", SplitLTOUnit);669if (UnifiedLTO)670M->addModuleFlag(Module::Error, "UnifiedLTO", 1);671}672673// Add an appropriate TargetLibraryInfo pass for the module's triple.674TargetLibraryInfoImpl TLII(ModuleTriple);675676// The -disable-simplify-libcalls flag actually disables all builtin optzns.677if (DisableSimplifyLibCalls)678TLII.disableAllFunctions();679else {680// Disable individual builtin functions in TargetLibraryInfo.681LibFunc F;682for (auto &FuncName : DisableBuiltins)683if (TLII.getLibFunc(FuncName, F))684TLII.setUnavailable(F);685else {686errs() << argv[0] << ": cannot disable nonexistent builtin function "687<< FuncName << '\n';688return 1;689}690}691692if (UseNPM) {693if (legacy::debugPassSpecified()) {694errs() << "-debug-pass does not work with the new PM, either use "695"-debug-pass-manager, or use the legacy PM\n";696return 1;697}698auto NumOLevel = OptLevelO0 + OptLevelO1 + OptLevelO2 + OptLevelO3 +699OptLevelOs + OptLevelOz;700if (NumOLevel > 1) {701errs() << "Cannot specify multiple -O#\n";702return 1;703}704if (NumOLevel > 0 && (PassPipeline.getNumOccurrences() > 0)) {705errs() << "Cannot specify -O# and --passes=/--foo-pass, use "706"-passes='default<O#>,other-pass'\n";707return 1;708}709std::string Pipeline = PassPipeline;710711if (OptLevelO0)712Pipeline = "default<O0>";713if (OptLevelO1)714Pipeline = "default<O1>";715if (OptLevelO2)716Pipeline = "default<O2>";717if (OptLevelO3)718Pipeline = "default<O3>";719if (OptLevelOs)720Pipeline = "default<Os>";721if (OptLevelOz)722Pipeline = "default<Oz>";723OutputKind OK = OK_NoOutput;724if (!NoOutput)725OK = OutputAssembly726? OK_OutputAssembly727: (OutputThinLTOBC ? OK_OutputThinLTOBitcode : OK_OutputBitcode);728729VerifierKind VK = VK_VerifyOut;730if (NoVerify)731VK = VK_NoVerifier;732else if (VerifyEach)733VK = VK_VerifyEachPass;734735// The user has asked to use the new pass manager and provided a pipeline736// string. Hand off the rest of the functionality to the new code for that737// layer.738return runPassPipeline(739argv[0], *M, TM.get(), &TLII, Out.get(), ThinLinkOut.get(),740RemarksFile.get(), Pipeline, PluginList, PassBuilderCallbacks,741OK, VK, PreserveAssemblyUseListOrder,742PreserveBitcodeUseListOrder, EmitSummaryIndex, EmitModuleHash,743EnableDebugify, VerifyDebugInfoPreserve, UnifiedLTO)744? 0745: 1;746}747748if (OptLevelO0 || OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz ||749OptLevelO3) {750errs() << "Cannot use -O# with legacy PM.\n";751return 1;752}753if (EmitSummaryIndex) {754errs() << "Cannot use -module-summary with legacy PM.\n";755return 1;756}757if (EmitModuleHash) {758errs() << "Cannot use -module-hash with legacy PM.\n";759return 1;760}761if (OutputThinLTOBC) {762errs() << "Cannot use -thinlto-bc with legacy PM.\n";763return 1;764}765// Create a PassManager to hold and optimize the collection of passes we are766// about to build. If the -debugify-each option is set, wrap each pass with767// the (-check)-debugify passes.768DebugifyCustomPassManager Passes;769DebugifyStatsMap DIStatsMap;770DebugInfoPerPass DebugInfoBeforePass;771if (DebugifyEach) {772Passes.setDebugifyMode(DebugifyMode::SyntheticDebugInfo);773Passes.setDIStatsMap(DIStatsMap);774} else if (VerifyEachDebugInfoPreserve) {775Passes.setDebugifyMode(DebugifyMode::OriginalDebugInfo);776Passes.setDebugInfoBeforePass(DebugInfoBeforePass);777if (!VerifyDIPreserveExport.empty())778Passes.setOrigDIVerifyBugsReportFilePath(VerifyDIPreserveExport);779}780781bool AddOneTimeDebugifyPasses =782(EnableDebugify && !DebugifyEach) ||783(VerifyDebugInfoPreserve && !VerifyEachDebugInfoPreserve);784785Passes.add(new TargetLibraryInfoWrapperPass(TLII));786787// Add internal analysis passes from the target machine.788Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()789: TargetIRAnalysis()));790791if (AddOneTimeDebugifyPasses) {792if (EnableDebugify) {793Passes.setDIStatsMap(DIStatsMap);794Passes.add(createDebugifyModulePass());795} else if (VerifyDebugInfoPreserve) {796Passes.setDebugInfoBeforePass(DebugInfoBeforePass);797Passes.add(createDebugifyModulePass(DebugifyMode::OriginalDebugInfo, "",798&(Passes.getDebugInfoPerPass())));799}800}801802if (TM) {803// FIXME: We should dyn_cast this when supported.804auto <M = static_cast<LLVMTargetMachine &>(*TM);805Pass *TPC = LTM.createPassConfig(Passes);806Passes.add(TPC);807}808809// Create a new optimization pass for each one specified on the command line810for (unsigned i = 0; i < PassList.size(); ++i) {811const PassInfo *PassInf = PassList[i];812if (PassInf->getNormalCtor()) {813Pass *P = PassInf->getNormalCtor()();814if (P) {815// Add the pass to the pass manager.816Passes.add(P);817// If we are verifying all of the intermediate steps, add the verifier.818if (VerifyEach)819Passes.add(createVerifierPass());820}821} else822errs() << argv[0] << ": cannot create pass: " << PassInf->getPassName()823<< "\n";824}825826// Check that the module is well formed on completion of optimization827if (!NoVerify && !VerifyEach)828Passes.add(createVerifierPass());829830if (AddOneTimeDebugifyPasses) {831if (EnableDebugify)832Passes.add(createCheckDebugifyModulePass(false));833else if (VerifyDebugInfoPreserve) {834if (!VerifyDIPreserveExport.empty())835Passes.setOrigDIVerifyBugsReportFilePath(VerifyDIPreserveExport);836Passes.add(createCheckDebugifyModulePass(837false, "", nullptr, DebugifyMode::OriginalDebugInfo,838&(Passes.getDebugInfoPerPass()), VerifyDIPreserveExport));839}840}841842// In run twice mode, we want to make sure the output is bit-by-bit843// equivalent if we run the pass manager again, so setup two buffers and844// a stream to write to them. Note that llc does something similar and it845// may be worth to abstract this out in the future.846SmallVector<char, 0> Buffer;847SmallVector<char, 0> FirstRunBuffer;848std::unique_ptr<raw_svector_ostream> BOS;849raw_ostream *OS = nullptr;850851const bool ShouldEmitOutput = !NoOutput;852853// Write bitcode or assembly to the output as the last step...854if (ShouldEmitOutput || RunTwice) {855assert(Out);856OS = &Out->os();857if (RunTwice) {858BOS = std::make_unique<raw_svector_ostream>(Buffer);859OS = BOS.get();860}861if (OutputAssembly)862Passes.add(createPrintModulePass(*OS, "", PreserveAssemblyUseListOrder));863else864Passes.add(createBitcodeWriterPass(*OS, PreserveBitcodeUseListOrder));865}866867// Before executing passes, print the final values of the LLVM options.868cl::PrintOptionValues();869870if (!RunTwice) {871// Now that we have all of the passes ready, run them.872Passes.run(*M);873} else {874// If requested, run all passes twice with the same pass manager to catch875// bugs caused by persistent state in the passes.876std::unique_ptr<Module> M2(CloneModule(*M));877// Run all passes on the original module first, so the second run processes878// the clone to catch CloneModule bugs.879Passes.run(*M);880FirstRunBuffer = Buffer;881Buffer.clear();882883Passes.run(*M2);884885// Compare the two outputs and make sure they're the same886assert(Out);887if (Buffer.size() != FirstRunBuffer.size() ||888(memcmp(Buffer.data(), FirstRunBuffer.data(), Buffer.size()) != 0)) {889errs()890<< "Running the pass manager twice changed the output.\n"891"Writing the result of the second run to the specified output.\n"892"To generate the one-run comparison binary, just run without\n"893"the compile-twice option\n";894if (ShouldEmitOutput) {895Out->os() << BOS->str();896Out->keep();897}898if (RemarksFile)899RemarksFile->keep();900return 1;901}902if (ShouldEmitOutput)903Out->os() << BOS->str();904}905906if (DebugifyEach && !DebugifyExport.empty())907exportDebugifyStats(DebugifyExport, Passes.getDebugifyStatsMap());908909// Declare success.910if (!NoOutput)911Out->keep();912913if (RemarksFile)914RemarksFile->keep();915916if (ThinLinkOut)917ThinLinkOut->keep();918919return 0;920}921922923