mirror of
https://github.com/RPCS3/llvm.git
synced 2026-01-31 01:25:19 +01:00
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@263275 91177308-0d34-0410-b5e6-96231b3b80d8
141 lines
4.9 KiB
C++
141 lines
4.9 KiB
C++
//===- FunctionIndexObjectFile.cpp - Function index file implementation ---===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Part of the FunctionIndexObjectFile class implementation.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Object/FunctionIndexObjectFile.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/Bitcode/ReaderWriter.h"
|
|
#include "llvm/IR/FunctionInfo.h"
|
|
#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;
|
|
|
|
FunctionIndexObjectFile::FunctionIndexObjectFile(
|
|
MemoryBufferRef Object, std::unique_ptr<FunctionInfoIndex> I)
|
|
: SymbolicFile(Binary::ID_FunctionIndex, Object), Index(std::move(I)) {}
|
|
|
|
FunctionIndexObjectFile::~FunctionIndexObjectFile() {}
|
|
|
|
std::unique_ptr<FunctionInfoIndex> FunctionIndexObjectFile::takeIndex() {
|
|
return std::move(Index);
|
|
}
|
|
|
|
ErrorOr<MemoryBufferRef>
|
|
FunctionIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
|
|
for (const SectionRef &Sec : Obj.sections()) {
|
|
if (Sec.isBitcode()) {
|
|
StringRef SecContents;
|
|
if (std::error_code EC = Sec.getContents(SecContents))
|
|
return EC;
|
|
return MemoryBufferRef(SecContents, Obj.getFileName());
|
|
}
|
|
}
|
|
|
|
return object_error::bitcode_section_not_found;
|
|
}
|
|
|
|
ErrorOr<MemoryBufferRef>
|
|
FunctionIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
|
|
sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
|
|
switch (Type) {
|
|
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: {
|
|
ErrorOr<std::unique_ptr<ObjectFile>> ObjFile =
|
|
ObjectFile::createObjectFile(Object, Type);
|
|
if (!ObjFile)
|
|
return ObjFile.getError();
|
|
return findBitcodeInObject(*ObjFile->get());
|
|
}
|
|
default:
|
|
return object_error::invalid_file_type;
|
|
}
|
|
}
|
|
|
|
// Looks for module summary index in the given memory buffer.
|
|
// returns true if found, else false.
|
|
bool FunctionIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
|
|
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) {
|
|
ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
|
if (!BCOrErr)
|
|
return false;
|
|
|
|
return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler);
|
|
}
|
|
|
|
// Parse function index in the given memory buffer.
|
|
// Return new FunctionIndexObjectFile instance containing parsed
|
|
// function summary/index.
|
|
ErrorOr<std::unique_ptr<FunctionIndexObjectFile>>
|
|
FunctionIndexObjectFile::create(MemoryBufferRef Object,
|
|
DiagnosticHandlerFunction DiagnosticHandler,
|
|
bool IsLazy) {
|
|
std::unique_ptr<FunctionInfoIndex> Index;
|
|
|
|
ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
|
|
if (!BCOrErr)
|
|
return BCOrErr.getError();
|
|
|
|
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<FunctionIndexObjectFile>(Object, std::move(Index));
|
|
}
|
|
|
|
// 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 FunctionIndexObjectFile::findFunctionSummaryInMemBuffer(
|
|
MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
|
|
StringRef FunctionName) {
|
|
sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
|
|
switch (Type) {
|
|
case sys::fs::file_magic::bitcode: {
|
|
return readFunctionSummary(Object, DiagnosticHandler, FunctionName,
|
|
std::move(Index));
|
|
}
|
|
default:
|
|
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) {
|
|
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);
|
|
EC = ObjOrErr.getError();
|
|
if (EC)
|
|
return EC;
|
|
|
|
object::FunctionIndexObjectFile &Obj = **ObjOrErr;
|
|
return Obj.takeIndex();
|
|
}
|