Home | History | Annotate | Download | only in Object
      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