diff options
Diffstat (limited to 'include/llvm/LTO')
-rw-r--r-- | include/llvm/LTO/Caching.h | 15 | ||||
-rw-r--r-- | include/llvm/LTO/Config.h | 8 | ||||
-rw-r--r-- | include/llvm/LTO/LTO.h | 197 | ||||
-rw-r--r-- | include/llvm/LTO/LTOBackend.h | 7 | ||||
-rw-r--r-- | include/llvm/LTO/legacy/LTOCodeGenerator.h | 7 | ||||
-rw-r--r-- | include/llvm/LTO/legacy/ThinLTOCodeGenerator.h | 19 |
6 files changed, 101 insertions, 152 deletions
diff --git a/include/llvm/LTO/Caching.h b/include/llvm/LTO/Caching.h index 3b96bd1dc301f..f5ec70e081c12 100644 --- a/include/llvm/LTO/Caching.h +++ b/include/llvm/LTO/Caching.h @@ -24,12 +24,19 @@ namespace lto { /// This type defines the callback to add a pre-existing native object file /// (e.g. in a cache). /// -/// File callbacks must be thread safe. -typedef std::function<void(unsigned Task, StringRef Path)> AddFileFn; +/// MB->getBufferIdentifier() is a valid path for the file at the time that it +/// was opened, but clients should prefer to access MB directly in order to +/// avoid a potential race condition. +/// +/// Buffer callbacks must be thread safe. +typedef std::function<void(unsigned Task, std::unique_ptr<MemoryBuffer> MB)> + AddBufferFn; /// Create a local file system cache which uses the given cache directory and -/// file callback. -NativeObjectCache localCache(std::string CacheDirectoryPath, AddFileFn AddFile); +/// 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 diff --git a/include/llvm/LTO/Config.h b/include/llvm/LTO/Config.h index 3aa48c9f7c286..ede6637dfa4dd 100644 --- a/include/llvm/LTO/Config.h +++ b/include/llvm/LTO/Config.h @@ -17,6 +17,7 @@ #include "llvm/IR/DiagnosticInfo.h" #include "llvm/Support/CodeGen.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include <functional> @@ -41,6 +42,7 @@ struct Config { Reloc::Model RelocModel = Reloc::PIC_; CodeModel::Model CodeModel = CodeModel::Default; CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; + TargetMachine::CodeGenFileType CGFileType = TargetMachine::CGFT_ObjectFile; unsigned OptLevel = 2; bool DisableVerify = false; @@ -68,6 +70,12 @@ struct Config { /// Sample PGO profile path. std::string SampleProfile; + /// Optimization remarks file path. + std::string RemarksFilename = ""; + + /// Whether to emit optimization remarks with hotness informations. + bool RemarksWithHotness = false; + bool ShouldDiscardValueNames = true; DiagnosticHandlerFunction DiagHandler; diff --git a/include/llvm/LTO/LTO.h b/include/llvm/LTO/LTO.h index 78ac73a7418cc..3772592757bec 100644 --- a/include/llvm/LTO/LTO.h +++ b/include/llvm/LTO/LTO.h @@ -19,12 +19,14 @@ #include "llvm/ADT/MapVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" -#include "llvm/CodeGen/Analysis.h" +#include "llvm/Analysis/ObjectUtils.h" #include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/ModuleSummaryIndex.h" #include "llvm/LTO/Config.h" #include "llvm/Linker/IRMover.h" -#include "llvm/Object/IRObjectFile.h" +#include "llvm/Object/IRSymtab.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/thread.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Transforms/IPO/FunctionImport.h" @@ -68,25 +70,35 @@ std::string getThinLTOOutputFile(const std::string &Path, const std::string &OldPrefix, const std::string &NewPrefix); +/// Setup optimization remarks. +Expected<std::unique_ptr<tool_output_file>> +setupOptimizationRemarks(LLVMContext &Context, StringRef LTORemarksFilename, + bool LTOPassRemarksWithHotness, int Count = -1); + class LTO; struct SymbolResolution; class ThinBackendProc; -/// An input file. This is a wrapper for ModuleSymbolTable that exposes only the +/// 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; - // FIXME: Remove the LLVMContext once we have bitcode symbol tables. - LLVMContext Ctx; - struct InputModule; - std::vector<InputModule> Mods; - ModuleSymbolTable SymTab; + std::vector<BitcodeModule> Mods; + SmallVector<char, 0> Strtab; + std::vector<Symbol> Symbols; - std::vector<StringRef> Comdats; - DenseMap<const Comdat *, unsigned> ComdatMap; + // [begin, end) for each module + std::vector<std::pair<size_t, size_t>> ModuleSymIndices; + + StringRef TargetTriple, SourceFileName, COFFLinkerOpts; + std::vector<StringRef> ComdatTable; public: ~InputFile(); @@ -94,143 +106,52 @@ public: /// Create an InputFile. static Expected<std::unique_ptr<InputFile>> create(MemoryBufferRef Object); - class symbol_iterator; - - /// This is a wrapper for ArrayRef<ModuleSymbolTable::Symbol>::iterator that - /// exposes only the information that an LTO client should need in order to do - /// symbol resolution. - /// - /// This object is ephemeral; it is only valid as long as an iterator obtained - /// from symbols() refers to it. - class Symbol { - friend symbol_iterator; + /// 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; - ArrayRef<ModuleSymbolTable::Symbol>::iterator I; - const ModuleSymbolTable &SymTab; - const InputFile *File; - uint32_t Flags; - SmallString<64> Name; - - bool shouldSkip() { - return !(Flags & object::BasicSymbolRef::SF_Global) || - (Flags & object::BasicSymbolRef::SF_FormatSpecific); - } - - void skip() { - ArrayRef<ModuleSymbolTable::Symbol>::iterator E = SymTab.symbols().end(); - while (I != E) { - Flags = SymTab.getSymbolFlags(*I); - if (!shouldSkip()) - break; - ++I; - } - if (I == E) - return; - - Name.clear(); - { - raw_svector_ostream OS(Name); - SymTab.printSymbolName(OS, *I); - } - } - - bool isGV() const { return I->is<GlobalValue *>(); } - GlobalValue *getGV() const { return I->get<GlobalValue *>(); } - public: - Symbol(ArrayRef<ModuleSymbolTable::Symbol>::iterator I, - const ModuleSymbolTable &SymTab, const InputFile *File) - : I(I), SymTab(SymTab), File(File) { - skip(); - } - - /// Returns the mangled name of the global. - StringRef getName() const { return Name; } - - uint32_t getFlags() const { return Flags; } - GlobalValue::VisibilityTypes getVisibility() const { - if (isGV()) - return getGV()->getVisibility(); - return GlobalValue::DefaultVisibility; - } - bool canBeOmittedFromSymbolTable() const { - return isGV() && llvm::canBeOmittedFromSymbolTable(getGV()); - } - bool isTLS() const { - // FIXME: Expose a thread-local flag for module asm symbols. - return isGV() && getGV()->isThreadLocal(); - } - - // Returns the index of the comdat this symbol is in or -1 if the symbol - // is not in a comdat. - // FIXME: We have to return Expected<int> because aliases point to an - // arbitrary ConstantExpr and that might not actually be a constant. That - // means we might not be able to find what an alias is aliased to and - // so find its comdat. - Expected<int> getComdatIndex() const; - - uint64_t getCommonSize() const { - assert(Flags & object::BasicSymbolRef::SF_Common); - if (!isGV()) - return 0; - return getGV()->getParent()->getDataLayout().getTypeAllocSize( - getGV()->getType()->getElementType()); - } - unsigned getCommonAlignment() const { - assert(Flags & object::BasicSymbolRef::SF_Common); - if (!isGV()) - return 0; - return getGV()->getAlignment(); - } - }; - - class symbol_iterator { - Symbol Sym; - - public: - symbol_iterator(ArrayRef<ModuleSymbolTable::Symbol>::iterator I, - const ModuleSymbolTable &SymTab, const InputFile *File) - : Sym(I, SymTab, File) {} - - symbol_iterator &operator++() { - ++Sym.I; - Sym.skip(); - return *this; - } - - symbol_iterator operator++(int) { - symbol_iterator I = *this; - ++*this; - return I; - } - - const Symbol &operator*() const { return Sym; } - const Symbol *operator->() const { return &Sym; } - - bool operator!=(const symbol_iterator &Other) const { - return Sym.I != Other.Sym.I; - } + 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::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::isExecutable; }; /// A range over the symbols in this InputFile. - iterator_range<symbol_iterator> symbols() { - return llvm::make_range( - symbol_iterator(SymTab.symbols().begin(), SymTab, this), - symbol_iterator(SymTab.symbols().end(), SymTab, this)); - } + ArrayRef<Symbol> symbols() const { return Symbols; } + + /// Returns linker options specified in the input file. + StringRef getCOFFLinkerOpts() const { return COFFLinkerOpts; } /// 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; + StringRef getSourceFileName() const { return SourceFileName; } // Returns a table with all the comdats used by this file. - ArrayRef<StringRef> getComdatTable() const { return Comdats; } + ArrayRef<StringRef> getComdatTable() const { return ComdatTable; } private: - iterator_range<symbol_iterator> module_symbols(InputModule &IM); + 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 @@ -418,20 +339,20 @@ private: // Global mapping from mangled symbol names to resolutions. StringMap<GlobalResolution> GlobalResolutions; - void addSymbolToGlobalRes(SmallPtrSet<GlobalValue *, 8> &Used, - const InputFile::Symbol &Sym, SymbolResolution Res, + void addSymbolToGlobalRes(const InputFile::Symbol &Sym, SymbolResolution Res, unsigned Partition); // 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, InputFile::InputModule &IM, + Error addModule(InputFile &Input, unsigned ModI, const SymbolResolution *&ResI, const SymbolResolution *ResE); - Error addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI, + Error addRegularLTO(BitcodeModule BM, + ArrayRef<InputFile::Symbol> Syms, + const SymbolResolution *&ResI, const SymbolResolution *ResE); - Error addThinLTO(BitcodeModule BM, Module &M, - iterator_range<InputFile::symbol_iterator> Syms, + Error addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, const SymbolResolution *&ResI, const SymbolResolution *ResE); Error runRegularLTO(AddStreamFn AddStream); diff --git a/include/llvm/LTO/LTOBackend.h b/include/llvm/LTO/LTOBackend.h index 933503afddc89..d4743f6940ff9 100644 --- a/include/llvm/LTO/LTOBackend.h +++ b/include/llvm/LTO/LTOBackend.h @@ -34,14 +34,15 @@ class Target; namespace lto { -/// Runs a regular LTO backend. +/// 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(Config &C, AddStreamFn AddStream, unsigned ParallelCodeGenParallelismLevel, - std::unique_ptr<Module> M); + std::unique_ptr<Module> M, ModuleSummaryIndex &CombinedIndex); /// Runs a ThinLTO backend. Error thinBackend(Config &C, unsigned Task, AddStreamFn AddStream, Module &M, - ModuleSummaryIndex &CombinedIndex, + const ModuleSummaryIndex &CombinedIndex, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, MapVector<StringRef, BitcodeModule> &ModuleMap); diff --git a/include/llvm/LTO/legacy/LTOCodeGenerator.h b/include/llvm/LTO/legacy/LTOCodeGenerator.h index f146821112803..952875fc854e8 100644 --- a/include/llvm/LTO/legacy/LTOCodeGenerator.h +++ b/include/llvm/LTO/legacy/LTOCodeGenerator.h @@ -41,6 +41,7 @@ #include "llvm/ADT/StringSet.h" #include "llvm/IR/GlobalValue.h" #include "llvm/IR/Module.h" +#include "llvm/Support/Error.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -174,6 +175,10 @@ struct LTOCodeGenerator { /// 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 setDiagnosticHandler(lto_diagnostic_handler_t, void *); LLVMContext &getContext() { return Context; } @@ -206,7 +211,6 @@ private: void emitError(const std::string &ErrMsg); void emitWarning(const std::string &ErrMsg); - bool setupOptimizationRemarks(); void finishOptimizationRemarks(); LLVMContext &Context; @@ -237,6 +241,7 @@ private: bool ShouldRestoreGlobalsLinkage = false; TargetMachine::CodeGenFileType FileType = TargetMachine::CGFT_ObjectFile; std::unique_ptr<tool_output_file> DiagnosticOutputFile; + bool Freestanding = false; }; } #endif diff --git a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h index 0cc3b26e96591..f9545333aabdf 100644 --- a/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h +++ b/include/llvm/LTO/legacy/ThinLTOCodeGenerator.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringSet.h" #include "llvm/ADT/Triple.h" #include "llvm/IR/ModuleSummaryIndex.h" +#include "llvm/Support/CachePruning.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Target/TargetOptions.h" @@ -140,9 +141,7 @@ public: struct CachingOptions { std::string Path; // Path to the cache, empty to disable. - int PruningInterval = 1200; // seconds, -1 to disable pruning. - unsigned int Expiration = 7 * 24 * 3600; // seconds (1w default). - unsigned MaxPercentageOfAvailableSpace = 75; // percentage. + CachePruningPolicy Policy; }; /// Provide a path to a directory where to store the cached files for @@ -153,14 +152,14 @@ public: /// negative value (default) to disable pruning. A value of 0 will be ignored. void setCachePruningInterval(int Interval) { if (Interval) - CacheOptions.PruningInterval = Interval; + 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.Expiration = Expiration; + CacheOptions.Policy.Expiration = std::chrono::seconds(Expiration); } /** @@ -178,7 +177,7 @@ public: */ void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) { if (Percentage) - CacheOptions.MaxPercentageOfAvailableSpace = Percentage; + CacheOptions.Policy.PercentageOfAvailableSpace = Percentage; } /**@}*/ @@ -206,6 +205,10 @@ public: 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; @@ -323,6 +326,10 @@ private: /// 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; }; |