Line data Source code
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/ADT/STLExtras.h"
15 : #include "llvm/ADT/StringRef.h"
16 : #include "llvm/Bitcode/BitcodeReader.h"
17 : #include "llvm/IR/ModuleSummaryIndex.h"
18 : #include "llvm/Object/Binary.h"
19 : #include "llvm/Object/Error.h"
20 : #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
21 : #include "llvm/Object/ObjectFile.h"
22 : #include "llvm/Support/CommandLine.h"
23 : #include "llvm/Support/Error.h"
24 : #include "llvm/Support/ErrorOr.h"
25 : #include "llvm/Support/FileSystem.h"
26 : #include "llvm/Support/MemoryBuffer.h"
27 : #include <algorithm>
28 : #include <memory>
29 : #include <system_error>
30 :
31 : using namespace llvm;
32 : using namespace object;
33 :
34 131428 : static cl::opt<bool> IgnoreEmptyThinLTOIndexFile(
35 : "ignore-empty-index-file", cl::ZeroOrMore,
36 197142 : cl::desc(
37 : "Ignore an empty index file and perform non-ThinLTO compilation"),
38 328570 : cl::init(false));
39 :
40 251 : ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
41 251 : MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
42 502 : : SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
43 251 : }
44 :
45 : ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() = default;
46 :
47 251 : std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
48 502 : return std::move(Index);
49 : }
50 :
51 : ErrorOr<MemoryBufferRef>
52 0 : ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
53 0 : for (const SectionRef &Sec : Obj.sections()) {
54 0 : if (Sec.isBitcode()) {
55 0 : StringRef SecContents;
56 0 : if (std::error_code EC = Sec.getContents(SecContents))
57 : return EC;
58 0 : return MemoryBufferRef(SecContents, Obj.getFileName());
59 : }
60 : }
61 :
62 : return object_error::bitcode_section_not_found;
63 : }
64 :
65 : ErrorOr<MemoryBufferRef>
66 252 : ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
67 252 : sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
68 252 : switch (Type) {
69 : case sys::fs::file_magic::bitcode:
70 : return Object;
71 : case sys::fs::file_magic::elf_relocatable:
72 : case sys::fs::file_magic::macho_object:
73 : case sys::fs::file_magic::coff_object: {
74 : Expected<std::unique_ptr<ObjectFile>> ObjFile =
75 0 : ObjectFile::createObjectFile(Object, Type);
76 0 : if (!ObjFile)
77 0 : return errorToErrorCode(ObjFile.takeError());
78 0 : return findBitcodeInObject(*ObjFile->get());
79 : }
80 : default:
81 : return object_error::invalid_file_type;
82 : }
83 : }
84 :
85 : // Parse module summary index in the given memory buffer.
86 : // Return new ModuleSummaryIndexObjectFile instance containing parsed
87 : // module summary/index.
88 : Expected<std::unique_ptr<ModuleSummaryIndexObjectFile>>
89 252 : ModuleSummaryIndexObjectFile::create(MemoryBufferRef Object) {
90 504 : ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
91 252 : if (!BCOrErr)
92 3 : return errorCodeToError(BCOrErr.getError());
93 :
94 : Expected<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
95 502 : getModuleSummaryIndex(BCOrErr.get());
96 :
97 251 : if (!IOrErr)
98 0 : return IOrErr.takeError();
99 :
100 753 : std::unique_ptr<ModuleSummaryIndex> Index = std::move(IOrErr.get());
101 502 : return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
102 502 : std::move(Index));
103 : }
104 :
105 : // Parse the module summary index out of an IR file and return the summary
106 : // index object if found, or nullptr if not.
107 : Expected<std::unique_ptr<ModuleSummaryIndex>>
108 170 : llvm::getModuleSummaryIndexForFile(StringRef Path, StringRef Identifier) {
109 : ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
110 340 : MemoryBuffer::getFileOrSTDIN(Path);
111 170 : std::error_code EC = FileOrErr.getError();
112 170 : if (EC)
113 3 : return errorCodeToError(EC);
114 338 : std::unique_ptr<MemoryBuffer> MemBuffer = std::move(FileOrErr.get());
115 : // If Identifier is non-empty, use it as the buffer identifier, which
116 : // will become the module path in the index.
117 169 : if (Identifier.empty())
118 169 : Identifier = MemBuffer->getBufferIdentifier();
119 507 : MemoryBufferRef BufferRef(MemBuffer->getBuffer(), Identifier);
120 170 : if (IgnoreEmptyThinLTOIndexFile && !BufferRef.getBufferSize())
121 1 : return nullptr;
122 : Expected<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
123 336 : object::ModuleSummaryIndexObjectFile::create(BufferRef);
124 168 : if (!ObjOrErr)
125 3 : return ObjOrErr.takeError();
126 :
127 334 : object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
128 334 : return Obj.takeIndex();
129 197142 : }
|