//===-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/Caching.h" #include "llvm/Support/Error.h" #include "llvm/Support/thread.h" #include "llvm/Transforms/IPO/FunctionAttrs.h" #include "llvm/Transforms/IPO/FunctionImport.h" namespace llvm { class Error; class IRMover; class LLVMContext; class MemoryBufferRef; class Module; class raw_pwrite_stream; 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 thinLTOFinalizeInModule. /// /// This is done for correctness (if value exported, ensure we always /// emit a copy), and compile-time optimization (allow drop of duplicates). void thinLTOResolvePrevailingInIndex( const lto::Config &C, 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. std::string computeLTOCacheKey( 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 DenseSet<GlobalValue::GUID> &CfiFunctionDefs = { … }; namespace lto { StringLiteral getThinLTODefaultCPU(const Triple &TheTriple); /// 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(StringRef Path, StringRef OldPrefix, StringRef NewPrefix); /// Setup optimization remarks. Expected<std::unique_ptr<ToolOutputFile>> setupLLVMOptimizationRemarks( LLVMContext &Context, StringRef RemarksFilename, StringRef RemarksPasses, StringRef RemarksFormat, bool RemarksWithHotness, std::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); /// Updates MemProf attributes (and metadata) based on whether the index /// has recorded that we are linking with allocation libraries containing /// the necessary APIs for downstream transformations. void updateMemProfAttributes(Module &Mod, const ModuleSummaryIndex &Index); 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 { … }; /// 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. ThinBackend; /// This ThinBackend runs the individual backend jobs in-process. /// The default value means to use one job per hardware core (not hyper-thread). /// OnWrite is callback which receives module identifier and notifies LTO user /// that index file for the module (and optionally imports file) was created. /// ShouldEmitIndexFiles being true will write sharded ThinLTO index files /// to the same path as the input module, with suffix ".thinlto.bc" /// ShouldEmitImportsFiles is true it also writes a list of imported files to a /// similar path with ".imports" appended instead. IndexWriteCallback; ThinBackend createInProcessThinBackend(ThreadPoolStrategy Parallelism, IndexWriteCallback OnWrite = nullptr, bool ShouldEmitIndexFiles = false, bool ShouldEmitImportsFiles = false); /// 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. If LinkedObjectsFile is not /// nullptr and NativeObjectPrefix is not empty then it replaces the prefix of /// the objects with NativeObjectPrefix instead of NewPrefix. OnWrite is /// callback which receives module identifier and notifies LTO user that index /// file for the module (and optionally imports file) was created. ThinBackend createWriteIndexesThinBackend(std::string OldPrefix, std::string NewPrefix, std::string NativeObjectPrefix, 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 { … }; /// 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 { … }; } // namespace lto } // namespace llvm #endif