summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object/ModuleSummaryIndexObjectFile.cpp
blob: ca45144f05f4d3b62cf7bc44821b9abd74222889 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
//===- ModuleSummaryIndexObjectFile.cpp - Summary index file implementation ==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Part of the ModuleSummaryIndexObjectFile class implementation.
//
//===----------------------------------------------------------------------===//

#include "llvm/Object/ModuleSummaryIndexObjectFile.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
using namespace object;

ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
    MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
    : SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
}

ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {}

std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
  return std::move(Index);
}

ErrorOr<MemoryBufferRef>
ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
  for (const SectionRef &Sec : Obj.sections()) {
    if (Sec.isBitcode()) {
      StringRef SecContents;
      if (std::error_code EC = Sec.getContents(SecContents))
        return EC;
      return MemoryBufferRef(SecContents, Obj.getFileName());
    }
  }

  return object_error::bitcode_section_not_found;
}

ErrorOr<MemoryBufferRef>
ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
  sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
  switch (Type) {
  case sys::fs::file_magic::bitcode:
    return Object;
  case sys::fs::file_magic::elf_relocatable:
  case sys::fs::file_magic::macho_object:
  case sys::fs::file_magic::coff_object: {
    Expected<std::unique_ptr<ObjectFile>> ObjFile =
        ObjectFile::createObjectFile(Object, Type);
    if (!ObjFile)
      return errorToErrorCode(ObjFile.takeError());
    return findBitcodeInObject(*ObjFile->get());
  }
  default:
    return object_error::invalid_file_type;
  }
}

// Looks for module summary index in the given memory buffer.
// returns true if found, else false.
bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
    MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler) {
  ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
  if (!BCOrErr)
    return false;

  return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler);
}

// Parse module summary index in the given memory buffer.
// Return new ModuleSummaryIndexObjectFile instance containing parsed
// module summary/index.
ErrorOr<std::unique_ptr<ModuleSummaryIndexObjectFile>>
ModuleSummaryIndexObjectFile::create(
    MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
    bool IsLazy) {
  std::unique_ptr<ModuleSummaryIndex> Index;

  ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
  if (!BCOrErr)
    return BCOrErr.getError();

  ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
      getModuleSummaryIndex(BCOrErr.get(), DiagnosticHandler, IsLazy);

  if (std::error_code EC = IOrErr.getError())
    return EC;

  Index = std::move(IOrErr.get());

  return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
                                                         std::move(Index));
}

// Parse the summary information for value with the
// given name out of the given buffer. Parsed information is
// stored on the index object saved in this object.
std::error_code ModuleSummaryIndexObjectFile::findGlobalValueSummaryInMemBuffer(
    MemoryBufferRef Object, DiagnosticHandlerFunction DiagnosticHandler,
    StringRef ValueName) {
  sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
  switch (Type) {
  case sys::fs::file_magic::bitcode: {
    return readGlobalValueSummary(Object, DiagnosticHandler, ValueName,
                                  std::move(Index));
  }
  default:
    return object_error::invalid_file_type;
  }
}

// Parse the module summary index out of an IR file and return the summary
// index object if found, or nullptr if not.
ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndexForFile(
    StringRef Path, DiagnosticHandlerFunction DiagnosticHandler) {
  ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
      MemoryBuffer::getFileOrSTDIN(Path);
  std::error_code EC = FileOrErr.getError();
  if (EC)
    return EC;
  MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
  ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
      object::ModuleSummaryIndexObjectFile::create(BufferRef,
                                                   DiagnosticHandler);
  EC = ObjOrErr.getError();
  if (EC)
    return EC;

  object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
  return Obj.takeIndex();
}
OpenPOWER on IntegriCloud