1*9880d681SAndroid Build Coastguard Worker //===- ModuleSummaryIndexObjectFile.cpp - Summary index file implementation ==//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Part of the ModuleSummaryIndexObjectFile class implementation.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/ReaderWriter.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/ModuleSummaryIndex.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
22*9880d681SAndroid Build Coastguard Worker using namespace llvm;
23*9880d681SAndroid Build Coastguard Worker using namespace object;
24*9880d681SAndroid Build Coastguard Worker
ModuleSummaryIndexObjectFile(MemoryBufferRef Object,std::unique_ptr<ModuleSummaryIndex> I)25*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
26*9880d681SAndroid Build Coastguard Worker MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
27*9880d681SAndroid Build Coastguard Worker : SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
28*9880d681SAndroid Build Coastguard Worker }
29*9880d681SAndroid Build Coastguard Worker
~ModuleSummaryIndexObjectFile()30*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {}
31*9880d681SAndroid Build Coastguard Worker
takeIndex()32*9880d681SAndroid Build Coastguard Worker std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
33*9880d681SAndroid Build Coastguard Worker return std::move(Index);
34*9880d681SAndroid Build Coastguard Worker }
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef>
findBitcodeInObject(const ObjectFile & Obj)37*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
38*9880d681SAndroid Build Coastguard Worker for (const SectionRef &Sec : Obj.sections()) {
39*9880d681SAndroid Build Coastguard Worker if (Sec.isBitcode()) {
40*9880d681SAndroid Build Coastguard Worker StringRef SecContents;
41*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = Sec.getContents(SecContents))
42*9880d681SAndroid Build Coastguard Worker return EC;
43*9880d681SAndroid Build Coastguard Worker return MemoryBufferRef(SecContents, Obj.getFileName());
44*9880d681SAndroid Build Coastguard Worker }
45*9880d681SAndroid Build Coastguard Worker }
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker return object_error::bitcode_section_not_found;
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef>
findBitcodeInMemBuffer(MemoryBufferRef Object)51*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
52*9880d681SAndroid Build Coastguard Worker sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
53*9880d681SAndroid Build Coastguard Worker switch (Type) {
54*9880d681SAndroid Build Coastguard Worker case sys::fs::file_magic::bitcode:
55*9880d681SAndroid Build Coastguard Worker return Object;
56*9880d681SAndroid Build Coastguard Worker case sys::fs::file_magic::elf_relocatable:
57*9880d681SAndroid Build Coastguard Worker case sys::fs::file_magic::macho_object:
58*9880d681SAndroid Build Coastguard Worker case sys::fs::file_magic::coff_object: {
59*9880d681SAndroid Build Coastguard Worker Expected<std::unique_ptr<ObjectFile>> ObjFile =
60*9880d681SAndroid Build Coastguard Worker ObjectFile::createObjectFile(Object, Type);
61*9880d681SAndroid Build Coastguard Worker if (!ObjFile)
62*9880d681SAndroid Build Coastguard Worker return errorToErrorCode(ObjFile.takeError());
63*9880d681SAndroid Build Coastguard Worker return findBitcodeInObject(*ObjFile->get());
64*9880d681SAndroid Build Coastguard Worker }
65*9880d681SAndroid Build Coastguard Worker default:
66*9880d681SAndroid Build Coastguard Worker return object_error::invalid_file_type;
67*9880d681SAndroid Build Coastguard Worker }
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker // Looks for module summary index in the given memory buffer.
71*9880d681SAndroid Build Coastguard Worker // returns true if found, else false.
hasGlobalValueSummaryInMemBuffer(MemoryBufferRef Object,const DiagnosticHandlerFunction & DiagnosticHandler)72*9880d681SAndroid Build Coastguard Worker bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
73*9880d681SAndroid Build Coastguard Worker MemoryBufferRef Object,
74*9880d681SAndroid Build Coastguard Worker const DiagnosticHandlerFunction &DiagnosticHandler) {
75*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
76*9880d681SAndroid Build Coastguard Worker if (!BCOrErr)
77*9880d681SAndroid Build Coastguard Worker return false;
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler);
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker
82*9880d681SAndroid Build Coastguard Worker // Parse module summary index in the given memory buffer.
83*9880d681SAndroid Build Coastguard Worker // Return new ModuleSummaryIndexObjectFile instance containing parsed
84*9880d681SAndroid Build Coastguard Worker // module summary/index.
85*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<ModuleSummaryIndexObjectFile>>
create(MemoryBufferRef Object,const DiagnosticHandlerFunction & DiagnosticHandler)86*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::create(
87*9880d681SAndroid Build Coastguard Worker MemoryBufferRef Object,
88*9880d681SAndroid Build Coastguard Worker const DiagnosticHandlerFunction &DiagnosticHandler) {
89*9880d681SAndroid Build Coastguard Worker std::unique_ptr<ModuleSummaryIndex> Index;
90*9880d681SAndroid Build Coastguard Worker
91*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
92*9880d681SAndroid Build Coastguard Worker if (!BCOrErr)
93*9880d681SAndroid Build Coastguard Worker return BCOrErr.getError();
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
96*9880d681SAndroid Build Coastguard Worker getModuleSummaryIndex(BCOrErr.get(), DiagnosticHandler);
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker if (std::error_code EC = IOrErr.getError())
99*9880d681SAndroid Build Coastguard Worker return EC;
100*9880d681SAndroid Build Coastguard Worker
101*9880d681SAndroid Build Coastguard Worker Index = std::move(IOrErr.get());
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
104*9880d681SAndroid Build Coastguard Worker std::move(Index));
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker
107*9880d681SAndroid Build Coastguard Worker // Parse the module summary index out of an IR file and return the summary
108*9880d681SAndroid Build Coastguard Worker // index object if found, or nullptr if not.
getModuleSummaryIndexForFile(StringRef Path,const DiagnosticHandlerFunction & DiagnosticHandler)109*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndexForFile(
110*9880d681SAndroid Build Coastguard Worker StringRef Path, const DiagnosticHandlerFunction &DiagnosticHandler) {
111*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
112*9880d681SAndroid Build Coastguard Worker MemoryBuffer::getFileOrSTDIN(Path);
113*9880d681SAndroid Build Coastguard Worker std::error_code EC = FileOrErr.getError();
114*9880d681SAndroid Build Coastguard Worker if (EC)
115*9880d681SAndroid Build Coastguard Worker return EC;
116*9880d681SAndroid Build Coastguard Worker MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
117*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
118*9880d681SAndroid Build Coastguard Worker object::ModuleSummaryIndexObjectFile::create(BufferRef,
119*9880d681SAndroid Build Coastguard Worker DiagnosticHandler);
120*9880d681SAndroid Build Coastguard Worker EC = ObjOrErr.getError();
121*9880d681SAndroid Build Coastguard Worker if (EC)
122*9880d681SAndroid Build Coastguard Worker return EC;
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
125*9880d681SAndroid Build Coastguard Worker return Obj.takeIndex();
126*9880d681SAndroid Build Coastguard Worker }
127