]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Object/ModuleSummaryIndexObjectFile.cpp
Update to tcsh 6.20.00
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Object / ModuleSummaryIndexObjectFile.cpp
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/BitcodeReader.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
25 static llvm::cl::opt<bool> IgnoreEmptyThinLTOIndexFile(
26     "ignore-empty-index-file", llvm::cl::ZeroOrMore,
27     llvm::cl::desc(
28         "Ignore an empty index file and perform non-ThinLTO compilation"),
29     llvm::cl::init(false));
30
31 ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
32     MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
33     : SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
34 }
35
36 ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {}
37
38 std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
39   return std::move(Index);
40 }
41
42 ErrorOr<MemoryBufferRef>
43 ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
44   for (const SectionRef &Sec : Obj.sections()) {
45     if (Sec.isBitcode()) {
46       StringRef SecContents;
47       if (std::error_code EC = Sec.getContents(SecContents))
48         return EC;
49       return MemoryBufferRef(SecContents, Obj.getFileName());
50     }
51   }
52
53   return object_error::bitcode_section_not_found;
54 }
55
56 ErrorOr<MemoryBufferRef>
57 ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
58   sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
59   switch (Type) {
60   case sys::fs::file_magic::bitcode:
61     return Object;
62   case sys::fs::file_magic::elf_relocatable:
63   case sys::fs::file_magic::macho_object:
64   case sys::fs::file_magic::coff_object: {
65     Expected<std::unique_ptr<ObjectFile>> ObjFile =
66         ObjectFile::createObjectFile(Object, Type);
67     if (!ObjFile)
68       return errorToErrorCode(ObjFile.takeError());
69     return findBitcodeInObject(*ObjFile->get());
70   }
71   default:
72     return object_error::invalid_file_type;
73   }
74 }
75
76 // Parse module summary index in the given memory buffer.
77 // Return new ModuleSummaryIndexObjectFile instance containing parsed
78 // module summary/index.
79 Expected<std::unique_ptr<ModuleSummaryIndexObjectFile>>
80 ModuleSummaryIndexObjectFile::create(MemoryBufferRef Object) {
81   ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
82   if (!BCOrErr)
83     return errorCodeToError(BCOrErr.getError());
84
85   Expected<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
86       getModuleSummaryIndex(BCOrErr.get());
87
88   if (!IOrErr)
89     return IOrErr.takeError();
90
91   std::unique_ptr<ModuleSummaryIndex> Index = std::move(IOrErr.get());
92   return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
93                                                          std::move(Index));
94 }
95
96 // Parse the module summary index out of an IR file and return the summary
97 // index object if found, or nullptr if not.
98 Expected<std::unique_ptr<ModuleSummaryIndex>>
99 llvm::getModuleSummaryIndexForFile(StringRef Path) {
100   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
101       MemoryBuffer::getFileOrSTDIN(Path);
102   std::error_code EC = FileOrErr.getError();
103   if (EC)
104     return errorCodeToError(EC);
105   MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
106   if (IgnoreEmptyThinLTOIndexFile && !BufferRef.getBufferSize())
107     return nullptr;
108   Expected<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
109       object::ModuleSummaryIndexObjectFile::create(BufferRef);
110   if (!ObjOrErr)
111     return ObjOrErr.takeError();
112
113   object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
114   return Obj.takeIndex();
115 }