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 25 ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile( 26 MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I) 27 : SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) { 28 } 29 30 ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {} 31 32 std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() { 33 return std::move(Index); 34 } 35 36 ErrorOr<MemoryBufferRef> 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> 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. 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>> 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. 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