2016-03-15 08:04:37 +08:00
|
|
|
//===- ModuleSummaryIndexObjectFile.cpp - Summary index file implementation ==//
|
2015-10-04 22:33:43 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2016-03-15 08:04:37 +08:00
|
|
|
// Part of the ModuleSummaryIndexObjectFile class implementation.
|
2015-10-04 22:33:43 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
|
2015-10-04 22:33:43 +08:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
|
|
|
#include "llvm/Bitcode/ReaderWriter.h"
|
2016-03-15 08:04:37 +08:00
|
|
|
#include "llvm/IR/ModuleSummaryIndex.h"
|
2015-10-04 22:33:43 +08:00
|
|
|
#include "llvm/MC/MCStreamer.h"
|
|
|
|
#include "llvm/Object/ObjectFile.h"
|
|
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
using namespace llvm;
|
|
|
|
using namespace object;
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
|
|
|
|
MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
|
|
|
|
: SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
|
|
|
|
}
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {}
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
|
2015-10-04 22:33:43 +08:00
|
|
|
return std::move(Index);
|
|
|
|
}
|
|
|
|
|
2015-11-03 02:02:11 +08:00
|
|
|
ErrorOr<MemoryBufferRef>
|
2016-03-15 08:04:37 +08:00
|
|
|
ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
2015-10-04 22:33:43 +08:00
|
|
|
for (const SectionRef &Sec : Obj.sections()) {
|
2016-03-01 03:40:10 +08:00
|
|
|
if (Sec.isBitcode()) {
|
2015-10-04 22:33:43 +08:00
|
|
|
StringRef SecContents;
|
2015-11-03 02:02:11 +08:00
|
|
|
if (std::error_code EC = Sec.getContents(SecContents))
|
|
|
|
return EC;
|
2015-10-04 22:33:43 +08:00
|
|
|
return MemoryBufferRef(SecContents, Obj.getFileName());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return object_error::bitcode_section_not_found;
|
|
|
|
}
|
|
|
|
|
2015-11-03 02:02:11 +08:00
|
|
|
ErrorOr<MemoryBufferRef>
|
2016-03-15 08:04:37 +08:00
|
|
|
ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
2015-10-04 22:33:43 +08:00
|
|
|
sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
|
|
|
|
switch (Type) {
|
2015-11-03 02:02:11 +08:00
|
|
|
case sys::fs::file_magic::bitcode:
|
|
|
|
return Object;
|
|
|
|
case sys::fs::file_magic::elf_relocatable:
|
|
|
|
case sys::fs::file_magic::macho_object:
|
|
|
|
case sys::fs::file_magic::coff_object: {
|
2016-04-07 06:14:09 +08:00
|
|
|
Expected<std::unique_ptr<ObjectFile>> ObjFile =
|
2015-11-03 02:02:11 +08:00
|
|
|
ObjectFile::createObjectFile(Object, Type);
|
|
|
|
if (!ObjFile)
|
2016-04-07 06:14:09 +08:00
|
|
|
return errorToErrorCode(ObjFile.takeError());
|
2015-11-03 02:02:11 +08:00
|
|
|
return findBitcodeInObject(*ObjFile->get());
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
return object_error::invalid_file_type;
|
2015-10-04 22:33:43 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
// Looks for module summary index in the given memory buffer.
|
2015-10-04 22:33:43 +08:00
|
|
|
// returns true if found, else false.
|
2016-03-15 08:04:37 +08:00
|
|
|
bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
2015-11-19 13:52:29 +08:00
|
|
|
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) {
|
2015-10-04 22:33:43 +08:00
|
|
|
ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
2015-11-03 02:02:11 +08:00
|
|
|
if (!BCOrErr)
|
|
|
|
return false;
|
2015-10-04 22:33:43 +08:00
|
|
|
|
[ThinLTO] Support for reference graph in per-module and combined summary.
Summary:
This patch adds support for including a full reference graph including
call graph edges and other GV references in the summary.
The reference graph edges can be used to make importing decisions
without materializing any source modules, can be used in the plugin
to make file staging decisions for distributed build systems, and is
expected to have other uses.
The call graph edges are recorded in each function summary in the
bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
there is PGO, where the ValueId can be mapped to the function GUID via
the ValueSymbolTable. In the function index in memory, the call graph
edges reference the target via the CalleeGUID instead of the
CalleeValueId.
The reference graph edges are recorded in each summary record with a
list of referenced value IDs, which can be mapped to value GUID via the
ValueSymbolTable.
Addtionally, a new summary record type is added to record references
from global variable initializers. A number of bitcode records and data
structures have been renamed to reflect the newly expanded scope of the
summary beyond functions. More cleanup will follow.
Reviewers: joker.eph, davidxl
Subscribers: joker.eph, llvm-commits
Differential Revision: http://reviews.llvm.org/D17212
llvm-svn: 263275
2016-03-12 02:52:24 +08:00
|
|
|
return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler);
|
2015-10-04 22:33:43 +08:00
|
|
|
}
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
// 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(
|
2016-04-22 09:52:00 +08:00
|
|
|
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) {
|
2016-03-15 08:04:37 +08:00
|
|
|
std::unique_ptr<ModuleSummaryIndex> Index;
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
2015-11-03 02:02:11 +08:00
|
|
|
if (!BCOrErr)
|
|
|
|
return BCOrErr.getError();
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
|
2016-04-22 09:52:00 +08:00
|
|
|
getModuleSummaryIndex(BCOrErr.get(), DiagnosticHandler);
|
2015-10-04 22:33:43 +08:00
|
|
|
|
2015-11-03 02:02:11 +08:00
|
|
|
if (std::error_code EC = IOrErr.getError())
|
|
|
|
return EC;
|
2015-10-04 22:33:43 +08:00
|
|
|
|
|
|
|
Index = std::move(IOrErr.get());
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
|
|
|
|
std::move(Index));
|
2015-10-04 22:33:43 +08:00
|
|
|
}
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
// Parse the module summary index out of an IR file and return the summary
|
2015-11-24 03:19:11 +08:00
|
|
|
// index object if found, or nullptr if not.
|
2016-03-15 08:04:37 +08:00
|
|
|
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndexForFile(
|
|
|
|
StringRef Path, DiagnosticHandlerFunction DiagnosticHandler) {
|
2015-11-24 03:19:11 +08:00
|
|
|
ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
|
|
|
|
MemoryBuffer::getFileOrSTDIN(Path);
|
|
|
|
std::error_code EC = FileOrErr.getError();
|
|
|
|
if (EC)
|
|
|
|
return EC;
|
|
|
|
MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
|
2016-03-15 08:04:37 +08:00
|
|
|
ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
|
|
|
|
object::ModuleSummaryIndexObjectFile::create(BufferRef,
|
|
|
|
DiagnosticHandler);
|
2015-11-24 03:19:11 +08:00
|
|
|
EC = ObjOrErr.getError();
|
|
|
|
if (EC)
|
|
|
|
return EC;
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
|
2015-11-24 03:19:11 +08:00
|
|
|
return Obj.takeIndex();
|
|
|
|
}
|