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