diff options
author | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@yandex-team.com> | 2023-06-29 10:00:50 +0300 |
commit | 6ffe9e53658409f212834330e13564e4952558f6 (patch) | |
tree | 85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm14/tools/opt | |
parent | 726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff) | |
download | ydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz |
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/llvm14/tools/opt')
-rw-r--r-- | contrib/libs/llvm14/tools/opt/AnalysisWrappers.cpp | 71 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/BreakpointPrinter.cpp | 71 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/BreakpointPrinter.h | 24 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/GraphPrinters.cpp | 45 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/NewPMDriver.cpp | 495 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/NewPMDriver.h | 79 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/PassPrinters.cpp | 212 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/PassPrinters.h | 40 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/PrintSCC.cpp | 111 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/opt.cpp | 1090 | ||||
-rw-r--r-- | contrib/libs/llvm14/tools/opt/ya.make | 98 |
11 files changed, 2336 insertions, 0 deletions
diff --git a/contrib/libs/llvm14/tools/opt/AnalysisWrappers.cpp b/contrib/libs/llvm14/tools/opt/AnalysisWrappers.cpp new file mode 100644 index 0000000000..2ae1da84a9 --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/AnalysisWrappers.cpp @@ -0,0 +1,71 @@ +//===- AnalysisWrappers.cpp - Wrappers around non-pass analyses -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines pass wrappers around LLVM analyses that don't make sense to +// be passes. It provides a nice standard pass interface to these classes so +// that they can be printed out by analyze. +// +// These classes are separated out of analyze.cpp so that it is more clear which +// code is the integral part of the analyze tool, and which part of the code is +// just making it so more passes are available. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/CallGraph.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +namespace { + /// ExternalFunctionsPassedConstants - This pass prints out call sites to + /// external functions that are called with constant arguments. This can be + /// useful when looking for standard library functions we should constant fold + /// or handle in alias analyses. + struct ExternalFunctionsPassedConstants : public ModulePass { + static char ID; // Pass ID, replacement for typeid + ExternalFunctionsPassedConstants() : ModulePass(ID) {} + bool runOnModule(Module &M) override { + for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) { + if (!I->isDeclaration()) continue; + + bool PrintedFn = false; + for (User *U : I->users()) { + Instruction *UI = dyn_cast<Instruction>(U); + if (!UI) continue; + + CallBase *CB = dyn_cast<CallBase>(UI); + if (!CB) + continue; + + for (auto AI = CB->arg_begin(), E = CB->arg_end(); AI != E; ++AI) { + if (!isa<Constant>(*AI)) continue; + + if (!PrintedFn) { + errs() << "Function '" << I->getName() << "':\n"; + PrintedFn = true; + } + errs() << *UI; + break; + } + } + } + + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + }; +} + +char ExternalFunctionsPassedConstants::ID = 0; +static RegisterPass<ExternalFunctionsPassedConstants> + P1("print-externalfnconstants", + "Print external fn callsites passed constants"); diff --git a/contrib/libs/llvm14/tools/opt/BreakpointPrinter.cpp b/contrib/libs/llvm14/tools/opt/BreakpointPrinter.cpp new file mode 100644 index 0000000000..a57a8c43c2 --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/BreakpointPrinter.cpp @@ -0,0 +1,71 @@ +//===- BreakpointPrinter.cpp - Breakpoint location printer ----------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Breakpoint location printer. +/// +//===----------------------------------------------------------------------===// +#include "BreakpointPrinter.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +namespace { + +struct BreakpointPrinter : public ModulePass { + raw_ostream &Out; + static char ID; + + BreakpointPrinter(raw_ostream &out) : ModulePass(ID), Out(out) {} + + void getContextName(const DIScope *Context, std::string &N) { + if (auto *NS = dyn_cast<DINamespace>(Context)) { + if (!NS->getName().empty()) { + getContextName(NS->getScope(), N); + N = N + NS->getName().str() + "::"; + } + } else if (auto *TY = dyn_cast<DIType>(Context)) { + if (!TY->getName().empty()) { + getContextName(TY->getScope(), N); + N = N + TY->getName().str() + "::"; + } + } + } + + bool runOnModule(Module &M) override { + StringSet<> Processed; + if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) + for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { + std::string Name; + auto *SP = cast_or_null<DISubprogram>(NMD->getOperand(i)); + if (!SP) + continue; + getContextName(SP->getScope(), Name); + Name = Name + SP->getName().str(); + if (!Name.empty() && Processed.insert(Name).second) { + Out << Name << "\n"; + } + } + return false; + } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } +}; + +char BreakpointPrinter::ID = 0; +} + +ModulePass *llvm::createBreakpointPrinter(raw_ostream &out) { + return new BreakpointPrinter(out); +} diff --git a/contrib/libs/llvm14/tools/opt/BreakpointPrinter.h b/contrib/libs/llvm14/tools/opt/BreakpointPrinter.h new file mode 100644 index 0000000000..2877555f85 --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/BreakpointPrinter.h @@ -0,0 +1,24 @@ +//===- BreakpointPrinter.h - Breakpoint location printer ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Breakpoint location printer. +/// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_OPT_BREAKPOINTPRINTER_H +#define LLVM_TOOLS_OPT_BREAKPOINTPRINTER_H + +namespace llvm { + +class ModulePass; +class raw_ostream; + +ModulePass *createBreakpointPrinter(raw_ostream &out); +} + +#endif // LLVM_TOOLS_OPT_BREAKPOINTPRINTER_H diff --git a/contrib/libs/llvm14/tools/opt/GraphPrinters.cpp b/contrib/libs/llvm14/tools/opt/GraphPrinters.cpp new file mode 100644 index 0000000000..611fb20513 --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/GraphPrinters.cpp @@ -0,0 +1,45 @@ +//===- GraphPrinters.cpp - DOT printers for various graph types -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines several printers for various different types of graphs used +// by the LLVM infrastructure. It uses the generic graph interface to convert +// the graph into a .dot graph. These graphs can then be processed with the +// "dot" tool to convert them to postscript or some other suitable format. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/Dominators.h" +#include "llvm/Pass.h" + +using namespace llvm; + +//===----------------------------------------------------------------------===// +// DomInfoPrinter Pass +//===----------------------------------------------------------------------===// + +namespace { + class DomInfoPrinter : public FunctionPass { + public: + static char ID; // Pass identification, replacement for typeid + DomInfoPrinter() : FunctionPass(ID) {} + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired<DominatorTreeWrapperPass>(); + } + + bool runOnFunction(Function &F) override { + getAnalysis<DominatorTreeWrapperPass>().print(dbgs()); + return false; + } + }; +} + +char DomInfoPrinter::ID = 0; +static RegisterPass<DomInfoPrinter> +DIP("print-dom-info", "Dominator Info Printer", true, true); diff --git a/contrib/libs/llvm14/tools/opt/NewPMDriver.cpp b/contrib/libs/llvm14/tools/opt/NewPMDriver.cpp new file mode 100644 index 0000000000..af33089394 --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/NewPMDriver.cpp @@ -0,0 +1,495 @@ +//===- NewPMDriver.cpp - Driver for opt with new PM -----------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file is just a split of the code that logically belongs in opt.cpp but +/// that includes the new pass manager headers. +/// +//===----------------------------------------------------------------------===// + +#include "NewPMDriver.h" +#include "PassPrinters.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/Analysis/CGSCCPassManager.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/IR/Dominators.h" +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Verifier.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/Passes/PassPlugin.h" +#include "llvm/Passes/StandardInstrumentations.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" +#include "llvm/Transforms/Instrumentation/AddressSanitizer.h" +#include "llvm/Transforms/Scalar/LoopPassManager.h" +#include "llvm/Transforms/Utils/Debugify.h" + +using namespace llvm; +using namespace opt_tool; + +namespace llvm { +cl::opt<bool> DebugifyEach( + "debugify-each", + cl::desc("Start each pass with debugify and end it with check-debugify")); + +cl::opt<std::string> + DebugifyExport("debugify-export", + cl::desc("Export per-pass debugify statistics to this file"), + cl::value_desc("filename")); +} // namespace llvm + +enum class DebugLogging { None, Normal, Verbose, Quiet }; + +static cl::opt<DebugLogging> DebugPM( + "debug-pass-manager", cl::Hidden, cl::ValueOptional, + cl::desc("Print pass management debugging information"), + cl::init(DebugLogging::None), + cl::values( + clEnumValN(DebugLogging::Normal, "", ""), + clEnumValN(DebugLogging::Quiet, "quiet", + "Skip printing info about analyses"), + clEnumValN( + DebugLogging::Verbose, "verbose", + "Print extra information about adaptors and pass managers"))); + +static cl::list<std::string> + PassPlugins("load-pass-plugin", + cl::desc("Load passes from plugin library")); + +// This flag specifies a textual description of the alias analysis pipeline to +// use when querying for aliasing information. It only works in concert with +// the "passes" flag above. +static cl::opt<std::string> + AAPipeline("aa-pipeline", + cl::desc("A textual description of the alias analysis " + "pipeline for handling managed aliasing queries"), + cl::Hidden, cl::init("default")); + +/// {{@ These options accept textual pipeline descriptions which will be +/// inserted into default pipelines at the respective extension points +static cl::opt<std::string> PeepholeEPPipeline( + "passes-ep-peephole", + cl::desc("A textual description of the function pass pipeline inserted at " + "the Peephole extension points into default pipelines"), + cl::Hidden); +static cl::opt<std::string> LateLoopOptimizationsEPPipeline( + "passes-ep-late-loop-optimizations", + cl::desc( + "A textual description of the loop pass pipeline inserted at " + "the LateLoopOptimizations extension point into default pipelines"), + cl::Hidden); +static cl::opt<std::string> LoopOptimizerEndEPPipeline( + "passes-ep-loop-optimizer-end", + cl::desc("A textual description of the loop pass pipeline inserted at " + "the LoopOptimizerEnd extension point into default pipelines"), + cl::Hidden); +static cl::opt<std::string> ScalarOptimizerLateEPPipeline( + "passes-ep-scalar-optimizer-late", + cl::desc("A textual description of the function pass pipeline inserted at " + "the ScalarOptimizerLate extension point into default pipelines"), + cl::Hidden); +static cl::opt<std::string> CGSCCOptimizerLateEPPipeline( + "passes-ep-cgscc-optimizer-late", + cl::desc("A textual description of the cgscc pass pipeline inserted at " + "the CGSCCOptimizerLate extension point into default pipelines"), + cl::Hidden); +static cl::opt<std::string> VectorizerStartEPPipeline( + "passes-ep-vectorizer-start", + cl::desc("A textual description of the function pass pipeline inserted at " + "the VectorizerStart extension point into default pipelines"), + cl::Hidden); +static cl::opt<std::string> PipelineStartEPPipeline( + "passes-ep-pipeline-start", + cl::desc("A textual description of the module pass pipeline inserted at " + "the PipelineStart extension point into default pipelines"), + cl::Hidden); +static cl::opt<std::string> PipelineEarlySimplificationEPPipeline( + "passes-ep-pipeline-early-simplification", + cl::desc("A textual description of the module pass pipeline inserted at " + "the EarlySimplification extension point into default pipelines"), + cl::Hidden); +static cl::opt<std::string> OptimizerLastEPPipeline( + "passes-ep-optimizer-last", + cl::desc("A textual description of the module pass pipeline inserted at " + "the OptimizerLast extension point into default pipelines"), + cl::Hidden); + +// Individual pipeline tuning options. +extern cl::opt<bool> DisableLoopUnrolling; + +namespace llvm { +extern cl::opt<PGOKind> PGOKindFlag; +extern cl::opt<std::string> ProfileFile; +extern cl::opt<CSPGOKind> CSPGOKindFlag; +extern cl::opt<std::string> CSProfileGenFile; +extern cl::opt<bool> DisableBasicAA; +extern cl::opt<bool> PrintPipelinePasses; +} // namespace llvm + +static cl::opt<std::string> + ProfileRemappingFile("profile-remapping-file", + cl::desc("Path to the profile remapping file."), + cl::Hidden); +static cl::opt<bool> DebugInfoForProfiling( + "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden, + cl::desc("Emit special debug info to enable PGO profile generation.")); +static cl::opt<bool> PseudoProbeForProfiling( + "new-pm-pseudo-probe-for-profiling", cl::init(false), cl::Hidden, + cl::desc("Emit pseudo probes to enable PGO profile generation.")); +/// @}} + +template <typename PassManagerT> +bool tryParsePipelineText(PassBuilder &PB, + const cl::opt<std::string> &PipelineOpt) { + if (PipelineOpt.empty()) + return false; + + // Verify the pipeline is parseable: + PassManagerT PM; + if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) { + errs() << "Could not parse -" << PipelineOpt.ArgStr + << " pipeline: " << toString(std::move(Err)) + << "... I'm going to ignore it.\n"; + return false; + } + return true; +} + +/// If one of the EPPipeline command line options was given, register callbacks +/// for parsing and inserting the given pipeline +static void registerEPCallbacks(PassBuilder &PB) { + if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline)) + PB.registerPeepholeEPCallback( + [&PB](FunctionPassManager &PM, OptimizationLevel Level) { + ExitOnError Err("Unable to parse PeepholeEP pipeline: "); + Err(PB.parsePassPipeline(PM, PeepholeEPPipeline)); + }); + if (tryParsePipelineText<LoopPassManager>(PB, + LateLoopOptimizationsEPPipeline)) + PB.registerLateLoopOptimizationsEPCallback( + [&PB](LoopPassManager &PM, OptimizationLevel Level) { + ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: "); + Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline)); + }); + if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline)) + PB.registerLoopOptimizerEndEPCallback( + [&PB](LoopPassManager &PM, OptimizationLevel Level) { + ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: "); + Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline)); + }); + if (tryParsePipelineText<FunctionPassManager>(PB, + ScalarOptimizerLateEPPipeline)) + PB.registerScalarOptimizerLateEPCallback( + [&PB](FunctionPassManager &PM, OptimizationLevel Level) { + ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: "); + Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline)); + }); + if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline)) + PB.registerCGSCCOptimizerLateEPCallback( + [&PB](CGSCCPassManager &PM, OptimizationLevel Level) { + ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: "); + Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline)); + }); + if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline)) + PB.registerVectorizerStartEPCallback( + [&PB](FunctionPassManager &PM, OptimizationLevel Level) { + ExitOnError Err("Unable to parse VectorizerStartEP pipeline: "); + Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline)); + }); + if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline)) + PB.registerPipelineStartEPCallback( + [&PB](ModulePassManager &PM, OptimizationLevel) { + ExitOnError Err("Unable to parse PipelineStartEP pipeline: "); + Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline)); + }); + if (tryParsePipelineText<ModulePassManager>( + PB, PipelineEarlySimplificationEPPipeline)) + PB.registerPipelineEarlySimplificationEPCallback( + [&PB](ModulePassManager &PM, OptimizationLevel) { + ExitOnError Err("Unable to parse EarlySimplification pipeline: "); + Err(PB.parsePassPipeline(PM, PipelineEarlySimplificationEPPipeline)); + }); + if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline)) + PB.registerOptimizerLastEPCallback( + [&PB](ModulePassManager &PM, OptimizationLevel) { + ExitOnError Err("Unable to parse OptimizerLastEP pipeline: "); + Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline)); + }); +} + +#define HANDLE_EXTENSION(Ext) \ + llvm::PassPluginLibraryInfo get##Ext##PluginInfo(); +#include "llvm/Support/Extension.def" + +bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, + TargetLibraryInfoImpl *TLII, ToolOutputFile *Out, + ToolOutputFile *ThinLTOLinkOut, + ToolOutputFile *OptRemarkFile, + StringRef PassPipeline, ArrayRef<StringRef> Passes, + OutputKind OK, VerifierKind VK, + bool ShouldPreserveAssemblyUseListOrder, + bool ShouldPreserveBitcodeUseListOrder, + bool EmitSummaryIndex, bool EmitModuleHash, + bool EnableDebugify) { + bool VerifyEachPass = VK == VK_VerifyEachPass; + + Optional<PGOOptions> P; + switch (PGOKindFlag) { + case InstrGen: + P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr); + break; + case InstrUse: + P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse); + break; + case SampleUse: + P = PGOOptions(ProfileFile, "", ProfileRemappingFile, + PGOOptions::SampleUse); + break; + case NoPGO: + if (DebugInfoForProfiling || PseudoProbeForProfiling) + P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction, + DebugInfoForProfiling, PseudoProbeForProfiling); + else + P = None; + } + if (CSPGOKindFlag != NoCSPGO) { + if (P && (P->Action == PGOOptions::IRInstr || + P->Action == PGOOptions::SampleUse)) + errs() << "CSPGOKind cannot be used with IRInstr or SampleUse"; + if (CSPGOKindFlag == CSInstrGen) { + if (CSProfileGenFile.empty()) + errs() << "CSInstrGen needs to specify CSProfileGenFile"; + if (P) { + P->CSAction = PGOOptions::CSIRInstr; + P->CSProfileGenFile = CSProfileGenFile; + } else + P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile, + PGOOptions::NoAction, PGOOptions::CSIRInstr); + } else /* CSPGOKindFlag == CSInstrUse */ { + if (!P) + errs() << "CSInstrUse needs to be together with InstrUse"; + P->CSAction = PGOOptions::CSIRUse; + } + } + if (TM) + TM->setPGOOption(P); + + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + + PassInstrumentationCallbacks PIC; + PrintPassOptions PrintPassOpts; + PrintPassOpts.Verbose = DebugPM == DebugLogging::Verbose; + PrintPassOpts.SkipAnalyses = DebugPM == DebugLogging::Quiet; + StandardInstrumentations SI(DebugPM != DebugLogging::None, VerifyEachPass, + PrintPassOpts); + SI.registerCallbacks(PIC, &FAM); + DebugifyEachInstrumentation Debugify; + if (DebugifyEach) + Debugify.registerCallbacks(PIC); + + PipelineTuningOptions PTO; + // LoopUnrolling defaults on to true and DisableLoopUnrolling is initialized + // to false above so we shouldn't necessarily need to check whether or not the + // option has been enabled. + PTO.LoopUnrolling = !DisableLoopUnrolling; + PassBuilder PB(TM, PTO, P, &PIC); + registerEPCallbacks(PB); + + // Load requested pass plugins and let them register pass builder callbacks + for (auto &PluginFN : PassPlugins) { + auto PassPlugin = PassPlugin::Load(PluginFN); + if (!PassPlugin) { + errs() << "Failed to load passes from '" << PluginFN + << "'. Request ignored.\n"; + continue; + } + + PassPlugin->registerPassBuilderCallbacks(PB); + } + + PB.registerPipelineParsingCallback( + [](StringRef Name, ModulePassManager &MPM, + ArrayRef<PassBuilder::PipelineElement>) { + AddressSanitizerOptions Opts; + if (Name == "asan-pipeline") { + MPM.addPass( + RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); + MPM.addPass(ModuleAddressSanitizerPass(Opts)); + return true; + } else if (Name == "asan-function-pipeline") { + MPM.addPass( + RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>()); + MPM.addPass( + createModuleToFunctionPassAdaptor(AddressSanitizerPass(Opts))); + return true; + } + return false; + }); + +#define HANDLE_EXTENSION(Ext) \ + get##Ext##PluginInfo().RegisterPassBuilderCallbacks(PB); +#include "llvm/Support/Extension.def" + + // Specially handle the alias analysis manager so that we can register + // a custom pipeline of AA passes with it. + AAManager AA; + if (Passes.empty()) { + if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) { + errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; + return false; + } + } + + // For compatibility with the legacy PM AA pipeline. + // AAResultsWrapperPass by default provides basic-aa in the legacy PM + // unless -disable-basic-aa is specified. + // TODO: remove this once tests implicitly requiring basic-aa use -passes= and + // -aa-pipeline=basic-aa. + if (!Passes.empty() && !DisableBasicAA) { + if (auto Err = PB.parseAAPipeline(AA, "basic-aa")) { + errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; + return false; + } + } + + // For compatibility with legacy pass manager. + // Alias analyses are not specially specified when using the legacy PM. + for (auto PassName : Passes) { + if (PB.isAAPassName(PassName)) { + if (auto Err = PB.parseAAPipeline(AA, PassName)) { + errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; + return false; + } + } + } + + // Register the AA manager first so that our version is the one used. + FAM.registerPass([&] { return std::move(AA); }); + // Register our TargetLibraryInfoImpl. + FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); }); + + // Register all the basic analyses with the managers. + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + + ModulePassManager MPM; + if (VK > VK_NoVerifier) + MPM.addPass(VerifierPass()); + if (EnableDebugify) + MPM.addPass(NewPMDebugifyPass()); + + // Add passes according to the -passes options. + if (!PassPipeline.empty()) { + assert(Passes.empty() && + "PassPipeline and Passes should not both contain passes"); + if (auto Err = PB.parsePassPipeline(MPM, PassPipeline)) { + errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; + return false; + } + } + // Add passes specified using the legacy PM syntax (i.e. not using + // -passes). This should be removed later when such support has been + // deprecated, i.e. when all lit tests running opt (and not using + // -enable-new-pm=0) have been updated to use -passes. + for (auto PassName : Passes) { + std::string ModifiedPassName(PassName.begin(), PassName.end()); + if (PB.isAnalysisPassName(PassName)) + ModifiedPassName = "require<" + ModifiedPassName + ">"; + // FIXME: These translations are supposed to be removed when lit tests that + // use these names have been updated to use the -passes syntax (and when the + // support for using the old syntax to specify passes is considered as + // deprecated for the new PM). + if (ModifiedPassName == "early-cse-memssa") + ModifiedPassName = "early-cse<memssa>"; + else if (ModifiedPassName == "post-inline-ee-instrument") + ModifiedPassName = "ee-instrument<post-inline>"; + else if (ModifiedPassName == "loop-extract-single") + ModifiedPassName = "loop-extract<single>"; + else if (ModifiedPassName == "lower-matrix-intrinsics-minimal") + ModifiedPassName = "lower-matrix-intrinsics<minimal>"; + if (auto Err = PB.parsePassPipeline(MPM, ModifiedPassName)) { + errs() << Arg0 << ": " << toString(std::move(Err)) << "\n"; + return false; + } + } + + if (VK > VK_NoVerifier) + MPM.addPass(VerifierPass()); + if (EnableDebugify) + MPM.addPass(NewPMCheckDebugifyPass()); + + // Add any relevant output pass at the end of the pipeline. + switch (OK) { + case OK_NoOutput: + break; // No output pass needed. + case OK_OutputAssembly: + MPM.addPass( + PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder)); + break; + case OK_OutputBitcode: + MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder, + EmitSummaryIndex, EmitModuleHash)); + break; + case OK_OutputThinLTOBitcode: + MPM.addPass(ThinLTOBitcodeWriterPass( + Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr)); + break; + } + + // Before executing passes, print the final values of the LLVM options. + cl::PrintOptionValues(); + + // Print a textual, '-passes=' compatible, representation of pipeline if + // requested. + if (PrintPipelinePasses) { + MPM.printPipeline(outs(), [&PIC](StringRef ClassName) { + auto PassName = PIC.getPassNameForClassName(ClassName); + return PassName.empty() ? ClassName : PassName; + }); + outs() << "\n"; + return true; + } + + // Now that we have all of the passes ready, run them. + MPM.run(M, MAM); + + // Declare success. + if (OK != OK_NoOutput) { + Out->keep(); + if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut) + ThinLTOLinkOut->keep(); + } + + if (OptRemarkFile) + OptRemarkFile->keep(); + + if (DebugifyEach && !DebugifyExport.empty()) + exportDebugifyStats(DebugifyExport, Debugify.StatsMap); + + return true; +} + +void llvm::printPasses(raw_ostream &OS) { + PassBuilder PB; + PB.printPassNames(OS); +} diff --git a/contrib/libs/llvm14/tools/opt/NewPMDriver.h b/contrib/libs/llvm14/tools/opt/NewPMDriver.h new file mode 100644 index 0000000000..056f7d6a9b --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/NewPMDriver.h @@ -0,0 +1,79 @@ +//===- NewPMDriver.h - Function to drive opt with the new PM ----*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// A single function which is called to drive the opt behavior for the new +/// PassManager. +/// +/// This is only in a separate TU with a header to avoid including all of the +/// old pass manager headers and the new pass manager headers into the same +/// file. Eventually all of the routines here will get folded back into +/// opt.cpp. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_OPT_NEWPMDRIVER_H +#define LLVM_TOOLS_OPT_NEWPMDRIVER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/CommandLine.h" + +namespace llvm { +class StringRef; +class Module; +class TargetMachine; +class ToolOutputFile; +class TargetLibraryInfoImpl; + +extern cl::opt<bool> DebugifyEach; +extern cl::opt<std::string> DebugifyExport; + +namespace opt_tool { +enum OutputKind { + OK_NoOutput, + OK_OutputAssembly, + OK_OutputBitcode, + OK_OutputThinLTOBitcode, +}; +enum VerifierKind { + VK_NoVerifier, + VK_VerifyInAndOut, + VK_VerifyEachPass +}; +enum PGOKind { + NoPGO, + InstrGen, + InstrUse, + SampleUse +}; +enum CSPGOKind { NoCSPGO, CSInstrGen, CSInstrUse }; +} + +void printPasses(raw_ostream &OS); + +/// Driver function to run the new pass manager over a module. +/// +/// This function only exists factored away from opt.cpp in order to prevent +/// inclusion of the new pass manager headers and the old headers into the same +/// file. It's interface is consequentially somewhat ad-hoc, but will go away +/// when the transition finishes. +/// +/// ThinLTOLinkOut is only used when OK is OK_OutputThinLTOBitcode, and can be +/// nullptr. +bool runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM, + TargetLibraryInfoImpl *TLII, ToolOutputFile *Out, + ToolOutputFile *ThinLinkOut, ToolOutputFile *OptRemarkFile, + StringRef PassPipeline, ArrayRef<StringRef> PassInfos, + opt_tool::OutputKind OK, opt_tool::VerifierKind VK, + bool ShouldPreserveAssemblyUseListOrder, + bool ShouldPreserveBitcodeUseListOrder, + bool EmitSummaryIndex, bool EmitModuleHash, + bool EnableDebugify); +} // namespace llvm + +#endif diff --git a/contrib/libs/llvm14/tools/opt/PassPrinters.cpp b/contrib/libs/llvm14/tools/opt/PassPrinters.cpp new file mode 100644 index 0000000000..4e81b5d29c --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/PassPrinters.cpp @@ -0,0 +1,212 @@ +//===- PassPrinters.cpp - Utilities to print analysis info for passes -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Utilities to print analysis info for various kinds of passes. +/// +//===----------------------------------------------------------------------===// + +#include "PassPrinters.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/CallGraphSCCPass.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/RegionInfo.h" +#include "llvm/Analysis/RegionPass.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Function.h" +#include "llvm/Pass.h" +#include "llvm/Support/raw_ostream.h" +#include <string> + +using namespace llvm; + +namespace { + +struct FunctionPassPrinter : public FunctionPass { + const PassInfo *PassToPrint; + raw_ostream &Out; + static char ID; + std::string PassName; + + FunctionPassPrinter(const PassInfo *PI, raw_ostream &out) + : FunctionPass(ID), PassToPrint(PI), Out(out) { + std::string PassToPrintName = std::string(PassToPrint->getPassName()); + PassName = "FunctionPass Printer: " + PassToPrintName; + } + + bool runOnFunction(Function &F) override { + Out << "Printing analysis '" << PassToPrint->getPassName() + << "' for function '" << F.getName() << "':\n"; + + // Get and print pass... + getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, F.getParent()); + return false; + } + + StringRef getPassName() const override { return PassName; } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char FunctionPassPrinter::ID = 0; + +struct CallGraphSCCPassPrinter : public CallGraphSCCPass { + static char ID; + const PassInfo *PassToPrint; + raw_ostream &Out; + std::string PassName; + + CallGraphSCCPassPrinter(const PassInfo *PI, raw_ostream &out) + : CallGraphSCCPass(ID), PassToPrint(PI), Out(out) { + std::string PassToPrintName = std::string(PassToPrint->getPassName()); + PassName = "CallGraphSCCPass Printer: " + PassToPrintName; + } + + bool runOnSCC(CallGraphSCC &SCC) override { + Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + + // Get and print pass... + for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { + Function *F = (*I)->getFunction(); + if (F) + getAnalysisID<Pass>(PassToPrint->getTypeInfo()) + .print(Out, F->getParent()); + } + return false; + } + + StringRef getPassName() const override { return PassName; } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char CallGraphSCCPassPrinter::ID = 0; + +struct ModulePassPrinter : public ModulePass { + static char ID; + const PassInfo *PassToPrint; + raw_ostream &Out; + std::string PassName; + + ModulePassPrinter(const PassInfo *PI, raw_ostream &out) + : ModulePass(ID), PassToPrint(PI), Out(out) { + std::string PassToPrintName = std::string(PassToPrint->getPassName()); + PassName = "ModulePass Printer: " + PassToPrintName; + } + + bool runOnModule(Module &M) override { + Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + + // Get and print pass... + getAnalysisID<Pass>(PassToPrint->getTypeInfo()).print(Out, &M); + return false; + } + + StringRef getPassName() const override { return PassName; } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char ModulePassPrinter::ID = 0; + +struct LoopPassPrinter : public LoopPass { + static char ID; + const PassInfo *PassToPrint; + raw_ostream &Out; + std::string PassName; + + LoopPassPrinter(const PassInfo *PI, raw_ostream &out) + : LoopPass(ID), PassToPrint(PI), Out(out) { + std::string PassToPrintName = std::string(PassToPrint->getPassName()); + PassName = "LoopPass Printer: " + PassToPrintName; + } + + bool runOnLoop(Loop *L, LPPassManager &LPM) override { + Out << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + + // Get and print pass... + getAnalysisID<Pass>(PassToPrint->getTypeInfo()) + .print(Out, L->getHeader()->getParent()->getParent()); + return false; + } + + StringRef getPassName() const override { return PassName; } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char LoopPassPrinter::ID = 0; + +struct RegionPassPrinter : public RegionPass { + static char ID; + const PassInfo *PassToPrint; + raw_ostream &Out; + std::string PassName; + + RegionPassPrinter(const PassInfo *PI, raw_ostream &out) + : RegionPass(ID), PassToPrint(PI), Out(out) { + std::string PassToPrintName = std::string(PassToPrint->getPassName()); + PassName = "RegionPass Printer: " + PassToPrintName; + } + + bool runOnRegion(Region *R, RGPassManager &RGM) override { + Out << "Printing analysis '" << PassToPrint->getPassName() << "' for " + << "region: '" << R->getNameStr() << "' in function '" + << R->getEntry()->getParent()->getName() << "':\n"; + // Get and print pass... + getAnalysisID<Pass>(PassToPrint->getTypeInfo()) + .print(Out, R->getEntry()->getParent()->getParent()); + return false; + } + + StringRef getPassName() const override { return PassName; } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.addRequiredID(PassToPrint->getTypeInfo()); + AU.setPreservesAll(); + } +}; + +char RegionPassPrinter::ID = 0; + +} // end anonymous namespace + +FunctionPass *llvm::createFunctionPassPrinter(const PassInfo *PI, + raw_ostream &OS) { + return new FunctionPassPrinter(PI, OS); +} + +CallGraphSCCPass *llvm::createCallGraphPassPrinter(const PassInfo *PI, + raw_ostream &OS) { + return new CallGraphSCCPassPrinter(PI, OS); +} + +ModulePass *llvm::createModulePassPrinter(const PassInfo *PI, raw_ostream &OS) { + return new ModulePassPrinter(PI, OS); +} + +LoopPass *llvm::createLoopPassPrinter(const PassInfo *PI, raw_ostream &OS) { + return new LoopPassPrinter(PI, OS); +} + +RegionPass *llvm::createRegionPassPrinter(const PassInfo *PI, raw_ostream &OS) { + return new RegionPassPrinter(PI, OS); +} diff --git a/contrib/libs/llvm14/tools/opt/PassPrinters.h b/contrib/libs/llvm14/tools/opt/PassPrinters.h new file mode 100644 index 0000000000..a4e1921399 --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/PassPrinters.h @@ -0,0 +1,40 @@ +//=- PassPrinters.h - Utilities to print analysis info for passes -*- C++ -*-=// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Utilities to print analysis info for various kinds of passes. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_OPT_PASSPRINTERS_H +#define LLVM_TOOLS_OPT_PASSPRINTERS_H + +namespace llvm { + +class CallGraphSCCPass; +class FunctionPass; +class ModulePass; +class LoopPass; +class PassInfo; +class raw_ostream; +class RegionPass; + +FunctionPass *createFunctionPassPrinter(const PassInfo *PI, raw_ostream &out); + +CallGraphSCCPass *createCallGraphPassPrinter(const PassInfo *PI, + raw_ostream &out); + +ModulePass *createModulePassPrinter(const PassInfo *PI, raw_ostream &out); + +LoopPass *createLoopPassPrinter(const PassInfo *PI, raw_ostream &out); + +RegionPass *createRegionPassPrinter(const PassInfo *PI, raw_ostream &out); + +} // end namespace llvm + +#endif // LLVM_TOOLS_OPT_PASSPRINTERS_H diff --git a/contrib/libs/llvm14/tools/opt/PrintSCC.cpp b/contrib/libs/llvm14/tools/opt/PrintSCC.cpp new file mode 100644 index 0000000000..1ca52745ff --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/PrintSCC.cpp @@ -0,0 +1,111 @@ +//===- PrintSCC.cpp - Enumerate SCCs in some key graphs -------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides passes to print out SCCs in a CFG or a CallGraph. +// Normally, you would not use these passes; instead, you would use the +// scc_iterator directly to enumerate SCCs and process them in some way. These +// passes serve three purposes: +// +// (1) As a reference for how to use the scc_iterator. +// (2) To print out the SCCs for a CFG or a CallGraph: +// analyze -print-cfg-sccs to print the SCCs in each CFG of a module. +// analyze -print-cfg-sccs -stats to print the #SCCs and the maximum SCC size. +// analyze -print-cfg-sccs -debug > /dev/null to watch the algorithm in action. +// +// and similarly: +// analyze -print-callgraph-sccs [-stats] [-debug] to print SCCs in the CallGraph +// +// (3) To test the scc_iterator. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/SCCIterator.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/IR/CFG.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + +namespace { + struct CFGSCC : public FunctionPass { + static char ID; // Pass identification, replacement for typeid + CFGSCC() : FunctionPass(ID) {} + bool runOnFunction(Function& func) override; + + void print(raw_ostream &O, const Module* = nullptr) const override { } + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + }; + + struct CallGraphSCC : public ModulePass { + static char ID; // Pass identification, replacement for typeid + CallGraphSCC() : ModulePass(ID) {} + + // run - Print out SCCs in the call graph for the specified module. + bool runOnModule(Module &M) override; + + void print(raw_ostream &O, const Module* = nullptr) const override { } + + // getAnalysisUsage - This pass requires the CallGraph. + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + AU.addRequired<CallGraphWrapperPass>(); + } + }; +} + +char CFGSCC::ID = 0; +static RegisterPass<CFGSCC> +Y("print-cfg-sccs", "Print SCCs of each function CFG"); + +char CallGraphSCC::ID = 0; +static RegisterPass<CallGraphSCC> +Z("print-callgraph-sccs", "Print SCCs of the Call Graph"); + +bool CFGSCC::runOnFunction(Function &F) { + unsigned sccNum = 0; + errs() << "SCCs for Function " << F.getName() << " in PostOrder:"; + for (scc_iterator<Function*> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) { + const std::vector<BasicBlock *> &nextSCC = *SCCI; + errs() << "\nSCC #" << ++sccNum << " : "; + for (BasicBlock *BB : nextSCC) { + BB->printAsOperand(errs(), false); + errs() << ", "; + } + if (nextSCC.size() == 1 && SCCI.hasCycle()) + errs() << " (Has self-loop)."; + } + errs() << "\n"; + + return true; +} + + +// run - Print out SCCs in the call graph for the specified module. +bool CallGraphSCC::runOnModule(Module &M) { + CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph(); + unsigned sccNum = 0; + errs() << "SCCs for the program in PostOrder:"; + for (scc_iterator<CallGraph*> SCCI = scc_begin(&CG); !SCCI.isAtEnd(); + ++SCCI) { + const std::vector<CallGraphNode*> &nextSCC = *SCCI; + errs() << "\nSCC #" << ++sccNum << " : "; + for (std::vector<CallGraphNode*>::const_iterator I = nextSCC.begin(), + E = nextSCC.end(); I != E; ++I) + errs() << ((*I)->getFunction() ? (*I)->getFunction()->getName() + : "external node") << ", "; + if (nextSCC.size() == 1 && SCCI.hasCycle()) + errs() << " (Has self-loop)."; + } + errs() << "\n"; + + return true; +} diff --git a/contrib/libs/llvm14/tools/opt/opt.cpp b/contrib/libs/llvm14/tools/opt/opt.cpp new file mode 100644 index 0000000000..7793a54717 --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/opt.cpp @@ -0,0 +1,1090 @@ +//===- opt.cpp - The LLVM Modular Optimizer -------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Optimizations may be specified an arbitrary number of times on the command +// line, They are run in the order specified. +// +//===----------------------------------------------------------------------===// + +#include "BreakpointPrinter.h" +#include "NewPMDriver.h" +#include "PassPrinters.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/CallGraphSCCPass.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/RegionPass.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/AsmParser/Parser.h" +#include "llvm/CodeGen/CommandFlags.h" +#include "llvm/CodeGen/TargetPassConfig.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LLVMRemarkStreamer.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/IR/LegacyPassNameParser.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/InitializePasses.h" +#include "llvm/LinkAllIR.h" +#include "llvm/LinkAllPasses.h" +#include "llvm/MC/SubtargetFeature.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Remarks/HotnessThresholdParser.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/InitLLVM.h" +#include "llvm/Support/PluginLoader.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/SystemUtils.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/Coroutines.h" +#include "llvm/Transforms/IPO/AlwaysInliner.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Transforms/IPO/WholeProgramDevirt.h" +#include "llvm/Transforms/Utils/Cloning.h" +#include "llvm/Transforms/Utils/Debugify.h" +#include <algorithm> +#include <memory> +using namespace llvm; +using namespace opt_tool; + +static codegen::RegisterCodeGenFlags CFG; + +// The OptimizationList is automatically populated with registered Passes by the +// PassNameParser. +static cl::list<const PassInfo *, bool, PassNameParser> PassList(cl::desc( + "Optimizations available (use '-passes=' for the new pass manager)")); + +static cl::opt<bool> EnableNewPassManager( + "enable-new-pm", + cl::desc("Enable the new pass manager, translating " + "'opt -foo' to 'opt -passes=foo'. This is strictly for the new PM " + "migration, use '-passes=' when possible."), + cl::init(LLVM_ENABLE_NEW_PASS_MANAGER)); + +// This flag specifies a textual description of the optimization pass pipeline +// to run over the module. This flag switches opt to use the new pass manager +// infrastructure, completely disabling all of the flags specific to the old +// pass management. +static cl::opt<std::string> PassPipeline( + "passes", + cl::desc( + "A textual description of the pass pipeline. To have analysis passes " + "available before a certain pass, add 'require<foo-analysis>'.")); + +static cl::opt<bool> PrintPasses("print-passes", + cl::desc("Print available passes that can be " + "specified in -passes=foo and exit")); + +static cl::opt<std::string> +InputFilename(cl::Positional, cl::desc("<input bitcode file>"), + cl::init("-"), cl::value_desc("filename")); + +static cl::opt<std::string> +OutputFilename("o", cl::desc("Override output filename"), + cl::value_desc("filename")); + +static cl::opt<bool> +Force("f", cl::desc("Enable binary output on terminals")); + +static cl::opt<bool> +NoOutput("disable-output", + cl::desc("Do not write result bitcode file"), cl::Hidden); + +static cl::opt<bool> +OutputAssembly("S", cl::desc("Write output as LLVM assembly")); + +static cl::opt<bool> + OutputThinLTOBC("thinlto-bc", + cl::desc("Write output as ThinLTO-ready bitcode")); + +static cl::opt<bool> + SplitLTOUnit("thinlto-split-lto-unit", + cl::desc("Enable splitting of a ThinLTO LTOUnit")); + +static cl::opt<std::string> ThinLinkBitcodeFile( + "thin-link-bitcode-file", cl::value_desc("filename"), + cl::desc( + "A file in which to write minimized bitcode for the thin link only")); + +static cl::opt<bool> +NoVerify("disable-verify", cl::desc("Do not run the verifier"), cl::Hidden); + +static cl::opt<bool> NoUpgradeDebugInfo("disable-upgrade-debug-info", + cl::desc("Generate invalid output"), + cl::ReallyHidden); + +static cl::opt<bool> VerifyEach("verify-each", + cl::desc("Verify after each transform")); + +static cl::opt<bool> + DisableDITypeMap("disable-debug-info-type-map", + cl::desc("Don't use a uniquing type map for debug info")); + +static cl::opt<bool> +StripDebug("strip-debug", + cl::desc("Strip debugger symbol info from translation unit")); + +static cl::opt<bool> + StripNamedMetadata("strip-named-metadata", + cl::desc("Strip module-level named metadata")); + + + +static cl::opt<bool> + OptLevelO0("O0", cl::desc("Optimization level 0. Similar to clang -O0. " + "Use -passes='default<O0>' for the new PM")); + +static cl::opt<bool> + OptLevelO1("O1", cl::desc("Optimization level 1. Similar to clang -O1. " + "Use -passes='default<O1>' for the new PM")); + +static cl::opt<bool> + OptLevelO2("O2", cl::desc("Optimization level 2. Similar to clang -O2. " + "Use -passes='default<O2>' for the new PM")); + +static cl::opt<bool> + OptLevelOs("Os", cl::desc("Like -O2 but size-conscious. Similar to clang " + "-Os. Use -passes='default<Os>' for the new PM")); + +static cl::opt<bool> OptLevelOz( + "Oz", + cl::desc("Like -O2 but optimize for code size above all else. Similar to " + "clang -Oz. Use -passes='default<Oz>' for the new PM")); + +static cl::opt<bool> + OptLevelO3("O3", cl::desc("Optimization level 3. Similar to clang -O3. " + "Use -passes='default<O3>' for the new PM")); + +static cl::opt<unsigned> CodeGenOptLevel( + "codegen-opt-level", + cl::desc("Override optimization level for codegen hooks, legacy PM only")); + +static cl::opt<std::string> +TargetTriple("mtriple", cl::desc("Override target triple for module")); + +cl::opt<bool> DisableLoopUnrolling( + "disable-loop-unrolling", + cl::desc("Disable loop unrolling in all relevant passes"), cl::init(false)); + +static cl::opt<bool> EmitSummaryIndex("module-summary", + cl::desc("Emit module summary index"), + cl::init(false)); + +static cl::opt<bool> EmitModuleHash("module-hash", cl::desc("Emit module hash"), + cl::init(false)); + +static cl::opt<bool> +DisableSimplifyLibCalls("disable-simplify-libcalls", + cl::desc("Disable simplify-libcalls")); + +static cl::list<std::string> +DisableBuiltins("disable-builtin", + cl::desc("Disable specific target library builtin function"), + cl::ZeroOrMore); + +static cl::opt<bool> + AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization. " + "Legacy pass manager only.")); + +static cl::opt<bool> EnableDebugify( + "enable-debugify", + cl::desc( + "Start the pipeline with debugify and end it with check-debugify")); + +static cl::opt<bool> VerifyDebugInfoPreserve( + "verify-debuginfo-preserve", + cl::desc("Start the pipeline with collecting and end it with checking of " + "debug info preservation.")); + +static cl::opt<bool> VerifyEachDebugInfoPreserve( + "verify-each-debuginfo-preserve", + cl::desc("Start each pass with collecting and end it with checking of " + "debug info preservation.")); + +static cl::opt<std::string> + VerifyDIPreserveExport("verify-di-preserve-export", + cl::desc("Export debug info preservation failures into " + "specified (JSON) file (should be abs path as we use" + " append mode to insert new JSON objects)"), + cl::value_desc("filename"), cl::init("")); + +static cl::opt<bool> +PrintBreakpoints("print-breakpoints-for-testing", + cl::desc("Print select breakpoints location for testing")); + +static cl::opt<std::string> ClDataLayout("data-layout", + cl::desc("data layout string to use"), + cl::value_desc("layout-string"), + cl::init("")); + +static cl::opt<bool> PreserveBitcodeUseListOrder( + "preserve-bc-uselistorder", + cl::desc("Preserve use-list order when writing LLVM bitcode."), + cl::init(true), cl::Hidden); + +static cl::opt<bool> PreserveAssemblyUseListOrder( + "preserve-ll-uselistorder", + cl::desc("Preserve use-list order when writing LLVM assembly."), + cl::init(false), cl::Hidden); + +static cl::opt<bool> RunTwice("run-twice", + cl::desc("Run all passes twice, re-using the " + "same pass manager (legacy PM only)."), + cl::init(false), cl::Hidden); + +static cl::opt<bool> DiscardValueNames( + "discard-value-names", + cl::desc("Discard names from Value (other than GlobalValue)."), + cl::init(false), cl::Hidden); + +static cl::opt<bool> Coroutines( + "enable-coroutines", + cl::desc("Enable coroutine passes."), + cl::init(false), cl::Hidden); + +static cl::opt<bool> TimeTrace( + "time-trace", + cl::desc("Record time trace")); + +static cl::opt<unsigned> TimeTraceGranularity( + "time-trace-granularity", + cl::desc("Minimum time granularity (in microseconds) traced by time profiler"), + cl::init(500), cl::Hidden); + +static cl::opt<std::string> + TimeTraceFile("time-trace-file", + cl::desc("Specify time trace file destination"), + cl::value_desc("filename")); + +static cl::opt<bool> RemarksWithHotness( + "pass-remarks-with-hotness", + cl::desc("With PGO, include profile count in optimization remarks"), + cl::Hidden); + +static cl::opt<Optional<uint64_t>, false, remarks::HotnessThresholdParser> + RemarksHotnessThreshold( + "pass-remarks-hotness-threshold", + cl::desc("Minimum profile count required for " + "an optimization remark to be output. " + "Use 'auto' to apply the threshold from profile summary."), + cl::value_desc("N or 'auto'"), cl::init(0), cl::Hidden); + +static cl::opt<std::string> + RemarksFilename("pass-remarks-output", + cl::desc("Output filename for pass remarks"), + cl::value_desc("filename")); + +static cl::opt<std::string> + RemarksPasses("pass-remarks-filter", + cl::desc("Only record optimization remarks from passes whose " + "names match the given regular expression"), + cl::value_desc("regex")); + +static cl::opt<std::string> RemarksFormat( + "pass-remarks-format", + cl::desc("The format used for serializing remarks (default: YAML)"), + cl::value_desc("format"), cl::init("yaml")); + +namespace llvm { +cl::opt<PGOKind> + PGOKindFlag("pgo-kind", cl::init(NoPGO), cl::Hidden, + cl::desc("The kind of profile guided optimization"), + cl::values(clEnumValN(NoPGO, "nopgo", "Do not use PGO."), + clEnumValN(InstrGen, "pgo-instr-gen-pipeline", + "Instrument the IR to generate profile."), + clEnumValN(InstrUse, "pgo-instr-use-pipeline", + "Use instrumented profile to guide PGO."), + clEnumValN(SampleUse, "pgo-sample-use-pipeline", + "Use sampled profile to guide PGO."))); +cl::opt<std::string> ProfileFile("profile-file", + cl::desc("Path to the profile."), cl::Hidden); + +cl::opt<CSPGOKind> CSPGOKindFlag( + "cspgo-kind", cl::init(NoCSPGO), cl::Hidden, + cl::desc("The kind of context sensitive profile guided optimization"), + cl::values( + clEnumValN(NoCSPGO, "nocspgo", "Do not use CSPGO."), + clEnumValN( + CSInstrGen, "cspgo-instr-gen-pipeline", + "Instrument (context sensitive) the IR to generate profile."), + clEnumValN( + CSInstrUse, "cspgo-instr-use-pipeline", + "Use instrumented (context sensitive) profile to guide PGO."))); +cl::opt<std::string> CSProfileGenFile( + "cs-profilegen-file", + cl::desc("Path to the instrumented context sensitive profile."), + cl::Hidden); +} // namespace llvm + +static inline void addPass(legacy::PassManagerBase &PM, Pass *P) { + // Add the pass to the pass manager... + PM.add(P); + + // If we are verifying all of the intermediate steps, add the verifier... + if (VerifyEach) + PM.add(createVerifierPass()); +} + +/// This routine adds optimization passes based on selected optimization level, +/// OptLevel. +/// +/// OptLevel - Optimization Level +static void AddOptimizationPasses(legacy::PassManagerBase &MPM, + legacy::FunctionPassManager &FPM, + TargetMachine *TM, unsigned OptLevel, + unsigned SizeLevel) { + if (!NoVerify || VerifyEach) + FPM.add(createVerifierPass()); // Verify that input is correct + + PassManagerBuilder Builder; + Builder.OptLevel = OptLevel; + Builder.SizeLevel = SizeLevel; + + if (OptLevel > 1) { + Builder.Inliner = createFunctionInliningPass(OptLevel, SizeLevel, false); + } else { + Builder.Inliner = createAlwaysInlinerLegacyPass(); + } + Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? + DisableLoopUnrolling : OptLevel == 0; + + Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; + + Builder.SLPVectorize = OptLevel > 1 && SizeLevel < 2; + + if (TM) + TM->adjustPassManager(Builder); + + if (Coroutines) + addCoroutinePassesToExtensionPoints(Builder); + + switch (PGOKindFlag) { + case InstrGen: + Builder.EnablePGOInstrGen = true; + Builder.PGOInstrGen = ProfileFile; + break; + case InstrUse: + Builder.PGOInstrUse = ProfileFile; + break; + case SampleUse: + Builder.PGOSampleUse = ProfileFile; + break; + default: + break; + } + + switch (CSPGOKindFlag) { + case CSInstrGen: + Builder.EnablePGOCSInstrGen = true; + break; + case CSInstrUse: + Builder.EnablePGOCSInstrUse = true; + break; + default: + break; + } + + Builder.populateFunctionPassManager(FPM); + Builder.populateModulePassManager(MPM); +} + +//===----------------------------------------------------------------------===// +// CodeGen-related helper functions. +// + +static CodeGenOpt::Level GetCodeGenOptLevel() { + if (CodeGenOptLevel.getNumOccurrences()) + return static_cast<CodeGenOpt::Level>(unsigned(CodeGenOptLevel)); + if (OptLevelO1) + return CodeGenOpt::Less; + if (OptLevelO2) + return CodeGenOpt::Default; + if (OptLevelO3) + return CodeGenOpt::Aggressive; + return CodeGenOpt::None; +} + +// Returns the TargetMachine instance or zero if no triple is provided. +static TargetMachine* GetTargetMachine(Triple TheTriple, StringRef CPUStr, + StringRef FeaturesStr, + const TargetOptions &Options) { + std::string Error; + const Target *TheTarget = + TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); + // Some modules don't specify a triple, and this is okay. + if (!TheTarget) { + return nullptr; + } + + return TheTarget->createTargetMachine( + TheTriple.getTriple(), codegen::getCPUStr(), codegen::getFeaturesStr(), + Options, codegen::getExplicitRelocModel(), + codegen::getExplicitCodeModel(), GetCodeGenOptLevel()); +} + +#ifdef BUILD_EXAMPLES +void initializeExampleIRTransforms(llvm::PassRegistry &Registry); +#endif + +struct TimeTracerRAII { + TimeTracerRAII(StringRef ProgramName) { + if (TimeTrace) + timeTraceProfilerInitialize(TimeTraceGranularity, ProgramName); + } + ~TimeTracerRAII() { + if (TimeTrace) { + if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) { + handleAllErrors(std::move(E), [&](const StringError &SE) { + errs() << SE.getMessage() << "\n"; + }); + return; + } + timeTraceProfilerCleanup(); + } + } +}; + +// For use in NPM transition. Currently this contains most codegen-specific +// passes. Remove passes from here when porting to the NPM. +// TODO: use a codegen version of PassRegistry.def/PassBuilder::is*Pass() once +// it exists. +static bool shouldPinPassToLegacyPM(StringRef Pass) { + std::vector<StringRef> PassNameExactToIgnore = { + "nvvm-reflect", + "nvvm-intr-range", + "amdgpu-simplifylib", + "amdgpu-usenative", + "amdgpu-promote-alloca", + "amdgpu-promote-alloca-to-vector", + "amdgpu-lower-kernel-attributes", + "amdgpu-propagate-attributes-early", + "amdgpu-propagate-attributes-late", + "amdgpu-unify-metadata", + "amdgpu-printf-runtime-binding", + "amdgpu-always-inline"}; + if (llvm::is_contained(PassNameExactToIgnore, Pass)) + return false; + + std::vector<StringRef> PassNamePrefix = { + "x86-", "xcore-", "wasm-", "systemz-", "ppc-", "nvvm-", + "nvptx-", "mips-", "lanai-", "hexagon-", "bpf-", "avr-", + "thumb2-", "arm-", "si-", "gcn-", "amdgpu-", "aarch64-", + "amdgcn-", "polly-", "riscv-"}; + std::vector<StringRef> PassNameContain = {"ehprepare"}; + std::vector<StringRef> PassNameExact = { + "safe-stack", "cost-model", + "codegenprepare", "interleaved-load-combine", + "unreachableblockelim", "verify-safepoint-ir", + "atomic-expand", "expandvp", + "hardware-loops", "type-promotion", + "mve-tail-predication", "interleaved-access", + "global-merge", "pre-isel-intrinsic-lowering", + "expand-reductions", "indirectbr-expand", + "generic-to-nvvm", "expandmemcmp", + "loop-reduce", "lower-amx-type", + "pre-amx-config", "lower-amx-intrinsics", + "polyhedral-info", "replace-with-veclib"}; + for (const auto &P : PassNamePrefix) + if (Pass.startswith(P)) + return true; + for (const auto &P : PassNameContain) + if (Pass.contains(P)) + return true; + return llvm::is_contained(PassNameExact, Pass); +} + +// For use in NPM transition. +static bool shouldForceLegacyPM() { + for (const auto &P : PassList) { + StringRef Arg = P->getPassArgument(); + if (shouldPinPassToLegacyPM(Arg)) + return true; + } + return false; +} + +//===----------------------------------------------------------------------===// +// main for opt +// +int main(int argc, char **argv) { + InitLLVM X(argc, argv); + + // Enable debug stream buffering. + EnableDebugBuffering = true; + + InitializeAllTargets(); + InitializeAllTargetMCs(); + InitializeAllAsmPrinters(); + InitializeAllAsmParsers(); + + // Initialize passes + PassRegistry &Registry = *PassRegistry::getPassRegistry(); + initializeCore(Registry); + initializeCoroutines(Registry); + initializeScalarOpts(Registry); + initializeObjCARCOpts(Registry); + initializeVectorization(Registry); + initializeIPO(Registry); + initializeAnalysis(Registry); + initializeTransformUtils(Registry); + initializeInstCombine(Registry); + initializeAggressiveInstCombine(Registry); + initializeInstrumentation(Registry); + initializeTarget(Registry); + // For codegen passes, only passes that do IR to IR transformation are + // supported. + initializeExpandMemCmpPassPass(Registry); + initializeScalarizeMaskedMemIntrinLegacyPassPass(Registry); + initializeCodeGenPreparePass(Registry); + initializeAtomicExpandPass(Registry); + initializeRewriteSymbolsLegacyPassPass(Registry); + initializeWinEHPreparePass(Registry); + initializeDwarfEHPrepareLegacyPassPass(Registry); + initializeSafeStackLegacyPassPass(Registry); + initializeSjLjEHPreparePass(Registry); + initializePreISelIntrinsicLoweringLegacyPassPass(Registry); + initializeGlobalMergePass(Registry); + initializeIndirectBrExpandPassPass(Registry); + initializeInterleavedLoadCombinePass(Registry); + initializeInterleavedAccessPass(Registry); + initializeEntryExitInstrumenterPass(Registry); + initializePostInlineEntryExitInstrumenterPass(Registry); + initializeUnreachableBlockElimLegacyPassPass(Registry); + initializeExpandReductionsPass(Registry); + initializeExpandVectorPredicationPass(Registry); + initializeWasmEHPreparePass(Registry); + initializeWriteBitcodePassPass(Registry); + initializeHardwareLoopsPass(Registry); + initializeTypePromotionPass(Registry); + initializeReplaceWithVeclibLegacyPass(Registry); + +#ifdef BUILD_EXAMPLES + initializeExampleIRTransforms(Registry); +#endif + + cl::ParseCommandLineOptions(argc, argv, + "llvm .bc -> .bc modular optimizer and analysis printer\n"); + + LLVMContext Context; + + if (AnalyzeOnly && NoOutput) { + errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n"; + return 1; + } + + // FIXME: once the legacy PM code is deleted, move runPassPipeline() here and + // construct the PassBuilder before parsing IR so we can reuse the same + // PassBuilder for print passes. + if (PrintPasses) { + printPasses(outs()); + return 0; + } + + TimeTracerRAII TimeTracer(argv[0]); + + SMDiagnostic Err; + + Context.setDiscardValueNames(DiscardValueNames); + if (!DisableDITypeMap) + Context.enableDebugTypeODRUniquing(); + + Expected<std::unique_ptr<ToolOutputFile>> RemarksFileOrErr = + setupLLVMOptimizationRemarks(Context, RemarksFilename, RemarksPasses, + RemarksFormat, RemarksWithHotness, + RemarksHotnessThreshold); + if (Error E = RemarksFileOrErr.takeError()) { + errs() << toString(std::move(E)) << '\n'; + return 1; + } + std::unique_ptr<ToolOutputFile> RemarksFile = std::move(*RemarksFileOrErr); + + // Load the input module... + auto SetDataLayout = [](StringRef) -> Optional<std::string> { + if (ClDataLayout.empty()) + return None; + return ClDataLayout; + }; + std::unique_ptr<Module> M; + if (NoUpgradeDebugInfo) + M = parseAssemblyFileWithIndexNoUpgradeDebugInfo( + InputFilename, Err, Context, nullptr, SetDataLayout) + .Mod; + else + M = parseIRFile(InputFilename, Err, Context, SetDataLayout); + + if (!M) { + Err.print(argv[0], errs()); + return 1; + } + + // Strip debug info before running the verifier. + if (StripDebug) + StripDebugInfo(*M); + + // Erase module-level named metadata, if requested. + if (StripNamedMetadata) { + while (!M->named_metadata_empty()) { + NamedMDNode *NMD = &*M->named_metadata_begin(); + M->eraseNamedMetadata(NMD); + } + } + + // If we are supposed to override the target triple or data layout, do so now. + if (!TargetTriple.empty()) + M->setTargetTriple(Triple::normalize(TargetTriple)); + + // Immediately run the verifier to catch any problems before starting up the + // pass pipelines. Otherwise we can crash on broken code during + // doInitialization(). + if (!NoVerify && verifyModule(*M, &errs())) { + errs() << argv[0] << ": " << InputFilename + << ": error: input module is broken!\n"; + return 1; + } + + // Enable testing of whole program devirtualization on this module by invoking + // the facility for updating public visibility to linkage unit visibility when + // specified by an internal option. This is normally done during LTO which is + // not performed via opt. + updateVCallVisibilityInModule(*M, + /* WholeProgramVisibilityEnabledInLTO */ false, + /* DynamicExportSymbols */ {}); + + // Figure out what stream we are supposed to write to... + std::unique_ptr<ToolOutputFile> Out; + std::unique_ptr<ToolOutputFile> ThinLinkOut; + if (NoOutput) { + if (!OutputFilename.empty()) + errs() << "WARNING: The -o (output filename) option is ignored when\n" + "the --disable-output option is used.\n"; + } else { + // Default to standard output. + if (OutputFilename.empty()) + OutputFilename = "-"; + + std::error_code EC; + sys::fs::OpenFlags Flags = + OutputAssembly ? sys::fs::OF_TextWithCRLF : sys::fs::OF_None; + Out.reset(new ToolOutputFile(OutputFilename, EC, Flags)); + if (EC) { + errs() << EC.message() << '\n'; + return 1; + } + + if (!ThinLinkBitcodeFile.empty()) { + ThinLinkOut.reset( + new ToolOutputFile(ThinLinkBitcodeFile, EC, sys::fs::OF_None)); + if (EC) { + errs() << EC.message() << '\n'; + return 1; + } + } + } + + Triple ModuleTriple(M->getTargetTriple()); + std::string CPUStr, FeaturesStr; + TargetMachine *Machine = nullptr; + const TargetOptions Options = + codegen::InitTargetOptionsFromCodeGenFlags(ModuleTriple); + + if (ModuleTriple.getArch()) { + CPUStr = codegen::getCPUStr(); + FeaturesStr = codegen::getFeaturesStr(); + Machine = GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options); + } else if (ModuleTriple.getArchName() != "unknown" && + ModuleTriple.getArchName() != "") { + errs() << argv[0] << ": unrecognized architecture '" + << ModuleTriple.getArchName() << "' provided.\n"; + return 1; + } + + std::unique_ptr<TargetMachine> TM(Machine); + + // Override function attributes based on CPUStr, FeaturesStr, and command line + // flags. + codegen::setFunctionAttributes(CPUStr, FeaturesStr, *M); + + // If the output is set to be emitted to standard out, and standard out is a + // console, print out a warning message and refuse to do it. We don't + // impress anyone by spewing tons of binary goo to a terminal. + if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) + if (CheckBitcodeOutputToConsole(Out->os())) + NoOutput = true; + + if (OutputThinLTOBC) + M->addModuleFlag(Module::Error, "EnableSplitLTOUnit", SplitLTOUnit); + + // Add an appropriate TargetLibraryInfo pass for the module's triple. + TargetLibraryInfoImpl TLII(ModuleTriple); + + // The -disable-simplify-libcalls flag actually disables all builtin optzns. + if (DisableSimplifyLibCalls) + TLII.disableAllFunctions(); + else { + // Disable individual builtin functions in TargetLibraryInfo. + LibFunc F; + for (auto &FuncName : DisableBuiltins) + if (TLII.getLibFunc(FuncName, F)) + TLII.setUnavailable(F); + else { + errs() << argv[0] << ": cannot disable nonexistent builtin function " + << FuncName << '\n'; + return 1; + } + } + + // If `-passes=` is specified, use NPM. + // If `-enable-new-pm` is specified and there are no codegen passes, use NPM. + // e.g. `-enable-new-pm -sroa` will use NPM. + // but `-enable-new-pm -codegenprepare` will still revert to legacy PM. + if ((EnableNewPassManager && !shouldForceLegacyPM()) || + PassPipeline.getNumOccurrences() > 0) { + if (AnalyzeOnly) { + errs() << "Cannot specify -analyze under new pass manager, either " + "specify '-enable-new-pm=0', or use the corresponding new pass " + "manager pass, e.g. '-passes=print<scalar-evolution>'. For a " + "full list of passes, see the '--print-passes' flag.\n"; + return 1; + } + if (legacy::debugPassSpecified()) { + errs() + << "-debug-pass does not work with the new PM, either use " + "-debug-pass-manager, or use the legacy PM (-enable-new-pm=0)\n"; + return 1; + } + if (PassPipeline.getNumOccurrences() > 0 && PassList.size() > 0) { + errs() + << "Cannot specify passes via both -foo-pass and --passes=foo-pass\n"; + return 1; + } + auto NumOLevel = OptLevelO0 + OptLevelO1 + OptLevelO2 + OptLevelO3 + + OptLevelOs + OptLevelOz; + if (NumOLevel > 1) { + errs() << "Cannot specify multiple -O#\n"; + return 1; + } + if (NumOLevel > 0 && PassPipeline.getNumOccurrences() > 0) { + errs() << "Cannot specify -O# and --passes=, use " + "-passes='default<O#>,other-pass'\n"; + return 1; + } + std::string Pipeline = PassPipeline; + + SmallVector<StringRef, 4> Passes; + if (OptLevelO0) + Pipeline = "default<O0>"; + if (OptLevelO1) + Pipeline = "default<O1>"; + if (OptLevelO2) + Pipeline = "default<O2>"; + if (OptLevelO3) + Pipeline = "default<O3>"; + if (OptLevelOs) + Pipeline = "default<Os>"; + if (OptLevelOz) + Pipeline = "default<Oz>"; + for (const auto &P : PassList) + Passes.push_back(P->getPassArgument()); + OutputKind OK = OK_NoOutput; + if (!NoOutput) + OK = OutputAssembly + ? OK_OutputAssembly + : (OutputThinLTOBC ? OK_OutputThinLTOBitcode : OK_OutputBitcode); + + VerifierKind VK = VK_VerifyInAndOut; + if (NoVerify) + VK = VK_NoVerifier; + else if (VerifyEach) + VK = VK_VerifyEachPass; + + // The user has asked to use the new pass manager and provided a pipeline + // string. Hand off the rest of the functionality to the new code for that + // layer. + return runPassPipeline(argv[0], *M, TM.get(), &TLII, Out.get(), + ThinLinkOut.get(), RemarksFile.get(), Pipeline, + Passes, OK, VK, PreserveAssemblyUseListOrder, + PreserveBitcodeUseListOrder, EmitSummaryIndex, + EmitModuleHash, EnableDebugify) + ? 0 + : 1; + } + + // Create a PassManager to hold and optimize the collection of passes we are + // about to build. If the -debugify-each option is set, wrap each pass with + // the (-check)-debugify passes. + DebugifyCustomPassManager Passes; + DebugifyStatsMap DIStatsMap; + DebugInfoPerPassMap DIPreservationMap; + if (DebugifyEach) { + Passes.setDebugifyMode(DebugifyMode::SyntheticDebugInfo); + Passes.setDIStatsMap(DIStatsMap); + } else if (VerifyEachDebugInfoPreserve) { + Passes.setDebugifyMode(DebugifyMode::OriginalDebugInfo); + Passes.setDIPreservationMap(DIPreservationMap); + if (!VerifyDIPreserveExport.empty()) + Passes.setOrigDIVerifyBugsReportFilePath(VerifyDIPreserveExport); + } + + bool AddOneTimeDebugifyPasses = + (EnableDebugify && !DebugifyEach) || + (VerifyDebugInfoPreserve && !VerifyEachDebugInfoPreserve); + + Passes.add(new TargetLibraryInfoWrapperPass(TLII)); + + // Add internal analysis passes from the target machine. + Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis() + : TargetIRAnalysis())); + + if (AddOneTimeDebugifyPasses) { + if (EnableDebugify) { + Passes.setDIStatsMap(DIStatsMap); + Passes.add(createDebugifyModulePass()); + } else if (VerifyDebugInfoPreserve) { + Passes.setDIPreservationMap(DIPreservationMap); + Passes.add(createDebugifyModulePass( + DebugifyMode::OriginalDebugInfo, "", + &(Passes.getDebugInfoPerPassMap()))); + } + } + + std::unique_ptr<legacy::FunctionPassManager> FPasses; + if (OptLevelO0 || OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || + OptLevelO3) { + FPasses.reset(new legacy::FunctionPassManager(M.get())); + FPasses->add(createTargetTransformInfoWrapperPass( + TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())); + } + + if (PrintBreakpoints) { + // Default to standard output. + if (!Out) { + if (OutputFilename.empty()) + OutputFilename = "-"; + + std::error_code EC; + Out = std::make_unique<ToolOutputFile>(OutputFilename, EC, + sys::fs::OF_None); + if (EC) { + errs() << EC.message() << '\n'; + return 1; + } + } + Passes.add(createBreakpointPrinter(Out->os())); + NoOutput = true; + } + + if (TM) { + // FIXME: We should dyn_cast this when supported. + auto <M = static_cast<LLVMTargetMachine &>(*TM); + Pass *TPC = LTM.createPassConfig(Passes); + Passes.add(TPC); + } + + // Create a new optimization pass for each one specified on the command line + for (unsigned i = 0; i < PassList.size(); ++i) { + if (OptLevelO0 && OptLevelO0.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, TM.get(), 0, 0); + OptLevelO0 = false; + } + + if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, TM.get(), 1, 0); + OptLevelO1 = false; + } + + if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 0); + OptLevelO2 = false; + } + + if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 1); + OptLevelOs = false; + } + + if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 2); + OptLevelOz = false; + } + + if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, TM.get(), 3, 0); + OptLevelO3 = false; + } + + const PassInfo *PassInf = PassList[i]; + Pass *P = nullptr; + if (PassInf->getNormalCtor()) + P = PassInf->getNormalCtor()(); + else + errs() << argv[0] << ": cannot create pass: " + << PassInf->getPassName() << "\n"; + if (P) { + PassKind Kind = P->getPassKind(); + addPass(Passes, P); + + if (AnalyzeOnly) { + switch (Kind) { + case PT_Region: + Passes.add(createRegionPassPrinter(PassInf, Out->os())); + break; + case PT_Loop: + Passes.add(createLoopPassPrinter(PassInf, Out->os())); + break; + case PT_Function: + Passes.add(createFunctionPassPrinter(PassInf, Out->os())); + break; + case PT_CallGraphSCC: + Passes.add(createCallGraphPassPrinter(PassInf, Out->os())); + break; + default: + Passes.add(createModulePassPrinter(PassInf, Out->os())); + break; + } + } + } + } + + if (OptLevelO0) + AddOptimizationPasses(Passes, *FPasses, TM.get(), 0, 0); + + if (OptLevelO1) + AddOptimizationPasses(Passes, *FPasses, TM.get(), 1, 0); + + if (OptLevelO2) + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 0); + + if (OptLevelOs) + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 1); + + if (OptLevelOz) + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 2); + + if (OptLevelO3) + AddOptimizationPasses(Passes, *FPasses, TM.get(), 3, 0); + + if (FPasses) { + FPasses->doInitialization(); + for (Function &F : *M) + FPasses->run(F); + FPasses->doFinalization(); + } + + // Check that the module is well formed on completion of optimization + if (!NoVerify && !VerifyEach) + Passes.add(createVerifierPass()); + + if (AddOneTimeDebugifyPasses) { + if (EnableDebugify) + Passes.add(createCheckDebugifyModulePass(false)); + else if (VerifyDebugInfoPreserve) { + if (!VerifyDIPreserveExport.empty()) + Passes.setOrigDIVerifyBugsReportFilePath(VerifyDIPreserveExport); + Passes.add(createCheckDebugifyModulePass( + false, "", nullptr, DebugifyMode::OriginalDebugInfo, + &(Passes.getDebugInfoPerPassMap()), VerifyDIPreserveExport)); + } + } + + // In run twice mode, we want to make sure the output is bit-by-bit + // equivalent if we run the pass manager again, so setup two buffers and + // a stream to write to them. Note that llc does something similar and it + // may be worth to abstract this out in the future. + SmallVector<char, 0> Buffer; + SmallVector<char, 0> FirstRunBuffer; + std::unique_ptr<raw_svector_ostream> BOS; + raw_ostream *OS = nullptr; + + const bool ShouldEmitOutput = !NoOutput && !AnalyzeOnly; + + // Write bitcode or assembly to the output as the last step... + if (ShouldEmitOutput || RunTwice) { + assert(Out); + OS = &Out->os(); + if (RunTwice) { + BOS = std::make_unique<raw_svector_ostream>(Buffer); + OS = BOS.get(); + } + if (OutputAssembly) { + if (EmitSummaryIndex) + report_fatal_error("Text output is incompatible with -module-summary"); + if (EmitModuleHash) + report_fatal_error("Text output is incompatible with -module-hash"); + Passes.add(createPrintModulePass(*OS, "", PreserveAssemblyUseListOrder)); + } else if (OutputThinLTOBC) + Passes.add(createWriteThinLTOBitcodePass( + *OS, ThinLinkOut ? &ThinLinkOut->os() : nullptr)); + else + Passes.add(createBitcodeWriterPass(*OS, PreserveBitcodeUseListOrder, + EmitSummaryIndex, EmitModuleHash)); + } + + // Before executing passes, print the final values of the LLVM options. + cl::PrintOptionValues(); + + if (!RunTwice) { + // Now that we have all of the passes ready, run them. + Passes.run(*M); + } else { + // If requested, run all passes twice with the same pass manager to catch + // bugs caused by persistent state in the passes. + std::unique_ptr<Module> M2(CloneModule(*M)); + // Run all passes on the original module first, so the second run processes + // the clone to catch CloneModule bugs. + Passes.run(*M); + FirstRunBuffer = Buffer; + Buffer.clear(); + + Passes.run(*M2); + + // Compare the two outputs and make sure they're the same + assert(Out); + if (Buffer.size() != FirstRunBuffer.size() || + (memcmp(Buffer.data(), FirstRunBuffer.data(), Buffer.size()) != 0)) { + errs() + << "Running the pass manager twice changed the output.\n" + "Writing the result of the second run to the specified output.\n" + "To generate the one-run comparison binary, just run without\n" + "the compile-twice option\n"; + if (ShouldEmitOutput) { + Out->os() << BOS->str(); + Out->keep(); + } + if (RemarksFile) + RemarksFile->keep(); + return 1; + } + if (ShouldEmitOutput) + Out->os() << BOS->str(); + } + + if (DebugifyEach && !DebugifyExport.empty()) + exportDebugifyStats(DebugifyExport, Passes.getDebugifyStatsMap()); + + // Declare success. + if (!NoOutput || PrintBreakpoints) + Out->keep(); + + if (RemarksFile) + RemarksFile->keep(); + + if (ThinLinkOut) + ThinLinkOut->keep(); + + return 0; +} diff --git a/contrib/libs/llvm14/tools/opt/ya.make b/contrib/libs/llvm14/tools/opt/ya.make new file mode 100644 index 0000000000..83fdf2510e --- /dev/null +++ b/contrib/libs/llvm14/tools/opt/ya.make @@ -0,0 +1,98 @@ +# Generated by devtools/yamaker. + +PROGRAM() + +LICENSE(Apache-2.0 WITH LLVM-exception) + +LICENSE_TEXTS(.yandex_meta/licenses.list.txt) + +PEERDIR( + contrib/libs/llvm14 + contrib/libs/llvm14/include + contrib/libs/llvm14/lib/Analysis + contrib/libs/llvm14/lib/AsmParser + contrib/libs/llvm14/lib/BinaryFormat + contrib/libs/llvm14/lib/Bitcode/Reader + contrib/libs/llvm14/lib/Bitcode/Writer + contrib/libs/llvm14/lib/Bitstream/Reader + contrib/libs/llvm14/lib/CodeGen + contrib/libs/llvm14/lib/CodeGen/AsmPrinter + contrib/libs/llvm14/lib/CodeGen/GlobalISel + contrib/libs/llvm14/lib/CodeGen/SelectionDAG + contrib/libs/llvm14/lib/DebugInfo/CodeView + contrib/libs/llvm14/lib/DebugInfo/DWARF + contrib/libs/llvm14/lib/Demangle + contrib/libs/llvm14/lib/Extensions + contrib/libs/llvm14/lib/Frontend/OpenMP + contrib/libs/llvm14/lib/IR + contrib/libs/llvm14/lib/IRReader + contrib/libs/llvm14/lib/Linker + contrib/libs/llvm14/lib/MC + contrib/libs/llvm14/lib/MC/MCDisassembler + contrib/libs/llvm14/lib/MC/MCParser + contrib/libs/llvm14/lib/Object + contrib/libs/llvm14/lib/Passes + contrib/libs/llvm14/lib/ProfileData + contrib/libs/llvm14/lib/Remarks + contrib/libs/llvm14/lib/Support + contrib/libs/llvm14/lib/Target + contrib/libs/llvm14/lib/Target/AArch64 + contrib/libs/llvm14/lib/Target/AArch64/AsmParser + contrib/libs/llvm14/lib/Target/AArch64/MCTargetDesc + contrib/libs/llvm14/lib/Target/AArch64/TargetInfo + contrib/libs/llvm14/lib/Target/AArch64/Utils + contrib/libs/llvm14/lib/Target/ARM + contrib/libs/llvm14/lib/Target/ARM/AsmParser + contrib/libs/llvm14/lib/Target/ARM/MCTargetDesc + contrib/libs/llvm14/lib/Target/ARM/TargetInfo + contrib/libs/llvm14/lib/Target/ARM/Utils + contrib/libs/llvm14/lib/Target/BPF + contrib/libs/llvm14/lib/Target/BPF/AsmParser + contrib/libs/llvm14/lib/Target/BPF/MCTargetDesc + contrib/libs/llvm14/lib/Target/BPF/TargetInfo + contrib/libs/llvm14/lib/Target/NVPTX + contrib/libs/llvm14/lib/Target/NVPTX/MCTargetDesc + contrib/libs/llvm14/lib/Target/NVPTX/TargetInfo + contrib/libs/llvm14/lib/Target/PowerPC + contrib/libs/llvm14/lib/Target/PowerPC/AsmParser + contrib/libs/llvm14/lib/Target/PowerPC/MCTargetDesc + contrib/libs/llvm14/lib/Target/PowerPC/TargetInfo + contrib/libs/llvm14/lib/Target/X86 + contrib/libs/llvm14/lib/Target/X86/AsmParser + contrib/libs/llvm14/lib/Target/X86/MCTargetDesc + contrib/libs/llvm14/lib/Target/X86/TargetInfo + contrib/libs/llvm14/lib/TextAPI + contrib/libs/llvm14/lib/Transforms/AggressiveInstCombine + contrib/libs/llvm14/lib/Transforms/CFGuard + contrib/libs/llvm14/lib/Transforms/Coroutines + contrib/libs/llvm14/lib/Transforms/IPO + contrib/libs/llvm14/lib/Transforms/InstCombine + contrib/libs/llvm14/lib/Transforms/Instrumentation + contrib/libs/llvm14/lib/Transforms/ObjCARC + contrib/libs/llvm14/lib/Transforms/Scalar + contrib/libs/llvm14/lib/Transforms/Utils + contrib/libs/llvm14/lib/Transforms/Vectorize + contrib/libs/llvm14/tools/polly/lib + contrib/libs/llvm14/tools/polly/lib/External/isl + contrib/libs/llvm14/tools/polly/lib/External/ppcg +) + +ADDINCL( + contrib/libs/llvm14/tools/opt +) + +NO_COMPILER_WARNINGS() + +NO_UTIL() + +SRCS( + AnalysisWrappers.cpp + BreakpointPrinter.cpp + GraphPrinters.cpp + NewPMDriver.cpp + PassPrinters.cpp + PrintSCC.cpp + opt.cpp +) + +END() |