mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:40:38 +00:00
[ThinLTO] Renaming of function index to module summary index (NFC)
(Resubmitting after fixing missing file issue) With the changes in r263275, there are now more than just functions in the summary. Completed the renaming of data structures (started in r263275) to reflect the wider scope. In particular, changed the FunctionIndex* data structures to ModuleIndex*, and renamed related variables and comments. Also renamed the files to reflect the changes. A companion clang patch will immediately succeed this patch to reflect this renaming. llvm-svn: 263513
This commit is contained in:
parent
ddb99141b3
commit
89e5e1dadb
@ -30,11 +30,11 @@ class PreservedAnalyses;
|
||||
/// If \c ShouldPreserveUseListOrder, encode use-list order so it can be
|
||||
/// reproduced when deserialized.
|
||||
///
|
||||
/// If \c EmitFunctionSummary, emit the function summary index (currently
|
||||
/// If \c EmitSummaryIndex, emit the summary index (currently
|
||||
/// for use in ThinLTO optimization).
|
||||
ModulePass *createBitcodeWriterPass(raw_ostream &Str,
|
||||
bool ShouldPreserveUseListOrder = false,
|
||||
bool EmitFunctionSummary = false);
|
||||
bool EmitSummaryIndex = false);
|
||||
|
||||
/// \brief Pass for writing a module of IR out to a bitcode file.
|
||||
///
|
||||
@ -43,7 +43,7 @@ ModulePass *createBitcodeWriterPass(raw_ostream &Str,
|
||||
class BitcodeWriterPass {
|
||||
raw_ostream &OS;
|
||||
bool ShouldPreserveUseListOrder;
|
||||
bool EmitFunctionSummary;
|
||||
bool EmitSummaryIndex;
|
||||
|
||||
public:
|
||||
/// \brief Construct a bitcode writer pass around a particular output stream.
|
||||
@ -51,13 +51,13 @@ public:
|
||||
/// If \c ShouldPreserveUseListOrder, encode use-list order so it can be
|
||||
/// reproduced when deserialized.
|
||||
///
|
||||
/// If \c EmitFunctionSummary, emit the function summary index (currently
|
||||
/// If \c EmitSummaryIndex, emit the summary index (currently
|
||||
/// for use in ThinLTO optimization).
|
||||
explicit BitcodeWriterPass(raw_ostream &OS,
|
||||
bool ShouldPreserveUseListOrder = false,
|
||||
bool EmitFunctionSummary = false)
|
||||
bool EmitSummaryIndex = false)
|
||||
: OS(OS), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
|
||||
EmitFunctionSummary(EmitFunctionSummary) {}
|
||||
EmitSummaryIndex(EmitSummaryIndex) {}
|
||||
|
||||
/// \brief Run the bitcode writer pass, and output the module to the selected
|
||||
/// output stream.
|
||||
|
@ -186,9 +186,9 @@ enum { BITCODE_CURRENT_EPOCH = 0 };
|
||||
MST_CODE_ENTRY = 1, // MST_ENTRY: [modid, namechar x N]
|
||||
};
|
||||
|
||||
// The function summary section uses different codes in the per-module
|
||||
// The summary section uses different codes in the per-module
|
||||
// and combined index cases.
|
||||
enum FunctionSummarySymtabCodes {
|
||||
enum GlobalValueSummarySymtabCodes {
|
||||
// PERMODULE: [valueid, linkage, instcount, numrefs, numrefs x valueid,
|
||||
// n x (valueid, callsitecount)]
|
||||
FS_PERMODULE = 1,
|
||||
|
@ -15,7 +15,7 @@
|
||||
#define LLVM_BITCODE_READERWRITER_H
|
||||
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
@ -74,25 +74,25 @@ namespace llvm {
|
||||
bool hasGlobalValueSummary(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler);
|
||||
|
||||
/// Parse the specified bitcode buffer, returning the function info index.
|
||||
/// If IsLazy is true, parse the entire function summary into
|
||||
/// the index. Otherwise skip the function summary section, and only create
|
||||
/// an index object with a map from function name to function summary offset.
|
||||
/// The index is used to perform lazy function summary reading later.
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>>
|
||||
getFunctionInfoIndex(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false);
|
||||
/// Parse the specified bitcode buffer, returning the module summary index.
|
||||
/// If IsLazy is true, parse the entire module summary into
|
||||
/// the index. Otherwise skip the module summary section, and only create
|
||||
/// an index object with a map from value name to the value's summary offset.
|
||||
/// The index is used to perform lazy summary reading later.
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>>
|
||||
getModuleSummaryIndex(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false);
|
||||
|
||||
/// This method supports lazy reading of function summary data from the
|
||||
/// This method supports lazy reading of summary data from the
|
||||
/// combined index during function importing. When reading the combined index
|
||||
/// file, getFunctionInfoIndex is first invoked with IsLazy=true.
|
||||
/// Then this method is called for each function considered for importing,
|
||||
/// to parse the summary information for the given function name into
|
||||
/// file, getModuleSummaryIndex is first invoked with IsLazy=true.
|
||||
/// Then this method is called for each value considered for importing,
|
||||
/// to parse the summary information for the given value name into
|
||||
/// the index.
|
||||
std::error_code readFunctionSummary(
|
||||
std::error_code readGlobalValueSummary(
|
||||
MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef FunctionName, std::unique_ptr<FunctionInfoIndex> Index);
|
||||
StringRef ValueName, std::unique_ptr<ModuleSummaryIndex> Index);
|
||||
|
||||
/// \brief Write the specified module to the specified raw output stream.
|
||||
///
|
||||
@ -112,7 +112,7 @@ namespace llvm {
|
||||
/// Write the specified module summary index to the given raw output stream,
|
||||
/// where it will be written in a new bitcode block. This is used when
|
||||
/// writing the combined index file for ThinLTO.
|
||||
void WriteIndexToFile(const FunctionInfoIndex &Index, raw_ostream &Out);
|
||||
void WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out);
|
||||
|
||||
/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
|
||||
/// for an LLVM IR bitcode wrapper.
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/FunctionInfo.h - Function Info Index ---------------*- C++ -*-===//
|
||||
//===-- llvm/ModuleSummaryIndex.h - Module Summary Index --------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -8,13 +8,13 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// @file
|
||||
/// FunctionInfo.h This file contains the declarations the classes that hold
|
||||
/// the module index and summary for function importing.
|
||||
/// ModuleSummaryIndex.h This file contains the declarations the classes that
|
||||
/// hold the module index and summary for function importing.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_IR_FUNCTIONINFO_H
|
||||
#define LLVM_IR_FUNCTIONINFO_H
|
||||
#ifndef LLVM_IR_MODULESUMMARYINDEX_H
|
||||
#define LLVM_IR_MODULESUMMARYINDEX_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
@ -62,7 +62,7 @@ private:
|
||||
/// module during importing.
|
||||
///
|
||||
/// This is only used during parsing of the combined index, or when
|
||||
/// parsing the per-module index for creation of the combined function index,
|
||||
/// parsing the per-module index for creation of the combined summary index,
|
||||
/// not during writing of the per-module index which doesn't contain a
|
||||
/// module path string table.
|
||||
StringRef ModulePath;
|
||||
@ -128,7 +128,7 @@ public:
|
||||
|
||||
private:
|
||||
/// Number of instructions (ignoring debug instructions, e.g.) computed
|
||||
/// during the initial compile step when the function index is first built.
|
||||
/// during the initial compile step when the summary index is first built.
|
||||
unsigned InstCount;
|
||||
|
||||
/// List of <CalleeGUID, CalleeInfo> call edge pairs from this function.
|
||||
@ -251,9 +251,7 @@ typedef StringMap<uint64_t> ModulePathStringTableTy;
|
||||
|
||||
/// Class to hold module path string table and global value map,
|
||||
/// and encapsulate methods for operating on them.
|
||||
/// FIXME: Rename this and other uses of Function.*Index to something
|
||||
/// that reflects the now-expanded scope of the summary beyond just functions.
|
||||
class FunctionInfoIndex {
|
||||
class ModuleSummaryIndex {
|
||||
private:
|
||||
/// Map from value name to list of information instances for values of that
|
||||
/// name (may be duplicates in the COMDAT case, e.g.).
|
||||
@ -263,12 +261,12 @@ private:
|
||||
ModulePathStringTableTy ModulePathStringTable;
|
||||
|
||||
public:
|
||||
FunctionInfoIndex() = default;
|
||||
ModuleSummaryIndex() = default;
|
||||
|
||||
// Disable the copy constructor and assignment operators, so
|
||||
// no unexpected copying/moving occurs.
|
||||
FunctionInfoIndex(const FunctionInfoIndex &) = delete;
|
||||
void operator=(const FunctionInfoIndex &) = delete;
|
||||
ModuleSummaryIndex(const ModuleSummaryIndex &) = delete;
|
||||
void operator=(const ModuleSummaryIndex &) = delete;
|
||||
|
||||
globalvalueinfo_iterator begin() { return GlobalValueMap.begin(); }
|
||||
const_globalvalueinfo_iterator begin() const {
|
||||
@ -278,8 +276,8 @@ public:
|
||||
const_globalvalueinfo_iterator end() const { return GlobalValueMap.end(); }
|
||||
|
||||
/// Get the list of global value info objects for a given value name.
|
||||
const GlobalValueInfoList &getGlobalValueInfoList(StringRef FuncName) {
|
||||
return GlobalValueMap[Function::getGUID(FuncName)];
|
||||
const GlobalValueInfoList &getGlobalValueInfoList(StringRef ValueName) {
|
||||
return GlobalValueMap[Function::getGUID(ValueName)];
|
||||
}
|
||||
|
||||
/// Get the list of global value info objects for a given value name.
|
||||
@ -322,7 +320,7 @@ public:
|
||||
/// assigning it the given module ID. Each module merged in should have
|
||||
/// a unique ID, necessary for consistent renaming of promoted
|
||||
/// static (local) variables.
|
||||
void mergeFrom(std::unique_ptr<FunctionInfoIndex> Other,
|
||||
void mergeFrom(std::unique_ptr<ModuleSummaryIndex> Other,
|
||||
uint64_t NextModuleId);
|
||||
|
||||
/// Convenience method for creating a promoted global name
|
@ -27,7 +27,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class FunctionInfoIndex;
|
||||
class ModuleSummaryIndex;
|
||||
class LLVMContext;
|
||||
class TargetMachine;
|
||||
|
||||
@ -177,21 +177,21 @@ public:
|
||||
*/
|
||||
|
||||
/**
|
||||
* Produce the combined function index from all the bitcode files:
|
||||
* Produce the combined summary index from all the bitcode files:
|
||||
* "thin-link".
|
||||
*/
|
||||
std::unique_ptr<FunctionInfoIndex> linkCombinedIndex();
|
||||
std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex();
|
||||
|
||||
/**
|
||||
* Perform promotion and renaming of exported internal functions.
|
||||
*/
|
||||
void promote(Module &Module, FunctionInfoIndex &Index);
|
||||
void promote(Module &Module, ModuleSummaryIndex &Index);
|
||||
|
||||
/**
|
||||
* Perform cross-module importing for the module identified by
|
||||
* ModuleIdentifier.
|
||||
*/
|
||||
void crossModuleImport(Module &Module, FunctionInfoIndex &Index);
|
||||
void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
|
||||
|
||||
/**
|
||||
* Perform post-importing ThinLTO optimizations.
|
||||
|
@ -10,7 +10,7 @@
|
||||
#ifndef LLVM_LINKER_LINKER_H
|
||||
#define LLVM_LINKER_LINKER_H
|
||||
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/Linker/IRMover.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -39,7 +39,7 @@ public:
|
||||
///
|
||||
/// Passing OverrideSymbols as true will have symbols from Src
|
||||
/// shadow those in the Dest.
|
||||
/// For ThinLTO function importing/exporting the \p FunctionInfoIndex
|
||||
/// For ThinLTO function importing/exporting the \p ModuleSummaryIndex
|
||||
/// is passed. If \p FunctionsToImport is provided, only the functions that
|
||||
/// are part of the set will be imported from the source module.
|
||||
/// The \p ValIDToTempMDMap is populated by the linker when function
|
||||
@ -47,7 +47,7 @@ public:
|
||||
///
|
||||
/// Returns true on error.
|
||||
bool linkInModule(std::unique_ptr<Module> Src, unsigned Flags = Flags::None,
|
||||
const FunctionInfoIndex *Index = nullptr,
|
||||
const ModuleSummaryIndex *Index = nullptr,
|
||||
DenseSet<const GlobalValue *> *FunctionsToImport = nullptr,
|
||||
DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr);
|
||||
|
||||
|
@ -42,8 +42,8 @@ protected:
|
||||
ID_Archive,
|
||||
ID_MachOUniversalBinary,
|
||||
ID_COFFImportFile,
|
||||
ID_IR, // LLVM IR
|
||||
ID_FunctionIndex, // Function summary index
|
||||
ID_IR, // LLVM IR
|
||||
ID_ModuleSummaryIndex, // Module summary index
|
||||
|
||||
// Object and children.
|
||||
ID_StartObjects,
|
||||
@ -123,7 +123,7 @@ public:
|
||||
return TypeID == ID_IR;
|
||||
}
|
||||
|
||||
bool isFunctionIndex() const { return TypeID == ID_FunctionIndex; }
|
||||
bool isModuleSummaryIndex() const { return TypeID == ID_ModuleSummaryIndex; }
|
||||
|
||||
bool isLittleEndian() const {
|
||||
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===- FunctionIndexObjectFile.h - Function index file implementation -----===//
|
||||
//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,36 +7,36 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the FunctionIndexObjectFile template class.
|
||||
// This file declares the ModuleSummaryIndexObjectFile template class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_FUNCTIONINDEXOBJECTFILE_H
|
||||
#define LLVM_OBJECT_FUNCTIONINDEXOBJECTFILE_H
|
||||
#ifndef LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
|
||||
#define LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
|
||||
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/Object/SymbolicFile.h"
|
||||
|
||||
namespace llvm {
|
||||
class FunctionInfoIndex;
|
||||
class ModuleSummaryIndex;
|
||||
class Module;
|
||||
|
||||
namespace object {
|
||||
class ObjectFile;
|
||||
|
||||
/// This class is used to read just the function summary index related
|
||||
/// This class is used to read just the module summary index related
|
||||
/// sections out of the given object (which may contain a single module's
|
||||
/// bitcode or be a combined index bitcode file). It builds a FunctionInfoIndex
|
||||
/// bitcode or be a combined index bitcode file). It builds a ModuleSummaryIndex
|
||||
/// object.
|
||||
class FunctionIndexObjectFile : public SymbolicFile {
|
||||
std::unique_ptr<FunctionInfoIndex> Index;
|
||||
class ModuleSummaryIndexObjectFile : public SymbolicFile {
|
||||
std::unique_ptr<ModuleSummaryIndex> Index;
|
||||
|
||||
public:
|
||||
FunctionIndexObjectFile(MemoryBufferRef Object,
|
||||
std::unique_ptr<FunctionInfoIndex> I);
|
||||
~FunctionIndexObjectFile() override;
|
||||
ModuleSummaryIndexObjectFile(MemoryBufferRef Object,
|
||||
std::unique_ptr<ModuleSummaryIndex> I);
|
||||
~ModuleSummaryIndexObjectFile() override;
|
||||
|
||||
// TODO: Walk through FunctionMap entries for function symbols.
|
||||
// TODO: Walk through GlobalValueMap entries for symbols.
|
||||
// However, currently these interfaces are not used by any consumers.
|
||||
void moveSymbolNext(DataRefImpl &Symb) const override {
|
||||
llvm_unreachable("not implemented");
|
||||
@ -59,13 +59,15 @@ public:
|
||||
return basic_symbol_iterator(BasicSymbolRef());
|
||||
}
|
||||
|
||||
const FunctionInfoIndex &getIndex() const {
|
||||
return const_cast<FunctionIndexObjectFile *>(this)->getIndex();
|
||||
const ModuleSummaryIndex &getIndex() const {
|
||||
return const_cast<ModuleSummaryIndexObjectFile *>(this)->getIndex();
|
||||
}
|
||||
FunctionInfoIndex &getIndex() { return *Index; }
|
||||
std::unique_ptr<FunctionInfoIndex> takeIndex();
|
||||
ModuleSummaryIndex &getIndex() { return *Index; }
|
||||
std::unique_ptr<ModuleSummaryIndex> takeIndex();
|
||||
|
||||
static inline bool classof(const Binary *v) { return v->isFunctionIndex(); }
|
||||
static inline bool classof(const Binary *v) {
|
||||
return v->isModuleSummaryIndex();
|
||||
}
|
||||
|
||||
/// \brief Finds and returns bitcode embedded in the given object file, or an
|
||||
/// error code if not found.
|
||||
@ -83,28 +85,28 @@ public:
|
||||
hasGlobalValueSummaryInMemBuffer(MemoryBufferRef Object,
|
||||
DiagnosticHandlerFunction DiagnosticHandler);
|
||||
|
||||
/// \brief Parse function index in the given memory buffer.
|
||||
/// Return new FunctionIndexObjectFile instance containing parsed function
|
||||
/// \brief Parse module summary index in the given memory buffer.
|
||||
/// Return new ModuleSummaryIndexObjectFile instance containing parsed module
|
||||
/// summary/index.
|
||||
static ErrorOr<std::unique_ptr<FunctionIndexObjectFile>>
|
||||
static ErrorOr<std::unique_ptr<ModuleSummaryIndexObjectFile>>
|
||||
create(MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false);
|
||||
|
||||
/// \brief Parse the function summary information for function with the
|
||||
/// \brief Parse the summary information for global value with the
|
||||
/// given name out of the given buffer. Parsed information is
|
||||
/// stored on the index object saved in this object.
|
||||
std::error_code
|
||||
findFunctionSummaryInMemBuffer(MemoryBufferRef Object,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef FunctionName);
|
||||
findGlobalValueSummaryInMemBuffer(MemoryBufferRef Object,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef ValueName);
|
||||
};
|
||||
}
|
||||
|
||||
/// Parse the function index out of an IR file and return the function
|
||||
/// index object if found, or nullptr if not.
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>>
|
||||
getFunctionIndexForFile(StringRef Path,
|
||||
DiagnosticHandlerFunction DiagnosticHandler);
|
||||
/// Parse the module summary index out of an IR file and return the module
|
||||
/// summary index object if found, or nullptr if not.
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>>
|
||||
getModuleSummaryIndexForFile(StringRef Path,
|
||||
DiagnosticHandlerFunction DiagnosticHandler);
|
||||
}
|
||||
|
||||
#endif
|
@ -21,7 +21,7 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class FunctionInfoIndex;
|
||||
class ModuleSummaryIndex;
|
||||
class ModulePass;
|
||||
class Pass;
|
||||
class Function;
|
||||
@ -89,7 +89,7 @@ ModulePass *createGVExtractionPass(std::vector<GlobalValue*>& GVs, bool
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// This pass performs iterative function importing from other modules.
|
||||
Pass *createFunctionImportPass(const FunctionInfoIndex *Index = nullptr);
|
||||
Pass *createFunctionImportPass(const ModuleSummaryIndex *Index = nullptr);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// createFunctionInliningPass - Return a new pass object that uses a heuristic
|
||||
|
@ -16,14 +16,14 @@
|
||||
namespace llvm {
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
class FunctionInfoIndex;
|
||||
class ModuleSummaryIndex;
|
||||
|
||||
/// The function importer is automatically importing function from other modules
|
||||
/// based on the provided summary informations.
|
||||
class FunctionImporter {
|
||||
|
||||
/// The summaries index used to trigger importing.
|
||||
const FunctionInfoIndex &Index;
|
||||
const ModuleSummaryIndex &Index;
|
||||
|
||||
/// Factory function to load a Module for a given identifier
|
||||
std::function<std::unique_ptr<Module>(StringRef Identifier)> ModuleLoader;
|
||||
@ -31,7 +31,7 @@ class FunctionImporter {
|
||||
public:
|
||||
/// Create a Function Importer.
|
||||
FunctionImporter(
|
||||
const FunctionInfoIndex &Index,
|
||||
const ModuleSummaryIndex &Index,
|
||||
std::function<std::unique_ptr<Module>(StringRef Identifier)> ModuleLoader)
|
||||
: Index(Index), ModuleLoader(ModuleLoader) {}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class FunctionInfoIndex;
|
||||
class ModuleSummaryIndex;
|
||||
class Pass;
|
||||
class TargetLibraryInfoImpl;
|
||||
class TargetMachine;
|
||||
@ -117,8 +117,8 @@ public:
|
||||
/// added to the per-module passes.
|
||||
Pass *Inliner;
|
||||
|
||||
/// The function summary index to use for function importing.
|
||||
const FunctionInfoIndex *FunctionIndex;
|
||||
/// The module summary index to use for function importing.
|
||||
const ModuleSummaryIndex *ModuleSummary;
|
||||
|
||||
bool DisableTailCalls;
|
||||
bool DisableUnitAtATime;
|
||||
|
@ -16,7 +16,7 @@
|
||||
#define LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
@ -27,14 +27,14 @@ class FunctionImportGlobalProcessing {
|
||||
/// The Module which we are exporting or importing functions from.
|
||||
Module &M;
|
||||
|
||||
/// Function index passed in for function importing/exporting handling.
|
||||
const FunctionInfoIndex &ImportIndex;
|
||||
/// Module summary index passed in for function importing/exporting handling.
|
||||
const ModuleSummaryIndex &ImportIndex;
|
||||
|
||||
/// Functions to import from this module, all other functions will be
|
||||
/// imported as declarations instead of definitions.
|
||||
DenseSet<const GlobalValue *> *FunctionsToImport;
|
||||
|
||||
/// Set to true if the given FunctionInfoIndex contains any functions
|
||||
/// Set to true if the given ModuleSummaryIndex contains any functions
|
||||
/// from this source module, in which case we must conservatively assume
|
||||
/// that any of its functions may be imported into another module
|
||||
/// as part of a different backend compilation process.
|
||||
@ -76,10 +76,10 @@ class FunctionImportGlobalProcessing {
|
||||
|
||||
public:
|
||||
FunctionImportGlobalProcessing(
|
||||
Module &M, const FunctionInfoIndex &Index,
|
||||
Module &M, const ModuleSummaryIndex &Index,
|
||||
DenseSet<const GlobalValue *> *FunctionsToImport = nullptr)
|
||||
: M(M), ImportIndex(Index), FunctionsToImport(FunctionsToImport) {
|
||||
// If we have a FunctionInfoIndex but no function to import,
|
||||
// If we have a ModuleSummaryIndex but no function to import,
|
||||
// then this is the primary module being compiled in a ThinLTO
|
||||
// backend compilation, and we need to see if it has functions that
|
||||
// may be exported to another backend compilation.
|
||||
@ -99,7 +99,7 @@ public:
|
||||
|
||||
/// Perform in-place global value handling on the given Module for
|
||||
/// exported local functions renamed and promoted for ThinLTO.
|
||||
bool renameModuleForThinLTO(Module &M, const FunctionInfoIndex &Index);
|
||||
bool renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
|
@ -7,13 +7,13 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Bitcode/BitstreamReader.h"
|
||||
#include "llvm/Bitcode/LLVMBitCodes.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/IR/AutoUpgrade.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/IR/DebugInfo.h"
|
||||
@ -25,9 +25,9 @@
|
||||
#include "llvm/IR/IntrinsicInst.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/OperandTraits.h"
|
||||
#include "llvm/IR/Operator.h"
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/IR/ValueHandle.h"
|
||||
#include "llvm/Support/DataStream.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
@ -413,11 +413,11 @@ private:
|
||||
|
||||
/// Class to manage reading and parsing function summary index bitcode
|
||||
/// files/sections.
|
||||
class FunctionIndexBitcodeReader {
|
||||
class ModuleSummaryIndexBitcodeReader {
|
||||
DiagnosticHandlerFunction DiagnosticHandler;
|
||||
|
||||
/// Eventually points to the module index built during parsing.
|
||||
FunctionInfoIndex *TheIndex = nullptr;
|
||||
ModuleSummaryIndex *TheIndex = nullptr;
|
||||
|
||||
std::unique_ptr<MemoryBuffer> Buffer;
|
||||
std::unique_ptr<BitstreamReader> StreamFile;
|
||||
@ -427,7 +427,7 @@ class FunctionIndexBitcodeReader {
|
||||
///
|
||||
/// If false, the summary section is fully parsed into the index during
|
||||
/// the initial parse. Otherwise, if true, the caller is expected to
|
||||
/// invoke \a readFunctionSummary for each summary needed, and the summary
|
||||
/// invoke \a readGlobalValueSummary for each summary needed, and the summary
|
||||
/// section is thus parsed lazily.
|
||||
bool IsLazy = false;
|
||||
|
||||
@ -452,7 +452,7 @@ class FunctionIndexBitcodeReader {
|
||||
// ValueSymbolTable. It is used after the VST is parsed to convert
|
||||
// call graph edges read from the function summary from referencing
|
||||
// callees by their ValueId to using the GUID instead, which is how
|
||||
// they are recorded in the function index being built.
|
||||
// they are recorded in the summary index being built.
|
||||
DenseMap<unsigned, uint64_t> ValueIdToCallGraphGUIDMap;
|
||||
|
||||
/// Map to save the association between summary offset in the VST to the
|
||||
@ -474,14 +474,13 @@ public:
|
||||
std::error_code error(BitcodeError E);
|
||||
std::error_code error(const Twine &Message);
|
||||
|
||||
FunctionIndexBitcodeReader(MemoryBuffer *Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false,
|
||||
bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
FunctionIndexBitcodeReader(DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false,
|
||||
bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
~FunctionIndexBitcodeReader() { freeState(); }
|
||||
ModuleSummaryIndexBitcodeReader(
|
||||
MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false, bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
ModuleSummaryIndexBitcodeReader(
|
||||
DiagnosticHandlerFunction DiagnosticHandler, bool IsLazy = false,
|
||||
bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
~ModuleSummaryIndexBitcodeReader() { freeState(); }
|
||||
|
||||
void freeState();
|
||||
|
||||
@ -493,12 +492,12 @@ public:
|
||||
/// \brief Main interface to parsing a bitcode buffer.
|
||||
/// \returns true if an error occurred.
|
||||
std::error_code parseSummaryIndexInto(std::unique_ptr<DataStreamer> Streamer,
|
||||
FunctionInfoIndex *I);
|
||||
ModuleSummaryIndex *I);
|
||||
|
||||
/// \brief Interface for parsing a summary lazily.
|
||||
std::error_code parseFunctionSummary(std::unique_ptr<DataStreamer> Streamer,
|
||||
FunctionInfoIndex *I,
|
||||
size_t FunctionSummaryOffset);
|
||||
std::error_code
|
||||
parseGlobalValueSummary(std::unique_ptr<DataStreamer> Streamer,
|
||||
ModuleSummaryIndex *I, size_t SummaryOffset);
|
||||
|
||||
private:
|
||||
std::error_code parseModule();
|
||||
@ -5414,44 +5413,44 @@ BitcodeReader::initLazyStream(std::unique_ptr<DataStreamer> Streamer) {
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code FunctionIndexBitcodeReader::error(BitcodeError E,
|
||||
const Twine &Message) {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::error(BitcodeError E,
|
||||
const Twine &Message) {
|
||||
return ::error(DiagnosticHandler, make_error_code(E), Message);
|
||||
}
|
||||
|
||||
std::error_code FunctionIndexBitcodeReader::error(const Twine &Message) {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::error(const Twine &Message) {
|
||||
return ::error(DiagnosticHandler,
|
||||
make_error_code(BitcodeError::CorruptedBitcode), Message);
|
||||
}
|
||||
|
||||
std::error_code FunctionIndexBitcodeReader::error(BitcodeError E) {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::error(BitcodeError E) {
|
||||
return ::error(DiagnosticHandler, make_error_code(E));
|
||||
}
|
||||
|
||||
FunctionIndexBitcodeReader::FunctionIndexBitcodeReader(
|
||||
ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader(
|
||||
MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy, bool CheckGlobalValSummaryPresenceOnly)
|
||||
: DiagnosticHandler(DiagnosticHandler), Buffer(Buffer), IsLazy(IsLazy),
|
||||
CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {}
|
||||
|
||||
FunctionIndexBitcodeReader::FunctionIndexBitcodeReader(
|
||||
ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader(
|
||||
DiagnosticHandlerFunction DiagnosticHandler, bool IsLazy,
|
||||
bool CheckGlobalValSummaryPresenceOnly)
|
||||
: DiagnosticHandler(DiagnosticHandler), Buffer(nullptr), IsLazy(IsLazy),
|
||||
CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {}
|
||||
|
||||
void FunctionIndexBitcodeReader::freeState() { Buffer = nullptr; }
|
||||
void ModuleSummaryIndexBitcodeReader::freeState() { Buffer = nullptr; }
|
||||
|
||||
void FunctionIndexBitcodeReader::releaseBuffer() { Buffer.release(); }
|
||||
void ModuleSummaryIndexBitcodeReader::releaseBuffer() { Buffer.release(); }
|
||||
|
||||
uint64_t FunctionIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) {
|
||||
uint64_t ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) {
|
||||
auto VGI = ValueIdToCallGraphGUIDMap.find(ValueId);
|
||||
assert(VGI != ValueIdToCallGraphGUIDMap.end());
|
||||
return VGI->second;
|
||||
}
|
||||
|
||||
GlobalValueInfo *
|
||||
FunctionIndexBitcodeReader::getInfoFromSummaryOffset(uint64_t Offset) {
|
||||
ModuleSummaryIndexBitcodeReader::getInfoFromSummaryOffset(uint64_t Offset) {
|
||||
auto I = SummaryOffsetToInfoMap.find(Offset);
|
||||
assert(I != SummaryOffsetToInfoMap.end());
|
||||
return I->second;
|
||||
@ -5463,7 +5462,7 @@ FunctionIndexBitcodeReader::getInfoFromSummaryOffset(uint64_t Offset) {
|
||||
// from global value name to GlobalValueInfo. The global value info contains
|
||||
// the function block's bitcode offset (if applicable), or the offset into the
|
||||
// summary section for the combined index.
|
||||
std::error_code FunctionIndexBitcodeReader::parseValueSymbolTable(
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseValueSymbolTable(
|
||||
uint64_t Offset,
|
||||
DenseMap<unsigned, GlobalValue::LinkageTypes> &ValueIdToLinkageMap) {
|
||||
assert(Offset > 0 && "Expected non-zero VST offset");
|
||||
@ -5564,7 +5563,7 @@ std::error_code FunctionIndexBitcodeReader::parseValueSymbolTable(
|
||||
// either the parsed summary information (when parsing summaries
|
||||
// eagerly), or just to the summary record's offset
|
||||
// if parsing lazily (IsLazy).
|
||||
std::error_code FunctionIndexBitcodeReader::parseModule() {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseModule() {
|
||||
if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
|
||||
return error("Invalid record");
|
||||
|
||||
@ -5701,7 +5700,7 @@ std::error_code FunctionIndexBitcodeReader::parseModule() {
|
||||
|
||||
// Eagerly parse the entire summary block. This populates the GlobalValueSummary
|
||||
// objects in the index.
|
||||
std::error_code FunctionIndexBitcodeReader::parseEntireSummary() {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
|
||||
if (Stream.EnterSubBlock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID))
|
||||
return error("Invalid record");
|
||||
|
||||
@ -5883,7 +5882,7 @@ std::error_code FunctionIndexBitcodeReader::parseEntireSummary() {
|
||||
|
||||
// Parse the module string table block into the Index.
|
||||
// This populates the ModulePathStringTable map in the index.
|
||||
std::error_code FunctionIndexBitcodeReader::parseModuleStringTable() {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseModuleStringTable() {
|
||||
if (Stream.EnterSubBlock(bitc::MODULE_STRTAB_BLOCK_ID))
|
||||
return error("Invalid record");
|
||||
|
||||
@ -5924,8 +5923,8 @@ std::error_code FunctionIndexBitcodeReader::parseModuleStringTable() {
|
||||
}
|
||||
|
||||
// Parse the function info index from the bitcode streamer into the given index.
|
||||
std::error_code FunctionIndexBitcodeReader::parseSummaryIndexInto(
|
||||
std::unique_ptr<DataStreamer> Streamer, FunctionInfoIndex *I) {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(
|
||||
std::unique_ptr<DataStreamer> Streamer, ModuleSummaryIndex *I) {
|
||||
TheIndex = I;
|
||||
|
||||
if (std::error_code EC = initStream(std::move(Streamer)))
|
||||
@ -5959,14 +5958,14 @@ std::error_code FunctionIndexBitcodeReader::parseSummaryIndexInto(
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the function information at the given offset in the buffer into
|
||||
// the index. Used to support lazy parsing of function summaries from the
|
||||
// Parse the summary information at the given offset in the buffer into
|
||||
// the index. Used to support lazy parsing of summaries from the
|
||||
// combined index during importing.
|
||||
// TODO: This function is not yet complete as it won't have a consumer
|
||||
// until ThinLTO function importing is added.
|
||||
std::error_code FunctionIndexBitcodeReader::parseFunctionSummary(
|
||||
std::unique_ptr<DataStreamer> Streamer, FunctionInfoIndex *I,
|
||||
size_t FunctionSummaryOffset) {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseGlobalValueSummary(
|
||||
std::unique_ptr<DataStreamer> Streamer, ModuleSummaryIndex *I,
|
||||
size_t SummaryOffset) {
|
||||
TheIndex = I;
|
||||
|
||||
if (std::error_code EC = initStream(std::move(Streamer)))
|
||||
@ -5976,7 +5975,7 @@ std::error_code FunctionIndexBitcodeReader::parseFunctionSummary(
|
||||
if (!hasValidBitcodeHeader(Stream))
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
Stream.JumpToBit(FunctionSummaryOffset);
|
||||
Stream.JumpToBit(SummaryOffset);
|
||||
|
||||
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
|
||||
|
||||
@ -6002,14 +6001,14 @@ std::error_code FunctionIndexBitcodeReader::parseFunctionSummary(
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code
|
||||
FunctionIndexBitcodeReader::initStream(std::unique_ptr<DataStreamer> Streamer) {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::initStream(
|
||||
std::unique_ptr<DataStreamer> Streamer) {
|
||||
if (Streamer)
|
||||
return initLazyStream(std::move(Streamer));
|
||||
return initStreamFromBuffer();
|
||||
}
|
||||
|
||||
std::error_code FunctionIndexBitcodeReader::initStreamFromBuffer() {
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::initStreamFromBuffer() {
|
||||
const unsigned char *BufPtr = (const unsigned char *)Buffer->getBufferStart();
|
||||
const unsigned char *BufEnd = BufPtr + Buffer->getBufferSize();
|
||||
|
||||
@ -6028,7 +6027,7 @@ std::error_code FunctionIndexBitcodeReader::initStreamFromBuffer() {
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code FunctionIndexBitcodeReader::initLazyStream(
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::initLazyStream(
|
||||
std::unique_ptr<DataStreamer> Streamer) {
|
||||
// Check and strip off the bitcode wrapper; BitstreamReader expects never to
|
||||
// see it.
|
||||
@ -6187,14 +6186,14 @@ std::string llvm::getBitcodeProducerString(MemoryBufferRef Buffer,
|
||||
// the index. Otherwise skip the function summary section, and only create
|
||||
// an index object with a map from function name to function summary offset.
|
||||
// The index is used to perform lazy function summary reading later.
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>>
|
||||
llvm::getFunctionInfoIndex(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy) {
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>>
|
||||
llvm::getModuleSummaryIndex(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy) {
|
||||
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
|
||||
FunctionIndexBitcodeReader R(Buf.get(), DiagnosticHandler, IsLazy);
|
||||
ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler, IsLazy);
|
||||
|
||||
auto Index = llvm::make_unique<FunctionInfoIndex>();
|
||||
auto Index = llvm::make_unique<ModuleSummaryIndex>();
|
||||
|
||||
auto cleanupOnError = [&](std::error_code EC) {
|
||||
R.releaseBuffer(); // Never take ownership on error.
|
||||
@ -6204,7 +6203,7 @@ llvm::getFunctionInfoIndex(MemoryBufferRef Buffer,
|
||||
if (std::error_code EC = R.parseSummaryIndexInto(nullptr, Index.get()))
|
||||
return cleanupOnError(EC);
|
||||
|
||||
Buf.release(); // The FunctionIndexBitcodeReader owns it now.
|
||||
Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
|
||||
return std::move(Index);
|
||||
}
|
||||
|
||||
@ -6212,7 +6211,7 @@ llvm::getFunctionInfoIndex(MemoryBufferRef Buffer,
|
||||
bool llvm::hasGlobalValueSummary(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
|
||||
FunctionIndexBitcodeReader R(Buf.get(), DiagnosticHandler, false, true);
|
||||
ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler, false, true);
|
||||
|
||||
auto cleanupOnError = [&](std::error_code EC) {
|
||||
R.releaseBuffer(); // Never take ownership on error.
|
||||
@ -6222,38 +6221,38 @@ bool llvm::hasGlobalValueSummary(MemoryBufferRef Buffer,
|
||||
if (std::error_code EC = R.parseSummaryIndexInto(nullptr, nullptr))
|
||||
return cleanupOnError(EC);
|
||||
|
||||
Buf.release(); // The FunctionIndexBitcodeReader owns it now.
|
||||
Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
|
||||
return R.foundGlobalValSummary();
|
||||
}
|
||||
|
||||
// This method supports lazy reading of function summary data from the combined
|
||||
// This method supports lazy reading of summary data from the combined
|
||||
// index during ThinLTO function importing. When reading the combined index
|
||||
// file, getFunctionInfoIndex is first invoked with IsLazy=true.
|
||||
// Then this method is called for each function considered for importing,
|
||||
// to parse the summary information for the given function name into
|
||||
// file, getModuleSummaryIndex is first invoked with IsLazy=true.
|
||||
// Then this method is called for each value considered for importing,
|
||||
// to parse the summary information for the given value name into
|
||||
// the index.
|
||||
std::error_code llvm::readFunctionSummary(
|
||||
std::error_code llvm::readGlobalValueSummary(
|
||||
MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef FunctionName, std::unique_ptr<FunctionInfoIndex> Index) {
|
||||
StringRef ValueName, std::unique_ptr<ModuleSummaryIndex> Index) {
|
||||
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
|
||||
FunctionIndexBitcodeReader R(Buf.get(), DiagnosticHandler);
|
||||
ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler);
|
||||
|
||||
auto cleanupOnError = [&](std::error_code EC) {
|
||||
R.releaseBuffer(); // Never take ownership on error.
|
||||
return EC;
|
||||
};
|
||||
|
||||
// Lookup the given function name in the FunctionMap, which may
|
||||
// contain a list of function infos in the case of a COMDAT. Walk through
|
||||
// and parse each function summary info at the function summary offset
|
||||
// Lookup the given value name in the GlobalValueMap, which may
|
||||
// contain a list of global value infos in the case of a COMDAT. Walk through
|
||||
// and parse each summary info at the summary offset
|
||||
// recorded when parsing the value symbol table.
|
||||
for (const auto &FI : Index->getGlobalValueInfoList(FunctionName)) {
|
||||
size_t FunctionSummaryOffset = FI->bitcodeIndex();
|
||||
for (const auto &FI : Index->getGlobalValueInfoList(ValueName)) {
|
||||
size_t SummaryOffset = FI->bitcodeIndex();
|
||||
if (std::error_code EC =
|
||||
R.parseFunctionSummary(nullptr, Index.get(), FunctionSummaryOffset))
|
||||
R.parseGlobalValueSummary(nullptr, Index.get(), SummaryOffset))
|
||||
return cleanupOnError(EC);
|
||||
}
|
||||
|
||||
Buf.release(); // The FunctionIndexBitcodeReader owns it now.
|
||||
Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
|
||||
return std::error_code();
|
||||
}
|
||||
|
@ -2245,7 +2245,7 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
|
||||
}
|
||||
|
||||
/// Emit names for globals/functions etc. The VSTOffsetPlaceholder,
|
||||
/// BitcodeStartBit and FunctionIndex are only passed for the module-level
|
||||
/// BitcodeStartBit and ModuleSummaryIndex are only passed for the module-level
|
||||
/// VST, where we are including a function bitcode index and need to
|
||||
/// backpatch the VST forward declaration record.
|
||||
static void WriteValueSymbolTable(
|
||||
@ -2347,7 +2347,6 @@ static void WriteValueSymbolTable(
|
||||
|
||||
// Save the word offset of the function (from the start of the
|
||||
// actual bitcode written to the stream).
|
||||
assert(FunctionIndex->count(F) == 1);
|
||||
uint64_t BitcodeIndex =
|
||||
(*FunctionIndex)[F]->bitcodeIndex() - BitcodeStartBit;
|
||||
assert((BitcodeIndex & 31) == 0 && "function block not 32-bit aligned");
|
||||
@ -2380,7 +2379,7 @@ static void WriteValueSymbolTable(
|
||||
/// Emit function names and summary offsets for the combined index
|
||||
/// used by ThinLTO.
|
||||
static void
|
||||
WriteCombinedValueSymbolTable(const FunctionInfoIndex &Index,
|
||||
WriteCombinedValueSymbolTable(const ModuleSummaryIndex &Index,
|
||||
BitstreamWriter &Stream,
|
||||
std::map<uint64_t, unsigned> &GUIDToValueIdMap,
|
||||
uint64_t VSTOffsetPlaceholder) {
|
||||
@ -2810,7 +2809,7 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) {
|
||||
|
||||
/// Write the module path strings, currently only used when generating
|
||||
/// a combined index file.
|
||||
static void WriteModStrings(const FunctionInfoIndex &I,
|
||||
static void WriteModStrings(const ModuleSummaryIndex &I,
|
||||
BitstreamWriter &Stream) {
|
||||
Stream.EnterSubblock(bitc::MODULE_STRTAB_BLOCK_ID, 3);
|
||||
|
||||
@ -3011,10 +3010,9 @@ static void WritePerModuleGlobalValueSummary(
|
||||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
/// Emit the combined function summary section into the combined index
|
||||
/// file.
|
||||
/// Emit the combined summary section into the combined index file.
|
||||
static void WriteCombinedGlobalValueSummary(
|
||||
const FunctionInfoIndex &I, BitstreamWriter &Stream,
|
||||
const ModuleSummaryIndex &I, BitstreamWriter &Stream,
|
||||
std::map<uint64_t, unsigned> &GUIDToValueIdMap, unsigned GlobalValueId) {
|
||||
Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 3);
|
||||
|
||||
@ -3354,7 +3352,7 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
|
||||
// Write the specified module summary index to the given raw output stream,
|
||||
// where it will be written in a new bitcode block. This is used when
|
||||
// writing the combined index file for ThinLTO.
|
||||
void llvm::WriteIndexToFile(const FunctionInfoIndex &Index, raw_ostream &Out) {
|
||||
void llvm::WriteIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out) {
|
||||
SmallVector<char, 0> Buffer;
|
||||
Buffer.reserve(256 * 1024);
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
using namespace llvm;
|
||||
|
||||
PreservedAnalyses BitcodeWriterPass::run(Module &M) {
|
||||
WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, EmitFunctionSummary);
|
||||
WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, EmitSummaryIndex);
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
@ -27,21 +27,20 @@ namespace {
|
||||
class WriteBitcodePass : public ModulePass {
|
||||
raw_ostream &OS; // raw_ostream to print on
|
||||
bool ShouldPreserveUseListOrder;
|
||||
bool EmitFunctionSummary;
|
||||
bool EmitSummaryIndex;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder,
|
||||
bool EmitFunctionSummary)
|
||||
bool EmitSummaryIndex)
|
||||
: ModulePass(ID), OS(o),
|
||||
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
|
||||
EmitFunctionSummary(EmitFunctionSummary) {}
|
||||
EmitSummaryIndex(EmitSummaryIndex) {}
|
||||
|
||||
const char *getPassName() const override { return "Bitcode Writer"; }
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder,
|
||||
EmitFunctionSummary);
|
||||
WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, EmitSummaryIndex);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@ -51,7 +50,7 @@ char WriteBitcodePass::ID = 0;
|
||||
|
||||
ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str,
|
||||
bool ShouldPreserveUseListOrder,
|
||||
bool EmitFunctionSummary) {
|
||||
bool EmitSummaryIndex) {
|
||||
return new WriteBitcodePass(Str, ShouldPreserveUseListOrder,
|
||||
EmitFunctionSummary);
|
||||
EmitSummaryIndex);
|
||||
}
|
||||
|
@ -37,12 +37,12 @@ add_llvm_library(LLVMCore
|
||||
Mangler.cpp
|
||||
Metadata.cpp
|
||||
Module.cpp
|
||||
ModuleSummaryIndex.cpp
|
||||
Operator.cpp
|
||||
Pass.cpp
|
||||
PassManager.cpp
|
||||
PassRegistry.cpp
|
||||
Statepoint.cpp
|
||||
FunctionInfo.cpp
|
||||
Type.cpp
|
||||
TypeFinder.cpp
|
||||
Use.cpp
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- FunctionInfo.cpp - Function Info Index ----------------------------===//
|
||||
//===-- ModuleSummaryIndex.cpp - Module Summary Index ---------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -12,14 +12,14 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
using namespace llvm;
|
||||
|
||||
// Create the combined module index/summary from multiple
|
||||
// per-module instances.
|
||||
void FunctionInfoIndex::mergeFrom(std::unique_ptr<FunctionInfoIndex> Other,
|
||||
uint64_t NextModuleId) {
|
||||
void ModuleSummaryIndex::mergeFrom(std::unique_ptr<ModuleSummaryIndex> Other,
|
||||
uint64_t NextModuleId) {
|
||||
|
||||
StringRef ModPath;
|
||||
for (auto &OtherGlobalValInfoLists : *Other) {
|
||||
@ -55,7 +55,7 @@ void FunctionInfoIndex::mergeFrom(std::unique_ptr<FunctionInfoIndex> Other,
|
||||
}
|
||||
}
|
||||
|
||||
void FunctionInfoIndex::removeEmptySummaryEntries() {
|
||||
void ModuleSummaryIndex::removeEmptySummaryEntries() {
|
||||
for (auto MI = begin(), MIE = end(); MI != MIE;) {
|
||||
// Only expect this to be called on a per-module index, which has a single
|
||||
// entry per value entry list.
|
@ -14,21 +14,21 @@
|
||||
|
||||
#include "llvm/LTO/ThinLTOCodeGenerator.h"
|
||||
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Bitcode/BitcodeWriterPass.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/DiagnosticPrinter.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IRReader/IRReader.h"
|
||||
#include "llvm/Linker/Linker.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/ThreadPool.h"
|
||||
@ -126,13 +126,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static void promoteModule(Module &TheModule, const FunctionInfoIndex &Index) {
|
||||
static void promoteModule(Module &TheModule, const ModuleSummaryIndex &Index) {
|
||||
if (renameModuleForThinLTO(TheModule, Index))
|
||||
report_fatal_error("renameModuleForThinLTO failed");
|
||||
}
|
||||
|
||||
static void crossImportIntoModule(Module &TheModule,
|
||||
const FunctionInfoIndex &Index,
|
||||
const ModuleSummaryIndex &Index,
|
||||
StringMap<MemoryBufferRef> &ModuleMap) {
|
||||
ModuleLoader Loader(TheModule.getContext(), ModuleMap);
|
||||
FunctionImporter Importer(Index, Loader);
|
||||
@ -183,7 +183,7 @@ std::unique_ptr<MemoryBuffer> codegenModule(Module &TheModule,
|
||||
}
|
||||
|
||||
static std::unique_ptr<MemoryBuffer>
|
||||
ProcessThinLTOModule(Module &TheModule, const FunctionInfoIndex &Index,
|
||||
ProcessThinLTOModule(Module &TheModule, const ModuleSummaryIndex &Index,
|
||||
StringMap<MemoryBufferRef> &ModuleMap, TargetMachine &TM,
|
||||
ThinLTOCodeGenerator::CachingOptions CacheOptions,
|
||||
StringRef SaveTempsDir, unsigned count) {
|
||||
@ -277,19 +277,19 @@ std::unique_ptr<TargetMachine> TargetMachineBuilder::create() const {
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce the combined function index from all the bitcode files:
|
||||
* Produce the combined summary index from all the bitcode files:
|
||||
* "thin-link".
|
||||
*/
|
||||
std::unique_ptr<FunctionInfoIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
|
||||
std::unique_ptr<FunctionInfoIndex> CombinedIndex;
|
||||
std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
|
||||
std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
|
||||
uint64_t NextModuleId = 0;
|
||||
for (auto &ModuleBuffer : Modules) {
|
||||
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
|
||||
object::FunctionIndexObjectFile::create(ModuleBuffer, diagnosticHandler,
|
||||
false);
|
||||
ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
||||
object::ModuleSummaryIndexObjectFile::create(ModuleBuffer,
|
||||
diagnosticHandler, false);
|
||||
if (std::error_code EC = ObjOrErr.getError()) {
|
||||
// FIXME diagnose
|
||||
errs() << "error: can't create FunctionIndexObjectFile for buffer: "
|
||||
errs() << "error: can't create ModuleSummaryIndexObjectFile for buffer: "
|
||||
<< EC.message() << "\n";
|
||||
return nullptr;
|
||||
}
|
||||
@ -307,7 +307,7 @@ std::unique_ptr<FunctionInfoIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
|
||||
* Perform promotion and renaming of exported internal functions.
|
||||
*/
|
||||
void ThinLTOCodeGenerator::promote(Module &TheModule,
|
||||
FunctionInfoIndex &Index) {
|
||||
ModuleSummaryIndex &Index) {
|
||||
promoteModule(TheModule, Index);
|
||||
}
|
||||
|
||||
@ -315,7 +315,7 @@ void ThinLTOCodeGenerator::promote(Module &TheModule,
|
||||
* Perform cross-module importing for the module identified by ModuleIdentifier.
|
||||
*/
|
||||
void ThinLTOCodeGenerator::crossModuleImport(Module &TheModule,
|
||||
FunctionInfoIndex &Index) {
|
||||
ModuleSummaryIndex &Index) {
|
||||
auto ModuleMap = generateModuleMap(Modules);
|
||||
crossImportIntoModule(TheModule, Index, ModuleMap);
|
||||
}
|
||||
|
@ -35,15 +35,15 @@ class ModuleLinker {
|
||||
/// For symbol clashes, prefer those from Src.
|
||||
unsigned Flags;
|
||||
|
||||
/// Function index passed into ModuleLinker for using in function
|
||||
/// Module summary index passed into ModuleLinker for using in function
|
||||
/// importing/exporting handling.
|
||||
const FunctionInfoIndex *ImportIndex;
|
||||
const ModuleSummaryIndex *ImportIndex;
|
||||
|
||||
/// Functions to import from source module, all other functions are
|
||||
/// imported as declarations instead of definitions.
|
||||
DenseSet<const GlobalValue *> *FunctionsToImport;
|
||||
|
||||
/// Set to true if the given FunctionInfoIndex contains any functions
|
||||
/// Set to true if the given ModuleSummaryIndex contains any functions
|
||||
/// from this source module, in which case we must conservatively assume
|
||||
/// that any of its functions may be imported into another module
|
||||
/// as part of a different backend compilation process.
|
||||
@ -124,15 +124,15 @@ class ModuleLinker {
|
||||
|
||||
public:
|
||||
ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags,
|
||||
const FunctionInfoIndex *Index = nullptr,
|
||||
const ModuleSummaryIndex *Index = nullptr,
|
||||
DenseSet<const GlobalValue *> *FunctionsToImport = nullptr,
|
||||
DenseMap<unsigned, MDNode *> *ValIDToTempMDMap = nullptr)
|
||||
: Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags), ImportIndex(Index),
|
||||
FunctionsToImport(FunctionsToImport),
|
||||
ValIDToTempMDMap(ValIDToTempMDMap) {
|
||||
assert((ImportIndex || !FunctionsToImport) &&
|
||||
"Expect a FunctionInfoIndex when importing");
|
||||
// If we have a FunctionInfoIndex but no function to import,
|
||||
"Expect a ModuleSummaryIndex when importing");
|
||||
// If we have a ModuleSummaryIndex but no function to import,
|
||||
// then this is the primary module being compiled in a ThinLTO
|
||||
// backend compilation, and we need to see if it has functions that
|
||||
// may be exported to another backend compilation.
|
||||
@ -549,7 +549,7 @@ bool ModuleLinker::run() {
|
||||
Linker::Linker(Module &M) : Mover(M) {}
|
||||
|
||||
bool Linker::linkInModule(std::unique_ptr<Module> Src, unsigned Flags,
|
||||
const FunctionInfoIndex *Index,
|
||||
const ModuleSummaryIndex *Index,
|
||||
DenseSet<const GlobalValue *> *FunctionsToImport,
|
||||
DenseMap<unsigned, MDNode *> *ValIDToTempMDMap) {
|
||||
ModuleLinker ModLinker(Mover, std::move(Src), Flags, Index, FunctionsToImport,
|
||||
|
@ -9,12 +9,12 @@ add_llvm_library(LLVMObject
|
||||
IRObjectFile.cpp
|
||||
MachOObjectFile.cpp
|
||||
MachOUniversal.cpp
|
||||
ModuleSummaryIndexObjectFile.cpp
|
||||
Object.cpp
|
||||
ObjectFile.cpp
|
||||
RecordStreamer.cpp
|
||||
SymbolicFile.cpp
|
||||
SymbolSize.cpp
|
||||
FunctionIndexObjectFile.cpp
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${LLVM_MAIN_INCLUDE_DIR}/llvm/Object
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===- FunctionIndexObjectFile.cpp - Function index file implementation ---===//
|
||||
//===- ModuleSummaryIndexObjectFile.cpp - Summary index file implementation ==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,14 +7,14 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the FunctionIndexObjectFile class implementation.
|
||||
// Part of the ModuleSummaryIndexObjectFile class implementation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/FunctionIndexObjectFile.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
@ -22,18 +22,19 @@
|
||||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
FunctionIndexObjectFile::FunctionIndexObjectFile(
|
||||
MemoryBufferRef Object, std::unique_ptr<FunctionInfoIndex> I)
|
||||
: SymbolicFile(Binary::ID_FunctionIndex, Object), Index(std::move(I)) {}
|
||||
ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
|
||||
MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
|
||||
: SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
|
||||
}
|
||||
|
||||
FunctionIndexObjectFile::~FunctionIndexObjectFile() {}
|
||||
ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {}
|
||||
|
||||
std::unique_ptr<FunctionInfoIndex> FunctionIndexObjectFile::takeIndex() {
|
||||
std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
|
||||
return std::move(Index);
|
||||
}
|
||||
|
||||
ErrorOr<MemoryBufferRef>
|
||||
FunctionIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
||||
ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
||||
for (const SectionRef &Sec : Obj.sections()) {
|
||||
if (Sec.isBitcode()) {
|
||||
StringRef SecContents;
|
||||
@ -47,7 +48,7 @@ FunctionIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
||||
}
|
||||
|
||||
ErrorOr<MemoryBufferRef>
|
||||
FunctionIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
||||
ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
||||
sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
|
||||
switch (Type) {
|
||||
case sys::fs::file_magic::bitcode:
|
||||
@ -68,7 +69,7 @@ FunctionIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
||||
|
||||
// Looks for module summary index in the given memory buffer.
|
||||
// returns true if found, else false.
|
||||
bool FunctionIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
||||
if (!BCOrErr)
|
||||
@ -77,64 +78,65 @@ bool FunctionIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler);
|
||||
}
|
||||
|
||||
// Parse function index in the given memory buffer.
|
||||
// Return new FunctionIndexObjectFile instance containing parsed
|
||||
// function summary/index.
|
||||
ErrorOr<std::unique_ptr<FunctionIndexObjectFile>>
|
||||
FunctionIndexObjectFile::create(MemoryBufferRef Object,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy) {
|
||||
std::unique_ptr<FunctionInfoIndex> Index;
|
||||
// Parse module summary index in the given memory buffer.
|
||||
// Return new ModuleSummaryIndexObjectFile instance containing parsed
|
||||
// module summary/index.
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndexObjectFile>>
|
||||
ModuleSummaryIndexObjectFile::create(
|
||||
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy) {
|
||||
std::unique_ptr<ModuleSummaryIndex> Index;
|
||||
|
||||
ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
||||
if (!BCOrErr)
|
||||
return BCOrErr.getError();
|
||||
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IOrErr = getFunctionInfoIndex(
|
||||
BCOrErr.get(), DiagnosticHandler, IsLazy);
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
|
||||
getModuleSummaryIndex(BCOrErr.get(), DiagnosticHandler, IsLazy);
|
||||
|
||||
if (std::error_code EC = IOrErr.getError())
|
||||
return EC;
|
||||
|
||||
Index = std::move(IOrErr.get());
|
||||
|
||||
return llvm::make_unique<FunctionIndexObjectFile>(Object, std::move(Index));
|
||||
return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
|
||||
std::move(Index));
|
||||
}
|
||||
|
||||
// Parse the function summary information for function with the
|
||||
// Parse the summary information for value with the
|
||||
// given name out of the given buffer. Parsed information is
|
||||
// stored on the index object saved in this object.
|
||||
std::error_code FunctionIndexObjectFile::findFunctionSummaryInMemBuffer(
|
||||
std::error_code ModuleSummaryIndexObjectFile::findGlobalValueSummaryInMemBuffer(
|
||||
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef FunctionName) {
|
||||
StringRef ValueName) {
|
||||
sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
|
||||
switch (Type) {
|
||||
case sys::fs::file_magic::bitcode: {
|
||||
return readFunctionSummary(Object, DiagnosticHandler, FunctionName,
|
||||
std::move(Index));
|
||||
return readGlobalValueSummary(Object, DiagnosticHandler, ValueName,
|
||||
std::move(Index));
|
||||
}
|
||||
default:
|
||||
return object_error::invalid_file_type;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the function index out of an IR file and return the function
|
||||
// Parse the module summary index out of an IR file and return the summary
|
||||
// index object if found, or nullptr if not.
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>>
|
||||
llvm::getFunctionIndexForFile(StringRef Path,
|
||||
DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndexForFile(
|
||||
StringRef Path, DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
|
||||
MemoryBuffer::getFileOrSTDIN(Path);
|
||||
std::error_code EC = FileOrErr.getError();
|
||||
if (EC)
|
||||
return EC;
|
||||
MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
|
||||
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
|
||||
object::FunctionIndexObjectFile::create(BufferRef, DiagnosticHandler);
|
||||
ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
||||
object::ModuleSummaryIndexObjectFile::create(BufferRef,
|
||||
DiagnosticHandler);
|
||||
EC = ObjOrErr.getError();
|
||||
if (EC)
|
||||
return EC;
|
||||
|
||||
object::FunctionIndexObjectFile &Obj = **ObjOrErr;
|
||||
object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
|
||||
return Obj.takeIndex();
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IRReader/IRReader.h"
|
||||
#include "llvm/Linker/Linker.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
@ -111,7 +111,7 @@ Module &ModuleLazyLoaderCache::operator()(StringRef Identifier) {
|
||||
/// calls not already in the \p VisitedFunctions map. If any are
|
||||
/// found they are added to the \p Worklist for importing.
|
||||
static void findExternalCalls(
|
||||
const Module &DestModule, Function &F, const FunctionInfoIndex &Index,
|
||||
const Module &DestModule, Function &F, const ModuleSummaryIndex &Index,
|
||||
VisitedFunctionTrackerTy &VisitedFunctions, unsigned Threshold,
|
||||
SmallVectorImpl<std::pair<StringRef, unsigned>> &Worklist) {
|
||||
// We need to suffix internal function calls imported from other modules,
|
||||
@ -141,7 +141,7 @@ static void findExternalCalls(
|
||||
if (CalledFunction->hasInternalLinkage()) {
|
||||
ImportedName = Renamed;
|
||||
}
|
||||
// Compute the global identifier used in the function index.
|
||||
// Compute the global identifier used in the summary index.
|
||||
auto CalledFunctionGlobalID = Function::getGlobalIdentifier(
|
||||
CalledFunction->getName(), CalledFunction->getLinkage(),
|
||||
CalledFunction->getParent()->getSourceFileName());
|
||||
@ -192,9 +192,9 @@ static void
|
||||
GetImportList(Module &DestModule,
|
||||
SmallVectorImpl<std::pair<StringRef, unsigned>> &Worklist,
|
||||
VisitedFunctionTrackerTy &VisitedFunctions,
|
||||
std::map<StringRef, DenseSet<const GlobalValue *>> &
|
||||
ModuleToFunctionsToImportMap,
|
||||
const FunctionInfoIndex &Index,
|
||||
std::map<StringRef, DenseSet<const GlobalValue *>>
|
||||
&ModuleToFunctionsToImportMap,
|
||||
const ModuleSummaryIndex &Index,
|
||||
ModuleLazyLoaderCache &ModuleLoaderCache) {
|
||||
while (!Worklist.empty()) {
|
||||
StringRef CalledFunctionName;
|
||||
@ -374,11 +374,11 @@ static void diagnosticHandler(const DiagnosticInfo &DI) {
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
/// Parse the function index out of an IR file and return the function
|
||||
/// Parse the summary index out of an IR file and return the summary
|
||||
/// index object if found, or nullptr if not.
|
||||
static std::unique_ptr<FunctionInfoIndex>
|
||||
getFunctionIndexForFile(StringRef Path, std::string &Error,
|
||||
DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
static std::unique_ptr<ModuleSummaryIndex>
|
||||
getModuleSummaryIndexForFile(StringRef Path, std::string &Error,
|
||||
DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
std::unique_ptr<MemoryBuffer> Buffer;
|
||||
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
|
||||
MemoryBuffer::getFile(Path);
|
||||
@ -387,9 +387,9 @@ getFunctionIndexForFile(StringRef Path, std::string &Error,
|
||||
return nullptr;
|
||||
}
|
||||
Buffer = std::move(BufferOrErr.get());
|
||||
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
|
||||
object::FunctionIndexObjectFile::create(Buffer->getMemBufferRef(),
|
||||
DiagnosticHandler);
|
||||
ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
||||
object::ModuleSummaryIndexObjectFile::create(Buffer->getMemBufferRef(),
|
||||
DiagnosticHandler);
|
||||
if (std::error_code EC = ObjOrErr.getError()) {
|
||||
Error = EC.message();
|
||||
return nullptr;
|
||||
@ -400,9 +400,9 @@ getFunctionIndexForFile(StringRef Path, std::string &Error,
|
||||
namespace {
|
||||
/// Pass that performs cross-module function import provided a summary file.
|
||||
class FunctionImportPass : public ModulePass {
|
||||
/// Optional function summary index to use for importing, otherwise
|
||||
/// Optional module summary index to use for importing, otherwise
|
||||
/// the summary-file option must be specified.
|
||||
const FunctionInfoIndex *Index;
|
||||
const ModuleSummaryIndex *Index;
|
||||
|
||||
public:
|
||||
/// Pass identification, replacement for typeid
|
||||
@ -413,19 +413,20 @@ public:
|
||||
return "Function Importing";
|
||||
}
|
||||
|
||||
explicit FunctionImportPass(const FunctionInfoIndex *Index = nullptr)
|
||||
explicit FunctionImportPass(const ModuleSummaryIndex *Index = nullptr)
|
||||
: ModulePass(ID), Index(Index) {}
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
if (SummaryFile.empty() && !Index)
|
||||
report_fatal_error("error: -function-import requires -summary-file or "
|
||||
"file from frontend\n");
|
||||
std::unique_ptr<FunctionInfoIndex> IndexPtr;
|
||||
std::unique_ptr<ModuleSummaryIndex> IndexPtr;
|
||||
if (!SummaryFile.empty()) {
|
||||
if (Index)
|
||||
report_fatal_error("error: -summary-file and index from frontend\n");
|
||||
std::string Error;
|
||||
IndexPtr = getFunctionIndexForFile(SummaryFile, Error, diagnosticHandler);
|
||||
IndexPtr =
|
||||
getModuleSummaryIndexForFile(SummaryFile, Error, diagnosticHandler);
|
||||
if (!IndexPtr) {
|
||||
errs() << "Error loading file '" << SummaryFile << "': " << Error
|
||||
<< "\n";
|
||||
@ -458,7 +459,7 @@ INITIALIZE_PASS_END(FunctionImportPass, "function-import",
|
||||
"Summary Based Function Import", false, false)
|
||||
|
||||
namespace llvm {
|
||||
Pass *createFunctionImportPass(const FunctionInfoIndex *Index = nullptr) {
|
||||
Pass *createFunctionImportPass(const ModuleSummaryIndex *Index = nullptr) {
|
||||
return new FunctionImportPass(Index);
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
@ -33,10 +33,10 @@
|
||||
#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
|
||||
#include "llvm/Transforms/IPO/FunctionAttrs.h"
|
||||
#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/Transforms/Scalar/GVN.h"
|
||||
#include "llvm/Transforms/Vectorize.h"
|
||||
#include "llvm/Transforms/Instrumentation.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -127,7 +127,7 @@ PassManagerBuilder::PassManagerBuilder() {
|
||||
SizeLevel = 0;
|
||||
LibraryInfo = nullptr;
|
||||
Inliner = nullptr;
|
||||
FunctionIndex = nullptr;
|
||||
ModuleSummary = nullptr;
|
||||
DisableUnitAtATime = false;
|
||||
DisableUnrollLoops = false;
|
||||
BBVectorize = RunBBVectorization;
|
||||
@ -572,8 +572,8 @@ void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) {
|
||||
// Provide AliasAnalysis services for optimizations.
|
||||
addInitialAliasAnalysisPasses(PM);
|
||||
|
||||
if (FunctionIndex)
|
||||
PM.add(createFunctionImportPass(FunctionIndex));
|
||||
if (ModuleSummary)
|
||||
PM.add(createFunctionImportPass(ModuleSummary));
|
||||
|
||||
// Allow forcing function attributes as a debugging and tuning aid.
|
||||
PM.add(createForceFunctionAttrsLegacyPass());
|
||||
@ -724,8 +724,8 @@ void PassManagerBuilder::populateThinLTOPassManager(
|
||||
if (VerifyInput)
|
||||
PM.add(createVerifierPass());
|
||||
|
||||
if (FunctionIndex)
|
||||
PM.add(createFunctionImportPass(FunctionIndex));
|
||||
if (ModuleSummary)
|
||||
PM.add(createFunctionImportPass(ModuleSummary));
|
||||
|
||||
populateModulePassManager(PM);
|
||||
|
||||
|
@ -68,7 +68,7 @@ bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal(
|
||||
// For now we are conservative in determining which variables are not
|
||||
// address taken by checking the unnamed addr flag. To be more aggressive,
|
||||
// the address taken information must be checked earlier during parsing
|
||||
// of the module and recorded in the function index for use when importing
|
||||
// of the module and recorded in the summary index for use when importing
|
||||
// from that module.
|
||||
auto *GVar = dyn_cast<GlobalVariable>(SGV);
|
||||
if (GVar && GVar->isConstant() && GVar->hasUnnamedAddr())
|
||||
@ -76,7 +76,7 @@ bool FunctionImportGlobalProcessing::doPromoteLocalToGlobal(
|
||||
|
||||
// Eventually we only need to promote functions in the exporting module that
|
||||
// are referenced by a potentially exported function (i.e. one that is in the
|
||||
// function index).
|
||||
// summary index).
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ std::string FunctionImportGlobalProcessing::getName(const GlobalValue *SGV) {
|
||||
// avoid naming conflicts between locals imported from different modules.
|
||||
if (SGV->hasLocalLinkage() &&
|
||||
(doPromoteLocalToGlobal(SGV) || isPerformingImport()))
|
||||
return FunctionInfoIndex::getGlobalNameForLocal(
|
||||
return ModuleSummaryIndex::getGlobalNameForLocal(
|
||||
SGV->getName(),
|
||||
ImportIndex.getModuleId(SGV->getParent()->getModuleIdentifier()));
|
||||
return SGV->getName();
|
||||
@ -231,7 +231,7 @@ bool FunctionImportGlobalProcessing::run() {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool llvm::renameModuleForThinLTO(Module &M, const FunctionInfoIndex &Index) {
|
||||
bool llvm::renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index) {
|
||||
FunctionImportGlobalProcessing ThinLTOProcessing(M, Index);
|
||||
return ThinLTOProcessing.run();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
; Test to check the callgraph in summary when there is PGO
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %s -o %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
|
||||
; RUN: llvm-as -function-summary %p/Inputs/thinlto-function-summary-callgraph.ll -o %t2.o
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto-function-summary-callgraph.ll -o %t2.o
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.o %t2.o
|
||||
; RUN: llvm-bcanalyzer -dump %t3.thinlto.bc | FileCheck %s --check-prefix=COMBINED
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
; Test to check the callgraph in summary
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %s -o %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
|
||||
; RUN: llvm-as -function-summary %p/Inputs/thinlto-function-summary-callgraph.ll -o %t2.o
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto-function-summary-callgraph.ll -o %t2.o
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.o %t2.o
|
||||
; RUN: llvm-bcanalyzer -dump %t3.thinlto.bc | FileCheck %s --check-prefix=COMBINED
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
; Test to check both the callgraph and refgraph in summary
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %s -o %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
|
||||
|
||||
; See if the calls and other references are recorded properly using the
|
||||
|
@ -1,7 +1,7 @@
|
||||
; RUN: llvm-as -function-summary < %s | llvm-bcanalyzer -dump | FileCheck %s -check-prefix=BC
|
||||
; Check for function summary block/records.
|
||||
; RUN: llvm-as -module-summary < %s | llvm-bcanalyzer -dump | FileCheck %s -check-prefix=BC
|
||||
; Check for summary block/records.
|
||||
|
||||
; Check the value ids in the function summary entries against the
|
||||
; Check the value ids in the summary entries against the
|
||||
; same in the ValueSumbolTable, to ensure the ordering is stable.
|
||||
; Also check the linkage field on the summary entries.
|
||||
; BC: <GLOBALVAL_SUMMARY_BLOCK
|
||||
@ -14,7 +14,7 @@
|
||||
; BC-NEXT: <FNENTRY {{.*}} op0=2 {{.*}}> record string = 'bar'
|
||||
; BC-NEXT: <FNENTRY {{.*}} op0=4 {{.*}}> record string = 'f'
|
||||
|
||||
; RUN: llvm-as -function-summary < %s | llvm-dis | FileCheck %s
|
||||
; RUN: llvm-as -module-summary < %s | llvm-dis | FileCheck %s
|
||||
; Check that this round-trips correctly.
|
||||
|
||||
; ModuleID = '<stdin>'
|
||||
|
@ -1,5 +1,5 @@
|
||||
; Check the linkage types in both the per-module and combined summaries.
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %s -o %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
|
||||
; RUN: llvm-lto -thinlto -o %t2 %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t2.thinlto.bc | FileCheck %s --check-prefix=COMBINED
|
||||
|
@ -1,18 +1,18 @@
|
||||
; First ensure that the ThinLTO handling in llvm-link and llvm-lto handles
|
||||
; bitcode without function summary sections gracefully.
|
||||
; bitcode without summary sections gracefully.
|
||||
; RUN: llvm-as %s -o %t.bc
|
||||
; RUN: llvm-as %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-link %t.bc -functionindex=%t.bc -S
|
||||
; RUN: llvm-link %t.bc -summary-index=%t.bc -S
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Do setup work for all below tests: generate bitcode and combined index
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Ensure statics are promoted/renamed correctly from this file (all but
|
||||
; constant variable need promotion).
|
||||
; RUN: llvm-link %t.bc -functionindex=%t3.thinlto.bc -S | FileCheck %s --check-prefix=EXPORTSTATIC
|
||||
; RUN: llvm-link %t.bc -summary-index=%t3.thinlto.bc -S | FileCheck %s --check-prefix=EXPORTSTATIC
|
||||
; EXPORTSTATIC-DAG: @staticvar.llvm.1 = hidden global
|
||||
; EXPORTSTATIC-DAG: @staticconstvar = internal unnamed_addr constant
|
||||
; EXPORTSTATIC-DAG: @P.llvm.1 = hidden global void ()* null
|
||||
@ -24,7 +24,7 @@
|
||||
; Also ensures that alias to a linkonce function is turned into a declaration
|
||||
; and that the associated linkonce function is not in the output, as it is
|
||||
; lazily linked and never referenced/materialized.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB1
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB1
|
||||
; IMPORTGLOB1-DAG: define available_externally void @globalfunc1
|
||||
; IMPORTGLOB1-DAG: declare void @weakalias
|
||||
; IMPORTGLOB1-DAG: declare void @analias
|
||||
@ -35,7 +35,7 @@
|
||||
; Ensure that weak alias to a non-imported function is correctly
|
||||
; turned into a declaration, but that strong alias to an imported function
|
||||
; is imported as alias.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB2
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB2
|
||||
; IMPORTGLOB2-DAG: declare void @analias
|
||||
; IMPORTGLOB2-DAG: define available_externally void @globalfunc2
|
||||
; IMPORTGLOB2-DAG: declare void @weakalias
|
||||
@ -43,7 +43,7 @@
|
||||
|
||||
; Ensure that strong alias imported in second pass of importing ends up
|
||||
; as an alias.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc1:%t.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB3
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=globalfunc1:%t.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB3
|
||||
; IMPORTGLOB3-DAG: declare void @analias
|
||||
; IMPORTGLOB3-DAG: define available_externally void @globalfunc1
|
||||
; IMPORTGLOB3-DAG: define available_externally void @globalfunc2
|
||||
@ -52,7 +52,7 @@
|
||||
; Ensure that strong alias imported in first pass of importing ends up
|
||||
; as an alias, and that seeing the alias definition during a second inlining
|
||||
; pass is handled correctly.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=globalfunc2:%t.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB4
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=globalfunc2:%t.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB4
|
||||
; IMPORTGLOB4-DAG: declare void @analias
|
||||
; IMPORTGLOB4-DAG: define available_externally void @globalfunc2
|
||||
; IMPORTGLOB4-DAG: define available_externally void @globalfunc1
|
||||
@ -60,13 +60,13 @@
|
||||
|
||||
; An alias to an imported function is imported as alias if the function is not
|
||||
; available_externally.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=linkoncefunc:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB5
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=linkoncefunc:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB5
|
||||
; IMPORTGLOB5-DAG: linkoncealias = alias void (...), bitcast (void ()* @linkoncefunc to void (...)*)
|
||||
; IMPORTGLOB5-DAG: define linkonce_odr void @linkoncefunc()
|
||||
|
||||
; Ensure that imported static variable and function references are correctly
|
||||
; promoted and renamed (including static constant variable).
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referencestatics:%t.bc -S | FileCheck %s --check-prefix=IMPORTSTATIC
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=referencestatics:%t.bc -S | FileCheck %s --check-prefix=IMPORTSTATIC
|
||||
; IMPORTSTATIC-DAG: @staticvar.llvm.1 = available_externally hidden global
|
||||
; IMPORTSTATIC-DAG: @staticconstvar.llvm.1 = internal unnamed_addr constant
|
||||
; IMPORTSTATIC-DAG: define available_externally i32 @referencestatics
|
||||
@ -77,18 +77,18 @@
|
||||
; Ensure that imported global (external) function and variable references
|
||||
; are handled correctly (including referenced variable imported as
|
||||
; available_externally definition)
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referenceglobals:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOBALS
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=referenceglobals:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOBALS
|
||||
; IMPORTGLOBALS-DAG: @globalvar = available_externally global
|
||||
; IMPORTGLOBALS-DAG: declare void @globalfunc1()
|
||||
; IMPORTGLOBALS-DAG: define available_externally i32 @referenceglobals
|
||||
|
||||
; Ensure that common variable correctly imported as common defition.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=referencecommon:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMMON
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=referencecommon:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMMON
|
||||
; IMPORTCOMMON-DAG: @commonvar = common global
|
||||
; IMPORTCOMMON-DAG: define available_externally i32 @referencecommon
|
||||
|
||||
; Ensure that imported static function pointer correctly promoted and renamed.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=callfuncptr:%t.bc -S | FileCheck %s --check-prefix=IMPORTFUNCPTR
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=callfuncptr:%t.bc -S | FileCheck %s --check-prefix=IMPORTFUNCPTR
|
||||
; IMPORTFUNCPTR-DAG: @P.llvm.1 = available_externally hidden global void ()* null
|
||||
; IMPORTFUNCPTR-DAG: define available_externally void @callfuncptr
|
||||
; IMPORTFUNCPTR-DAG: %0 = load void ()*, void ()** @P.llvm.1
|
||||
@ -96,7 +96,7 @@
|
||||
; Ensure that imported weak function reference/definition handled properly.
|
||||
; Imported weak_any definition should be skipped with warning, and imported
|
||||
; reference should turned into an external_weak declaration.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=callweakfunc:%t.bc -import=weakfunc:%t.bc -S 2>&1 | FileCheck %s --check-prefix=IMPORTWEAKFUNC
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=callweakfunc:%t.bc -import=weakfunc:%t.bc -S 2>&1 | FileCheck %s --check-prefix=IMPORTWEAKFUNC
|
||||
; IMPORTWEAKFUNC-DAG: Ignoring import request for weak-any function weakfunc
|
||||
; IMPORTWEAKFUNC-DAG: declare extern_weak void @weakfunc
|
||||
; IMPORTWEAKFUNC-DAG: define available_externally void @callweakfunc
|
||||
|
@ -1,7 +1,7 @@
|
||||
; RUN: llvm-as -function-summary %s -o %t1.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/funcimport2.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t1.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport2.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t1.bc %t2.bc
|
||||
; RUN: llvm-link -import=bar:%t2.bc %t1.bc -functionindex=%t3.thinlto.bc -S | FileCheck %s
|
||||
; RUN: llvm-link -import=bar:%t2.bc %t1.bc -summary-index=%t3.thinlto.bc -S | FileCheck %s
|
||||
|
||||
; CHECK: define linkonce_odr hidden void @foo() {
|
||||
define available_externally hidden void @foo() {
|
||||
|
@ -1,9 +1,9 @@
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/funcimport_appending_global.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport_appending_global.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Do the import now
|
||||
; RUN: llvm-link %t.bc -functionindex=%t3.thinlto.bc -import=foo:%t2.bc -S | FileCheck %s
|
||||
; RUN: llvm-link %t.bc -summary-index=%t3.thinlto.bc -import=foo:%t2.bc -S | FileCheck %s
|
||||
|
||||
; Ensure that global constructor (appending linkage) is not imported
|
||||
; CHECK-NOT: @llvm.global_ctors = {{.*}}@foo
|
||||
|
@ -1,17 +1,17 @@
|
||||
; Do setup work for all below tests: generate bitcode and combined index
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/funcimport_comdat.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport_comdat.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Ensure linking of comdat containing external linkage global and function
|
||||
; removes the imported available_externally defs from comdat.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=comdat1_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=comdat1_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT
|
||||
; IMPORTCOMDAT-NOT: $comdat1 = comdat any
|
||||
; IMPORTCOMDAT-NOT: comdat($comdat1)
|
||||
|
||||
; Ensure linking of comdat containing internal linkage function with alias
|
||||
; removes the imported and promoted available_externally defs from comdat.
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=comdat2_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT2
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=comdat2_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT2
|
||||
; IMPORTCOMDAT2-NOT: $comdat2 = comdat any
|
||||
; IMPORTCOMDAT2-NOT: comdat($comdat2)
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
; Do setup work for all below tests: generate bitcode and combined index
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/thinlto_funcimport_debug.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto_funcimport_debug.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; If we import func1 and not func2 we should only link DISubprogram for func1
|
||||
; RUN: llvm-link %t2.bc -functionindex=%t3.thinlto.bc -import=func1:%t.bc -S | FileCheck %s
|
||||
; RUN: llvm-link %t2.bc -summary-index=%t3.thinlto.bc -import=func1:%t.bc -S | FileCheck %s
|
||||
|
||||
; CHECK: declare i32 @func2
|
||||
; CHECK: define available_externally i32 @func1
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Do setup work for all below tests: generate bitcode and combined index
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto-action=thinlink -o %t3.bc %t.bc %t2.bc
|
||||
|
||||
; Ensure statics are promoted/renamed correctly from this file (all but
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Do setup work for all below tests: generate bitcode and combined index
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/adjustable_threshold.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/adjustable_threshold.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Test import with default progressive instruction factor
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Do setup work for all below tests: generate bitcode and combined index
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Do the import now
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Do setup work for all below tests: generate bitcode and combined index
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/funcimport_alias.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport_alias.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Do the import now. Ensures that the importer handles an external call
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Do setup work for all below tests: generate bitcode and combined index
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-summary %p/Inputs/funcimport_debug.ll -o %t2.bc
|
||||
; RUN: llvm-as -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport_debug.ll -o %t2.bc
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Do the import now and confirm that metadata is linked for imported function.
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: llc %s -o %t.o -filetype=obj -relocation-model=pic
|
||||
; RUN: llvm-as -function-summary %p/Inputs/pr19901-1.ll -o %t2.o
|
||||
; RUN: llvm-as -module-summary %p/Inputs/pr19901-1.ll -o %t2.o
|
||||
; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \
|
||||
; RUN: --plugin-opt=thinlto \
|
||||
; RUN: -shared -m elf_x86_64 -o %t.so %t2.o %t.o
|
||||
|
@ -1,5 +1,5 @@
|
||||
; First ensure that the ThinLTO handling in the gold plugin handles
|
||||
; bitcode without function summary sections gracefully.
|
||||
; bitcode without summary sections gracefully.
|
||||
; RUN: llvm-as %s -o %t.o
|
||||
; RUN: llvm-as %p/Inputs/thinlto.ll -o %t2.o
|
||||
; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \
|
||||
@ -12,9 +12,9 @@
|
||||
; RUN: -shared %t.o %t2.o -o %t4
|
||||
; RUN: llvm-nm %t4 | FileCheck %s --check-prefix=NM
|
||||
|
||||
; Next generate function summary sections and test gold handling.
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-summary %p/Inputs/thinlto.ll -o %t2.o
|
||||
; Next generate summary sections and test gold handling.
|
||||
; RUN: llvm-as -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto.ll -o %t2.o
|
||||
|
||||
; Ensure gold generates an index and not a binary if requested.
|
||||
; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-summary %p/Inputs/thinlto_linkonceresolution.ll -o %t2.o
|
||||
; RUN: llvm-as -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto_linkonceresolution.ll -o %t2.o
|
||||
|
||||
; Ensure the plugin ensures that for ThinLTO the prevailing copy of a
|
||||
; linkonce symbol is changed to weak to ensure it is not eliminated.
|
||||
|
@ -1,6 +1,6 @@
|
||||
; Test combined function index generation for ThinLTO via llvm-lto.
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-summary %p/Inputs/thinlto.ll -o %t2.o
|
||||
; RUN: llvm-as -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto.ll -o %t2.o
|
||||
; RUN: llvm-lto -thinlto -o %t3 %t.o %t2.o
|
||||
; RUN: llvm-bcanalyzer -dump %t3.thinlto.bc | FileCheck %s --check-prefix=COMBINED
|
||||
; RUN: not test -e %t3
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/Linker/IRMover.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Object/IRObjectFile.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
@ -624,8 +624,8 @@ static const void *getSymbolsAndView(claimed_file &F) {
|
||||
return View;
|
||||
}
|
||||
|
||||
static std::unique_ptr<FunctionInfoIndex>
|
||||
getFunctionIndexForFile(claimed_file &F, ld_plugin_input_file &Info) {
|
||||
static std::unique_ptr<ModuleSummaryIndex>
|
||||
getModuleSummaryIndexForFile(claimed_file &F, ld_plugin_input_file &Info) {
|
||||
const void *View = getSymbolsAndView(F);
|
||||
if (!View)
|
||||
return nullptr;
|
||||
@ -635,18 +635,20 @@ getFunctionIndexForFile(claimed_file &F, ld_plugin_input_file &Info) {
|
||||
|
||||
// Don't bother trying to build an index if there is no summary information
|
||||
// in this bitcode file.
|
||||
if (!object::FunctionIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
if (!object::ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
BufferRef, diagnosticHandler))
|
||||
return std::unique_ptr<FunctionInfoIndex>(nullptr);
|
||||
return std::unique_ptr<ModuleSummaryIndex>(nullptr);
|
||||
|
||||
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
|
||||
object::FunctionIndexObjectFile::create(BufferRef, diagnosticHandler);
|
||||
ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
||||
object::ModuleSummaryIndexObjectFile::create(BufferRef,
|
||||
diagnosticHandler);
|
||||
|
||||
if (std::error_code EC = ObjOrErr.getError())
|
||||
message(LDPL_FATAL, "Could not read function index bitcode from file : %s",
|
||||
message(LDPL_FATAL,
|
||||
"Could not read module summary index bitcode from file : %s",
|
||||
EC.message().c_str());
|
||||
|
||||
object::FunctionIndexObjectFile &Obj = **ObjOrErr;
|
||||
object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
|
||||
|
||||
return Obj.takeIndex();
|
||||
}
|
||||
@ -844,8 +846,8 @@ class CodeGen {
|
||||
/// The task ID when this was invoked in a thread (ThinLTO).
|
||||
int TaskID;
|
||||
|
||||
/// The function index for ThinLTO tasks.
|
||||
const FunctionInfoIndex *CombinedIndex;
|
||||
/// The module summary index for ThinLTO tasks.
|
||||
const ModuleSummaryIndex *CombinedIndex;
|
||||
|
||||
/// The target machine for generating code for this module.
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
@ -862,11 +864,11 @@ public:
|
||||
}
|
||||
/// Constructor used by ThinLTO.
|
||||
CodeGen(std::unique_ptr<llvm::Module> M, raw_fd_ostream *OS, int TaskID,
|
||||
const FunctionInfoIndex *CombinedIndex, std::string Filename)
|
||||
const ModuleSummaryIndex *CombinedIndex, std::string Filename)
|
||||
: M(std::move(M)), OS(OS), TaskID(TaskID), CombinedIndex(CombinedIndex),
|
||||
SaveTempsFilename(Filename) {
|
||||
assert(options::thinlto == !!CombinedIndex &&
|
||||
"Expected function index iff performing ThinLTO");
|
||||
"Expected module summary index iff performing ThinLTO");
|
||||
initTargetMachine();
|
||||
}
|
||||
|
||||
@ -951,7 +953,7 @@ void CodeGen::runLTOPasses() {
|
||||
PMB.LoopVectorize = true;
|
||||
PMB.SLPVectorize = true;
|
||||
PMB.OptLevel = options::OptLevel;
|
||||
PMB.FunctionIndex = CombinedIndex;
|
||||
PMB.ModuleSummary = CombinedIndex;
|
||||
PMB.populateLTOPassManager(passes);
|
||||
passes.run(*M);
|
||||
}
|
||||
@ -1094,7 +1096,7 @@ static bool linkInModule(LLVMContext &Context, IRMover &L, claimed_file &F,
|
||||
static void thinLTOBackendTask(claimed_file &F, const void *View,
|
||||
ld_plugin_input_file &File,
|
||||
raw_fd_ostream *ApiFile,
|
||||
const FunctionInfoIndex &CombinedIndex,
|
||||
const ModuleSummaryIndex &CombinedIndex,
|
||||
raw_fd_ostream *OS, unsigned TaskID) {
|
||||
// Need to use a separate context for each task
|
||||
LLVMContext Context;
|
||||
@ -1115,7 +1117,7 @@ static void thinLTOBackendTask(claimed_file &F, const void *View,
|
||||
|
||||
/// Launch each module's backend pipeline in a separate task in a thread pool.
|
||||
static void thinLTOBackends(raw_fd_ostream *ApiFile,
|
||||
const FunctionInfoIndex &CombinedIndex) {
|
||||
const ModuleSummaryIndex &CombinedIndex) {
|
||||
unsigned TaskCount = 0;
|
||||
std::vector<ThinLTOTaskInfo> Tasks;
|
||||
Tasks.reserve(Modules.size());
|
||||
@ -1184,18 +1186,18 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) {
|
||||
cl::ParseCommandLineOptions(NumOpts, &options::extra[0]);
|
||||
|
||||
// If we are doing ThinLTO compilation, simply build the combined
|
||||
// function index/summary and emit it. We don't need to parse the modules
|
||||
// module index/summary and emit it. We don't need to parse the modules
|
||||
// and link them in this case.
|
||||
if (options::thinlto) {
|
||||
FunctionInfoIndex CombinedIndex;
|
||||
ModuleSummaryIndex CombinedIndex;
|
||||
uint64_t NextModuleId = 0;
|
||||
for (claimed_file &F : Modules) {
|
||||
PluginInputFile InputFile(F.handle);
|
||||
|
||||
std::unique_ptr<FunctionInfoIndex> Index =
|
||||
getFunctionIndexForFile(F, InputFile.file());
|
||||
std::unique_ptr<ModuleSummaryIndex> Index =
|
||||
getModuleSummaryIndexForFile(F, InputFile.file());
|
||||
|
||||
// Skip files without a function summary.
|
||||
// Skip files without a module summary.
|
||||
if (Index)
|
||||
CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
|
||||
}
|
||||
|
@ -44,9 +44,9 @@ Force("f", cl::desc("Enable binary output on terminals"));
|
||||
static cl::opt<bool>
|
||||
DisableOutput("disable-output", cl::desc("Disable output"), cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
EmitFunctionSummary("function-summary", cl::desc("Emit function summary index"),
|
||||
cl::init(false));
|
||||
static cl::opt<bool> EmitSummaryIndex("module-summary",
|
||||
cl::desc("Emit module summary index"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool>
|
||||
DumpAsm("d", cl::desc("Print assembly as parsed"), cl::Hidden);
|
||||
@ -82,7 +82,7 @@ static void WriteOutputFile(const Module *M) {
|
||||
|
||||
if (Force || !CheckBitcodeOutputToConsole(Out->os(), true))
|
||||
WriteBitcodeToFile(M, Out->os(), PreserveBitcodeUseListOrder,
|
||||
EmitFunctionSummary);
|
||||
EmitSummaryIndex);
|
||||
|
||||
// Declare success.
|
||||
Out->keep();
|
||||
|
@ -12,18 +12,18 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Linker/Linker.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/IR/AutoUpgrade.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/IR/DiagnosticPrinter.h"
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/Verifier.h"
|
||||
#include "llvm/IRReader/IRReader.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.h"
|
||||
#include "llvm/Linker/Linker.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
@ -52,15 +52,14 @@ static cl::list<std::string> Imports(
|
||||
cl::desc("Pair of function name and filename, where function should be "
|
||||
"imported from bitcode in filename"));
|
||||
|
||||
// Option to support testing of function importing. The function index
|
||||
// Option to support testing of function importing. The module summary
|
||||
// must be specified in the case were we request imports via the -import
|
||||
// option, as well as when compiling any module with functions that may be
|
||||
// exported (imported by a different llvm-link -import invocation), to ensure
|
||||
// consistent promotion and renaming of locals.
|
||||
static cl::opt<std::string> FunctionIndex("functionindex",
|
||||
cl::desc("Function index filename"),
|
||||
cl::init(""),
|
||||
cl::value_desc("filename"));
|
||||
static cl::opt<std::string>
|
||||
SummaryIndex("summary-index", cl::desc("Module summary index filename"),
|
||||
cl::init(""), cl::value_desc("filename"));
|
||||
|
||||
static cl::opt<std::string>
|
||||
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
|
||||
@ -192,10 +191,10 @@ static bool importFunctions(const char *argv0, LLVMContext &Context,
|
||||
if (Verbose)
|
||||
errs() << "Importing " << FunctionName << " from " << FileName << "\n";
|
||||
|
||||
std::unique_ptr<FunctionInfoIndex> Index;
|
||||
if (!FunctionIndex.empty()) {
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
|
||||
llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler);
|
||||
std::unique_ptr<ModuleSummaryIndex> Index;
|
||||
if (!SummaryIndex.empty()) {
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(SummaryIndex, diagnosticHandler);
|
||||
std::error_code EC = IndexOrErr.getError();
|
||||
if (EC) {
|
||||
errs() << EC.message() << '\n';
|
||||
@ -259,12 +258,12 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a function index is supplied, load it so linkInModule can treat
|
||||
// If a module summary index is supplied, load it so linkInModule can treat
|
||||
// local functions/variables as exported and promote if necessary.
|
||||
std::unique_ptr<FunctionInfoIndex> Index;
|
||||
if (!FunctionIndex.empty()) {
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
|
||||
llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler);
|
||||
std::unique_ptr<ModuleSummaryIndex> Index;
|
||||
if (!SummaryIndex.empty()) {
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(SummaryIndex, diagnosticHandler);
|
||||
std::error_code EC = IndexOrErr.getError();
|
||||
if (EC) {
|
||||
errs() << EC.message() << '\n';
|
||||
|
@ -19,9 +19,9 @@
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IRReader/IRReader.h"
|
||||
#include "llvm/LTO/LTOCodeGenerator.h"
|
||||
#include "llvm/LTO/ThinLTOCodeGenerator.h"
|
||||
#include "llvm/LTO/LTOModule.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.h"
|
||||
#include "llvm/LTO/ThinLTOCodeGenerator.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
@ -251,16 +251,16 @@ static void listSymbols(const TargetOptions &Options) {
|
||||
///
|
||||
/// This is meant to enable testing of ThinLTO combined index generation,
|
||||
/// currently available via the gold plugin via -thinlto.
|
||||
static void createCombinedFunctionIndex() {
|
||||
FunctionInfoIndex CombinedIndex;
|
||||
static void createCombinedModuleSummaryIndex() {
|
||||
ModuleSummaryIndex CombinedIndex;
|
||||
uint64_t NextModuleId = 0;
|
||||
for (auto &Filename : InputFilenames) {
|
||||
CurrentActivity = "loading file '" + Filename + "'";
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
|
||||
llvm::getFunctionIndexForFile(Filename, diagnosticHandler);
|
||||
std::unique_ptr<FunctionInfoIndex> Index = std::move(IndexOrErr.get());
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(Filename, diagnosticHandler);
|
||||
std::unique_ptr<ModuleSummaryIndex> Index = std::move(IndexOrErr.get());
|
||||
CurrentActivity = "";
|
||||
// Skip files without a function summary.
|
||||
// Skip files without a module summary.
|
||||
if (!Index)
|
||||
continue;
|
||||
CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
|
||||
@ -277,7 +277,7 @@ static void createCombinedFunctionIndex() {
|
||||
namespace thinlto {
|
||||
|
||||
std::vector<std::unique_ptr<MemoryBuffer>>
|
||||
loadAllFilesForIndex(const FunctionInfoIndex &Index) {
|
||||
loadAllFilesForIndex(const ModuleSummaryIndex &Index) {
|
||||
std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
|
||||
|
||||
for (auto &ModPath : Index.modPathStringEntries()) {
|
||||
@ -290,12 +290,12 @@ loadAllFilesForIndex(const FunctionInfoIndex &Index) {
|
||||
return InputBuffers;
|
||||
}
|
||||
|
||||
std::unique_ptr<FunctionInfoIndex> loadCombinedIndex() {
|
||||
std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() {
|
||||
if (ThinLTOIndex.empty())
|
||||
report_fatal_error("Missing -thinlto-index for ThinLTO promotion stage");
|
||||
auto CurrentActivity = "loading file '" + ThinLTOIndex + "'";
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
|
||||
llvm::getFunctionIndexForFile(ThinLTOIndex, diagnosticHandler);
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(ThinLTOIndex, diagnosticHandler);
|
||||
error(IndexOrErr, "error " + CurrentActivity);
|
||||
return std::move(IndexOrErr.get());
|
||||
}
|
||||
@ -557,7 +557,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
if (ThinLTO) {
|
||||
createCombinedFunctionIndex();
|
||||
createCombinedModuleSummaryIndex();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user