forked from OSchip/llvm-project
Revert "[ThinLTO] Renaming of function index to module summary index (NFC)"
This reverts commit r263490. Missed a file. llvm-svn: 263493
This commit is contained in:
parent
9c6cd5df8c
commit
cec0cae313
|
@ -30,11 +30,11 @@ class PreservedAnalyses;
|
|||
/// If \c ShouldPreserveUseListOrder, encode use-list order so it can be
|
||||
/// reproduced when deserialized.
|
||||
///
|
||||
/// If \c EmitSummaryIndex, emit the summary index (currently
|
||||
/// If \c EmitFunctionSummary, emit the function summary index (currently
|
||||
/// for use in ThinLTO optimization).
|
||||
ModulePass *createBitcodeWriterPass(raw_ostream &Str,
|
||||
bool ShouldPreserveUseListOrder = false,
|
||||
bool EmitSummaryIndex = false);
|
||||
bool EmitFunctionSummary = 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 EmitSummaryIndex;
|
||||
bool EmitFunctionSummary;
|
||||
|
||||
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 EmitSummaryIndex, emit the summary index (currently
|
||||
/// If \c EmitFunctionSummary, emit the function summary index (currently
|
||||
/// for use in ThinLTO optimization).
|
||||
explicit BitcodeWriterPass(raw_ostream &OS,
|
||||
bool ShouldPreserveUseListOrder = false,
|
||||
bool EmitSummaryIndex = false)
|
||||
bool EmitFunctionSummary = false)
|
||||
: OS(OS), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
|
||||
EmitSummaryIndex(EmitSummaryIndex) {}
|
||||
EmitFunctionSummary(EmitFunctionSummary) {}
|
||||
|
||||
/// \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 summary section uses different codes in the per-module
|
||||
// The function summary section uses different codes in the per-module
|
||||
// and combined index cases.
|
||||
enum GlobalValueSummarySymtabCodes {
|
||||
enum FunctionSummarySymtabCodes {
|
||||
// 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/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/FunctionInfo.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 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);
|
||||
/// 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);
|
||||
|
||||
/// This method supports lazy reading of summary data from the
|
||||
/// This method supports lazy reading of function summary data from the
|
||||
/// combined index during function importing. When reading the combined index
|
||||
/// 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
|
||||
/// 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
|
||||
/// the index.
|
||||
std::error_code readGlobalValueSummary(
|
||||
std::error_code readFunctionSummary(
|
||||
MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef ValueName, std::unique_ptr<ModuleSummaryIndex> Index);
|
||||
StringRef FunctionName, std::unique_ptr<FunctionInfoIndex> 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 ModuleSummaryIndex &Index, raw_ostream &Out);
|
||||
void WriteIndexToFile(const FunctionInfoIndex &Index, raw_ostream &Out);
|
||||
|
||||
/// isBitcodeWrapper - Return true if the given bytes are the magic bytes
|
||||
/// for an LLVM IR bitcode wrapper.
|
||||
|
|
|
@ -0,0 +1,361 @@
|
|||
//===-- llvm/FunctionInfo.h - Function Info Index ---------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// @file
|
||||
/// FunctionInfo.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
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// \brief Class to accumulate and hold information about a callee.
|
||||
struct CalleeInfo {
|
||||
/// The static number of callsites calling corresponding function.
|
||||
unsigned CallsiteCount;
|
||||
/// The cumulative profile count of calls to corresponding function
|
||||
/// (if using PGO, otherwise 0).
|
||||
uint64_t ProfileCount;
|
||||
CalleeInfo() : CallsiteCount(0), ProfileCount(0) {}
|
||||
CalleeInfo(unsigned CallsiteCount, uint64_t ProfileCount)
|
||||
: CallsiteCount(CallsiteCount), ProfileCount(ProfileCount) {}
|
||||
CalleeInfo &operator+=(uint64_t RHSProfileCount) {
|
||||
CallsiteCount++;
|
||||
ProfileCount += RHSProfileCount;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Function and variable summary information to aid decisions and
|
||||
/// implementation of importing.
|
||||
///
|
||||
/// This is a separate class from GlobalValueInfo to enable lazy reading of this
|
||||
/// summary information from the combined index file during imporing.
|
||||
class GlobalValueSummary {
|
||||
public:
|
||||
/// \brief Sububclass discriminator (for dyn_cast<> et al.)
|
||||
enum SummaryKind { FunctionKind, GlobalVarKind };
|
||||
|
||||
private:
|
||||
/// Kind of summary for use in dyn_cast<> et al.
|
||||
SummaryKind Kind;
|
||||
|
||||
/// \brief Path of module IR containing value's definition, used to locate
|
||||
/// 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,
|
||||
/// not during writing of the per-module index which doesn't contain a
|
||||
/// module path string table.
|
||||
StringRef ModulePath;
|
||||
|
||||
/// \brief The linkage type of the associated global value.
|
||||
///
|
||||
/// One use is to flag values that have local linkage types and need to
|
||||
/// have module identifier appended before placing into the combined
|
||||
/// index, to disambiguate from other values with the same name.
|
||||
/// In the future this will be used to update and optimize linkage
|
||||
/// types based on global summary-based analysis.
|
||||
GlobalValue::LinkageTypes Linkage;
|
||||
|
||||
/// List of GUIDs of values referenced by this global value's definition
|
||||
/// (either by the initializer of a global variable, or referenced
|
||||
/// from within a function). This does not include functions called, which
|
||||
/// are listed in the derived FunctionSummary object.
|
||||
std::vector<uint64_t> RefEdgeList;
|
||||
|
||||
protected:
|
||||
/// GlobalValueSummary constructor.
|
||||
GlobalValueSummary(SummaryKind K, GlobalValue::LinkageTypes Linkage)
|
||||
: Kind(K), Linkage(Linkage) {}
|
||||
|
||||
public:
|
||||
virtual ~GlobalValueSummary() = default;
|
||||
|
||||
/// Which kind of summary subclass this is.
|
||||
SummaryKind getSummaryKind() const { return Kind; }
|
||||
|
||||
/// Set the path to the module containing this function, for use in
|
||||
/// the combined index.
|
||||
void setModulePath(StringRef ModPath) { ModulePath = ModPath; }
|
||||
|
||||
/// Get the path to the module containing this function.
|
||||
StringRef modulePath() const { return ModulePath; }
|
||||
|
||||
/// Return linkage type recorded for this global value.
|
||||
GlobalValue::LinkageTypes linkage() const { return Linkage; }
|
||||
|
||||
/// Record a reference from this global value to the global value identified
|
||||
/// by \p RefGUID.
|
||||
void addRefEdge(uint64_t RefGUID) { RefEdgeList.push_back(RefGUID); }
|
||||
|
||||
/// Record a reference from this global value to each global value identified
|
||||
/// in \p RefEdges.
|
||||
void addRefEdges(DenseSet<unsigned> &RefEdges) {
|
||||
for (auto &RI : RefEdges)
|
||||
addRefEdge(RI);
|
||||
}
|
||||
|
||||
/// Return the list of GUIDs referenced by this global value definition.
|
||||
std::vector<uint64_t> &refs() { return RefEdgeList; }
|
||||
const std::vector<uint64_t> &refs() const { return RefEdgeList; }
|
||||
};
|
||||
|
||||
/// \brief Function summary information to aid decisions and implementation of
|
||||
/// importing.
|
||||
class FunctionSummary : public GlobalValueSummary {
|
||||
public:
|
||||
/// <CalleeGUID, CalleeInfo> call edge pair.
|
||||
typedef std::pair<uint64_t, CalleeInfo> EdgeTy;
|
||||
|
||||
private:
|
||||
/// Number of instructions (ignoring debug instructions, e.g.) computed
|
||||
/// during the initial compile step when the function index is first built.
|
||||
unsigned InstCount;
|
||||
|
||||
/// List of <CalleeGUID, CalleeInfo> call edge pairs from this function.
|
||||
std::vector<EdgeTy> CallGraphEdgeList;
|
||||
|
||||
public:
|
||||
/// Summary constructors.
|
||||
FunctionSummary(GlobalValue::LinkageTypes Linkage, unsigned NumInsts)
|
||||
: GlobalValueSummary(FunctionKind, Linkage), InstCount(NumInsts) {}
|
||||
|
||||
/// Check if this is a function summary.
|
||||
static bool classof(const GlobalValueSummary *GVS) {
|
||||
return GVS->getSummaryKind() == FunctionKind;
|
||||
}
|
||||
|
||||
/// Get the instruction count recorded for this function.
|
||||
unsigned instCount() const { return InstCount; }
|
||||
|
||||
/// Record a call graph edge from this function to the function identified
|
||||
/// by \p CalleeGUID, with \p CalleeInfo including the cumulative profile
|
||||
/// count (across all calls from this function) or 0 if no PGO.
|
||||
void addCallGraphEdge(uint64_t CalleeGUID, CalleeInfo Info) {
|
||||
CallGraphEdgeList.push_back(std::make_pair(CalleeGUID, Info));
|
||||
}
|
||||
|
||||
/// Record a call graph edge from this function to each function recorded
|
||||
/// in \p CallGraphEdges.
|
||||
void addCallGraphEdges(DenseMap<unsigned, CalleeInfo> &CallGraphEdges) {
|
||||
for (auto &EI : CallGraphEdges)
|
||||
addCallGraphEdge(EI.first, EI.second);
|
||||
}
|
||||
|
||||
/// Return the list of <CalleeGUID, ProfileCount> pairs.
|
||||
std::vector<EdgeTy> &edges() { return CallGraphEdgeList; }
|
||||
const std::vector<EdgeTy> &edges() const { return CallGraphEdgeList; }
|
||||
};
|
||||
|
||||
/// \brief Global variable summary information to aid decisions and
|
||||
/// implementation of importing.
|
||||
///
|
||||
/// Currently this doesn't add anything to the base \p GlobalValueSummary,
|
||||
/// but is a placeholder as additional info may be added to the summary
|
||||
/// for variables.
|
||||
class GlobalVarSummary : public GlobalValueSummary {
|
||||
|
||||
public:
|
||||
/// Summary constructors.
|
||||
GlobalVarSummary(GlobalValue::LinkageTypes Linkage)
|
||||
: GlobalValueSummary(GlobalVarKind, Linkage) {}
|
||||
|
||||
/// Check if this is a global variable summary.
|
||||
static bool classof(const GlobalValueSummary *GVS) {
|
||||
return GVS->getSummaryKind() == GlobalVarKind;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Class to hold pointer to summary object and information required
|
||||
/// for parsing or writing it.
|
||||
class GlobalValueInfo {
|
||||
private:
|
||||
/// Summary information used to help make ThinLTO importing decisions.
|
||||
std::unique_ptr<GlobalValueSummary> Summary;
|
||||
|
||||
/// \brief The bitcode offset corresponding to either an associated
|
||||
/// function's function body record, or to an associated summary record,
|
||||
/// depending on whether this is a per-module or combined index.
|
||||
///
|
||||
/// This bitcode offset is written to or read from the associated
|
||||
/// \a ValueSymbolTable entry for a function.
|
||||
/// For the per-module index this holds the bitcode offset of a
|
||||
/// function's body record within bitcode module block in its module,
|
||||
/// although this field is currently only used when writing the VST
|
||||
/// (it is set to 0 and also unused when this is a global variable).
|
||||
/// For the combined index this holds the offset of the corresponding
|
||||
/// summary record, to enable associating the combined index
|
||||
/// VST records with the summary records.
|
||||
uint64_t BitcodeIndex;
|
||||
|
||||
public:
|
||||
GlobalValueInfo(uint64_t Offset = 0,
|
||||
std::unique_ptr<GlobalValueSummary> Summary = nullptr)
|
||||
: Summary(std::move(Summary)), BitcodeIndex(Offset) {}
|
||||
|
||||
/// Record the summary information parsed out of the summary block during
|
||||
/// parsing or combined index creation.
|
||||
void setSummary(std::unique_ptr<GlobalValueSummary> GVSummary) {
|
||||
Summary = std::move(GVSummary);
|
||||
}
|
||||
|
||||
/// Get the summary recorded for this global value.
|
||||
GlobalValueSummary *summary() const { return Summary.get(); }
|
||||
|
||||
/// Get the bitcode index recorded for this value symbol table entry.
|
||||
uint64_t bitcodeIndex() const { return BitcodeIndex; }
|
||||
|
||||
/// Set the bitcode index recorded for this value symbol table entry.
|
||||
void setBitcodeIndex(uint64_t Offset) { BitcodeIndex = Offset; }
|
||||
};
|
||||
|
||||
/// List of global value info structures for a particular value held
|
||||
/// in the GlobalValueMap. Requires a vector in the case of multiple
|
||||
/// COMDAT values of the same name.
|
||||
typedef std::vector<std::unique_ptr<GlobalValueInfo>> GlobalValueInfoList;
|
||||
|
||||
/// Map from global value GUID to corresponding info structures.
|
||||
/// Use a std::map rather than a DenseMap since it will likely incur
|
||||
/// less overhead, as the value type is not very small and the size
|
||||
/// of the map is unknown, resulting in inefficiencies due to repeated
|
||||
/// insertions and resizing.
|
||||
typedef std::map<uint64_t, GlobalValueInfoList> GlobalValueInfoMapTy;
|
||||
|
||||
/// Type used for iterating through the global value info map.
|
||||
typedef GlobalValueInfoMapTy::const_iterator const_globalvalueinfo_iterator;
|
||||
typedef GlobalValueInfoMapTy::iterator globalvalueinfo_iterator;
|
||||
|
||||
/// String table to hold/own module path strings, which additionally holds the
|
||||
/// module ID assigned to each module during the plugin step. The StringMap
|
||||
/// makes a copy of and owns inserted strings.
|
||||
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 {
|
||||
private:
|
||||
/// Map from value name to list of information instances for values of that
|
||||
/// name (may be duplicates in the COMDAT case, e.g.).
|
||||
GlobalValueInfoMapTy GlobalValueMap;
|
||||
|
||||
/// Holds strings for combined index, mapping to the corresponding module ID.
|
||||
ModulePathStringTableTy ModulePathStringTable;
|
||||
|
||||
public:
|
||||
FunctionInfoIndex() = default;
|
||||
|
||||
// Disable the copy constructor and assignment operators, so
|
||||
// no unexpected copying/moving occurs.
|
||||
FunctionInfoIndex(const FunctionInfoIndex &) = delete;
|
||||
void operator=(const FunctionInfoIndex &) = delete;
|
||||
|
||||
globalvalueinfo_iterator begin() { return GlobalValueMap.begin(); }
|
||||
const_globalvalueinfo_iterator begin() const {
|
||||
return GlobalValueMap.begin();
|
||||
}
|
||||
globalvalueinfo_iterator end() { return GlobalValueMap.end(); }
|
||||
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)];
|
||||
}
|
||||
|
||||
/// Get the list of global value info objects for a given value name.
|
||||
const const_globalvalueinfo_iterator
|
||||
findGlobalValueInfoList(StringRef ValueName) const {
|
||||
return GlobalValueMap.find(Function::getGUID(ValueName));
|
||||
}
|
||||
|
||||
/// Get the list of global value info objects for a given value GUID.
|
||||
const const_globalvalueinfo_iterator
|
||||
findGlobalValueInfoList(uint64_t ValueGUID) const {
|
||||
return GlobalValueMap.find(ValueGUID);
|
||||
}
|
||||
|
||||
/// Add a global value info for a value of the given name.
|
||||
void addGlobalValueInfo(StringRef ValueName,
|
||||
std::unique_ptr<GlobalValueInfo> Info) {
|
||||
GlobalValueMap[Function::getGUID(ValueName)].push_back(std::move(Info));
|
||||
}
|
||||
|
||||
/// Add a global value info for a value of the given GUID.
|
||||
void addGlobalValueInfo(uint64_t ValueGUID,
|
||||
std::unique_ptr<GlobalValueInfo> Info) {
|
||||
GlobalValueMap[ValueGUID].push_back(std::move(Info));
|
||||
}
|
||||
|
||||
/// Iterator to allow writer to walk through table during emission.
|
||||
iterator_range<StringMap<uint64_t>::const_iterator>
|
||||
modPathStringEntries() const {
|
||||
return llvm::make_range(ModulePathStringTable.begin(),
|
||||
ModulePathStringTable.end());
|
||||
}
|
||||
|
||||
/// Get the module ID recorded for the given module path.
|
||||
uint64_t getModuleId(const StringRef ModPath) const {
|
||||
return ModulePathStringTable.lookup(ModPath);
|
||||
}
|
||||
|
||||
/// Add the given per-module index into this module index/summary,
|
||||
/// 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,
|
||||
uint64_t NextModuleId);
|
||||
|
||||
/// Convenience method for creating a promoted global name
|
||||
/// for the given value name of a local, and its original module's ID.
|
||||
static std::string getGlobalNameForLocal(StringRef Name, uint64_t ModId) {
|
||||
SmallString<256> NewName(Name);
|
||||
NewName += ".llvm.";
|
||||
raw_svector_ostream(NewName) << ModId;
|
||||
return NewName.str();
|
||||
}
|
||||
|
||||
/// Add a new module path, mapped to the given module Id, and return StringRef
|
||||
/// owned by string table map.
|
||||
StringRef addModulePath(StringRef ModPath, uint64_t ModId) {
|
||||
return ModulePathStringTable.insert(std::make_pair(ModPath, ModId))
|
||||
.first->first();
|
||||
}
|
||||
|
||||
/// Check if the given Module has any functions available for exporting
|
||||
/// in the index. We consider any module present in the ModulePathStringTable
|
||||
/// to have exported functions.
|
||||
bool hasExportedFunctions(const Module &M) const {
|
||||
return ModulePathStringTable.count(M.getModuleIdentifier());
|
||||
}
|
||||
|
||||
/// Remove entries in the GlobalValueMap that have empty summaries due to the
|
||||
/// eager nature of map entry creation during VST parsing. These would
|
||||
/// also be suppressed during combined index generation in mergeFrom(),
|
||||
/// but if there was only one module or this was the first module we might
|
||||
/// not invoke mergeFrom.
|
||||
void removeEmptySummaryEntries();
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
|
@ -27,7 +27,7 @@
|
|||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
class ModuleSummaryIndex;
|
||||
class FunctionInfoIndex;
|
||||
class LLVMContext;
|
||||
class TargetMachine;
|
||||
|
||||
|
@ -177,21 +177,21 @@ public:
|
|||
*/
|
||||
|
||||
/**
|
||||
* Produce the combined summary index from all the bitcode files:
|
||||
* Produce the combined function index from all the bitcode files:
|
||||
* "thin-link".
|
||||
*/
|
||||
std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex();
|
||||
std::unique_ptr<FunctionInfoIndex> linkCombinedIndex();
|
||||
|
||||
/**
|
||||
* Perform promotion and renaming of exported internal functions.
|
||||
*/
|
||||
void promote(Module &Module, ModuleSummaryIndex &Index);
|
||||
void promote(Module &Module, FunctionInfoIndex &Index);
|
||||
|
||||
/**
|
||||
* Perform cross-module importing for the module identified by
|
||||
* ModuleIdentifier.
|
||||
*/
|
||||
void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
|
||||
void crossModuleImport(Module &Module, FunctionInfoIndex &Index);
|
||||
|
||||
/**
|
||||
* Perform post-importing ThinLTO optimizations.
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef LLVM_LINKER_LINKER_H
|
||||
#define LLVM_LINKER_LINKER_H
|
||||
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/FunctionInfo.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 ModuleSummaryIndex
|
||||
/// For ThinLTO function importing/exporting the \p FunctionInfoIndex
|
||||
/// 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 ModuleSummaryIndex *Index = nullptr,
|
||||
const FunctionInfoIndex *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_ModuleSummaryIndex, // Module summary index
|
||||
ID_IR, // LLVM IR
|
||||
ID_FunctionIndex, // Function summary index
|
||||
|
||||
// Object and children.
|
||||
ID_StartObjects,
|
||||
|
@ -123,7 +123,7 @@ public:
|
|||
return TypeID == ID_IR;
|
||||
}
|
||||
|
||||
bool isModuleSummaryIndex() const { return TypeID == ID_ModuleSummaryIndex; }
|
||||
bool isFunctionIndex() const { return TypeID == ID_FunctionIndex; }
|
||||
|
||||
bool isLittleEndian() const {
|
||||
return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===- ModuleSummaryIndexObjectFile.h - Summary index file implementation -=//
|
||||
//===- FunctionIndexObjectFile.h - Function index file implementation -----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -7,36 +7,36 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares the ModuleSummaryIndexObjectFile template class.
|
||||
// This file declares the FunctionIndexObjectFile template class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
|
||||
#define LLVM_OBJECT_MODULESUMMARYINDEXOBJECTFILE_H
|
||||
#ifndef LLVM_OBJECT_FUNCTIONINDEXOBJECTFILE_H
|
||||
#define LLVM_OBJECT_FUNCTIONINDEXOBJECTFILE_H
|
||||
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/Object/SymbolicFile.h"
|
||||
|
||||
namespace llvm {
|
||||
class ModuleSummaryIndex;
|
||||
class FunctionInfoIndex;
|
||||
class Module;
|
||||
|
||||
namespace object {
|
||||
class ObjectFile;
|
||||
|
||||
/// This class is used to read just the module summary index related
|
||||
/// This class is used to read just the function 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 ModuleSummaryIndex
|
||||
/// bitcode or be a combined index bitcode file). It builds a FunctionInfoIndex
|
||||
/// object.
|
||||
class ModuleSummaryIndexObjectFile : public SymbolicFile {
|
||||
std::unique_ptr<ModuleSummaryIndex> Index;
|
||||
class FunctionIndexObjectFile : public SymbolicFile {
|
||||
std::unique_ptr<FunctionInfoIndex> Index;
|
||||
|
||||
public:
|
||||
ModuleSummaryIndexObjectFile(MemoryBufferRef Object,
|
||||
std::unique_ptr<ModuleSummaryIndex> I);
|
||||
~ModuleSummaryIndexObjectFile() override;
|
||||
FunctionIndexObjectFile(MemoryBufferRef Object,
|
||||
std::unique_ptr<FunctionInfoIndex> I);
|
||||
~FunctionIndexObjectFile() override;
|
||||
|
||||
// TODO: Walk through GlobalValueMap entries for symbols.
|
||||
// TODO: Walk through FunctionMap entries for function symbols.
|
||||
// However, currently these interfaces are not used by any consumers.
|
||||
void moveSymbolNext(DataRefImpl &Symb) const override {
|
||||
llvm_unreachable("not implemented");
|
||||
|
@ -59,15 +59,13 @@ public:
|
|||
return basic_symbol_iterator(BasicSymbolRef());
|
||||
}
|
||||
|
||||
const ModuleSummaryIndex &getIndex() const {
|
||||
return const_cast<ModuleSummaryIndexObjectFile *>(this)->getIndex();
|
||||
const FunctionInfoIndex &getIndex() const {
|
||||
return const_cast<FunctionIndexObjectFile *>(this)->getIndex();
|
||||
}
|
||||
ModuleSummaryIndex &getIndex() { return *Index; }
|
||||
std::unique_ptr<ModuleSummaryIndex> takeIndex();
|
||||
FunctionInfoIndex &getIndex() { return *Index; }
|
||||
std::unique_ptr<FunctionInfoIndex> takeIndex();
|
||||
|
||||
static inline bool classof(const Binary *v) {
|
||||
return v->isModuleSummaryIndex();
|
||||
}
|
||||
static inline bool classof(const Binary *v) { return v->isFunctionIndex(); }
|
||||
|
||||
/// \brief Finds and returns bitcode embedded in the given object file, or an
|
||||
/// error code if not found.
|
||||
|
@ -85,28 +83,28 @@ public:
|
|||
hasGlobalValueSummaryInMemBuffer(MemoryBufferRef Object,
|
||||
DiagnosticHandlerFunction DiagnosticHandler);
|
||||
|
||||
/// \brief Parse module summary index in the given memory buffer.
|
||||
/// Return new ModuleSummaryIndexObjectFile instance containing parsed module
|
||||
/// \brief Parse function index in the given memory buffer.
|
||||
/// Return new FunctionIndexObjectFile instance containing parsed function
|
||||
/// summary/index.
|
||||
static ErrorOr<std::unique_ptr<ModuleSummaryIndexObjectFile>>
|
||||
static ErrorOr<std::unique_ptr<FunctionIndexObjectFile>>
|
||||
create(MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false);
|
||||
|
||||
/// \brief Parse the summary information for global value with the
|
||||
/// \brief Parse the function summary information for function with the
|
||||
/// given name out of the given buffer. Parsed information is
|
||||
/// stored on the index object saved in this object.
|
||||
std::error_code
|
||||
findGlobalValueSummaryInMemBuffer(MemoryBufferRef Object,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef ValueName);
|
||||
findFunctionSummaryInMemBuffer(MemoryBufferRef Object,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef FunctionName);
|
||||
};
|
||||
}
|
||||
|
||||
/// 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);
|
||||
/// 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);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
class ModuleSummaryIndex;
|
||||
class FunctionInfoIndex;
|
||||
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 ModuleSummaryIndex *Index = nullptr);
|
||||
Pass *createFunctionImportPass(const FunctionInfoIndex *Index = nullptr);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// createFunctionInliningPass - Return a new pass object that uses a heuristic
|
||||
|
|
|
@ -16,14 +16,14 @@
|
|||
namespace llvm {
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
class ModuleSummaryIndex;
|
||||
class FunctionInfoIndex;
|
||||
|
||||
/// 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 ModuleSummaryIndex &Index;
|
||||
const FunctionInfoIndex &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 ModuleSummaryIndex &Index,
|
||||
const FunctionInfoIndex &Index,
|
||||
std::function<std::unique_ptr<Module>(StringRef Identifier)> ModuleLoader)
|
||||
: Index(Index), ModuleLoader(ModuleLoader) {}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class ModuleSummaryIndex;
|
||||
class FunctionInfoIndex;
|
||||
class Pass;
|
||||
class TargetLibraryInfoImpl;
|
||||
class TargetMachine;
|
||||
|
@ -117,8 +117,8 @@ public:
|
|||
/// added to the per-module passes.
|
||||
Pass *Inliner;
|
||||
|
||||
/// The module summary index to use for function importing.
|
||||
const ModuleSummaryIndex *ModuleSummary;
|
||||
/// The function summary index to use for function importing.
|
||||
const FunctionInfoIndex *FunctionIndex;
|
||||
|
||||
bool DisableTailCalls;
|
||||
bool DisableUnitAtATime;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#define LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
|
||||
namespace llvm {
|
||||
class Module;
|
||||
|
@ -27,14 +27,14 @@ class FunctionImportGlobalProcessing {
|
|||
/// The Module which we are exporting or importing functions from.
|
||||
Module &M;
|
||||
|
||||
/// Module summary index passed in for function importing/exporting handling.
|
||||
const ModuleSummaryIndex &ImportIndex;
|
||||
/// Function index passed in for function importing/exporting handling.
|
||||
const FunctionInfoIndex &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 ModuleSummaryIndex contains any functions
|
||||
/// Set to true if the given FunctionInfoIndex 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 ModuleSummaryIndex &Index,
|
||||
Module &M, const FunctionInfoIndex &Index,
|
||||
DenseSet<const GlobalValue *> *FunctionsToImport = nullptr)
|
||||
: M(M), ImportIndex(Index), FunctionsToImport(FunctionsToImport) {
|
||||
// If we have a ModuleSummaryIndex but no function to import,
|
||||
// If we have a FunctionInfoIndex 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 ModuleSummaryIndex &Index);
|
||||
bool renameModuleForThinLTO(Module &M, const FunctionInfoIndex &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 ModuleSummaryIndexBitcodeReader {
|
||||
class FunctionIndexBitcodeReader {
|
||||
DiagnosticHandlerFunction DiagnosticHandler;
|
||||
|
||||
/// Eventually points to the module index built during parsing.
|
||||
ModuleSummaryIndex *TheIndex = nullptr;
|
||||
FunctionInfoIndex *TheIndex = nullptr;
|
||||
|
||||
std::unique_ptr<MemoryBuffer> Buffer;
|
||||
std::unique_ptr<BitstreamReader> StreamFile;
|
||||
|
@ -427,7 +427,7 @@ class ModuleSummaryIndexBitcodeReader {
|
|||
///
|
||||
/// 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 readGlobalValueSummary for each summary needed, and the summary
|
||||
/// invoke \a readFunctionSummary for each summary needed, and the summary
|
||||
/// section is thus parsed lazily.
|
||||
bool IsLazy = false;
|
||||
|
||||
|
@ -452,7 +452,7 @@ class ModuleSummaryIndexBitcodeReader {
|
|||
// 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 summary index being built.
|
||||
// they are recorded in the function index being built.
|
||||
DenseMap<unsigned, uint64_t> ValueIdToCallGraphGUIDMap;
|
||||
|
||||
/// Map to save the association between summary offset in the VST to the
|
||||
|
@ -474,13 +474,14 @@ public:
|
|||
std::error_code error(BitcodeError E);
|
||||
std::error_code error(const Twine &Message);
|
||||
|
||||
ModuleSummaryIndexBitcodeReader(
|
||||
MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false, bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
ModuleSummaryIndexBitcodeReader(
|
||||
DiagnosticHandlerFunction DiagnosticHandler, bool IsLazy = false,
|
||||
bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
~ModuleSummaryIndexBitcodeReader() { freeState(); }
|
||||
FunctionIndexBitcodeReader(MemoryBuffer *Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false,
|
||||
bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
FunctionIndexBitcodeReader(DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy = false,
|
||||
bool CheckGlobalValSummaryPresenceOnly = false);
|
||||
~FunctionIndexBitcodeReader() { freeState(); }
|
||||
|
||||
void freeState();
|
||||
|
||||
|
@ -492,12 +493,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,
|
||||
ModuleSummaryIndex *I);
|
||||
FunctionInfoIndex *I);
|
||||
|
||||
/// \brief Interface for parsing a summary lazily.
|
||||
std::error_code
|
||||
parseGlobalValueSummary(std::unique_ptr<DataStreamer> Streamer,
|
||||
ModuleSummaryIndex *I, size_t SummaryOffset);
|
||||
std::error_code parseFunctionSummary(std::unique_ptr<DataStreamer> Streamer,
|
||||
FunctionInfoIndex *I,
|
||||
size_t FunctionSummaryOffset);
|
||||
|
||||
private:
|
||||
std::error_code parseModule();
|
||||
|
@ -5413,44 +5414,44 @@ BitcodeReader::initLazyStream(std::unique_ptr<DataStreamer> Streamer) {
|
|||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::error(BitcodeError E,
|
||||
const Twine &Message) {
|
||||
std::error_code FunctionIndexBitcodeReader::error(BitcodeError E,
|
||||
const Twine &Message) {
|
||||
return ::error(DiagnosticHandler, make_error_code(E), Message);
|
||||
}
|
||||
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::error(const Twine &Message) {
|
||||
std::error_code FunctionIndexBitcodeReader::error(const Twine &Message) {
|
||||
return ::error(DiagnosticHandler,
|
||||
make_error_code(BitcodeError::CorruptedBitcode), Message);
|
||||
}
|
||||
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::error(BitcodeError E) {
|
||||
std::error_code FunctionIndexBitcodeReader::error(BitcodeError E) {
|
||||
return ::error(DiagnosticHandler, make_error_code(E));
|
||||
}
|
||||
|
||||
ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader(
|
||||
FunctionIndexBitcodeReader::FunctionIndexBitcodeReader(
|
||||
MemoryBuffer *Buffer, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy, bool CheckGlobalValSummaryPresenceOnly)
|
||||
: DiagnosticHandler(DiagnosticHandler), Buffer(Buffer), IsLazy(IsLazy),
|
||||
CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {}
|
||||
|
||||
ModuleSummaryIndexBitcodeReader::ModuleSummaryIndexBitcodeReader(
|
||||
FunctionIndexBitcodeReader::FunctionIndexBitcodeReader(
|
||||
DiagnosticHandlerFunction DiagnosticHandler, bool IsLazy,
|
||||
bool CheckGlobalValSummaryPresenceOnly)
|
||||
: DiagnosticHandler(DiagnosticHandler), Buffer(nullptr), IsLazy(IsLazy),
|
||||
CheckGlobalValSummaryPresenceOnly(CheckGlobalValSummaryPresenceOnly) {}
|
||||
|
||||
void ModuleSummaryIndexBitcodeReader::freeState() { Buffer = nullptr; }
|
||||
void FunctionIndexBitcodeReader::freeState() { Buffer = nullptr; }
|
||||
|
||||
void ModuleSummaryIndexBitcodeReader::releaseBuffer() { Buffer.release(); }
|
||||
void FunctionIndexBitcodeReader::releaseBuffer() { Buffer.release(); }
|
||||
|
||||
uint64_t ModuleSummaryIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) {
|
||||
uint64_t FunctionIndexBitcodeReader::getGUIDFromValueId(unsigned ValueId) {
|
||||
auto VGI = ValueIdToCallGraphGUIDMap.find(ValueId);
|
||||
assert(VGI != ValueIdToCallGraphGUIDMap.end());
|
||||
return VGI->second;
|
||||
}
|
||||
|
||||
GlobalValueInfo *
|
||||
ModuleSummaryIndexBitcodeReader::getInfoFromSummaryOffset(uint64_t Offset) {
|
||||
FunctionIndexBitcodeReader::getInfoFromSummaryOffset(uint64_t Offset) {
|
||||
auto I = SummaryOffsetToInfoMap.find(Offset);
|
||||
assert(I != SummaryOffsetToInfoMap.end());
|
||||
return I->second;
|
||||
|
@ -5462,7 +5463,7 @@ ModuleSummaryIndexBitcodeReader::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 ModuleSummaryIndexBitcodeReader::parseValueSymbolTable(
|
||||
std::error_code FunctionIndexBitcodeReader::parseValueSymbolTable(
|
||||
uint64_t Offset,
|
||||
DenseMap<unsigned, GlobalValue::LinkageTypes> &ValueIdToLinkageMap) {
|
||||
assert(Offset > 0 && "Expected non-zero VST offset");
|
||||
|
@ -5563,7 +5564,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::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 ModuleSummaryIndexBitcodeReader::parseModule() {
|
||||
std::error_code FunctionIndexBitcodeReader::parseModule() {
|
||||
if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID))
|
||||
return error("Invalid record");
|
||||
|
||||
|
@ -5700,7 +5701,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseModule() {
|
|||
|
||||
// Eagerly parse the entire summary block. This populates the GlobalValueSummary
|
||||
// objects in the index.
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
|
||||
std::error_code FunctionIndexBitcodeReader::parseEntireSummary() {
|
||||
if (Stream.EnterSubBlock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID))
|
||||
return error("Invalid record");
|
||||
|
||||
|
@ -5882,7 +5883,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseEntireSummary() {
|
|||
|
||||
// Parse the module string table block into the Index.
|
||||
// This populates the ModulePathStringTable map in the index.
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseModuleStringTable() {
|
||||
std::error_code FunctionIndexBitcodeReader::parseModuleStringTable() {
|
||||
if (Stream.EnterSubBlock(bitc::MODULE_STRTAB_BLOCK_ID))
|
||||
return error("Invalid record");
|
||||
|
||||
|
@ -5923,8 +5924,8 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseModuleStringTable() {
|
|||
}
|
||||
|
||||
// Parse the function info index from the bitcode streamer into the given index.
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(
|
||||
std::unique_ptr<DataStreamer> Streamer, ModuleSummaryIndex *I) {
|
||||
std::error_code FunctionIndexBitcodeReader::parseSummaryIndexInto(
|
||||
std::unique_ptr<DataStreamer> Streamer, FunctionInfoIndex *I) {
|
||||
TheIndex = I;
|
||||
|
||||
if (std::error_code EC = initStream(std::move(Streamer)))
|
||||
|
@ -5958,14 +5959,14 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseSummaryIndexInto(
|
|||
}
|
||||
}
|
||||
|
||||
// Parse the summary information at the given offset in the buffer into
|
||||
// the index. Used to support lazy parsing of summaries from the
|
||||
// Parse the function information at the given offset in the buffer into
|
||||
// the index. Used to support lazy parsing of function 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 ModuleSummaryIndexBitcodeReader::parseGlobalValueSummary(
|
||||
std::unique_ptr<DataStreamer> Streamer, ModuleSummaryIndex *I,
|
||||
size_t SummaryOffset) {
|
||||
std::error_code FunctionIndexBitcodeReader::parseFunctionSummary(
|
||||
std::unique_ptr<DataStreamer> Streamer, FunctionInfoIndex *I,
|
||||
size_t FunctionSummaryOffset) {
|
||||
TheIndex = I;
|
||||
|
||||
if (std::error_code EC = initStream(std::move(Streamer)))
|
||||
|
@ -5975,7 +5976,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseGlobalValueSummary(
|
|||
if (!hasValidBitcodeHeader(Stream))
|
||||
return error("Invalid bitcode signature");
|
||||
|
||||
Stream.JumpToBit(SummaryOffset);
|
||||
Stream.JumpToBit(FunctionSummaryOffset);
|
||||
|
||||
BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
|
||||
|
||||
|
@ -6001,14 +6002,14 @@ std::error_code ModuleSummaryIndexBitcodeReader::parseGlobalValueSummary(
|
|||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::initStream(
|
||||
std::unique_ptr<DataStreamer> Streamer) {
|
||||
std::error_code
|
||||
FunctionIndexBitcodeReader::initStream(std::unique_ptr<DataStreamer> Streamer) {
|
||||
if (Streamer)
|
||||
return initLazyStream(std::move(Streamer));
|
||||
return initStreamFromBuffer();
|
||||
}
|
||||
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::initStreamFromBuffer() {
|
||||
std::error_code FunctionIndexBitcodeReader::initStreamFromBuffer() {
|
||||
const unsigned char *BufPtr = (const unsigned char *)Buffer->getBufferStart();
|
||||
const unsigned char *BufEnd = BufPtr + Buffer->getBufferSize();
|
||||
|
||||
|
@ -6027,7 +6028,7 @@ std::error_code ModuleSummaryIndexBitcodeReader::initStreamFromBuffer() {
|
|||
return std::error_code();
|
||||
}
|
||||
|
||||
std::error_code ModuleSummaryIndexBitcodeReader::initLazyStream(
|
||||
std::error_code FunctionIndexBitcodeReader::initLazyStream(
|
||||
std::unique_ptr<DataStreamer> Streamer) {
|
||||
// Check and strip off the bitcode wrapper; BitstreamReader expects never to
|
||||
// see it.
|
||||
|
@ -6186,14 +6187,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<ModuleSummaryIndex>>
|
||||
llvm::getModuleSummaryIndex(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy) {
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>>
|
||||
llvm::getFunctionInfoIndex(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler,
|
||||
bool IsLazy) {
|
||||
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
|
||||
ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler, IsLazy);
|
||||
FunctionIndexBitcodeReader R(Buf.get(), DiagnosticHandler, IsLazy);
|
||||
|
||||
auto Index = llvm::make_unique<ModuleSummaryIndex>();
|
||||
auto Index = llvm::make_unique<FunctionInfoIndex>();
|
||||
|
||||
auto cleanupOnError = [&](std::error_code EC) {
|
||||
R.releaseBuffer(); // Never take ownership on error.
|
||||
|
@ -6203,7 +6204,7 @@ llvm::getModuleSummaryIndex(MemoryBufferRef Buffer,
|
|||
if (std::error_code EC = R.parseSummaryIndexInto(nullptr, Index.get()))
|
||||
return cleanupOnError(EC);
|
||||
|
||||
Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
|
||||
Buf.release(); // The FunctionIndexBitcodeReader owns it now.
|
||||
return std::move(Index);
|
||||
}
|
||||
|
||||
|
@ -6211,7 +6212,7 @@ llvm::getModuleSummaryIndex(MemoryBufferRef Buffer,
|
|||
bool llvm::hasGlobalValueSummary(MemoryBufferRef Buffer,
|
||||
DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
|
||||
ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler, false, true);
|
||||
FunctionIndexBitcodeReader R(Buf.get(), DiagnosticHandler, false, true);
|
||||
|
||||
auto cleanupOnError = [&](std::error_code EC) {
|
||||
R.releaseBuffer(); // Never take ownership on error.
|
||||
|
@ -6221,38 +6222,38 @@ bool llvm::hasGlobalValueSummary(MemoryBufferRef Buffer,
|
|||
if (std::error_code EC = R.parseSummaryIndexInto(nullptr, nullptr))
|
||||
return cleanupOnError(EC);
|
||||
|
||||
Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
|
||||
Buf.release(); // The FunctionIndexBitcodeReader owns it now.
|
||||
return R.foundGlobalValSummary();
|
||||
}
|
||||
|
||||
// This method supports lazy reading of summary data from the combined
|
||||
// This method supports lazy reading of function summary data from the combined
|
||||
// index during ThinLTO function importing. When reading the combined index
|
||||
// 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
|
||||
// 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
|
||||
// the index.
|
||||
std::error_code llvm::readGlobalValueSummary(
|
||||
std::error_code llvm::readFunctionSummary(
|
||||
MemoryBufferRef Buffer, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef ValueName, std::unique_ptr<ModuleSummaryIndex> Index) {
|
||||
StringRef FunctionName, std::unique_ptr<FunctionInfoIndex> Index) {
|
||||
std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false);
|
||||
ModuleSummaryIndexBitcodeReader R(Buf.get(), DiagnosticHandler);
|
||||
FunctionIndexBitcodeReader R(Buf.get(), DiagnosticHandler);
|
||||
|
||||
auto cleanupOnError = [&](std::error_code EC) {
|
||||
R.releaseBuffer(); // Never take ownership on error.
|
||||
return EC;
|
||||
};
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// recorded when parsing the value symbol table.
|
||||
for (const auto &FI : Index->getGlobalValueInfoList(ValueName)) {
|
||||
size_t SummaryOffset = FI->bitcodeIndex();
|
||||
for (const auto &FI : Index->getGlobalValueInfoList(FunctionName)) {
|
||||
size_t FunctionSummaryOffset = FI->bitcodeIndex();
|
||||
if (std::error_code EC =
|
||||
R.parseGlobalValueSummary(nullptr, Index.get(), SummaryOffset))
|
||||
R.parseFunctionSummary(nullptr, Index.get(), FunctionSummaryOffset))
|
||||
return cleanupOnError(EC);
|
||||
}
|
||||
|
||||
Buf.release(); // The ModuleSummaryIndexBitcodeReader owns it now.
|
||||
Buf.release(); // The FunctionIndexBitcodeReader 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 ModuleSummaryIndex are only passed for the module-level
|
||||
/// BitcodeStartBit and FunctionIndex 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,6 +2347,7 @@ 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");
|
||||
|
@ -2379,7 +2380,7 @@ static void WriteValueSymbolTable(
|
|||
/// Emit function names and summary offsets for the combined index
|
||||
/// used by ThinLTO.
|
||||
static void
|
||||
WriteCombinedValueSymbolTable(const ModuleSummaryIndex &Index,
|
||||
WriteCombinedValueSymbolTable(const FunctionInfoIndex &Index,
|
||||
BitstreamWriter &Stream,
|
||||
std::map<uint64_t, unsigned> &GUIDToValueIdMap,
|
||||
uint64_t VSTOffsetPlaceholder) {
|
||||
|
@ -2809,7 +2810,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 ModuleSummaryIndex &I,
|
||||
static void WriteModStrings(const FunctionInfoIndex &I,
|
||||
BitstreamWriter &Stream) {
|
||||
Stream.EnterSubblock(bitc::MODULE_STRTAB_BLOCK_ID, 3);
|
||||
|
||||
|
@ -3010,9 +3011,10 @@ static void WritePerModuleGlobalValueSummary(
|
|||
Stream.ExitBlock();
|
||||
}
|
||||
|
||||
/// Emit the combined summary section into the combined index file.
|
||||
/// Emit the combined function summary section into the combined index
|
||||
/// file.
|
||||
static void WriteCombinedGlobalValueSummary(
|
||||
const ModuleSummaryIndex &I, BitstreamWriter &Stream,
|
||||
const FunctionInfoIndex &I, BitstreamWriter &Stream,
|
||||
std::map<uint64_t, unsigned> &GUIDToValueIdMap, unsigned GlobalValueId) {
|
||||
Stream.EnterSubblock(bitc::GLOBALVAL_SUMMARY_BLOCK_ID, 3);
|
||||
|
||||
|
@ -3352,7 +3354,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 ModuleSummaryIndex &Index, raw_ostream &Out) {
|
||||
void llvm::WriteIndexToFile(const FunctionInfoIndex &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, EmitSummaryIndex);
|
||||
WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, EmitFunctionSummary);
|
||||
return PreservedAnalyses::all();
|
||||
}
|
||||
|
||||
|
@ -27,20 +27,21 @@ namespace {
|
|||
class WriteBitcodePass : public ModulePass {
|
||||
raw_ostream &OS; // raw_ostream to print on
|
||||
bool ShouldPreserveUseListOrder;
|
||||
bool EmitSummaryIndex;
|
||||
bool EmitFunctionSummary;
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder,
|
||||
bool EmitSummaryIndex)
|
||||
bool EmitFunctionSummary)
|
||||
: ModulePass(ID), OS(o),
|
||||
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
|
||||
EmitSummaryIndex(EmitSummaryIndex) {}
|
||||
EmitFunctionSummary(EmitFunctionSummary) {}
|
||||
|
||||
const char *getPassName() const override { return "Bitcode Writer"; }
|
||||
|
||||
bool runOnModule(Module &M) override {
|
||||
WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, EmitSummaryIndex);
|
||||
WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder,
|
||||
EmitFunctionSummary);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
@ -50,7 +51,7 @@ char WriteBitcodePass::ID = 0;
|
|||
|
||||
ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str,
|
||||
bool ShouldPreserveUseListOrder,
|
||||
bool EmitSummaryIndex) {
|
||||
bool EmitFunctionSummary) {
|
||||
return new WriteBitcodePass(Str, ShouldPreserveUseListOrder,
|
||||
EmitSummaryIndex);
|
||||
EmitFunctionSummary);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
//===-- FunctionInfo.cpp - Function Info Index ----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the module index and summary classes for the
|
||||
// IR library.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/IR/FunctionInfo.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) {
|
||||
|
||||
StringRef ModPath;
|
||||
for (auto &OtherGlobalValInfoLists : *Other) {
|
||||
uint64_t ValueGUID = OtherGlobalValInfoLists.first;
|
||||
GlobalValueInfoList &List = OtherGlobalValInfoLists.second;
|
||||
|
||||
// Assert that the value info list only has one entry, since we shouldn't
|
||||
// have duplicate names within a single per-module index.
|
||||
assert(List.size() == 1);
|
||||
std::unique_ptr<GlobalValueInfo> Info = std::move(List.front());
|
||||
|
||||
// Skip if there was no summary section.
|
||||
if (!Info->summary())
|
||||
continue;
|
||||
|
||||
// Add the module path string ref for this module if we haven't already
|
||||
// saved a reference to it.
|
||||
if (ModPath.empty())
|
||||
ModPath = addModulePath(Info->summary()->modulePath(), NextModuleId);
|
||||
else
|
||||
assert(ModPath == Info->summary()->modulePath() &&
|
||||
"Each module in the combined map should have a unique ID");
|
||||
|
||||
// Note the module path string ref was copied above and is still owned by
|
||||
// the original per-module index. Reset it to the new module path
|
||||
// string reference owned by the combined index.
|
||||
Info->summary()->setModulePath(ModPath);
|
||||
|
||||
// Add new value info to existing list. There may be duplicates when
|
||||
// combining GlobalValueMap entries, due to COMDAT values. Any local
|
||||
// values were given unique global IDs.
|
||||
addGlobalValueInfo(ValueGUID, std::move(Info));
|
||||
}
|
||||
}
|
||||
|
||||
void FunctionInfoIndex::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.
|
||||
assert(MI->second.size() == 1);
|
||||
if (!MI->second[0]->summary())
|
||||
MI = GlobalValueMap.erase(MI);
|
||||
else
|
||||
++MI;
|
||||
}
|
||||
}
|
|
@ -14,21 +14,21 @@
|
|||
|
||||
#include "llvm/LTO/ThinLTOCodeGenerator.h"
|
||||
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/Analysis/TargetLibraryInfo.h"
|
||||
#include "llvm/Analysis/TargetTransformInfo.h"
|
||||
#include "llvm/Bitcode/BitcodeWriterPass.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Bitcode/BitcodeWriterPass.h"
|
||||
#include "llvm/ExecutionEngine/ObjectMemoryBuffer.h"
|
||||
#include "llvm/IR/DiagnosticPrinter.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/DiagnosticPrinter.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/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.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 ModuleSummaryIndex &Index) {
|
||||
static void promoteModule(Module &TheModule, const FunctionInfoIndex &Index) {
|
||||
if (renameModuleForThinLTO(TheModule, Index))
|
||||
report_fatal_error("renameModuleForThinLTO failed");
|
||||
}
|
||||
|
||||
static void crossImportIntoModule(Module &TheModule,
|
||||
const ModuleSummaryIndex &Index,
|
||||
const FunctionInfoIndex &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 ModuleSummaryIndex &Index,
|
||||
ProcessThinLTOModule(Module &TheModule, const FunctionInfoIndex &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 summary index from all the bitcode files:
|
||||
* Produce the combined function index from all the bitcode files:
|
||||
* "thin-link".
|
||||
*/
|
||||
std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
|
||||
std::unique_ptr<ModuleSummaryIndex> CombinedIndex;
|
||||
std::unique_ptr<FunctionInfoIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
|
||||
std::unique_ptr<FunctionInfoIndex> CombinedIndex;
|
||||
uint64_t NextModuleId = 0;
|
||||
for (auto &ModuleBuffer : Modules) {
|
||||
ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
||||
object::ModuleSummaryIndexObjectFile::create(ModuleBuffer,
|
||||
diagnosticHandler, false);
|
||||
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
|
||||
object::FunctionIndexObjectFile::create(ModuleBuffer, diagnosticHandler,
|
||||
false);
|
||||
if (std::error_code EC = ObjOrErr.getError()) {
|
||||
// FIXME diagnose
|
||||
errs() << "error: can't create ModuleSummaryIndexObjectFile for buffer: "
|
||||
errs() << "error: can't create FunctionIndexObjectFile for buffer: "
|
||||
<< EC.message() << "\n";
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -307,7 +307,7 @@ std::unique_ptr<ModuleSummaryIndex> ThinLTOCodeGenerator::linkCombinedIndex() {
|
|||
* Perform promotion and renaming of exported internal functions.
|
||||
*/
|
||||
void ThinLTOCodeGenerator::promote(Module &TheModule,
|
||||
ModuleSummaryIndex &Index) {
|
||||
FunctionInfoIndex &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,
|
||||
ModuleSummaryIndex &Index) {
|
||||
FunctionInfoIndex &Index) {
|
||||
auto ModuleMap = generateModuleMap(Modules);
|
||||
crossImportIntoModule(TheModule, Index, ModuleMap);
|
||||
}
|
||||
|
|
|
@ -35,15 +35,15 @@ class ModuleLinker {
|
|||
/// For symbol clashes, prefer those from Src.
|
||||
unsigned Flags;
|
||||
|
||||
/// Module summary index passed into ModuleLinker for using in function
|
||||
/// Function index passed into ModuleLinker for using in function
|
||||
/// importing/exporting handling.
|
||||
const ModuleSummaryIndex *ImportIndex;
|
||||
const FunctionInfoIndex *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 ModuleSummaryIndex contains any functions
|
||||
/// Set to true if the given FunctionInfoIndex 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 ModuleSummaryIndex *Index = nullptr,
|
||||
const FunctionInfoIndex *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 ModuleSummaryIndex when importing");
|
||||
// If we have a ModuleSummaryIndex but no function to import,
|
||||
"Expect a FunctionInfoIndex when importing");
|
||||
// If we have a FunctionInfoIndex 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 ModuleSummaryIndex *Index,
|
||||
const FunctionInfoIndex *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 @@
|
|||
//===- ModuleSummaryIndexObjectFile.cpp - Summary index file implementation ==//
|
||||
//===- FunctionIndexObjectFile.cpp - Function index file implementation ---===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -7,14 +7,14 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the ModuleSummaryIndexObjectFile class implementation.
|
||||
// Part of the FunctionIndexObjectFile class implementation.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/IR/ModuleSummaryIndex.h"
|
||||
#include "llvm/IR/FunctionInfo.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
@ -22,19 +22,18 @@
|
|||
using namespace llvm;
|
||||
using namespace object;
|
||||
|
||||
ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
|
||||
MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
|
||||
: SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
|
||||
}
|
||||
FunctionIndexObjectFile::FunctionIndexObjectFile(
|
||||
MemoryBufferRef Object, std::unique_ptr<FunctionInfoIndex> I)
|
||||
: SymbolicFile(Binary::ID_FunctionIndex, Object), Index(std::move(I)) {}
|
||||
|
||||
ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {}
|
||||
FunctionIndexObjectFile::~FunctionIndexObjectFile() {}
|
||||
|
||||
std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
|
||||
std::unique_ptr<FunctionInfoIndex> FunctionIndexObjectFile::takeIndex() {
|
||||
return std::move(Index);
|
||||
}
|
||||
|
||||
ErrorOr<MemoryBufferRef>
|
||||
ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
||||
FunctionIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
||||
for (const SectionRef &Sec : Obj.sections()) {
|
||||
if (Sec.isBitcode()) {
|
||||
StringRef SecContents;
|
||||
|
@ -48,7 +47,7 @@ ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
|||
}
|
||||
|
||||
ErrorOr<MemoryBufferRef>
|
||||
ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
||||
FunctionIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
||||
sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
|
||||
switch (Type) {
|
||||
case sys::fs::file_magic::bitcode:
|
||||
|
@ -69,7 +68,7 @@ ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
|||
|
||||
// Looks for module summary index in the given memory buffer.
|
||||
// returns true if found, else false.
|
||||
bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
bool FunctionIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
||||
if (!BCOrErr)
|
||||
|
@ -78,65 +77,64 @@ bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
|||
return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler);
|
||||
}
|
||||
|
||||
// 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;
|
||||
// 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;
|
||||
|
||||
ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
||||
if (!BCOrErr)
|
||||
return BCOrErr.getError();
|
||||
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
|
||||
getModuleSummaryIndex(BCOrErr.get(), DiagnosticHandler, IsLazy);
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IOrErr = getFunctionInfoIndex(
|
||||
BCOrErr.get(), DiagnosticHandler, IsLazy);
|
||||
|
||||
if (std::error_code EC = IOrErr.getError())
|
||||
return EC;
|
||||
|
||||
Index = std::move(IOrErr.get());
|
||||
|
||||
return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
|
||||
std::move(Index));
|
||||
return llvm::make_unique<FunctionIndexObjectFile>(Object, std::move(Index));
|
||||
}
|
||||
|
||||
// Parse the summary information for value with the
|
||||
// Parse the function summary information for function with the
|
||||
// given name out of the given buffer. Parsed information is
|
||||
// stored on the index object saved in this object.
|
||||
std::error_code ModuleSummaryIndexObjectFile::findGlobalValueSummaryInMemBuffer(
|
||||
std::error_code FunctionIndexObjectFile::findFunctionSummaryInMemBuffer(
|
||||
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
|
||||
StringRef ValueName) {
|
||||
StringRef FunctionName) {
|
||||
sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
|
||||
switch (Type) {
|
||||
case sys::fs::file_magic::bitcode: {
|
||||
return readGlobalValueSummary(Object, DiagnosticHandler, ValueName,
|
||||
std::move(Index));
|
||||
return readFunctionSummary(Object, DiagnosticHandler, FunctionName,
|
||||
std::move(Index));
|
||||
}
|
||||
default:
|
||||
return object_error::invalid_file_type;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the module summary index out of an IR file and return the summary
|
||||
// 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<ModuleSummaryIndex>> llvm::getModuleSummaryIndexForFile(
|
||||
StringRef Path, DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>>
|
||||
llvm::getFunctionIndexForFile(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::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
||||
object::ModuleSummaryIndexObjectFile::create(BufferRef,
|
||||
DiagnosticHandler);
|
||||
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
|
||||
object::FunctionIndexObjectFile::create(BufferRef, DiagnosticHandler);
|
||||
EC = ObjOrErr.getError();
|
||||
if (EC)
|
||||
return EC;
|
||||
|
||||
object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
|
||||
object::FunctionIndexObjectFile &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/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.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 ModuleSummaryIndex &Index,
|
||||
const Module &DestModule, Function &F, const FunctionInfoIndex &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 summary index.
|
||||
// Compute the global identifier used in the function 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 ModuleSummaryIndex &Index,
|
||||
std::map<StringRef, DenseSet<const GlobalValue *>> &
|
||||
ModuleToFunctionsToImportMap,
|
||||
const FunctionInfoIndex &Index,
|
||||
ModuleLazyLoaderCache &ModuleLoaderCache) {
|
||||
while (!Worklist.empty()) {
|
||||
StringRef CalledFunctionName;
|
||||
|
@ -374,11 +374,11 @@ static void diagnosticHandler(const DiagnosticInfo &DI) {
|
|||
OS << '\n';
|
||||
}
|
||||
|
||||
/// Parse the summary index out of an IR file and return the summary
|
||||
/// Parse the function index out of an IR file and return the function
|
||||
/// index object if found, or nullptr if not.
|
||||
static std::unique_ptr<ModuleSummaryIndex>
|
||||
getModuleSummaryIndexForFile(StringRef Path, std::string &Error,
|
||||
DiagnosticHandlerFunction DiagnosticHandler) {
|
||||
static std::unique_ptr<FunctionInfoIndex>
|
||||
getFunctionIndexForFile(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 @@ getModuleSummaryIndexForFile(StringRef Path, std::string &Error,
|
|||
return nullptr;
|
||||
}
|
||||
Buffer = std::move(BufferOrErr.get());
|
||||
ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
||||
object::ModuleSummaryIndexObjectFile::create(Buffer->getMemBufferRef(),
|
||||
DiagnosticHandler);
|
||||
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
|
||||
object::FunctionIndexObjectFile::create(Buffer->getMemBufferRef(),
|
||||
DiagnosticHandler);
|
||||
if (std::error_code EC = ObjOrErr.getError()) {
|
||||
Error = EC.message();
|
||||
return nullptr;
|
||||
|
@ -400,9 +400,9 @@ getModuleSummaryIndexForFile(StringRef Path, std::string &Error,
|
|||
namespace {
|
||||
/// Pass that performs cross-module function import provided a summary file.
|
||||
class FunctionImportPass : public ModulePass {
|
||||
/// Optional module summary index to use for importing, otherwise
|
||||
/// Optional function summary index to use for importing, otherwise
|
||||
/// the summary-file option must be specified.
|
||||
const ModuleSummaryIndex *Index;
|
||||
const FunctionInfoIndex *Index;
|
||||
|
||||
public:
|
||||
/// Pass identification, replacement for typeid
|
||||
|
@ -413,20 +413,19 @@ public:
|
|||
return "Function Importing";
|
||||
}
|
||||
|
||||
explicit FunctionImportPass(const ModuleSummaryIndex *Index = nullptr)
|
||||
explicit FunctionImportPass(const FunctionInfoIndex *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<ModuleSummaryIndex> IndexPtr;
|
||||
std::unique_ptr<FunctionInfoIndex> IndexPtr;
|
||||
if (!SummaryFile.empty()) {
|
||||
if (Index)
|
||||
report_fatal_error("error: -summary-file and index from frontend\n");
|
||||
std::string Error;
|
||||
IndexPtr =
|
||||
getModuleSummaryIndexForFile(SummaryFile, Error, diagnosticHandler);
|
||||
IndexPtr = getFunctionIndexForFile(SummaryFile, Error, diagnosticHandler);
|
||||
if (!IndexPtr) {
|
||||
errs() << "Error loading file '" << SummaryFile << "': " << Error
|
||||
<< "\n";
|
||||
|
@ -459,7 +458,7 @@ INITIALIZE_PASS_END(FunctionImportPass, "function-import",
|
|||
"Summary Based Function Import", false, false)
|
||||
|
||||
namespace llvm {
|
||||
Pass *createFunctionImportPass(const ModuleSummaryIndex *Index = nullptr) {
|
||||
Pass *createFunctionImportPass(const FunctionInfoIndex *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;
|
||||
ModuleSummary = nullptr;
|
||||
FunctionIndex = 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 (ModuleSummary)
|
||||
PM.add(createFunctionImportPass(ModuleSummary));
|
||||
if (FunctionIndex)
|
||||
PM.add(createFunctionImportPass(FunctionIndex));
|
||||
|
||||
// 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 (ModuleSummary)
|
||||
PM.add(createFunctionImportPass(ModuleSummary));
|
||||
if (FunctionIndex)
|
||||
PM.add(createFunctionImportPass(FunctionIndex));
|
||||
|
||||
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 summary index for use when importing
|
||||
// of the module and recorded in the function 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
|
||||
// summary index).
|
||||
// function 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 ModuleSummaryIndex::getGlobalNameForLocal(
|
||||
return FunctionInfoIndex::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 ModuleSummaryIndex &Index) {
|
||||
bool llvm::renameModuleForThinLTO(Module &M, const FunctionInfoIndex &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 -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto-function-summary-callgraph.ll -o %t2.o
|
||||
; RUN: llvm-as -function-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 -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-bcanalyzer -dump %t.o | FileCheck %s
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto-function-summary-callgraph.ll -o %t2.o
|
||||
; RUN: llvm-as -function-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 -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-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 -module-summary < %s | llvm-bcanalyzer -dump | FileCheck %s -check-prefix=BC
|
||||
; Check for summary block/records.
|
||||
; RUN: llvm-as -function-summary < %s | llvm-bcanalyzer -dump | FileCheck %s -check-prefix=BC
|
||||
; Check for function summary block/records.
|
||||
|
||||
; Check the value ids in the summary entries against the
|
||||
; Check the value ids in the function 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 -module-summary < %s | llvm-dis | FileCheck %s
|
||||
; RUN: llvm-as -function-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 -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-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 summary sections gracefully.
|
||||
; bitcode without function 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 -summary-index=%t.bc -S
|
||||
; RUN: llvm-link %t.bc -functionindex=%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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-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 -summary-index=%t3.thinlto.bc -S | FileCheck %s --check-prefix=EXPORTSTATIC
|
||||
; RUN: llvm-link %t.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB1
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB2
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=globalfunc1:%t.bc -import=globalfunc2:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB3
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=globalfunc2:%t.bc -import=globalfunc1:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB4
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=linkoncefunc:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOB5
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=referencestatics:%t.bc -S | FileCheck %s --check-prefix=IMPORTSTATIC
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=referenceglobals:%t.bc -S | FileCheck %s --check-prefix=IMPORTGLOBALS
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=referencecommon:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMMON
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=callfuncptr:%t.bc -S | FileCheck %s --check-prefix=IMPORTFUNCPTR
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=callweakfunc:%t.bc -import=weakfunc:%t.bc -S 2>&1 | FileCheck %s --check-prefix=IMPORTWEAKFUNC
|
||||
; 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
|
||||
; 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 -module-summary %s -o %t1.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport2.ll -o %t2.bc
|
||||
; RUN: llvm-as -function-summary %s -o %t1.bc
|
||||
; RUN: llvm-as -function-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 -summary-index=%t3.thinlto.bc -S | FileCheck %s
|
||||
; RUN: llvm-link -import=bar:%t2.bc %t1.bc -functionindex=%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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport_appending_global.ll -o %t2.bc
|
||||
; 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-lto -thinlto -o %t3 %t.bc %t2.bc
|
||||
|
||||
; Do the import now
|
||||
; RUN: llvm-link %t.bc -summary-index=%t3.thinlto.bc -import=foo:%t2.bc -S | FileCheck %s
|
||||
; RUN: llvm-link %t.bc -functionindex=%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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport_comdat.ll -o %t2.bc
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-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 -summary-index=%t3.thinlto.bc -import=comdat1_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -summary-index=%t3.thinlto.bc -import=comdat2_func1:%t.bc -S | FileCheck %s --check-prefix=IMPORTCOMDAT2
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto_funcimport_debug.ll -o %t2.bc
|
||||
; 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-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 -summary-index=%t3.thinlto.bc -import=func1:%t.bc -S | FileCheck %s
|
||||
; RUN: llvm-link %t2.bc -functionindex=%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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/adjustable_threshold.ll -o %t2.bc
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport.ll -o %t2.bc
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport_alias.ll -o %t2.bc
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-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 -module-summary %s -o %t.bc
|
||||
; RUN: llvm-as -module-summary %p/Inputs/funcimport_debug.ll -o %t2.bc
|
||||
; RUN: llvm-as -function-summary %s -o %t.bc
|
||||
; RUN: llvm-as -function-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 -module-summary %p/Inputs/pr19901-1.ll -o %t2.o
|
||||
; RUN: llvm-as -function-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 summary sections gracefully.
|
||||
; bitcode without function 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 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
|
||||
; 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
|
||||
|
||||
; Ensure gold generates an index and not a binary if requested.
|
||||
; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
; RUN: llvm-as -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto_linkonceresolution.ll -o %t2.o
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-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 -module-summary %s -o %t.o
|
||||
; RUN: llvm-as -module-summary %p/Inputs/thinlto.ll -o %t2.o
|
||||
; RUN: llvm-as -function-summary %s -o %t.o
|
||||
; RUN: llvm-as -function-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/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.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<ModuleSummaryIndex>
|
||||
getModuleSummaryIndexForFile(claimed_file &F, ld_plugin_input_file &Info) {
|
||||
static std::unique_ptr<FunctionInfoIndex>
|
||||
getFunctionIndexForFile(claimed_file &F, ld_plugin_input_file &Info) {
|
||||
const void *View = getSymbolsAndView(F);
|
||||
if (!View)
|
||||
return nullptr;
|
||||
|
@ -635,20 +635,18 @@ getModuleSummaryIndexForFile(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::ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
if (!object::FunctionIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
||||
BufferRef, diagnosticHandler))
|
||||
return std::unique_ptr<ModuleSummaryIndex>(nullptr);
|
||||
return std::unique_ptr<FunctionInfoIndex>(nullptr);
|
||||
|
||||
ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
||||
object::ModuleSummaryIndexObjectFile::create(BufferRef,
|
||||
diagnosticHandler);
|
||||
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
|
||||
object::FunctionIndexObjectFile::create(BufferRef, diagnosticHandler);
|
||||
|
||||
if (std::error_code EC = ObjOrErr.getError())
|
||||
message(LDPL_FATAL,
|
||||
"Could not read module summary index bitcode from file : %s",
|
||||
message(LDPL_FATAL, "Could not read function index bitcode from file : %s",
|
||||
EC.message().c_str());
|
||||
|
||||
object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
|
||||
object::FunctionIndexObjectFile &Obj = **ObjOrErr;
|
||||
|
||||
return Obj.takeIndex();
|
||||
}
|
||||
|
@ -846,8 +844,8 @@ class CodeGen {
|
|||
/// The task ID when this was invoked in a thread (ThinLTO).
|
||||
int TaskID;
|
||||
|
||||
/// The module summary index for ThinLTO tasks.
|
||||
const ModuleSummaryIndex *CombinedIndex;
|
||||
/// The function index for ThinLTO tasks.
|
||||
const FunctionInfoIndex *CombinedIndex;
|
||||
|
||||
/// The target machine for generating code for this module.
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
|
@ -864,11 +862,11 @@ public:
|
|||
}
|
||||
/// Constructor used by ThinLTO.
|
||||
CodeGen(std::unique_ptr<llvm::Module> M, raw_fd_ostream *OS, int TaskID,
|
||||
const ModuleSummaryIndex *CombinedIndex, std::string Filename)
|
||||
const FunctionInfoIndex *CombinedIndex, std::string Filename)
|
||||
: M(std::move(M)), OS(OS), TaskID(TaskID), CombinedIndex(CombinedIndex),
|
||||
SaveTempsFilename(Filename) {
|
||||
assert(options::thinlto == !!CombinedIndex &&
|
||||
"Expected module summary index iff performing ThinLTO");
|
||||
"Expected function index iff performing ThinLTO");
|
||||
initTargetMachine();
|
||||
}
|
||||
|
||||
|
@ -953,7 +951,7 @@ void CodeGen::runLTOPasses() {
|
|||
PMB.LoopVectorize = true;
|
||||
PMB.SLPVectorize = true;
|
||||
PMB.OptLevel = options::OptLevel;
|
||||
PMB.ModuleSummary = CombinedIndex;
|
||||
PMB.FunctionIndex = CombinedIndex;
|
||||
PMB.populateLTOPassManager(passes);
|
||||
passes.run(*M);
|
||||
}
|
||||
|
@ -1096,7 +1094,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 ModuleSummaryIndex &CombinedIndex,
|
||||
const FunctionInfoIndex &CombinedIndex,
|
||||
raw_fd_ostream *OS, unsigned TaskID) {
|
||||
// Need to use a separate context for each task
|
||||
LLVMContext Context;
|
||||
|
@ -1117,7 +1115,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 ModuleSummaryIndex &CombinedIndex) {
|
||||
const FunctionInfoIndex &CombinedIndex) {
|
||||
unsigned TaskCount = 0;
|
||||
std::vector<ThinLTOTaskInfo> Tasks;
|
||||
Tasks.reserve(Modules.size());
|
||||
|
@ -1186,18 +1184,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
|
||||
// module index/summary and emit it. We don't need to parse the modules
|
||||
// function index/summary and emit it. We don't need to parse the modules
|
||||
// and link them in this case.
|
||||
if (options::thinlto) {
|
||||
ModuleSummaryIndex CombinedIndex;
|
||||
FunctionInfoIndex CombinedIndex;
|
||||
uint64_t NextModuleId = 0;
|
||||
for (claimed_file &F : Modules) {
|
||||
PluginInputFile InputFile(F.handle);
|
||||
|
||||
std::unique_ptr<ModuleSummaryIndex> Index =
|
||||
getModuleSummaryIndexForFile(F, InputFile.file());
|
||||
std::unique_ptr<FunctionInfoIndex> Index =
|
||||
getFunctionIndexForFile(F, InputFile.file());
|
||||
|
||||
// Skip files without a module summary.
|
||||
// Skip files without a function 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> EmitSummaryIndex("module-summary",
|
||||
cl::desc("Emit module summary index"),
|
||||
cl::init(false));
|
||||
static cl::opt<bool>
|
||||
EmitFunctionSummary("function-summary", cl::desc("Emit function 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,
|
||||
EmitSummaryIndex);
|
||||
EmitFunctionSummary);
|
||||
|
||||
// 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/Linker/Linker.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
|
@ -52,14 +52,15 @@ 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 module summary
|
||||
// Option to support testing of function importing. The function index
|
||||
// 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>
|
||||
SummaryIndex("summary-index", cl::desc("Module summary index filename"),
|
||||
cl::init(""), cl::value_desc("filename"));
|
||||
static cl::opt<std::string> FunctionIndex("functionindex",
|
||||
cl::desc("Function index filename"),
|
||||
cl::init(""),
|
||||
cl::value_desc("filename"));
|
||||
|
||||
static cl::opt<std::string>
|
||||
OutputFilename("o", cl::desc("Override output filename"), cl::init("-"),
|
||||
|
@ -191,10 +192,10 @@ static bool importFunctions(const char *argv0, LLVMContext &Context,
|
|||
if (Verbose)
|
||||
errs() << "Importing " << FunctionName << " from " << FileName << "\n";
|
||||
|
||||
std::unique_ptr<ModuleSummaryIndex> Index;
|
||||
if (!SummaryIndex.empty()) {
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(SummaryIndex, diagnosticHandler);
|
||||
std::unique_ptr<FunctionInfoIndex> Index;
|
||||
if (!FunctionIndex.empty()) {
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
|
||||
llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler);
|
||||
std::error_code EC = IndexOrErr.getError();
|
||||
if (EC) {
|
||||
errs() << EC.message() << '\n';
|
||||
|
@ -258,12 +259,12 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
|
|||
return false;
|
||||
}
|
||||
|
||||
// If a module summary index is supplied, load it so linkInModule can treat
|
||||
// If a function index is supplied, load it so linkInModule can treat
|
||||
// local functions/variables as exported and promote if necessary.
|
||||
std::unique_ptr<ModuleSummaryIndex> Index;
|
||||
if (!SummaryIndex.empty()) {
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(SummaryIndex, diagnosticHandler);
|
||||
std::unique_ptr<FunctionInfoIndex> Index;
|
||||
if (!FunctionIndex.empty()) {
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
|
||||
llvm::getFunctionIndexForFile(FunctionIndex, 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/LTOModule.h"
|
||||
#include "llvm/LTO/ThinLTOCodeGenerator.h"
|
||||
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
||||
#include "llvm/LTO/LTOModule.h"
|
||||
#include "llvm/Object/FunctionIndexObjectFile.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 createCombinedModuleSummaryIndex() {
|
||||
ModuleSummaryIndex CombinedIndex;
|
||||
static void createCombinedFunctionIndex() {
|
||||
FunctionInfoIndex CombinedIndex;
|
||||
uint64_t NextModuleId = 0;
|
||||
for (auto &Filename : InputFilenames) {
|
||||
CurrentActivity = "loading file '" + Filename + "'";
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(Filename, diagnosticHandler);
|
||||
std::unique_ptr<ModuleSummaryIndex> Index = std::move(IndexOrErr.get());
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
|
||||
llvm::getFunctionIndexForFile(Filename, diagnosticHandler);
|
||||
std::unique_ptr<FunctionInfoIndex> Index = std::move(IndexOrErr.get());
|
||||
CurrentActivity = "";
|
||||
// Skip files without a module summary.
|
||||
// Skip files without a function summary.
|
||||
if (!Index)
|
||||
continue;
|
||||
CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId);
|
||||
|
@ -277,7 +277,7 @@ static void createCombinedModuleSummaryIndex() {
|
|||
namespace thinlto {
|
||||
|
||||
std::vector<std::unique_ptr<MemoryBuffer>>
|
||||
loadAllFilesForIndex(const ModuleSummaryIndex &Index) {
|
||||
loadAllFilesForIndex(const FunctionInfoIndex &Index) {
|
||||
std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers;
|
||||
|
||||
for (auto &ModPath : Index.modPathStringEntries()) {
|
||||
|
@ -290,12 +290,12 @@ loadAllFilesForIndex(const ModuleSummaryIndex &Index) {
|
|||
return InputBuffers;
|
||||
}
|
||||
|
||||
std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() {
|
||||
std::unique_ptr<FunctionInfoIndex> loadCombinedIndex() {
|
||||
if (ThinLTOIndex.empty())
|
||||
report_fatal_error("Missing -thinlto-index for ThinLTO promotion stage");
|
||||
auto CurrentActivity = "loading file '" + ThinLTOIndex + "'";
|
||||
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(ThinLTOIndex, diagnosticHandler);
|
||||
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
|
||||
llvm::getFunctionIndexForFile(ThinLTOIndex, diagnosticHandler);
|
||||
error(IndexOrErr, "error " + CurrentActivity);
|
||||
return std::move(IndexOrErr.get());
|
||||
}
|
||||
|
@ -557,7 +557,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
if (ThinLTO) {
|
||||
createCombinedModuleSummaryIndex();
|
||||
createCombinedFunctionIndex();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue