diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/llvm12/include/llvm/LTO | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/llvm12/include/llvm/LTO')
9 files changed, 1821 insertions, 0 deletions
diff --git a/contrib/libs/llvm12/include/llvm/LTO/Caching.h b/contrib/libs/llvm12/include/llvm/LTO/Caching.h new file mode 100644 index 0000000000..bada5be3ee --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/Caching.h @@ -0,0 +1,50 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===- Caching.h - LLVM Link Time Optimizer Configuration -----------------===// +// +// 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 the localCache function, which allows clients to add a +// filesystem cache to ThinLTO. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_CACHING_H +#define LLVM_LTO_CACHING_H + +#include "llvm/LTO/LTO.h" +#include <string> + +namespace llvm { +namespace lto { + +/// This type defines the callback to add a pre-existing native object file +/// (e.g. in a cache). +/// +/// Buffer callbacks must be thread safe. +using AddBufferFn = + std::function<void(unsigned Task, std::unique_ptr<MemoryBuffer> MB)>; + +/// Create a local file system cache which uses the given cache directory and +/// file callback. This function also creates the cache directory if it does not +/// already exist. +Expected<NativeObjectCache> localCache(StringRef CacheDirectoryPath, + AddBufferFn AddBuffer); + +} // namespace lto +} // namespace llvm + +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/LTO/Config.h b/contrib/libs/llvm12/include/llvm/LTO/Config.h new file mode 100644 index 0000000000..2c215dd839 --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/Config.h @@ -0,0 +1,293 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-Config.h - LLVM Link Time Optimizer Configuration ---------*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file defines the lto::Config data structure, which allows clients to +// configure LTO. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_CONFIG_H +#define LLVM_LTO_CONFIG_H + +#include "llvm/ADT/DenseSet.h" +#include "llvm/Config/llvm-config.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManager.h" +#include "llvm/Passes/PassBuilder.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Target/TargetOptions.h" + +#include <functional> + +namespace llvm { + +class Error; +class Module; +class ModuleSummaryIndex; +class raw_pwrite_stream; + +namespace lto { + +/// LTO configuration. A linker can configure LTO by setting fields in this data +/// structure and passing it to the lto::LTO constructor. +struct Config { + // Note: when adding fields here, consider whether they need to be added to + // computeCacheKey in LTO.cpp. + std::string CPU; + TargetOptions Options; + std::vector<std::string> MAttrs; + std::vector<std::string> PassPlugins; + /// For adding passes that run right before codegen. + std::function<void(legacy::PassManager &)> PreCodeGenPassesHook; + Optional<Reloc::Model> RelocModel = Reloc::PIC_; + Optional<CodeModel::Model> CodeModel = None; + CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; + CodeGenFileType CGFileType = CGFT_ObjectFile; + unsigned OptLevel = 2; + bool DisableVerify = false; + + /// Use the new pass manager + bool UseNewPM = LLVM_ENABLE_NEW_PASS_MANAGER; + + /// Flag to indicate that the optimizer should not assume builtins are present + /// on the target. + bool Freestanding = false; + + /// Disable entirely the optimizer, including importing for ThinLTO + bool CodeGenOnly = false; + + /// Run PGO context sensitive IR instrumentation. + bool RunCSIRInstr = false; + + /// Asserts whether we can assume whole program visibility during the LTO + /// link. + bool HasWholeProgramVisibility = false; + + /// Always emit a Regular LTO object even when it is empty because no Regular + /// LTO modules were linked. This option is useful for some build system which + /// want to know a priori all possible output files. + bool AlwaysEmitRegularLTOObj = false; + + /// If this field is set, the set of passes run in the middle-end optimizer + /// will be the one specified by the string. Only works with the new pass + /// manager as the old one doesn't have this ability. + std::string OptPipeline; + + // If this field is set, it has the same effect of specifying an AA pipeline + // identified by the string. Only works with the new pass manager, in + // conjunction OptPipeline. + std::string AAPipeline; + + /// Setting this field will replace target triples in input files with this + /// triple. + std::string OverrideTriple; + + /// Setting this field will replace unspecified target triples in input files + /// with this triple. + std::string DefaultTriple; + + /// Context Sensitive PGO profile path. + std::string CSIRProfile; + + /// Sample PGO profile path. + std::string SampleProfile; + + /// Name remapping file for profile data. + std::string ProfileRemapping; + + /// The directory to store .dwo files. + std::string DwoDir; + + /// The name for the split debug info file used for the DW_AT_[GNU_]dwo_name + /// attribute in the skeleton CU. This should generally only be used when + /// running an individual backend directly via thinBackend(), as otherwise + /// all objects would use the same .dwo file. Not used as output path. + std::string SplitDwarfFile; + + /// The path to write a .dwo file to. This should generally only be used when + /// running an individual backend directly via thinBackend(), as otherwise + /// all .dwo files will be written to the same path. Not used in skeleton CU. + std::string SplitDwarfOutput; + + /// Optimization remarks file path. + std::string RemarksFilename; + + /// Optimization remarks pass filter. + std::string RemarksPasses; + + /// Whether to emit optimization remarks with hotness informations. + bool RemarksWithHotness = false; + + /// The minimum hotness value a diagnostic needs in order to be included in + /// optimization diagnostics. + /// + /// The threshold is an Optional value, which maps to one of the 3 states: + /// 1. 0 => threshold disabled. All emarks will be printed. + /// 2. positive int => manual threshold by user. Remarks with hotness exceed + /// threshold will be printed. + /// 3. None => 'auto' threshold by user. The actual value is not + /// available at command line, but will be synced with + /// hotness threhold from profile summary during + /// compilation. + /// + /// If threshold option is not specified, it is disabled by default. + llvm::Optional<uint64_t> RemarksHotnessThreshold = 0; + + /// The format used for serializing remarks (default: YAML). + std::string RemarksFormat; + + /// Whether to emit the pass manager debuggging informations. + bool DebugPassManager = false; + + /// Statistics output file path. + std::string StatsFile; + + /// Specific thinLTO modules to compile. + std::vector<std::string> ThinLTOModulesToCompile; + + /// Time trace enabled. + bool TimeTraceEnabled = false; + + /// Time trace granularity. + unsigned TimeTraceGranularity = 500; + + bool ShouldDiscardValueNames = true; + DiagnosticHandlerFunction DiagHandler; + + /// If this field is set, LTO will write input file paths and symbol + /// resolutions here in llvm-lto2 command line flag format. This can be + /// used for testing and for running the LTO pipeline outside of the linker + /// with llvm-lto2. + std::unique_ptr<raw_ostream> ResolutionFile; + + /// Tunable parameters for passes in the default pipelines. + PipelineTuningOptions PTO; + + /// The following callbacks deal with tasks, which normally represent the + /// entire optimization and code generation pipeline for what will become a + /// single native object file. Each task has a unique identifier between 0 and + /// getMaxTasks()-1, which is supplied to the callback via the Task parameter. + /// A task represents the entire pipeline for ThinLTO and regular + /// (non-parallel) LTO, but a parallel code generation task will be split into + /// N tasks before code generation, where N is the parallelism level. + /// + /// LTO may decide to stop processing a task at any time, for example if the + /// module is empty or if a module hook (see below) returns false. For this + /// reason, the client should not expect to receive exactly getMaxTasks() + /// native object files. + + /// A module hook may be used by a linker to perform actions during the LTO + /// pipeline. For example, a linker may use this function to implement + /// -save-temps. If this function returns false, any further processing for + /// that task is aborted. + /// + /// Module hooks must be thread safe with respect to the linker's internal + /// data structures. A module hook will never be called concurrently from + /// multiple threads with the same task ID, or the same module. + /// + /// Note that in out-of-process backend scenarios, none of the hooks will be + /// called for ThinLTO tasks. + using ModuleHookFn = std::function<bool(unsigned Task, const Module &)>; + + /// This module hook is called after linking (regular LTO) or loading + /// (ThinLTO) the module, before modifying it. + ModuleHookFn PreOptModuleHook; + + /// This hook is called after promoting any internal functions + /// (ThinLTO-specific). + ModuleHookFn PostPromoteModuleHook; + + /// This hook is called after internalizing the module. + ModuleHookFn PostInternalizeModuleHook; + + /// This hook is called after importing from other modules (ThinLTO-specific). + ModuleHookFn PostImportModuleHook; + + /// This module hook is called after optimization is complete. + ModuleHookFn PostOptModuleHook; + + /// This module hook is called before code generation. It is similar to the + /// PostOptModuleHook, but for parallel code generation it is called after + /// splitting the module. + ModuleHookFn PreCodeGenModuleHook; + + /// A combined index hook is called after all per-module indexes have been + /// combined (ThinLTO-specific). It can be used to implement -save-temps for + /// the combined index. + /// + /// If this function returns false, any further processing for ThinLTO tasks + /// is aborted. + /// + /// It is called regardless of whether the backend is in-process, although it + /// is not called from individual backend processes. + using CombinedIndexHookFn = std::function<bool( + const ModuleSummaryIndex &Index, + const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)>; + CombinedIndexHookFn CombinedIndexHook; + + /// This is a convenience function that configures this Config object to write + /// temporary files named after the given OutputFileName for each of the LTO + /// phases to disk. A client can use this function to implement -save-temps. + /// + /// FIXME: Temporary files derived from ThinLTO backends are currently named + /// after the input file name, rather than the output file name, when + /// UseInputModulePath is set to true. + /// + /// Specifically, it (1) sets each of the above module hooks and the combined + /// index hook to a function that calls the hook function (if any) that was + /// present in the appropriate field when the addSaveTemps function was + /// called, and writes the module to a bitcode file with a name prefixed by + /// the given output file name, and (2) creates a resolution file whose name + /// is prefixed by the given output file name and sets ResolutionFile to its + /// file handle. + Error addSaveTemps(std::string OutputFileName, + bool UseInputModulePath = false); +}; + +struct LTOLLVMDiagnosticHandler : public DiagnosticHandler { + DiagnosticHandlerFunction *Fn; + LTOLLVMDiagnosticHandler(DiagnosticHandlerFunction *DiagHandlerFn) + : Fn(DiagHandlerFn) {} + bool handleDiagnostics(const DiagnosticInfo &DI) override { + (*Fn)(DI); + return true; + } +}; +/// A derived class of LLVMContext that initializes itself according to a given +/// Config object. The purpose of this class is to tie ownership of the +/// diagnostic handler to the context, as opposed to the Config object (which +/// may be ephemeral). +// FIXME: This should not be required as diagnostic handler is not callback. +struct LTOLLVMContext : LLVMContext { + + LTOLLVMContext(const Config &C) : DiagHandler(C.DiagHandler) { + setDiscardValueNames(C.ShouldDiscardValueNames); + enableDebugTypeODRUniquing(); + setDiagnosticHandler( + std::make_unique<LTOLLVMDiagnosticHandler>(&DiagHandler), true); + } + DiagnosticHandlerFunction DiagHandler; +}; + +} +} + +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/LTO/LTO.h b/contrib/libs/llvm12/include/llvm/LTO/LTO.h new file mode 100644 index 0000000000..b02400ad3d --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/LTO.h @@ -0,0 +1,475 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-LTO.h - LLVM Link Time 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 +// +//===----------------------------------------------------------------------===// +// +// This file declares functions and classes used to support LTO. It is intended +// to be used both by LTO classes as well as by clients (gold-plugin) that +// don't utilize the LTO code generator interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_LTO_H +#define LLVM_LTO_LTO_H + +#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/LTO/Config.h" +#include "llvm/Object/IRSymtab.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/thread.h" +#include "llvm/Transforms/IPO/FunctionImport.h" + +namespace llvm { + +class Error; +class IRMover; +class LLVMContext; +class MemoryBufferRef; +class Module; +class raw_pwrite_stream; +class Target; +class ToolOutputFile; + +/// Resolve linkage for prevailing symbols in the \p Index. Linkage changes +/// recorded in the index and the ThinLTO backends must apply the changes to +/// the module via thinLTOResolvePrevailingInModule. +/// +/// This is done for correctness (if value exported, ensure we always +/// emit a copy), and compile-time optimization (allow drop of duplicates). +void thinLTOResolvePrevailingInIndex( + ModuleSummaryIndex &Index, + function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> + isPrevailing, + function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> + recordNewLinkage, + const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols); + +/// Update the linkages in the given \p Index to mark exported values +/// as external and non-exported values as internal. The ThinLTO backends +/// must apply the changes to the Module via thinLTOInternalizeModule. +void thinLTOInternalizeAndPromoteInIndex( + ModuleSummaryIndex &Index, + function_ref<bool(StringRef, ValueInfo)> isExported, + function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> + isPrevailing); + +/// Computes a unique hash for the Module considering the current list of +/// export/import and other global analysis results. +/// The hash is produced in \p Key. +void computeLTOCacheKey( + SmallString<40> &Key, const lto::Config &Conf, + const ModuleSummaryIndex &Index, StringRef ModuleID, + const FunctionImporter::ImportMapTy &ImportList, + const FunctionImporter::ExportSetTy &ExportList, + const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, + const GVSummaryMapTy &DefinedGlobals, + const std::set<GlobalValue::GUID> &CfiFunctionDefs = {}, + const std::set<GlobalValue::GUID> &CfiFunctionDecls = {}); + +namespace lto { + +/// Given the original \p Path to an output file, replace any path +/// prefix matching \p OldPrefix with \p NewPrefix. Also, create the +/// resulting directory if it does not yet exist. +std::string getThinLTOOutputFile(const std::string &Path, + const std::string &OldPrefix, + const std::string &NewPrefix); + +/// Setup optimization remarks. +Expected<std::unique_ptr<ToolOutputFile>> setupLLVMOptimizationRemarks( + LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, + StringRef RemarksFormat, bool RemarksWithHotness, + Optional<uint64_t> RemarksHotnessThreshold = 0, int Count = -1); + +/// Setups the output file for saving statistics. +Expected<std::unique_ptr<ToolOutputFile>> +setupStatsFile(StringRef StatsFilename); + +/// Produces a container ordering for optimal multi-threaded processing. Returns +/// ordered indices to elements in the input array. +std::vector<int> generateModulesOrdering(ArrayRef<BitcodeModule *> R); + +class LTO; +struct SymbolResolution; +class ThinBackendProc; + +/// An input file. This is a symbol table wrapper that only exposes the +/// information that an LTO client should need in order to do symbol resolution. +class InputFile { +public: + class Symbol; + +private: + // FIXME: Remove LTO class friendship once we have bitcode symbol tables. + friend LTO; + InputFile() = default; + + std::vector<BitcodeModule> Mods; + SmallVector<char, 0> Strtab; + std::vector<Symbol> Symbols; + + // [begin, end) for each module + std::vector<std::pair<size_t, size_t>> ModuleSymIndices; + + StringRef TargetTriple, SourceFileName, COFFLinkerOpts; + std::vector<StringRef> DependentLibraries; + std::vector<StringRef> ComdatTable; + +public: + ~InputFile(); + + /// Create an InputFile. + static Expected<std::unique_ptr<InputFile>> create(MemoryBufferRef Object); + + /// The purpose of this class is to only expose the symbol information that an + /// LTO client should need in order to do symbol resolution. + class Symbol : irsymtab::Symbol { + friend LTO; + + public: + Symbol(const irsymtab::Symbol &S) : irsymtab::Symbol(S) {} + + using irsymtab::Symbol::isUndefined; + using irsymtab::Symbol::isCommon; + using irsymtab::Symbol::isWeak; + using irsymtab::Symbol::isIndirect; + using irsymtab::Symbol::getName; + using irsymtab::Symbol::getIRName; + using irsymtab::Symbol::getVisibility; + using irsymtab::Symbol::canBeOmittedFromSymbolTable; + using irsymtab::Symbol::isTLS; + using irsymtab::Symbol::getComdatIndex; + using irsymtab::Symbol::getCommonSize; + using irsymtab::Symbol::getCommonAlignment; + using irsymtab::Symbol::getCOFFWeakExternalFallback; + using irsymtab::Symbol::getSectionName; + using irsymtab::Symbol::isExecutable; + using irsymtab::Symbol::isUsed; + }; + + /// A range over the symbols in this InputFile. + ArrayRef<Symbol> symbols() const { return Symbols; } + + /// Returns linker options specified in the input file. + StringRef getCOFFLinkerOpts() const { return COFFLinkerOpts; } + + /// Returns dependent library specifiers from the input file. + ArrayRef<StringRef> getDependentLibraries() const { return DependentLibraries; } + + /// Returns the path to the InputFile. + StringRef getName() const; + + /// Returns the input file's target triple. + StringRef getTargetTriple() const { return TargetTriple; } + + /// Returns the source file path specified at compile time. + StringRef getSourceFileName() const { return SourceFileName; } + + // Returns a table with all the comdats used by this file. + ArrayRef<StringRef> getComdatTable() const { return ComdatTable; } + + // Returns the only BitcodeModule from InputFile. + BitcodeModule &getSingleBitcodeModule(); + +private: + ArrayRef<Symbol> module_symbols(unsigned I) const { + const auto &Indices = ModuleSymIndices[I]; + return {Symbols.data() + Indices.first, Symbols.data() + Indices.second}; + } +}; + +/// This class wraps an output stream for a native object. Most clients should +/// just be able to return an instance of this base class from the stream +/// callback, but if a client needs to perform some action after the stream is +/// written to, that can be done by deriving from this class and overriding the +/// destructor. +class NativeObjectStream { +public: + NativeObjectStream(std::unique_ptr<raw_pwrite_stream> OS) : OS(std::move(OS)) {} + std::unique_ptr<raw_pwrite_stream> OS; + virtual ~NativeObjectStream() = default; +}; + +/// This type defines the callback to add a native object that is generated on +/// the fly. +/// +/// Stream callbacks must be thread safe. +using AddStreamFn = + std::function<std::unique_ptr<NativeObjectStream>(unsigned Task)>; + +/// This is the type of a native object cache. To request an item from the +/// cache, pass a unique string as the Key. For hits, the cached file will be +/// added to the link and this function will return AddStreamFn(). For misses, +/// the cache will return a stream callback which must be called at most once to +/// produce content for the stream. The native object stream produced by the +/// stream callback will add the file to the link after the stream is written +/// to. +/// +/// Clients generally look like this: +/// +/// if (AddStreamFn AddStream = Cache(Task, Key)) +/// ProduceContent(AddStream); +using NativeObjectCache = + std::function<AddStreamFn(unsigned Task, StringRef Key)>; + +/// A ThinBackend defines what happens after the thin-link phase during ThinLTO. +/// The details of this type definition aren't important; clients can only +/// create a ThinBackend using one of the create*ThinBackend() functions below. +using ThinBackend = std::function<std::unique_ptr<ThinBackendProc>( + const Config &C, ModuleSummaryIndex &CombinedIndex, + StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, + AddStreamFn AddStream, NativeObjectCache Cache)>; + +/// This ThinBackend runs the individual backend jobs in-process. +/// The default value means to use one job per hardware core (not hyper-thread). +ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism); + +/// This ThinBackend writes individual module indexes to files, instead of +/// running the individual backend jobs. This backend is for distributed builds +/// where separate processes will invoke the real backends. +/// +/// To find the path to write the index to, the backend checks if the path has a +/// prefix of OldPrefix; if so, it replaces that prefix with NewPrefix. It then +/// appends ".thinlto.bc" and writes the index to that path. If +/// ShouldEmitImportsFiles is true it also writes a list of imported files to a +/// similar path with ".imports" appended instead. +/// LinkedObjectsFile is an output stream to write the list of object files for +/// the final ThinLTO linking. Can be nullptr. +/// OnWrite is callback which receives module identifier and notifies LTO user +/// that index file for the module (and optionally imports file) was created. +using IndexWriteCallback = std::function<void(const std::string &)>; +ThinBackend createWriteIndexesThinBackend(std::string OldPrefix, + std::string NewPrefix, + bool ShouldEmitImportsFiles, + raw_fd_ostream *LinkedObjectsFile, + IndexWriteCallback OnWrite); + +/// This class implements a resolution-based interface to LLVM's LTO +/// functionality. It supports regular LTO, parallel LTO code generation and +/// ThinLTO. You can use it from a linker in the following way: +/// - Set hooks and code generation options (see lto::Config struct defined in +/// Config.h), and use the lto::Config object to create an lto::LTO object. +/// - Create lto::InputFile objects using lto::InputFile::create(), then use +/// the symbols() function to enumerate its symbols and compute a resolution +/// for each symbol (see SymbolResolution below). +/// - After the linker has visited each input file (and each regular object +/// file) and computed a resolution for each symbol, take each lto::InputFile +/// and pass it and an array of symbol resolutions to the add() function. +/// - Call the getMaxTasks() function to get an upper bound on the number of +/// native object files that LTO may add to the link. +/// - Call the run() function. This function will use the supplied AddStream +/// and Cache functions to add up to getMaxTasks() native object files to +/// the link. +class LTO { + friend InputFile; + +public: + /// Create an LTO object. A default constructed LTO object has a reasonable + /// production configuration, but you can customize it by passing arguments to + /// this constructor. + /// FIXME: We do currently require the DiagHandler field to be set in Conf. + /// Until that is fixed, a Config argument is required. + LTO(Config Conf, ThinBackend Backend = nullptr, + unsigned ParallelCodeGenParallelismLevel = 1); + ~LTO(); + + /// Add an input file to the LTO link, using the provided symbol resolutions. + /// The symbol resolutions must appear in the enumeration order given by + /// InputFile::symbols(). + Error add(std::unique_ptr<InputFile> Obj, ArrayRef<SymbolResolution> Res); + + /// Returns an upper bound on the number of tasks that the client may expect. + /// This may only be called after all IR object files have been added. For a + /// full description of tasks see LTOBackend.h. + unsigned getMaxTasks() const; + + /// Runs the LTO pipeline. This function calls the supplied AddStream + /// function to add native object files to the link. + /// + /// The Cache parameter is optional. If supplied, it will be used to cache + /// native object files and add them to the link. + /// + /// The client will receive at most one callback (via either AddStream or + /// Cache) for each task identifier. + Error run(AddStreamFn AddStream, NativeObjectCache Cache = nullptr); + + /// Static method that returns a list of libcall symbols that can be generated + /// by LTO but might not be visible from bitcode symbol table. + static ArrayRef<const char*> getRuntimeLibcallSymbols(); + +private: + Config Conf; + + struct RegularLTOState { + RegularLTOState(unsigned ParallelCodeGenParallelismLevel, + const Config &Conf); + struct CommonResolution { + uint64_t Size = 0; + MaybeAlign Align; + /// Record if at least one instance of the common was marked as prevailing + bool Prevailing = false; + }; + std::map<std::string, CommonResolution> Commons; + + unsigned ParallelCodeGenParallelismLevel; + LTOLLVMContext Ctx; + std::unique_ptr<Module> CombinedModule; + std::unique_ptr<IRMover> Mover; + + // This stores the information about a regular LTO module that we have added + // to the link. It will either be linked immediately (for modules without + // summaries) or after summary-based dead stripping (for modules with + // summaries). + struct AddedModule { + std::unique_ptr<Module> M; + std::vector<GlobalValue *> Keep; + }; + std::vector<AddedModule> ModsWithSummaries; + bool EmptyCombinedModule = true; + } RegularLTO; + + using ModuleMapType = MapVector<StringRef, BitcodeModule>; + + struct ThinLTOState { + ThinLTOState(ThinBackend Backend); + + ThinBackend Backend; + ModuleSummaryIndex CombinedIndex; + // The full set of bitcode modules in input order. + ModuleMapType ModuleMap; + // The bitcode modules to compile, if specified by the LTO Config. + Optional<ModuleMapType> ModulesToCompile; + DenseMap<GlobalValue::GUID, StringRef> PrevailingModuleForGUID; + } ThinLTO; + + // The global resolution for a particular (mangled) symbol name. This is in + // particular necessary to track whether each symbol can be internalized. + // Because any input file may introduce a new cross-partition reference, we + // cannot make any final internalization decisions until all input files have + // been added and the client has called run(). During run() we apply + // internalization decisions either directly to the module (for regular LTO) + // or to the combined index (for ThinLTO). + struct GlobalResolution { + /// The unmangled name of the global. + std::string IRName; + + /// Keep track if the symbol is visible outside of a module with a summary + /// (i.e. in either a regular object or a regular LTO module without a + /// summary). + bool VisibleOutsideSummary = false; + + bool UnnamedAddr = true; + + /// True if module contains the prevailing definition. + bool Prevailing = false; + + /// Returns true if module contains the prevailing definition and symbol is + /// an IR symbol. For example when module-level inline asm block is used, + /// symbol can be prevailing in module but have no IR name. + bool isPrevailingIRSymbol() const { return Prevailing && !IRName.empty(); } + + /// This field keeps track of the partition number of this global. The + /// regular LTO object is partition 0, while each ThinLTO object has its own + /// partition number from 1 onwards. + /// + /// Any global that is defined or used by more than one partition, or that + /// is referenced externally, may not be internalized. + /// + /// Partitions generally have a one-to-one correspondence with tasks, except + /// that we use partition 0 for all parallel LTO code generation partitions. + /// Any partitioning of the combined LTO object is done internally by the + /// LTO backend. + unsigned Partition = Unknown; + + /// Special partition numbers. + enum : unsigned { + /// A partition number has not yet been assigned to this global. + Unknown = -1u, + + /// This global is either used by more than one partition or has an + /// external reference, and therefore cannot be internalized. + External = -2u, + + /// The RegularLTO partition + RegularLTO = 0, + }; + }; + + // Global mapping from mangled symbol names to resolutions. + StringMap<GlobalResolution> GlobalResolutions; + + void addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms, + ArrayRef<SymbolResolution> Res, unsigned Partition, + bool InSummary); + + // These functions take a range of symbol resolutions [ResI, ResE) and consume + // the resolutions used by a single input module by incrementing ResI. After + // these functions return, [ResI, ResE) will refer to the resolution range for + // the remaining modules in the InputFile. + Error addModule(InputFile &Input, unsigned ModI, + const SymbolResolution *&ResI, const SymbolResolution *ResE); + + Expected<RegularLTOState::AddedModule> + addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, + const SymbolResolution *&ResI, const SymbolResolution *ResE); + Error linkRegularLTO(RegularLTOState::AddedModule Mod, + bool LivenessFromIndex); + + Error addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, + const SymbolResolution *&ResI, const SymbolResolution *ResE); + + Error runRegularLTO(AddStreamFn AddStream); + Error runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, + const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols); + + Error checkPartiallySplit(); + + mutable bool CalledGetMaxTasks = false; + + // Use Optional to distinguish false from not yet initialized. + Optional<bool> EnableSplitLTOUnit; +}; + +/// The resolution for a symbol. The linker must provide a SymbolResolution for +/// each global symbol based on its internal resolution of that symbol. +struct SymbolResolution { + SymbolResolution() + : Prevailing(0), FinalDefinitionInLinkageUnit(0), VisibleToRegularObj(0), + LinkerRedefined(0) {} + + /// The linker has chosen this definition of the symbol. + unsigned Prevailing : 1; + + /// The definition of this symbol is unpreemptable at runtime and is known to + /// be in this linkage unit. + unsigned FinalDefinitionInLinkageUnit : 1; + + /// The definition of this symbol is visible outside of the LTO unit. + unsigned VisibleToRegularObj : 1; + + /// Linker redefined version of the symbol which appeared in -wrap or -defsym + /// linker option. + unsigned LinkerRedefined : 1; +}; + +} // namespace lto +} // namespace llvm + +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/LTO/LTOBackend.h b/contrib/libs/llvm12/include/llvm/LTO/LTOBackend.h new file mode 100644 index 0000000000..01e2108bc1 --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/LTOBackend.h @@ -0,0 +1,88 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-LTOBackend.h - LLVM Link Time Optimizer Backend ---------------------===// +// +// 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 implements the "backend" phase of LTO, i.e. it performs +// optimization and code generation on a loaded module. It is generally used +// internally by the LTO class but can also be used independently, for example +// to implement a standalone ThinLTO backend. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_LTOBACKEND_H +#define LLVM_LTO_LTOBACKEND_H + +#include "llvm/ADT/MapVector.h" +#include "llvm/IR/DiagnosticInfo.h" +#include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/LTO/LTO.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Transforms/IPO/FunctionImport.h" + +namespace llvm { + +class BitcodeModule; +class Error; +class Module; +class Target; + +namespace lto { + +/// Runs middle-end LTO optimizations on \p Mod. +bool opt(const Config &Conf, TargetMachine *TM, unsigned Task, Module &Mod, + bool IsThinLTO, ModuleSummaryIndex *ExportSummary, + const ModuleSummaryIndex *ImportSummary, + const std::vector<uint8_t> &CmdArgs); + +/// Runs a regular LTO backend. The regular LTO backend can also act as the +/// regular LTO phase of ThinLTO, which may need to access the combined index. +Error backend(const Config &C, AddStreamFn AddStream, + unsigned ParallelCodeGenParallelismLevel, + std::unique_ptr<Module> M, ModuleSummaryIndex &CombinedIndex); + +/// Runs a ThinLTO backend. +Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream, + Module &M, const ModuleSummaryIndex &CombinedIndex, + const FunctionImporter::ImportMapTy &ImportList, + const GVSummaryMapTy &DefinedGlobals, + MapVector<StringRef, BitcodeModule> &ModuleMap, + const std::vector<uint8_t> &CmdArgs = std::vector<uint8_t>()); + +Error finalizeOptimizationRemarks( + std::unique_ptr<ToolOutputFile> DiagOutputFile); + +/// Returns the BitcodeModule that is ThinLTO. +BitcodeModule *findThinLTOModule(MutableArrayRef<BitcodeModule> BMs); + +/// Variant of the above. +Expected<BitcodeModule> findThinLTOModule(MemoryBufferRef MBRef); + +/// Distributed ThinLTO: load the referenced modules, keeping their buffers +/// alive in the provided OwnedImportLifetimeManager. Returns false if the +/// operation failed. +bool loadReferencedModules( + const Module &M, const ModuleSummaryIndex &CombinedIndex, + FunctionImporter::ImportMapTy &ImportList, + MapVector<llvm::StringRef, llvm::BitcodeModule> &ModuleMap, + std::vector<std::unique_ptr<llvm::MemoryBuffer>> + &OwnedImportsLifetimeManager); +} +} + +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/LTO/SummaryBasedOptimizations.h b/contrib/libs/llvm12/include/llvm/LTO/SummaryBasedOptimizations.h new file mode 100644 index 0000000000..b4ecb85286 --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/SummaryBasedOptimizations.h @@ -0,0 +1,27 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//=- llvm/LTO/SummaryBasedOptimizations.h -Link time optimizations-*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_SUMMARYBASEDOPTIMIZATIONS_H +#define LLVM_LTO_SUMMARYBASEDOPTIMIZATIONS_H +namespace llvm { +class ModuleSummaryIndex; +void computeSyntheticCounts(ModuleSummaryIndex &Index); + +} // namespace llvm +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOCodeGenerator.h b/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOCodeGenerator.h new file mode 100644 index 0000000000..d0de7221c2 --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOCodeGenerator.h @@ -0,0 +1,258 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-LTOCodeGenerator.h - LLVM Link Time 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 +// +//===----------------------------------------------------------------------===// +// +// This file declares the LTOCodeGenerator class. +// +// LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO. +// +// The Pre-IPO phase compiles source code into bitcode file. The resulting +// bitcode files, along with object files and libraries, will be fed to the +// linker to through the IPO and Post-IPO phases. By using obj-file extension, +// the resulting bitcode file disguises itself as an object file, and therefore +// obviates the need of writing a special set of the make-rules only for LTO +// compilation. +// +// The IPO phase perform inter-procedural analyses and optimizations, and +// the Post-IPO consists two sub-phases: intra-procedural scalar optimizations +// (SOPT), and intra-procedural target-dependent code generator (CG). +// +// As of this writing, we don't separate IPO and the Post-IPO SOPT. They +// are intermingled together, and are driven by a single pass manager (see +// PassManagerBuilder::populateLTOPassManager()). +// +// The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages. +// The "CodeGenerator" here is bit confusing. Don't confuse the "CodeGenerator" +// with the machine specific code generator. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_LTOCODEGENERATOR_H +#define LLVM_LTO_LTOCODEGENERATOR_H + +#include "llvm-c/lto.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/IR/GlobalValue.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" +#include <string> +#include <vector> + +/// Enable global value internalization in LTO. +extern llvm::cl::opt<bool> EnableLTOInternalization; + +namespace llvm { +template <typename T> class ArrayRef; + class LLVMContext; + class DiagnosticInfo; + class Linker; + class Mangler; + class MemoryBuffer; + class TargetLibraryInfo; + class TargetMachine; + class raw_ostream; + class raw_pwrite_stream; + +//===----------------------------------------------------------------------===// +/// C++ class which implements the opaque lto_code_gen_t type. +/// +struct LTOCodeGenerator { + static const char *getVersionString(); + + LTOCodeGenerator(LLVMContext &Context); + ~LTOCodeGenerator(); + + /// Merge given module. Return true on success. + /// + /// Resets \a HasVerifiedInput. + bool addModule(struct LTOModule *); + + /// Set the destination module. + /// + /// Resets \a HasVerifiedInput. + void setModule(std::unique_ptr<LTOModule> M); + + void setAsmUndefinedRefs(struct LTOModule *); + void setTargetOptions(const TargetOptions &Options); + void setDebugInfo(lto_debug_model); + void setCodePICModel(Optional<Reloc::Model> Model) { RelocModel = Model; } + + /// Set the file type to be emitted (assembly or object code). + /// The default is CGFT_ObjectFile. + void setFileType(CodeGenFileType FT) { FileType = FT; } + + void setCpu(StringRef MCpu) { this->MCpu = std::string(MCpu); } + void setAttrs(std::vector<std::string> MAttrs) { this->MAttrs = MAttrs; } + void setOptLevel(unsigned OptLevel); + + void setShouldInternalize(bool Value) { ShouldInternalize = Value; } + void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; } + + /// Restore linkage of globals + /// + /// When set, the linkage of globals will be restored prior to code + /// generation. That is, a global symbol that had external linkage prior to + /// LTO will be emitted with external linkage again; and a local will remain + /// local. Note that this option only affects the end result - globals may + /// still be internalized in the process of LTO and may be modified and/or + /// deleted where legal. + /// + /// The default behavior will internalize globals (unless on the preserve + /// list) and, if parallel code generation is enabled, will externalize + /// all locals. + void setShouldRestoreGlobalsLinkage(bool Value) { + ShouldRestoreGlobalsLinkage = Value; + } + + void addMustPreserveSymbol(StringRef Sym) { MustPreserveSymbols.insert(Sym); } + + /// Pass options to the driver and optimization passes. + /// + /// These options are not necessarily for debugging purpose (the function + /// name is misleading). This function should be called before + /// LTOCodeGenerator::compilexxx(), and + /// LTOCodeGenerator::writeMergedModules(). + void setCodeGenDebugOptions(ArrayRef<StringRef> Opts); + + /// Parse the options set in setCodeGenDebugOptions. + /// + /// Like \a setCodeGenDebugOptions(), this must be called before + /// LTOCodeGenerator::compilexxx() and + /// LTOCodeGenerator::writeMergedModules(). + void parseCodeGenDebugOptions(); + + /// Write the merged module to the file specified by the given path. Return + /// true on success. + /// + /// Calls \a verifyMergedModuleOnce(). + bool writeMergedModules(StringRef Path); + + /// Compile the merged module into a *single* output file; the path to output + /// file is returned to the caller via argument "name". Return true on + /// success. + /// + /// \note It is up to the linker to remove the intermediate output file. Do + /// not try to remove the object file in LTOCodeGenerator's destructor as we + /// don't who (LTOCodeGenerator or the output file) will last longer. + bool compile_to_file(const char **Name); + + /// As with compile_to_file(), this function compiles the merged module into + /// single output file. Instead of returning the output file path to the + /// caller (linker), it brings the output to a buffer, and returns the buffer + /// to the caller. This function should delete the intermediate file once + /// its content is brought to memory. Return NULL if the compilation was not + /// successful. + std::unique_ptr<MemoryBuffer> compile(); + + /// Optimizes the merged module. Returns true on success. + /// + /// Calls \a verifyMergedModuleOnce(). + bool optimize(); + + /// Compiles the merged optimized module into a single output file. It brings + /// the output to a buffer, and returns the buffer to the caller. Return NULL + /// if the compilation was not successful. + std::unique_ptr<MemoryBuffer> compileOptimized(); + + /// Compile the merged optimized module into out.size() output files each + /// representing a linkable partition of the module. If out contains more + /// than one element, code generation is done in parallel with out.size() + /// threads. Output files will be written to members of out. Returns true on + /// success. + /// + /// Calls \a verifyMergedModuleOnce(). + bool compileOptimized(ArrayRef<raw_pwrite_stream *> Out); + + /// Enable the Freestanding mode: indicate that the optimizer should not + /// assume builtins are present on the target. + void setFreestanding(bool Enabled) { Freestanding = Enabled; } + + void setDisableVerify(bool Value) { DisableVerify = Value; } + + void setDiagnosticHandler(lto_diagnostic_handler_t, void *); + + LLVMContext &getContext() { return Context; } + + void resetMergedModule() { MergedModule.reset(); } + void DiagnosticHandler(const DiagnosticInfo &DI); + +private: + void initializeLTOPasses(); + + /// Verify the merged module on first call. + /// + /// Sets \a HasVerifiedInput on first call and doesn't run again on the same + /// input. + void verifyMergedModuleOnce(); + + bool compileOptimizedToFile(const char **Name); + void restoreLinkageForExternals(); + void applyScopeRestrictions(); + void preserveDiscardableGVs( + Module &TheModule, + llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV); + + bool determineTarget(); + std::unique_ptr<TargetMachine> createTargetMachine(); + + void emitError(const std::string &ErrMsg); + void emitWarning(const std::string &ErrMsg); + + void finishOptimizationRemarks(); + + LLVMContext &Context; + std::unique_ptr<Module> MergedModule; + std::unique_ptr<Linker> TheLinker; + std::unique_ptr<TargetMachine> TargetMach; + bool EmitDwarfDebugInfo = false; + bool ScopeRestrictionsDone = false; + bool HasVerifiedInput = false; + Optional<Reloc::Model> RelocModel; + StringSet<> MustPreserveSymbols; + StringSet<> AsmUndefinedRefs; + StringMap<GlobalValue::LinkageTypes> ExternalSymbols; + std::vector<std::string> CodegenOptions; + std::string FeatureStr; + std::string MCpu; + std::vector<std::string> MAttrs; + std::string NativeObjectPath; + TargetOptions Options; + CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; + const Target *MArch = nullptr; + std::string TripleStr; + unsigned OptLevel = 2; + lto_diagnostic_handler_t DiagHandler = nullptr; + void *DiagContext = nullptr; + bool ShouldInternalize = EnableLTOInternalization; + bool ShouldEmbedUselists = false; + bool ShouldRestoreGlobalsLinkage = false; + CodeGenFileType FileType = CGFT_ObjectFile; + std::unique_ptr<ToolOutputFile> DiagnosticOutputFile; + bool Freestanding = false; + std::unique_ptr<ToolOutputFile> StatsFile = nullptr; + bool DisableVerify = false; +}; +} +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOModule.h b/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOModule.h new file mode 100644 index 0000000000..c89a3ec9d3 --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/legacy/LTOModule.h @@ -0,0 +1,231 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-LTOModule.h - LLVM Link Time 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 +// +//===----------------------------------------------------------------------===// +// +// This file declares the LTOModule class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_LTOMODULE_H +#define LLVM_LTO_LTOMODULE_H + +#include "llvm-c/lto.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/IR/Module.h" +#include "llvm/LTO/LTO.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Object/ModuleSymbolTable.h" +#include "llvm/Target/TargetMachine.h" +#include <string> +#include <vector> + +// Forward references to llvm classes. +namespace llvm { + class Function; + class GlobalValue; + class MemoryBuffer; + class TargetOptions; + class Value; + +//===----------------------------------------------------------------------===// +/// C++ class which implements the opaque lto_module_t type. +/// +struct LTOModule { +private: + struct NameAndAttributes { + StringRef name; + uint32_t attributes = 0; + bool isFunction = 0; + const GlobalValue *symbol = 0; + }; + + std::unique_ptr<LLVMContext> OwnedContext; + + std::string LinkerOpts; + + std::unique_ptr<Module> Mod; + MemoryBufferRef MBRef; + ModuleSymbolTable SymTab; + std::unique_ptr<TargetMachine> _target; + std::vector<NameAndAttributes> _symbols; + + // _defines and _undefines only needed to disambiguate tentative definitions + StringSet<> _defines; + StringMap<NameAndAttributes> _undefines; + std::vector<StringRef> _asm_undefines; + + LTOModule(std::unique_ptr<Module> M, MemoryBufferRef MBRef, + TargetMachine *TM); + +public: + ~LTOModule(); + + /// Returns 'true' if the file or memory contents is LLVM bitcode. + static bool isBitcodeFile(const void *mem, size_t length); + static bool isBitcodeFile(StringRef path); + + /// Returns 'true' if the Module is produced for ThinLTO. + bool isThinLTO(); + + /// Returns 'true' if the memory buffer is LLVM bitcode for the specified + /// triple. + static bool isBitcodeForTarget(MemoryBuffer *memBuffer, + StringRef triplePrefix); + + /// Returns a string representing the producer identification stored in the + /// bitcode, or "" if the bitcode does not contains any. + /// + static std::string getProducerString(MemoryBuffer *Buffer); + + /// Create a MemoryBuffer from a memory range with an optional name. + static std::unique_ptr<MemoryBuffer> + makeBuffer(const void *mem, size_t length, StringRef name = ""); + + /// Create an LTOModule. N.B. These methods take ownership of the buffer. The + /// caller must have initialized the Targets, the TargetMCs, the AsmPrinters, + /// and the AsmParsers by calling: + /// + /// InitializeAllTargets(); + /// InitializeAllTargetMCs(); + /// InitializeAllAsmPrinters(); + /// InitializeAllAsmParsers(); + static ErrorOr<std::unique_ptr<LTOModule>> + createFromFile(LLVMContext &Context, StringRef path, + const TargetOptions &options); + static ErrorOr<std::unique_ptr<LTOModule>> + createFromOpenFile(LLVMContext &Context, int fd, StringRef path, size_t size, + const TargetOptions &options); + static ErrorOr<std::unique_ptr<LTOModule>> + createFromOpenFileSlice(LLVMContext &Context, int fd, StringRef path, + size_t map_size, off_t offset, + const TargetOptions &options); + static ErrorOr<std::unique_ptr<LTOModule>> + createFromBuffer(LLVMContext &Context, const void *mem, size_t length, + const TargetOptions &options, StringRef path = ""); + static ErrorOr<std::unique_ptr<LTOModule>> + createInLocalContext(std::unique_ptr<LLVMContext> Context, const void *mem, + size_t length, const TargetOptions &options, + StringRef path); + + const Module &getModule() const { return *Mod; } + Module &getModule() { return *Mod; } + + std::unique_ptr<Module> takeModule() { return std::move(Mod); } + + /// Return the Module's target triple. + const std::string &getTargetTriple() { + return getModule().getTargetTriple(); + } + + /// Set the Module's target triple. + void setTargetTriple(StringRef Triple) { + getModule().setTargetTriple(Triple); + } + + /// Get the number of symbols + uint32_t getSymbolCount() { + return _symbols.size(); + } + + /// Get the attributes for a symbol at the specified index. + lto_symbol_attributes getSymbolAttributes(uint32_t index) { + if (index < _symbols.size()) + return lto_symbol_attributes(_symbols[index].attributes); + return lto_symbol_attributes(0); + } + + /// Get the name of the symbol at the specified index. + StringRef getSymbolName(uint32_t index) { + if (index < _symbols.size()) + return _symbols[index].name; + return StringRef(); + } + + const GlobalValue *getSymbolGV(uint32_t index) { + if (index < _symbols.size()) + return _symbols[index].symbol; + return nullptr; + } + + StringRef getLinkerOpts() { return LinkerOpts; } + + const std::vector<StringRef> &getAsmUndefinedRefs() { return _asm_undefines; } + + static lto::InputFile *createInputFile(const void *buffer, size_t buffer_size, + const char *path, std::string &out_error); + + static size_t getDependentLibraryCount(lto::InputFile *input); + + static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size); + + Expected<uint32_t> getMachOCPUType() const; + + Expected<uint32_t> getMachOCPUSubType() const; + +private: + /// Parse metadata from the module + // FIXME: it only parses "llvm.linker.options" metadata at the moment + // FIXME: can't access metadata in lazily loaded modules + void parseMetadata(); + + /// Parse the symbols from the module and model-level ASM and add them to + /// either the defined or undefined lists. + void parseSymbols(); + + /// Add a symbol which isn't defined just yet to a list to be resolved later. + void addPotentialUndefinedSymbol(ModuleSymbolTable::Symbol Sym, + bool isFunc); + + /// Add a defined symbol to the list. + void addDefinedSymbol(StringRef Name, const GlobalValue *def, + bool isFunction); + + /// Add a data symbol as defined to the list. + void addDefinedDataSymbol(ModuleSymbolTable::Symbol Sym); + void addDefinedDataSymbol(StringRef Name, const GlobalValue *v); + + /// Add a function symbol as defined to the list. + void addDefinedFunctionSymbol(ModuleSymbolTable::Symbol Sym); + void addDefinedFunctionSymbol(StringRef Name, const Function *F); + + /// Add a global symbol from module-level ASM to the defined list. + void addAsmGlobalSymbol(StringRef, lto_symbol_attributes scope); + + /// Add a global symbol from module-level ASM to the undefined list. + void addAsmGlobalSymbolUndef(StringRef); + + /// Parse i386/ppc ObjC class data structure. + void addObjCClass(const GlobalVariable *clgv); + + /// Parse i386/ppc ObjC category data structure. + void addObjCCategory(const GlobalVariable *clgv); + + /// Parse i386/ppc ObjC class list data structure. + void addObjCClassRef(const GlobalVariable *clgv); + + /// Get string that the data pointer points to. + bool objcClassNameFromExpression(const Constant *c, std::string &name); + + /// Create an LTOModule (private version). + static ErrorOr<std::unique_ptr<LTOModule>> + makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options, + LLVMContext &Context, bool ShouldBeLazy); +}; +} +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/contrib/libs/llvm12/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h new file mode 100644 index 0000000000..de004376ee --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -0,0 +1,357 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//===-ThinLTOCodeGenerator.h - LLVM Link Time 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 +// +//===----------------------------------------------------------------------===// +// +// This file declares the ThinLTOCodeGenerator class, similar to the +// LTOCodeGenerator but for the ThinLTO scheme. It provides an interface for +// linker plugin. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_THINLTOCODEGENERATOR_H +#define LLVM_LTO_THINLTOCODEGENERATOR_H + +#include "llvm-c/lto.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/ADT/Triple.h" +#include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/LTO/LTO.h" +#include "llvm/Support/CachePruning.h" +#include "llvm/Support/CodeGen.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Target/TargetOptions.h" + +#include <string> + +namespace llvm { +class StringRef; +class LLVMContext; +class TargetMachine; + +/// Helper to gather options relevant to the target machine creation +struct TargetMachineBuilder { + Triple TheTriple; + std::string MCpu; + std::string MAttr; + TargetOptions Options; + Optional<Reloc::Model> RelocModel; + CodeGenOpt::Level CGOptLevel = CodeGenOpt::Aggressive; + + std::unique_ptr<TargetMachine> create() const; +}; + +/// This class define an interface similar to the LTOCodeGenerator, but adapted +/// for ThinLTO processing. +/// The ThinLTOCodeGenerator is not intended to be reuse for multiple +/// compilation: the model is that the client adds modules to the generator and +/// ask to perform the ThinLTO optimizations / codegen, and finally destroys the +/// codegenerator. +class ThinLTOCodeGenerator { +public: + /// Add given module to the code generator. + void addModule(StringRef Identifier, StringRef Data); + + /** + * Adds to a list of all global symbols that must exist in the final generated + * code. If a symbol is not listed there, it will be optimized away if it is + * inlined into every usage. + */ + void preserveSymbol(StringRef Name); + + /** + * Adds to a list of all global symbols that are cross-referenced between + * ThinLTO files. If the ThinLTO CodeGenerator can ensure that every + * references from a ThinLTO module to this symbol is optimized away, then + * the symbol can be discarded. + */ + void crossReferenceSymbol(StringRef Name); + + /** + * Process all the modules that were added to the code generator in parallel. + * + * Client can access the resulting object files using getProducedBinaries(), + * unless setGeneratedObjectsDirectory() has been called, in which case + * results are available through getProducedBinaryFiles(). + */ + void run(); + + /** + * Return the "in memory" binaries produced by the code generator. This is + * filled after run() unless setGeneratedObjectsDirectory() has been + * called, in which case results are available through + * getProducedBinaryFiles(). + */ + std::vector<std::unique_ptr<MemoryBuffer>> &getProducedBinaries() { + return ProducedBinaries; + } + + /** + * Return the "on-disk" binaries produced by the code generator. This is + * filled after run() when setGeneratedObjectsDirectory() has been + * called, in which case results are available through getProducedBinaries(). + */ + std::vector<std::string> &getProducedBinaryFiles() { + return ProducedBinaryFiles; + } + + /** + * \defgroup Options setters + * @{ + */ + + /** + * \defgroup Cache controlling options + * + * These entry points control the ThinLTO cache. The cache is intended to + * support incremental build, and thus needs to be persistent accross build. + * The client enabled the cache by supplying a path to an existing directory. + * The code generator will use this to store objects files that may be reused + * during a subsequent build. + * To avoid filling the disk space, a few knobs are provided: + * - The pruning interval limit the frequency at which the garbage collector + * will try to scan the cache directory to prune it from expired entries. + * Setting to -1 disable the pruning (default). Setting to 0 will force + * pruning to occur. + * - The pruning expiration time indicates to the garbage collector how old + * an entry needs to be to be removed. + * - Finally, the garbage collector can be instructed to prune the cache till + * the occupied space goes below a threshold. + * @{ + */ + + struct CachingOptions { + std::string Path; // Path to the cache, empty to disable. + CachePruningPolicy Policy; + }; + + /// Provide a path to a directory where to store the cached files for + /// incremental build. + void setCacheDir(std::string Path) { CacheOptions.Path = std::move(Path); } + + /// Cache policy: interval (seconds) between two prunes of the cache. Set to a + /// negative value to disable pruning. A value of 0 will force pruning to + /// occur. + void setCachePruningInterval(int Interval) { + if(Interval < 0) + CacheOptions.Policy.Interval.reset(); + else + CacheOptions.Policy.Interval = std::chrono::seconds(Interval); + } + + /// Cache policy: expiration (in seconds) for an entry. + /// A value of 0 will be ignored. + void setCacheEntryExpiration(unsigned Expiration) { + if (Expiration) + CacheOptions.Policy.Expiration = std::chrono::seconds(Expiration); + } + + /** + * Sets the maximum cache size that can be persistent across build, in terms + * of percentage of the available space on the disk. Set to 100 to indicate + * no limit, 50 to indicate that the cache size will not be left over + * half the available space. A value over 100 will be reduced to 100, and a + * value of 0 will be ignored. + * + * + * The formula looks like: + * AvailableSpace = FreeSpace + ExistingCacheSize + * NewCacheSize = AvailableSpace * P/100 + * + */ + void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) { + if (Percentage) + CacheOptions.Policy.MaxSizePercentageOfAvailableSpace = Percentage; + } + + /// Cache policy: the maximum size for the cache directory in bytes. A value + /// over the amount of available space on the disk will be reduced to the + /// amount of available space. A value of 0 will be ignored. + void setCacheMaxSizeBytes(uint64_t MaxSizeBytes) { + if (MaxSizeBytes) + CacheOptions.Policy.MaxSizeBytes = MaxSizeBytes; + } + + /// Cache policy: the maximum number of files in the cache directory. A value + /// of 0 will be ignored. + void setCacheMaxSizeFiles(unsigned MaxSizeFiles) { + if (MaxSizeFiles) + CacheOptions.Policy.MaxSizeFiles = MaxSizeFiles; + } + + /**@}*/ + + /// Set the path to a directory where to save temporaries at various stages of + /// the processing. + void setSaveTempsDir(std::string Path) { SaveTempsDir = std::move(Path); } + + /// Set the path to a directory where to save generated object files. This + /// path can be used by a linker to request on-disk files instead of in-memory + /// buffers. When set, results are available through getProducedBinaryFiles() + /// instead of getProducedBinaries(). + void setGeneratedObjectsDirectory(std::string Path) { + SavedObjectsDirectoryPath = std::move(Path); + } + + /// CPU to use to initialize the TargetMachine + void setCpu(std::string Cpu) { TMBuilder.MCpu = std::move(Cpu); } + + /// Subtarget attributes + void setAttr(std::string MAttr) { TMBuilder.MAttr = std::move(MAttr); } + + /// TargetMachine options + void setTargetOptions(TargetOptions Options) { + TMBuilder.Options = std::move(Options); + } + + /// Enable the Freestanding mode: indicate that the optimizer should not + /// assume builtins are present on the target. + void setFreestanding(bool Enabled) { Freestanding = Enabled; } + + /// CodeModel + void setCodePICModel(Optional<Reloc::Model> Model) { + TMBuilder.RelocModel = Model; + } + + /// CodeGen optimization level + void setCodeGenOptLevel(CodeGenOpt::Level CGOptLevel) { + TMBuilder.CGOptLevel = CGOptLevel; + } + + /// IR optimization level: from 0 to 3. + void setOptLevel(unsigned NewOptLevel) { + OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel; + } + + /// Disable CodeGen, only run the stages till codegen and stop. The output + /// will be bitcode. + void disableCodeGen(bool Disable) { DisableCodeGen = Disable; } + + /// Perform CodeGen only: disable all other stages. + void setCodeGenOnly(bool CGOnly) { CodeGenOnly = CGOnly; } + + /**@}*/ + + /** + * \defgroup Set of APIs to run individual stages in isolation. + * @{ + */ + + /** + * Produce the combined summary index from all the bitcode files: + * "thin-link". + */ + std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex(); + + /** + * Perform promotion and renaming of exported internal functions, + * and additionally resolve weak and linkonce symbols. + * Index is updated to reflect linkage changes from weak resolution. + */ + void promote(Module &Module, ModuleSummaryIndex &Index, + const lto::InputFile &File); + + /** + * Compute and emit the imported files for module at \p ModulePath. + */ + void emitImports(Module &Module, StringRef OutputName, + ModuleSummaryIndex &Index, + const lto::InputFile &File); + + /** + * Perform cross-module importing for the module identified by + * ModuleIdentifier. + */ + void crossModuleImport(Module &Module, ModuleSummaryIndex &Index, + const lto::InputFile &File); + + /** + * Compute the list of summaries needed for importing into module. + */ + void gatherImportedSummariesForModule( + Module &Module, ModuleSummaryIndex &Index, + std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex, + const lto::InputFile &File); + + /** + * Perform internalization. Index is updated to reflect linkage changes. + */ + void internalize(Module &Module, ModuleSummaryIndex &Index, + const lto::InputFile &File); + + /** + * Perform post-importing ThinLTO optimizations. + */ + void optimize(Module &Module); + + /** + * Write temporary object file to SavedObjectDirectoryPath, write symlink + * to Cache directory if needed. Returns the path to the generated file in + * SavedObjectsDirectoryPath. + */ + std::string writeGeneratedObject(int count, StringRef CacheEntryPath, + const MemoryBuffer &OutputBuffer); + /**@}*/ + +private: + /// Helper factory to build a TargetMachine + TargetMachineBuilder TMBuilder; + + /// Vector holding the in-memory buffer containing the produced binaries, when + /// SavedObjectsDirectoryPath isn't set. + std::vector<std::unique_ptr<MemoryBuffer>> ProducedBinaries; + + /// Path to generated files in the supplied SavedObjectsDirectoryPath if any. + std::vector<std::string> ProducedBinaryFiles; + + /// Vector holding the input buffers containing the bitcode modules to + /// process. + std::vector<std::unique_ptr<lto::InputFile>> Modules; + + /// Set of symbols that need to be preserved outside of the set of bitcode + /// files. + StringSet<> PreservedSymbols; + + /// Set of symbols that are cross-referenced between bitcode files. + StringSet<> CrossReferencedSymbols; + + /// Control the caching behavior. + CachingOptions CacheOptions; + + /// Path to a directory to save the temporary bitcode files. + std::string SaveTempsDir; + + /// Path to a directory to save the generated object files. + std::string SavedObjectsDirectoryPath; + + /// Flag to enable/disable CodeGen. When set to true, the process stops after + /// optimizations and a bitcode is produced. + bool DisableCodeGen = false; + + /// Flag to indicate that only the CodeGen will be performed, no cross-module + /// importing or optimization. + bool CodeGenOnly = false; + + /// Flag to indicate that the optimizer should not assume builtins are present + /// on the target. + bool Freestanding = false; + + /// IR Optimization Level [0-3]. + unsigned OptLevel = 3; +}; +} +#endif + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif diff --git a/contrib/libs/llvm12/include/llvm/LTO/legacy/UpdateCompilerUsed.h b/contrib/libs/llvm12/include/llvm/LTO/legacy/UpdateCompilerUsed.h new file mode 100644 index 0000000000..b26e25f0be --- /dev/null +++ b/contrib/libs/llvm12/include/llvm/LTO/legacy/UpdateCompilerUsed.h @@ -0,0 +1,42 @@ +#pragma once + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +//==------ UpdateCompilerUsed.h - LLVM Link Time Optimizer Utility --------===// +// +// 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 declares a helper class to update llvm.compiler_used metadata. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LTO_UPDATE_COMPILER_USED_H +#define LLVM_LTO_UPDATE_COMPILER_USED_H + +#include "llvm/ADT/StringSet.h" +#include "llvm/IR/GlobalValue.h" + +namespace llvm { +class Module; +class TargetMachine; + +/// Find all globals in \p TheModule that are referenced in +/// \p AsmUndefinedRefs, as well as the user-supplied functions definitions that +/// are also libcalls, and create or update the magic "llvm.compiler_used" +/// global in \p TheModule. +void updateCompilerUsed(Module &TheModule, const TargetMachine &TM, + const StringSet<> &AsmUndefinedRefs); +} + +#endif // LLVM_LTO_UPDATE_COMPILER_USED_H + +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif |