[ThinLTO] Deduplicate function index loading into shared helper (NFC)

Add a shared helper routine to read the function index from a file
and create/return the function index object. Use it in llvm-link and
llvm-lto.

llvm-svn: 253903
This commit is contained in:
Teresa Johnson 2015-11-23 19:19:11 +00:00
parent d0430e8580
commit 6b92316811
4 changed files with 35 additions and 50 deletions

View File

@ -99,6 +99,13 @@ public:
StringRef FunctionName);
};
}
/// 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,
const Module *ExportingModule = nullptr);
}
#endif

View File

@ -120,3 +120,26 @@ std::error_code FunctionIndexObjectFile::findFunctionSummaryInMemBuffer(
return object_error::invalid_file_type;
}
}
// 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>>
llvm::getFunctionIndexForFile(StringRef Path,
DiagnosticHandlerFunction DiagnosticHandler,
const Module *ExportingModule) {
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(Path);
std::error_code EC = FileOrErr.getError();
if (EC)
return EC;
MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
object::FunctionIndexObjectFile::create(BufferRef, DiagnosticHandler,
ExportingModule);
EC = ObjOrErr.getError();
if (EC)
return EC;
object::FunctionIndexObjectFile &Obj = **ObjOrErr;
return Obj.takeIndex();
}

View File

@ -141,27 +141,6 @@ static void diagnosticHandler(const DiagnosticInfo &DI) {
errs() << '\n';
}
/// Load a function index if requested by the -functionindex option.
static ErrorOr<std::unique_ptr<FunctionInfoIndex>>
loadIndex(const Module *ExportingModule = nullptr) {
assert(!FunctionIndex.empty());
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
MemoryBuffer::getFileOrSTDIN(FunctionIndex);
std::error_code EC = FileOrErr.getError();
if (EC)
return EC;
MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
object::FunctionIndexObjectFile::create(BufferRef, diagnosticHandler,
ExportingModule);
EC = ObjOrErr.getError();
if (EC)
return EC;
object::FunctionIndexObjectFile &Obj = **ObjOrErr;
return Obj.takeIndex();
}
/// Import any functions requested via the -import option.
static bool importFunctions(const char *argv0, LLVMContext &Context,
Linker &L) {
@ -208,7 +187,8 @@ static bool importFunctions(const char *argv0, LLVMContext &Context,
std::unique_ptr<FunctionInfoIndex> Index;
if (!FunctionIndex.empty()) {
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = loadIndex();
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler);
std::error_code EC = IndexOrErr.getError();
if (EC) {
errs() << EC.message() << '\n';
@ -245,7 +225,8 @@ static bool linkFiles(const char *argv0, LLVMContext &Context, Linker &L,
// local functions/variables as exported and promote if necessary.
std::unique_ptr<FunctionInfoIndex> Index;
if (!FunctionIndex.empty()) {
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr = loadIndex(&*M);
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
llvm::getFunctionIndexForFile(FunctionIndex, diagnosticHandler, &*M);
std::error_code EC = IndexOrErr.getError();
if (EC) {
errs() << EC.message() << '\n';

View File

@ -190,32 +190,6 @@ static int listSymbols(StringRef Command, const TargetOptions &Options) {
return 0;
}
/// Parse the function index out of an IR file and return the function
/// index object if found, or nullptr if not.
static ErrorOr<std::unique_ptr<FunctionInfoIndex>>
getFunctionIndexForFile(StringRef Path,
DiagnosticHandlerFunction DiagnosticHandler) {
std::unique_ptr<MemoryBuffer> Buffer;
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
MemoryBuffer::getFile(Path);
if (std::error_code EC = BufferOrErr.getError())
return EC;
Buffer = std::move(BufferOrErr.get());
// Don't bother trying to build an index if there is no summary information
// in this bitcode file.
if (!object::FunctionIndexObjectFile::hasFunctionSummaryInMemBuffer(
Buffer->getMemBufferRef(), DiagnosticHandler))
return std::unique_ptr<FunctionInfoIndex>(nullptr);
ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
object::FunctionIndexObjectFile::create(Buffer->getMemBufferRef(),
DiagnosticHandler);
if (std::error_code EC = ObjOrErr.getError())
return EC;
return (*ObjOrErr)->takeIndex();
}
/// Create a combined index file from the input IR files and write it.
///
/// This is meant to enable testing of ThinLTO combined index generation,
@ -225,7 +199,7 @@ static int createCombinedFunctionIndex(StringRef Command) {
uint64_t NextModuleId = 0;
for (auto &Filename : InputFilenames) {
ErrorOr<std::unique_ptr<FunctionInfoIndex>> IndexOrErr =
getFunctionIndexForFile(Filename, diagnosticHandler);
llvm::getFunctionIndexForFile(Filename, diagnosticHandler);
if (std::error_code EC = IndexOrErr.getError()) {
std::string Error = EC.message();
errs() << Command << ": error loading file '" << Filename