xref: /aosp_15_r20/external/llvm/lib/Object/ModuleSummaryIndexObjectFile.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===- ModuleSummaryIndexObjectFile.cpp - Summary index file implementation ==//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // Part of the ModuleSummaryIndexObjectFile class implementation.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Bitcode/ReaderWriter.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/ModuleSummaryIndex.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCStreamer.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/ObjectFile.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
22*9880d681SAndroid Build Coastguard Worker using namespace llvm;
23*9880d681SAndroid Build Coastguard Worker using namespace object;
24*9880d681SAndroid Build Coastguard Worker 
ModuleSummaryIndexObjectFile(MemoryBufferRef Object,std::unique_ptr<ModuleSummaryIndex> I)25*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::ModuleSummaryIndexObjectFile(
26*9880d681SAndroid Build Coastguard Worker     MemoryBufferRef Object, std::unique_ptr<ModuleSummaryIndex> I)
27*9880d681SAndroid Build Coastguard Worker     : SymbolicFile(Binary::ID_ModuleSummaryIndex, Object), Index(std::move(I)) {
28*9880d681SAndroid Build Coastguard Worker }
29*9880d681SAndroid Build Coastguard Worker 
~ModuleSummaryIndexObjectFile()30*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::~ModuleSummaryIndexObjectFile() {}
31*9880d681SAndroid Build Coastguard Worker 
takeIndex()32*9880d681SAndroid Build Coastguard Worker std::unique_ptr<ModuleSummaryIndex> ModuleSummaryIndexObjectFile::takeIndex() {
33*9880d681SAndroid Build Coastguard Worker   return std::move(Index);
34*9880d681SAndroid Build Coastguard Worker }
35*9880d681SAndroid Build Coastguard Worker 
36*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef>
findBitcodeInObject(const ObjectFile & Obj)37*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::findBitcodeInObject(const ObjectFile &Obj) {
38*9880d681SAndroid Build Coastguard Worker   for (const SectionRef &Sec : Obj.sections()) {
39*9880d681SAndroid Build Coastguard Worker     if (Sec.isBitcode()) {
40*9880d681SAndroid Build Coastguard Worker       StringRef SecContents;
41*9880d681SAndroid Build Coastguard Worker       if (std::error_code EC = Sec.getContents(SecContents))
42*9880d681SAndroid Build Coastguard Worker         return EC;
43*9880d681SAndroid Build Coastguard Worker       return MemoryBufferRef(SecContents, Obj.getFileName());
44*9880d681SAndroid Build Coastguard Worker     }
45*9880d681SAndroid Build Coastguard Worker   }
46*9880d681SAndroid Build Coastguard Worker 
47*9880d681SAndroid Build Coastguard Worker   return object_error::bitcode_section_not_found;
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker 
50*9880d681SAndroid Build Coastguard Worker ErrorOr<MemoryBufferRef>
findBitcodeInMemBuffer(MemoryBufferRef Object)51*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::findBitcodeInMemBuffer(MemoryBufferRef Object) {
52*9880d681SAndroid Build Coastguard Worker   sys::fs::file_magic Type = sys::fs::identify_magic(Object.getBuffer());
53*9880d681SAndroid Build Coastguard Worker   switch (Type) {
54*9880d681SAndroid Build Coastguard Worker   case sys::fs::file_magic::bitcode:
55*9880d681SAndroid Build Coastguard Worker     return Object;
56*9880d681SAndroid Build Coastguard Worker   case sys::fs::file_magic::elf_relocatable:
57*9880d681SAndroid Build Coastguard Worker   case sys::fs::file_magic::macho_object:
58*9880d681SAndroid Build Coastguard Worker   case sys::fs::file_magic::coff_object: {
59*9880d681SAndroid Build Coastguard Worker     Expected<std::unique_ptr<ObjectFile>> ObjFile =
60*9880d681SAndroid Build Coastguard Worker         ObjectFile::createObjectFile(Object, Type);
61*9880d681SAndroid Build Coastguard Worker     if (!ObjFile)
62*9880d681SAndroid Build Coastguard Worker       return errorToErrorCode(ObjFile.takeError());
63*9880d681SAndroid Build Coastguard Worker     return findBitcodeInObject(*ObjFile->get());
64*9880d681SAndroid Build Coastguard Worker   }
65*9880d681SAndroid Build Coastguard Worker   default:
66*9880d681SAndroid Build Coastguard Worker     return object_error::invalid_file_type;
67*9880d681SAndroid Build Coastguard Worker   }
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker // Looks for module summary index in the given memory buffer.
71*9880d681SAndroid Build Coastguard Worker // returns true if found, else false.
hasGlobalValueSummaryInMemBuffer(MemoryBufferRef Object,const DiagnosticHandlerFunction & DiagnosticHandler)72*9880d681SAndroid Build Coastguard Worker bool ModuleSummaryIndexObjectFile::hasGlobalValueSummaryInMemBuffer(
73*9880d681SAndroid Build Coastguard Worker     MemoryBufferRef Object,
74*9880d681SAndroid Build Coastguard Worker     const DiagnosticHandlerFunction &DiagnosticHandler) {
75*9880d681SAndroid Build Coastguard Worker   ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
76*9880d681SAndroid Build Coastguard Worker   if (!BCOrErr)
77*9880d681SAndroid Build Coastguard Worker     return false;
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker   return hasGlobalValueSummary(BCOrErr.get(), DiagnosticHandler);
80*9880d681SAndroid Build Coastguard Worker }
81*9880d681SAndroid Build Coastguard Worker 
82*9880d681SAndroid Build Coastguard Worker // Parse module summary index in the given memory buffer.
83*9880d681SAndroid Build Coastguard Worker // Return new ModuleSummaryIndexObjectFile instance containing parsed
84*9880d681SAndroid Build Coastguard Worker // module summary/index.
85*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<ModuleSummaryIndexObjectFile>>
create(MemoryBufferRef Object,const DiagnosticHandlerFunction & DiagnosticHandler)86*9880d681SAndroid Build Coastguard Worker ModuleSummaryIndexObjectFile::create(
87*9880d681SAndroid Build Coastguard Worker     MemoryBufferRef Object,
88*9880d681SAndroid Build Coastguard Worker     const DiagnosticHandlerFunction &DiagnosticHandler) {
89*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<ModuleSummaryIndex> Index;
90*9880d681SAndroid Build Coastguard Worker 
91*9880d681SAndroid Build Coastguard Worker   ErrorOr<MemoryBufferRef> BCOrErr = findBitcodeInMemBuffer(Object);
92*9880d681SAndroid Build Coastguard Worker   if (!BCOrErr)
93*9880d681SAndroid Build Coastguard Worker     return BCOrErr.getError();
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IOrErr =
96*9880d681SAndroid Build Coastguard Worker       getModuleSummaryIndex(BCOrErr.get(), DiagnosticHandler);
97*9880d681SAndroid Build Coastguard Worker 
98*9880d681SAndroid Build Coastguard Worker   if (std::error_code EC = IOrErr.getError())
99*9880d681SAndroid Build Coastguard Worker     return EC;
100*9880d681SAndroid Build Coastguard Worker 
101*9880d681SAndroid Build Coastguard Worker   Index = std::move(IOrErr.get());
102*9880d681SAndroid Build Coastguard Worker 
103*9880d681SAndroid Build Coastguard Worker   return llvm::make_unique<ModuleSummaryIndexObjectFile>(Object,
104*9880d681SAndroid Build Coastguard Worker                                                          std::move(Index));
105*9880d681SAndroid Build Coastguard Worker }
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker // Parse the module summary index out of an IR file and return the summary
108*9880d681SAndroid Build Coastguard Worker // index object if found, or nullptr if not.
getModuleSummaryIndexForFile(StringRef Path,const DiagnosticHandlerFunction & DiagnosticHandler)109*9880d681SAndroid Build Coastguard Worker ErrorOr<std::unique_ptr<ModuleSummaryIndex>> llvm::getModuleSummaryIndexForFile(
110*9880d681SAndroid Build Coastguard Worker     StringRef Path, const DiagnosticHandlerFunction &DiagnosticHandler) {
111*9880d681SAndroid Build Coastguard Worker   ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
112*9880d681SAndroid Build Coastguard Worker       MemoryBuffer::getFileOrSTDIN(Path);
113*9880d681SAndroid Build Coastguard Worker   std::error_code EC = FileOrErr.getError();
114*9880d681SAndroid Build Coastguard Worker   if (EC)
115*9880d681SAndroid Build Coastguard Worker     return EC;
116*9880d681SAndroid Build Coastguard Worker   MemoryBufferRef BufferRef = (FileOrErr.get())->getMemBufferRef();
117*9880d681SAndroid Build Coastguard Worker   ErrorOr<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> ObjOrErr =
118*9880d681SAndroid Build Coastguard Worker       object::ModuleSummaryIndexObjectFile::create(BufferRef,
119*9880d681SAndroid Build Coastguard Worker                                                    DiagnosticHandler);
120*9880d681SAndroid Build Coastguard Worker   EC = ObjOrErr.getError();
121*9880d681SAndroid Build Coastguard Worker   if (EC)
122*9880d681SAndroid Build Coastguard Worker     return EC;
123*9880d681SAndroid Build Coastguard Worker 
124*9880d681SAndroid Build Coastguard Worker   object::ModuleSummaryIndexObjectFile &Obj = **ObjOrErr;
125*9880d681SAndroid Build Coastguard Worker   return Obj.takeIndex();
126*9880d681SAndroid Build Coastguard Worker }
127