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