summaryrefslogtreecommitdiff
path: root/include/llvm/LTO
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/LTO')
-rw-r--r--include/llvm/LTO/Caching.h15
-rw-r--r--include/llvm/LTO/Config.h8
-rw-r--r--include/llvm/LTO/LTO.h197
-rw-r--r--include/llvm/LTO/LTOBackend.h7
-rw-r--r--include/llvm/LTO/legacy/LTOCodeGenerator.h7
-rw-r--r--include/llvm/LTO/legacy/ThinLTOCodeGenerator.h19
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;
};