10b57cec5SDimitry Andric //===-LTO.h - LLVM Link Time Optimizer ------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares functions and classes used to support LTO. It is intended 100b57cec5SDimitry Andric // to be used both by LTO classes as well as by clients (gold-plugin) that 110b57cec5SDimitry Andric // don't utilize the LTO code generator interfaces. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_LTO_LTO_H 160b57cec5SDimitry Andric #define LLVM_LTO_LTO_H 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "llvm/ADT/MapVector.h" 190b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 200b57cec5SDimitry Andric #include "llvm/ADT/StringSet.h" 210b57cec5SDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 220b57cec5SDimitry Andric #include "llvm/IR/ModuleSummaryIndex.h" 230b57cec5SDimitry Andric #include "llvm/IR/RemarkStreamer.h" 240b57cec5SDimitry Andric #include "llvm/LTO/Config.h" 250b57cec5SDimitry Andric #include "llvm/Linker/IRMover.h" 260b57cec5SDimitry Andric #include "llvm/Object/IRSymtab.h" 270b57cec5SDimitry Andric #include "llvm/Support/Error.h" 280b57cec5SDimitry Andric #include "llvm/Support/ToolOutputFile.h" 290b57cec5SDimitry Andric #include "llvm/Support/thread.h" 300b57cec5SDimitry Andric #include "llvm/Target/TargetOptions.h" 310b57cec5SDimitry Andric #include "llvm/Transforms/IPO/FunctionImport.h" 320b57cec5SDimitry Andric 330b57cec5SDimitry Andric namespace llvm { 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric class BitcodeModule; 360b57cec5SDimitry Andric class Error; 370b57cec5SDimitry Andric class LLVMContext; 380b57cec5SDimitry Andric class MemoryBufferRef; 390b57cec5SDimitry Andric class Module; 400b57cec5SDimitry Andric class Target; 410b57cec5SDimitry Andric class raw_pwrite_stream; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric /// Resolve linkage for prevailing symbols in the \p Index. Linkage changes 440b57cec5SDimitry Andric /// recorded in the index and the ThinLTO backends must apply the changes to 450b57cec5SDimitry Andric /// the module via thinLTOResolvePrevailingInModule. 460b57cec5SDimitry Andric /// 470b57cec5SDimitry Andric /// This is done for correctness (if value exported, ensure we always 480b57cec5SDimitry Andric /// emit a copy), and compile-time optimization (allow drop of duplicates). 490b57cec5SDimitry Andric void thinLTOResolvePrevailingInIndex( 500b57cec5SDimitry Andric ModuleSummaryIndex &Index, 510b57cec5SDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 520b57cec5SDimitry Andric isPrevailing, 530b57cec5SDimitry Andric function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 540b57cec5SDimitry Andric recordNewLinkage, 550b57cec5SDimitry Andric const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols); 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric /// Update the linkages in the given \p Index to mark exported values 580b57cec5SDimitry Andric /// as external and non-exported values as internal. The ThinLTO backends 590b57cec5SDimitry Andric /// must apply the changes to the Module via thinLTOInternalizeModule. 600b57cec5SDimitry Andric void thinLTOInternalizeAndPromoteInIndex( 610b57cec5SDimitry Andric ModuleSummaryIndex &Index, 62*480093f4SDimitry Andric function_ref<bool(StringRef, ValueInfo)> isExported, 638bcb0991SDimitry Andric function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 648bcb0991SDimitry Andric isPrevailing); 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric /// Computes a unique hash for the Module considering the current list of 670b57cec5SDimitry Andric /// export/import and other global analysis results. 680b57cec5SDimitry Andric /// The hash is produced in \p Key. 690b57cec5SDimitry Andric void computeLTOCacheKey( 700b57cec5SDimitry Andric SmallString<40> &Key, const lto::Config &Conf, 710b57cec5SDimitry Andric const ModuleSummaryIndex &Index, StringRef ModuleID, 720b57cec5SDimitry Andric const FunctionImporter::ImportMapTy &ImportList, 730b57cec5SDimitry Andric const FunctionImporter::ExportSetTy &ExportList, 740b57cec5SDimitry Andric const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, 750b57cec5SDimitry Andric const GVSummaryMapTy &DefinedGlobals, 760b57cec5SDimitry Andric const std::set<GlobalValue::GUID> &CfiFunctionDefs = {}, 770b57cec5SDimitry Andric const std::set<GlobalValue::GUID> &CfiFunctionDecls = {}); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric namespace lto { 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric /// Given the original \p Path to an output file, replace any path 820b57cec5SDimitry Andric /// prefix matching \p OldPrefix with \p NewPrefix. Also, create the 830b57cec5SDimitry Andric /// resulting directory if it does not yet exist. 840b57cec5SDimitry Andric std::string getThinLTOOutputFile(const std::string &Path, 850b57cec5SDimitry Andric const std::string &OldPrefix, 860b57cec5SDimitry Andric const std::string &NewPrefix); 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric /// Setup optimization remarks. 890b57cec5SDimitry Andric Expected<std::unique_ptr<ToolOutputFile>> 900b57cec5SDimitry Andric setupOptimizationRemarks(LLVMContext &Context, StringRef RemarksFilename, 910b57cec5SDimitry Andric StringRef RemarksPasses, StringRef RemarksFormat, 920b57cec5SDimitry Andric bool RemarksWithHotness, int Count = -1); 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric /// Setups the output file for saving statistics. 950b57cec5SDimitry Andric Expected<std::unique_ptr<ToolOutputFile>> 960b57cec5SDimitry Andric setupStatsFile(StringRef StatsFilename); 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric class LTO; 990b57cec5SDimitry Andric struct SymbolResolution; 1000b57cec5SDimitry Andric class ThinBackendProc; 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric /// An input file. This is a symbol table wrapper that only exposes the 1030b57cec5SDimitry Andric /// information that an LTO client should need in order to do symbol resolution. 1040b57cec5SDimitry Andric class InputFile { 1050b57cec5SDimitry Andric public: 1060b57cec5SDimitry Andric class Symbol; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric private: 1090b57cec5SDimitry Andric // FIXME: Remove LTO class friendship once we have bitcode symbol tables. 1100b57cec5SDimitry Andric friend LTO; 1110b57cec5SDimitry Andric InputFile() = default; 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric std::vector<BitcodeModule> Mods; 1140b57cec5SDimitry Andric SmallVector<char, 0> Strtab; 1150b57cec5SDimitry Andric std::vector<Symbol> Symbols; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // [begin, end) for each module 1180b57cec5SDimitry Andric std::vector<std::pair<size_t, size_t>> ModuleSymIndices; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric StringRef TargetTriple, SourceFileName, COFFLinkerOpts; 1210b57cec5SDimitry Andric std::vector<StringRef> DependentLibraries; 1220b57cec5SDimitry Andric std::vector<StringRef> ComdatTable; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric public: 1250b57cec5SDimitry Andric ~InputFile(); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric /// Create an InputFile. 1280b57cec5SDimitry Andric static Expected<std::unique_ptr<InputFile>> create(MemoryBufferRef Object); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric /// The purpose of this class is to only expose the symbol information that an 1310b57cec5SDimitry Andric /// LTO client should need in order to do symbol resolution. 1320b57cec5SDimitry Andric class Symbol : irsymtab::Symbol { 1330b57cec5SDimitry Andric friend LTO; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric public: 1360b57cec5SDimitry Andric Symbol(const irsymtab::Symbol &S) : irsymtab::Symbol(S) {} 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric using irsymtab::Symbol::isUndefined; 1390b57cec5SDimitry Andric using irsymtab::Symbol::isCommon; 1400b57cec5SDimitry Andric using irsymtab::Symbol::isWeak; 1410b57cec5SDimitry Andric using irsymtab::Symbol::isIndirect; 1420b57cec5SDimitry Andric using irsymtab::Symbol::getName; 1430b57cec5SDimitry Andric using irsymtab::Symbol::getIRName; 1440b57cec5SDimitry Andric using irsymtab::Symbol::getVisibility; 1450b57cec5SDimitry Andric using irsymtab::Symbol::canBeOmittedFromSymbolTable; 1460b57cec5SDimitry Andric using irsymtab::Symbol::isTLS; 1470b57cec5SDimitry Andric using irsymtab::Symbol::getComdatIndex; 1480b57cec5SDimitry Andric using irsymtab::Symbol::getCommonSize; 1490b57cec5SDimitry Andric using irsymtab::Symbol::getCommonAlignment; 1500b57cec5SDimitry Andric using irsymtab::Symbol::getCOFFWeakExternalFallback; 1510b57cec5SDimitry Andric using irsymtab::Symbol::getSectionName; 1520b57cec5SDimitry Andric using irsymtab::Symbol::isExecutable; 1530b57cec5SDimitry Andric using irsymtab::Symbol::isUsed; 1540b57cec5SDimitry Andric }; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric /// A range over the symbols in this InputFile. 1570b57cec5SDimitry Andric ArrayRef<Symbol> symbols() const { return Symbols; } 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric /// Returns linker options specified in the input file. 1600b57cec5SDimitry Andric StringRef getCOFFLinkerOpts() const { return COFFLinkerOpts; } 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andric /// Returns dependent library specifiers from the input file. 1630b57cec5SDimitry Andric ArrayRef<StringRef> getDependentLibraries() const { return DependentLibraries; } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric /// Returns the path to the InputFile. 1660b57cec5SDimitry Andric StringRef getName() const; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric /// Returns the input file's target triple. 1690b57cec5SDimitry Andric StringRef getTargetTriple() const { return TargetTriple; } 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andric /// Returns the source file path specified at compile time. 1720b57cec5SDimitry Andric StringRef getSourceFileName() const { return SourceFileName; } 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andric // Returns a table with all the comdats used by this file. 1750b57cec5SDimitry Andric ArrayRef<StringRef> getComdatTable() const { return ComdatTable; } 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric // Returns the only BitcodeModule from InputFile. 1780b57cec5SDimitry Andric BitcodeModule &getSingleBitcodeModule(); 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric private: 1810b57cec5SDimitry Andric ArrayRef<Symbol> module_symbols(unsigned I) const { 1820b57cec5SDimitry Andric const auto &Indices = ModuleSymIndices[I]; 1830b57cec5SDimitry Andric return {Symbols.data() + Indices.first, Symbols.data() + Indices.second}; 1840b57cec5SDimitry Andric } 1850b57cec5SDimitry Andric }; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric /// This class wraps an output stream for a native object. Most clients should 1880b57cec5SDimitry Andric /// just be able to return an instance of this base class from the stream 1890b57cec5SDimitry Andric /// callback, but if a client needs to perform some action after the stream is 1900b57cec5SDimitry Andric /// written to, that can be done by deriving from this class and overriding the 1910b57cec5SDimitry Andric /// destructor. 1920b57cec5SDimitry Andric class NativeObjectStream { 1930b57cec5SDimitry Andric public: 1940b57cec5SDimitry Andric NativeObjectStream(std::unique_ptr<raw_pwrite_stream> OS) : OS(std::move(OS)) {} 1950b57cec5SDimitry Andric std::unique_ptr<raw_pwrite_stream> OS; 1960b57cec5SDimitry Andric virtual ~NativeObjectStream() = default; 1970b57cec5SDimitry Andric }; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric /// This type defines the callback to add a native object that is generated on 2000b57cec5SDimitry Andric /// the fly. 2010b57cec5SDimitry Andric /// 2020b57cec5SDimitry Andric /// Stream callbacks must be thread safe. 2030b57cec5SDimitry Andric using AddStreamFn = 2040b57cec5SDimitry Andric std::function<std::unique_ptr<NativeObjectStream>(unsigned Task)>; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric /// This is the type of a native object cache. To request an item from the 2070b57cec5SDimitry Andric /// cache, pass a unique string as the Key. For hits, the cached file will be 2080b57cec5SDimitry Andric /// added to the link and this function will return AddStreamFn(). For misses, 2090b57cec5SDimitry Andric /// the cache will return a stream callback which must be called at most once to 2100b57cec5SDimitry Andric /// produce content for the stream. The native object stream produced by the 2110b57cec5SDimitry Andric /// stream callback will add the file to the link after the stream is written 2120b57cec5SDimitry Andric /// to. 2130b57cec5SDimitry Andric /// 2140b57cec5SDimitry Andric /// Clients generally look like this: 2150b57cec5SDimitry Andric /// 2160b57cec5SDimitry Andric /// if (AddStreamFn AddStream = Cache(Task, Key)) 2170b57cec5SDimitry Andric /// ProduceContent(AddStream); 2180b57cec5SDimitry Andric using NativeObjectCache = 2190b57cec5SDimitry Andric std::function<AddStreamFn(unsigned Task, StringRef Key)>; 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric /// A ThinBackend defines what happens after the thin-link phase during ThinLTO. 2220b57cec5SDimitry Andric /// The details of this type definition aren't important; clients can only 2230b57cec5SDimitry Andric /// create a ThinBackend using one of the create*ThinBackend() functions below. 2240b57cec5SDimitry Andric using ThinBackend = std::function<std::unique_ptr<ThinBackendProc>( 225*480093f4SDimitry Andric const Config &C, ModuleSummaryIndex &CombinedIndex, 2260b57cec5SDimitry Andric StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 2270b57cec5SDimitry Andric AddStreamFn AddStream, NativeObjectCache Cache)>; 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric /// This ThinBackend runs the individual backend jobs in-process. 2300b57cec5SDimitry Andric ThinBackend createInProcessThinBackend(unsigned ParallelismLevel); 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric /// This ThinBackend writes individual module indexes to files, instead of 2330b57cec5SDimitry Andric /// running the individual backend jobs. This backend is for distributed builds 2340b57cec5SDimitry Andric /// where separate processes will invoke the real backends. 2350b57cec5SDimitry Andric /// 2360b57cec5SDimitry Andric /// To find the path to write the index to, the backend checks if the path has a 2370b57cec5SDimitry Andric /// prefix of OldPrefix; if so, it replaces that prefix with NewPrefix. It then 2380b57cec5SDimitry Andric /// appends ".thinlto.bc" and writes the index to that path. If 2390b57cec5SDimitry Andric /// ShouldEmitImportsFiles is true it also writes a list of imported files to a 2400b57cec5SDimitry Andric /// similar path with ".imports" appended instead. 2410b57cec5SDimitry Andric /// LinkedObjectsFile is an output stream to write the list of object files for 2420b57cec5SDimitry Andric /// the final ThinLTO linking. Can be nullptr. 2430b57cec5SDimitry Andric /// OnWrite is callback which receives module identifier and notifies LTO user 2440b57cec5SDimitry Andric /// that index file for the module (and optionally imports file) was created. 2450b57cec5SDimitry Andric using IndexWriteCallback = std::function<void(const std::string &)>; 2460b57cec5SDimitry Andric ThinBackend createWriteIndexesThinBackend(std::string OldPrefix, 2470b57cec5SDimitry Andric std::string NewPrefix, 2480b57cec5SDimitry Andric bool ShouldEmitImportsFiles, 2490b57cec5SDimitry Andric raw_fd_ostream *LinkedObjectsFile, 2500b57cec5SDimitry Andric IndexWriteCallback OnWrite); 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric /// This class implements a resolution-based interface to LLVM's LTO 2530b57cec5SDimitry Andric /// functionality. It supports regular LTO, parallel LTO code generation and 2540b57cec5SDimitry Andric /// ThinLTO. You can use it from a linker in the following way: 2550b57cec5SDimitry Andric /// - Set hooks and code generation options (see lto::Config struct defined in 2560b57cec5SDimitry Andric /// Config.h), and use the lto::Config object to create an lto::LTO object. 2570b57cec5SDimitry Andric /// - Create lto::InputFile objects using lto::InputFile::create(), then use 2580b57cec5SDimitry Andric /// the symbols() function to enumerate its symbols and compute a resolution 2590b57cec5SDimitry Andric /// for each symbol (see SymbolResolution below). 2600b57cec5SDimitry Andric /// - After the linker has visited each input file (and each regular object 2610b57cec5SDimitry Andric /// file) and computed a resolution for each symbol, take each lto::InputFile 2620b57cec5SDimitry Andric /// and pass it and an array of symbol resolutions to the add() function. 2630b57cec5SDimitry Andric /// - Call the getMaxTasks() function to get an upper bound on the number of 2640b57cec5SDimitry Andric /// native object files that LTO may add to the link. 2650b57cec5SDimitry Andric /// - Call the run() function. This function will use the supplied AddStream 2660b57cec5SDimitry Andric /// and Cache functions to add up to getMaxTasks() native object files to 2670b57cec5SDimitry Andric /// the link. 2680b57cec5SDimitry Andric class LTO { 2690b57cec5SDimitry Andric friend InputFile; 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric public: 2720b57cec5SDimitry Andric /// Create an LTO object. A default constructed LTO object has a reasonable 2730b57cec5SDimitry Andric /// production configuration, but you can customize it by passing arguments to 2740b57cec5SDimitry Andric /// this constructor. 2750b57cec5SDimitry Andric /// FIXME: We do currently require the DiagHandler field to be set in Conf. 2760b57cec5SDimitry Andric /// Until that is fixed, a Config argument is required. 2770b57cec5SDimitry Andric LTO(Config Conf, ThinBackend Backend = nullptr, 2780b57cec5SDimitry Andric unsigned ParallelCodeGenParallelismLevel = 1); 2790b57cec5SDimitry Andric ~LTO(); 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric /// Add an input file to the LTO link, using the provided symbol resolutions. 2820b57cec5SDimitry Andric /// The symbol resolutions must appear in the enumeration order given by 2830b57cec5SDimitry Andric /// InputFile::symbols(). 2840b57cec5SDimitry Andric Error add(std::unique_ptr<InputFile> Obj, ArrayRef<SymbolResolution> Res); 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric /// Returns an upper bound on the number of tasks that the client may expect. 2870b57cec5SDimitry Andric /// This may only be called after all IR object files have been added. For a 2880b57cec5SDimitry Andric /// full description of tasks see LTOBackend.h. 2890b57cec5SDimitry Andric unsigned getMaxTasks() const; 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric /// Runs the LTO pipeline. This function calls the supplied AddStream 2920b57cec5SDimitry Andric /// function to add native object files to the link. 2930b57cec5SDimitry Andric /// 2940b57cec5SDimitry Andric /// The Cache parameter is optional. If supplied, it will be used to cache 2950b57cec5SDimitry Andric /// native object files and add them to the link. 2960b57cec5SDimitry Andric /// 2970b57cec5SDimitry Andric /// The client will receive at most one callback (via either AddStream or 2980b57cec5SDimitry Andric /// Cache) for each task identifier. 2990b57cec5SDimitry Andric Error run(AddStreamFn AddStream, NativeObjectCache Cache = nullptr); 3000b57cec5SDimitry Andric 3018bcb0991SDimitry Andric /// Static method that returns a list of libcall symbols that can be generated 3028bcb0991SDimitry Andric /// by LTO but might not be visible from bitcode symbol table. 3038bcb0991SDimitry Andric static ArrayRef<const char*> getRuntimeLibcallSymbols(); 3048bcb0991SDimitry Andric 3050b57cec5SDimitry Andric private: 3060b57cec5SDimitry Andric Config Conf; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric struct RegularLTOState { 309*480093f4SDimitry Andric RegularLTOState(unsigned ParallelCodeGenParallelismLevel, 310*480093f4SDimitry Andric const Config &Conf); 3110b57cec5SDimitry Andric struct CommonResolution { 3120b57cec5SDimitry Andric uint64_t Size = 0; 3138bcb0991SDimitry Andric MaybeAlign Align; 3140b57cec5SDimitry Andric /// Record if at least one instance of the common was marked as prevailing 3150b57cec5SDimitry Andric bool Prevailing = false; 3160b57cec5SDimitry Andric }; 3170b57cec5SDimitry Andric std::map<std::string, CommonResolution> Commons; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric unsigned ParallelCodeGenParallelismLevel; 3200b57cec5SDimitry Andric LTOLLVMContext Ctx; 3210b57cec5SDimitry Andric std::unique_ptr<Module> CombinedModule; 3220b57cec5SDimitry Andric std::unique_ptr<IRMover> Mover; 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric // This stores the information about a regular LTO module that we have added 3250b57cec5SDimitry Andric // to the link. It will either be linked immediately (for modules without 3260b57cec5SDimitry Andric // summaries) or after summary-based dead stripping (for modules with 3270b57cec5SDimitry Andric // summaries). 3280b57cec5SDimitry Andric struct AddedModule { 3290b57cec5SDimitry Andric std::unique_ptr<Module> M; 3300b57cec5SDimitry Andric std::vector<GlobalValue *> Keep; 3310b57cec5SDimitry Andric }; 3320b57cec5SDimitry Andric std::vector<AddedModule> ModsWithSummaries; 3330b57cec5SDimitry Andric } RegularLTO; 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric struct ThinLTOState { 3360b57cec5SDimitry Andric ThinLTOState(ThinBackend Backend); 3370b57cec5SDimitry Andric 3380b57cec5SDimitry Andric ThinBackend Backend; 3390b57cec5SDimitry Andric ModuleSummaryIndex CombinedIndex; 3400b57cec5SDimitry Andric MapVector<StringRef, BitcodeModule> ModuleMap; 3410b57cec5SDimitry Andric DenseMap<GlobalValue::GUID, StringRef> PrevailingModuleForGUID; 3420b57cec5SDimitry Andric } ThinLTO; 3430b57cec5SDimitry Andric 3440b57cec5SDimitry Andric // The global resolution for a particular (mangled) symbol name. This is in 3450b57cec5SDimitry Andric // particular necessary to track whether each symbol can be internalized. 3460b57cec5SDimitry Andric // Because any input file may introduce a new cross-partition reference, we 3470b57cec5SDimitry Andric // cannot make any final internalization decisions until all input files have 3480b57cec5SDimitry Andric // been added and the client has called run(). During run() we apply 3490b57cec5SDimitry Andric // internalization decisions either directly to the module (for regular LTO) 3500b57cec5SDimitry Andric // or to the combined index (for ThinLTO). 3510b57cec5SDimitry Andric struct GlobalResolution { 3520b57cec5SDimitry Andric /// The unmangled name of the global. 3530b57cec5SDimitry Andric std::string IRName; 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric /// Keep track if the symbol is visible outside of a module with a summary 3560b57cec5SDimitry Andric /// (i.e. in either a regular object or a regular LTO module without a 3570b57cec5SDimitry Andric /// summary). 3580b57cec5SDimitry Andric bool VisibleOutsideSummary = false; 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric bool UnnamedAddr = true; 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andric /// True if module contains the prevailing definition. 3630b57cec5SDimitry Andric bool Prevailing = false; 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andric /// Returns true if module contains the prevailing definition and symbol is 3660b57cec5SDimitry Andric /// an IR symbol. For example when module-level inline asm block is used, 3670b57cec5SDimitry Andric /// symbol can be prevailing in module but have no IR name. 3680b57cec5SDimitry Andric bool isPrevailingIRSymbol() const { return Prevailing && !IRName.empty(); } 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric /// This field keeps track of the partition number of this global. The 3710b57cec5SDimitry Andric /// regular LTO object is partition 0, while each ThinLTO object has its own 3720b57cec5SDimitry Andric /// partition number from 1 onwards. 3730b57cec5SDimitry Andric /// 3740b57cec5SDimitry Andric /// Any global that is defined or used by more than one partition, or that 3750b57cec5SDimitry Andric /// is referenced externally, may not be internalized. 3760b57cec5SDimitry Andric /// 3770b57cec5SDimitry Andric /// Partitions generally have a one-to-one correspondence with tasks, except 3780b57cec5SDimitry Andric /// that we use partition 0 for all parallel LTO code generation partitions. 3790b57cec5SDimitry Andric /// Any partitioning of the combined LTO object is done internally by the 3800b57cec5SDimitry Andric /// LTO backend. 3810b57cec5SDimitry Andric unsigned Partition = Unknown; 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric /// Special partition numbers. 3840b57cec5SDimitry Andric enum : unsigned { 3850b57cec5SDimitry Andric /// A partition number has not yet been assigned to this global. 3860b57cec5SDimitry Andric Unknown = -1u, 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric /// This global is either used by more than one partition or has an 3890b57cec5SDimitry Andric /// external reference, and therefore cannot be internalized. 3900b57cec5SDimitry Andric External = -2u, 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric /// The RegularLTO partition 3930b57cec5SDimitry Andric RegularLTO = 0, 3940b57cec5SDimitry Andric }; 3950b57cec5SDimitry Andric }; 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric // Global mapping from mangled symbol names to resolutions. 3980b57cec5SDimitry Andric StringMap<GlobalResolution> GlobalResolutions; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric void addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms, 4010b57cec5SDimitry Andric ArrayRef<SymbolResolution> Res, unsigned Partition, 4020b57cec5SDimitry Andric bool InSummary); 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric // These functions take a range of symbol resolutions [ResI, ResE) and consume 4050b57cec5SDimitry Andric // the resolutions used by a single input module by incrementing ResI. After 4060b57cec5SDimitry Andric // these functions return, [ResI, ResE) will refer to the resolution range for 4070b57cec5SDimitry Andric // the remaining modules in the InputFile. 4080b57cec5SDimitry Andric Error addModule(InputFile &Input, unsigned ModI, 4090b57cec5SDimitry Andric const SymbolResolution *&ResI, const SymbolResolution *ResE); 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric Expected<RegularLTOState::AddedModule> 4120b57cec5SDimitry Andric addRegularLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, 4130b57cec5SDimitry Andric const SymbolResolution *&ResI, const SymbolResolution *ResE); 4140b57cec5SDimitry Andric Error linkRegularLTO(RegularLTOState::AddedModule Mod, 4150b57cec5SDimitry Andric bool LivenessFromIndex); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric Error addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, 4180b57cec5SDimitry Andric const SymbolResolution *&ResI, const SymbolResolution *ResE); 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric Error runRegularLTO(AddStreamFn AddStream); 4210b57cec5SDimitry Andric Error runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, 4220b57cec5SDimitry Andric const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols); 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric Error checkPartiallySplit(); 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric mutable bool CalledGetMaxTasks = false; 4270b57cec5SDimitry Andric 4280b57cec5SDimitry Andric // Use Optional to distinguish false from not yet initialized. 4290b57cec5SDimitry Andric Optional<bool> EnableSplitLTOUnit; 4300b57cec5SDimitry Andric }; 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric /// The resolution for a symbol. The linker must provide a SymbolResolution for 4330b57cec5SDimitry Andric /// each global symbol based on its internal resolution of that symbol. 4340b57cec5SDimitry Andric struct SymbolResolution { 4350b57cec5SDimitry Andric SymbolResolution() 4360b57cec5SDimitry Andric : Prevailing(0), FinalDefinitionInLinkageUnit(0), VisibleToRegularObj(0), 4370b57cec5SDimitry Andric LinkerRedefined(0) {} 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric /// The linker has chosen this definition of the symbol. 4400b57cec5SDimitry Andric unsigned Prevailing : 1; 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric /// The definition of this symbol is unpreemptable at runtime and is known to 4430b57cec5SDimitry Andric /// be in this linkage unit. 4440b57cec5SDimitry Andric unsigned FinalDefinitionInLinkageUnit : 1; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric /// The definition of this symbol is visible outside of the LTO unit. 4470b57cec5SDimitry Andric unsigned VisibleToRegularObj : 1; 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric /// Linker redefined version of the symbol which appeared in -wrap or -defsym 4500b57cec5SDimitry Andric /// linker option. 4510b57cec5SDimitry Andric unsigned LinkerRedefined : 1; 4520b57cec5SDimitry Andric }; 4530b57cec5SDimitry Andric 4540b57cec5SDimitry Andric } // namespace lto 4550b57cec5SDimitry Andric } // namespace llvm 4560b57cec5SDimitry Andric 4570b57cec5SDimitry Andric #endif 458