llvm.org GIT mirror llvm / dc61d3e
Object: Extract a ModuleSymbolTable class from IRObjectFile. This class represents a symbol table built from in-memory IR. It provides access to GlobalValues and should only be used if such access is required (e.g. in the LTO implementation). We will eventually change IRObjectFile to read from a bitcode symbol table rather than using ModuleSymbolTable, so it would not be able to expose the module. Differential Revision: https://reviews.llvm.org/D27073 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@288319 91177308-0d34-0410-b5e6-96231b3b80d8 Peter Collingbourne 3 years ago
8 changed file(s) with 262 addition(s) and 168 deletion(s). Raw diff Collapse all Expand all
1414 #define LLVM_OBJECT_IROBJECTFILE_H
1515
1616 #include "llvm/ADT/PointerUnion.h"
17 #include "llvm/Object/ModuleSymbolTable.h"
1718 #include "llvm/Object/SymbolicFile.h"
1819
1920 namespace llvm {
2728
2829 class IRObjectFile : public SymbolicFile {
2930 std::unique_ptr M;
30 std::unique_ptr Mang;
31 typedef std::pair AsmSymbol;
32 SpecificBumpPtrAllocator AsmSymbols;
33
34 typedef PointerUnion Sym;
35 std::vector SymTab;
36 static Sym getSym(DataRefImpl &Symb) {
37 return *reinterpret_cast(Symb.p);
38 }
31 ModuleSymbolTable SymTab;
3932
4033 public:
4134 IRObjectFile(MemoryBufferRef Object, std::unique_ptr M);
6962 /// error code if not found.
7063 static ErrorOr findBitcodeInObject(const ObjectFile &Obj);
7164
72 /// Parse inline ASM and collect the symbols that are not defined in
73 /// the current module.
74 ///
75 /// For each found symbol, call \p AsmUndefinedRefs with the name of the
76 /// symbol found and the associated flags.
77 static void CollectAsmUndefinedRefs(
78 const Triple &TheTriple, StringRef InlineAsm,
79 function_ref AsmUndefinedRefs);
80
8165 /// \brief Finds and returns bitcode in the given memory buffer (which may
8266 /// be either a bitcode file or a native object file with embedded bitcode),
8367 /// or an error code if not found.
0 //===- ModuleSymbolTable.h - symbol table for in-memory IR ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class represents a symbol table built from in-memory IR. It provides
10 // access to GlobalValues and should only be used if such access is required
11 // (e.g. in the LTO implementation).
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_OBJECT_MODULESYMBOLTABLE_H
16 #define LLVM_OBJECT_MODULESYMBOLTABLE_H
17
18 #include "llvm/ADT/PointerUnion.h"
19 #include "llvm/ADT/Triple.h"
20 #include "llvm/IR/Mangler.h"
21 #include "llvm/Object/SymbolicFile.h"
22 #include
23 #include
24
25 namespace llvm {
26
27 class GlobalValue;
28
29 class ModuleSymbolTable {
30 public:
31 typedef std::pair AsmSymbol;
32 typedef PointerUnion Symbol;
33
34 private:
35 Module *FirstMod = nullptr;
36
37 SpecificBumpPtrAllocator AsmSymbols;
38 std::vector SymTab;
39 Mangler Mang;
40
41 public:
42 ArrayRef symbols() const { return SymTab; }
43 void addModule(Module *M);
44
45 void printSymbolName(raw_ostream &OS, Symbol S) const;
46 uint32_t getSymbolFlags(Symbol S) const;
47
48 /// Parse inline ASM and collect the symbols that are defined or referenced in
49 /// the current module.
50 ///
51 /// For each found symbol, call \p AsmSymbol with the name of the symbol found
52 /// and the associated flags.
53 static void CollectAsmSymbols(
54 const Triple &TheTriple, StringRef InlineAsm,
55 function_ref AsmSymbol);
56 };
57
58 }
59
60 #endif
268268 // Also, any values used but not defined within module level asm should
269269 // be listed on the llvm.used or llvm.compiler.used global and marked as
270270 // referenced from there.
271 // FIXME: Rename CollectAsmUndefinedRefs to something more general, as we
272 // are also using it to find the file-scope locals defined in module asm.
273 object::IRObjectFile::CollectAsmUndefinedRefs(
271 ModuleSymbolTable::CollectAsmSymbols(
274272 Triple(M.getTargetTriple()), M.getModuleInlineAsm(),
275273 [&M, &Index](StringRef Name, object::BasicSymbolRef::Flags Flags) {
276274 // Symbols not marked as Weak or Global are local definitions.
279279 // Collect the list of undefined symbols used in asm and update
280280 // llvm.compiler.used to prevent optimization to drop these from the output.
281281 StringSet<> AsmUndefinedRefs;
282 object::IRObjectFile::CollectAsmUndefinedRefs(
282 ModuleSymbolTable::CollectAsmSymbols(
283283 Triple(Mod.getTargetTriple()), Mod.getModuleInlineAsm(),
284284 [&AsmUndefinedRefs](StringRef Name, object::BasicSymbolRef::Flags Flags) {
285285 if (Flags & object::BasicSymbolRef::SF_Undefined)
99 MachOObjectFile.cpp
1010 MachOUniversal.cpp
1111 ModuleSummaryIndexObjectFile.cpp
12 ModuleSymbolTable.cpp
1213 Object.cpp
1314 ObjectFile.cpp
1415 RecordStreamer.cpp
3636
3737 IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr Mod)
3838 : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
39 Mang.reset(new Mangler());
40
41 for (Function &F : *M)
42 SymTab.push_back(&F);
43 for (GlobalVariable &GV : M->globals())
44 SymTab.push_back(&GV);
45 for (GlobalAlias &GA : M->aliases())
46 SymTab.push_back(&GA);
47
48 CollectAsmUndefinedRefs(Triple(M->getTargetTriple()), M->getModuleInlineAsm(),
49 [this](StringRef Name, BasicSymbolRef::Flags Flags) {
50 SymTab.push_back(new (AsmSymbols.Allocate())
51 AsmSymbol(Name, Flags));
52 });
53 }
54
55 // Parse inline ASM and collect the list of symbols that are not defined in
56 // the current module. This is inspired from IRObjectFile.
57 void IRObjectFile::CollectAsmUndefinedRefs(
58 const Triple &TT, StringRef InlineAsm,
59 function_ref AsmUndefinedRefs) {
60 if (InlineAsm.empty())
61 return;
62
63 std::string Err;
64 const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
65 assert(T && T->hasMCAsmParser());
66
67 std::unique_ptr MRI(T->createMCRegInfo(TT.str()));
68 if (!MRI)
69 return;
70
71 std::unique_ptr MAI(T->createMCAsmInfo(*MRI, TT.str()));
72 if (!MAI)
73 return;
74
75 std::unique_ptr STI(
76 T->createMCSubtargetInfo(TT.str(), "", ""));
77 if (!STI)
78 return;
79
80 std::unique_ptr MCII(T->createMCInstrInfo());
81 if (!MCII)
82 return;
83
84 MCObjectFileInfo MOFI;
85 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
86 MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx);
87 RecordStreamer Streamer(MCCtx);
88 T->createNullTargetStreamer(Streamer);
89
90 std::unique_ptr Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
91 SourceMgr SrcMgr;
92 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
93 std::unique_ptr Parser(
94 createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
95
96 MCTargetOptions MCOptions;
97 std::unique_ptr TAP(
98 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
99 if (!TAP)
100 return;
101
102 Parser->setTargetParser(*TAP);
103 if (Parser->Run(false))
104 return;
105
106 for (auto &KV : Streamer) {
107 StringRef Key = KV.first();
108 RecordStreamer::State Value = KV.second;
109 uint32_t Res = BasicSymbolRef::SF_None;
110 switch (Value) {
111 case RecordStreamer::NeverSeen:
112 llvm_unreachable("NeverSeen should have been replaced earlier");
113 case RecordStreamer::DefinedGlobal:
114 Res |= BasicSymbolRef::SF_Global;
115 break;
116 case RecordStreamer::Defined:
117 break;
118 case RecordStreamer::Global:
119 case RecordStreamer::Used:
120 Res |= BasicSymbolRef::SF_Undefined;
121 Res |= BasicSymbolRef::SF_Global;
122 break;
123 case RecordStreamer::DefinedWeak:
124 Res |= BasicSymbolRef::SF_Weak;
125 Res |= BasicSymbolRef::SF_Global;
126 break;
127 case RecordStreamer::UndefinedWeak:
128 Res |= BasicSymbolRef::SF_Weak;
129 Res |= BasicSymbolRef::SF_Undefined;
130 }
131 AsmUndefinedRefs(Key, BasicSymbolRef::Flags(Res));
132 }
39 SymTab.addModule(M.get());
13340 }
13441
13542 IRObjectFile::~IRObjectFile() {}
13643
44 static ModuleSymbolTable::Symbol getSym(DataRefImpl &Symb) {
45 return *reinterpret_cast(Symb.p);
46 }
47
13748 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
138 Symb.p += sizeof(Sym);
49 Symb.p += sizeof(ModuleSymbolTable::Symbol);
13950 }
14051
14152 std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
14253 DataRefImpl Symb) const {
143 Sym S = getSym(Symb);
144 if (S.is()) {
145 OS << S.get()->first;
146 return std::error_code();
147 }
148
149 auto *GV = S.get();
150 if (GV->hasDLLImportStorageClass())
151 OS << "__imp_";
152
153 if (Mang)
154 Mang->getNameWithPrefix(OS, GV, false);
155 else
156 OS << GV->getName();
157
54 SymTab.printSymbolName(OS, getSym(Symb));
15855 return std::error_code();
15956 }
16057
16158 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
162 Sym S = getSym(Symb);
163 if (S.is())
164 return S.get()->second;
165
166 auto *GV = S.get();
167
168 uint32_t Res = BasicSymbolRef::SF_None;
169 if (GV->isDeclarationForLinker())
170 Res |= BasicSymbolRef::SF_Undefined;
171 else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage())
172 Res |= BasicSymbolRef::SF_Hidden;
173 if (const GlobalVariable *GVar = dyn_cast(GV)) {
174 if (GVar->isConstant())
175 Res |= BasicSymbolRef::SF_Const;
176 }
177 if (GV->hasPrivateLinkage())
178 Res |= BasicSymbolRef::SF_FormatSpecific;
179 if (!GV->hasLocalLinkage())
180 Res |= BasicSymbolRef::SF_Global;
181 if (GV->hasCommonLinkage())
182 Res |= BasicSymbolRef::SF_Common;
183 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
184 GV->hasExternalWeakLinkage())
185 Res |= BasicSymbolRef::SF_Weak;
186
187 if (GV->getName().startswith("llvm."))
188 Res |= BasicSymbolRef::SF_FormatSpecific;
189 else if (auto *Var = dyn_cast(GV)) {
190 if (Var->getSection() == "llvm.metadata")
191 Res |= BasicSymbolRef::SF_FormatSpecific;
192 }
193
194 return Res;
59 return SymTab.getSymbolFlags(getSym(Symb));
19560 }
19661
19762 GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) {
20267
20368 basic_symbol_iterator IRObjectFile::symbol_begin() const {
20469 DataRefImpl Ret;
205 Ret.p = reinterpret_cast(SymTab.data());
70 Ret.p = reinterpret_cast(SymTab.symbols().data());
20671 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
20772 }
20873
20974 basic_symbol_iterator IRObjectFile::symbol_end() const {
21075 DataRefImpl Ret;
211 Ret.p = reinterpret_cast(SymTab.data() + SymTab.size());
76 Ret.p = reinterpret_cast(SymTab.symbols().data() +
77 SymTab.symbols().size());
21278 return basic_symbol_iterator(BasicSymbolRef(Ret, this));
21379 }
21480
0 //===- ModuleSymbolTable.cpp - symbol table for in-memory IR ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class represents a symbol table built from in-memory IR. It provides
10 // access to GlobalValues and should only be used if such access is required
11 // (e.g. in the LTO implementation).
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Object/IRObjectFile.h"
16 #include "RecordStreamer.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/Bitcode/BitcodeReader.h"
19 #include "llvm/IR/GVMaterializer.h"
20 #include "llvm/IR/LLVMContext.h"
21 #include "llvm/IR/Mangler.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/MC/MCAsmInfo.h"
24 #include "llvm/MC/MCContext.h"
25 #include "llvm/MC/MCInstrInfo.h"
26 #include "llvm/MC/MCObjectFileInfo.h"
27 #include "llvm/MC/MCParser/MCAsmParser.h"
28 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
29 #include "llvm/MC/MCRegisterInfo.h"
30 #include "llvm/MC/MCSubtargetInfo.h"
31 #include "llvm/Object/ObjectFile.h"
32 #include "llvm/Support/MemoryBuffer.h"
33 #include "llvm/Support/SourceMgr.h"
34 #include "llvm/Support/TargetRegistry.h"
35 #include "llvm/Support/raw_ostream.h"
36 using namespace llvm;
37 using namespace object;
38
39 void ModuleSymbolTable::addModule(Module *M) {
40 if (FirstMod)
41 assert(FirstMod->getTargetTriple() == M->getTargetTriple());
42 else
43 FirstMod = M;
44
45 for (Function &F : *M)
46 SymTab.push_back(&F);
47 for (GlobalVariable &GV : M->globals())
48 SymTab.push_back(&GV);
49 for (GlobalAlias &GA : M->aliases())
50 SymTab.push_back(&GA);
51
52 CollectAsmSymbols(Triple(M->getTargetTriple()), M->getModuleInlineAsm(),
53 [this](StringRef Name, BasicSymbolRef::Flags Flags) {
54 SymTab.push_back(new (AsmSymbols.Allocate())
55 AsmSymbol(Name, Flags));
56 });
57 }
58
59 void ModuleSymbolTable::CollectAsmSymbols(
60 const Triple &TT, StringRef InlineAsm,
61 function_ref AsmSymbol) {
62 if (InlineAsm.empty())
63 return;
64
65 std::string Err;
66 const Target *T = TargetRegistry::lookupTarget(TT.str(), Err);
67 assert(T && T->hasMCAsmParser());
68
69 std::unique_ptr MRI(T->createMCRegInfo(TT.str()));
70 if (!MRI)
71 return;
72
73 std::unique_ptr MAI(T->createMCAsmInfo(*MRI, TT.str()));
74 if (!MAI)
75 return;
76
77 std::unique_ptr STI(
78 T->createMCSubtargetInfo(TT.str(), "", ""));
79 if (!STI)
80 return;
81
82 std::unique_ptr MCII(T->createMCInstrInfo());
83 if (!MCII)
84 return;
85
86 MCObjectFileInfo MOFI;
87 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI);
88 MOFI.InitMCObjectFileInfo(TT, /*PIC*/ false, CodeModel::Default, MCCtx);
89 RecordStreamer Streamer(MCCtx);
90 T->createNullTargetStreamer(Streamer);
91
92 std::unique_ptr Buffer(MemoryBuffer::getMemBuffer(InlineAsm));
93 SourceMgr SrcMgr;
94 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
95 std::unique_ptr Parser(
96 createMCAsmParser(SrcMgr, MCCtx, Streamer, *MAI));
97
98 MCTargetOptions MCOptions;
99 std::unique_ptr TAP(
100 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions));
101 if (!TAP)
102 return;
103
104 Parser->setTargetParser(*TAP);
105 if (Parser->Run(false))
106 return;
107
108 for (auto &KV : Streamer) {
109 StringRef Key = KV.first();
110 RecordStreamer::State Value = KV.second;
111 uint32_t Res = BasicSymbolRef::SF_None;
112 switch (Value) {
113 case RecordStreamer::NeverSeen:
114 llvm_unreachable("NeverSeen should have been replaced earlier");
115 case RecordStreamer::DefinedGlobal:
116 Res |= BasicSymbolRef::SF_Global;
117 break;
118 case RecordStreamer::Defined:
119 break;
120 case RecordStreamer::Global:
121 case RecordStreamer::Used:
122 Res |= BasicSymbolRef::SF_Undefined;
123 Res |= BasicSymbolRef::SF_Global;
124 break;
125 case RecordStreamer::DefinedWeak:
126 Res |= BasicSymbolRef::SF_Weak;
127 Res |= BasicSymbolRef::SF_Global;
128 break;
129 case RecordStreamer::UndefinedWeak:
130 Res |= BasicSymbolRef::SF_Weak;
131 Res |= BasicSymbolRef::SF_Undefined;
132 }
133 AsmSymbol(Key, BasicSymbolRef::Flags(Res));
134 }
135 }
136
137 void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
138 if (S.is()) {
139 OS << S.get()->first;
140 return;
141 }
142
143 auto *GV = S.get();
144 if (GV->hasDLLImportStorageClass())
145 OS << "__imp_";
146
147 Mang.getNameWithPrefix(OS, GV, false);
148 }
149
150 uint32_t ModuleSymbolTable::getSymbolFlags(Symbol S) const {
151 if (S.is())
152 return S.get()->second;
153
154 auto *GV = S.get();
155
156 uint32_t Res = BasicSymbolRef::SF_None;
157 if (GV->isDeclarationForLinker())
158 Res |= BasicSymbolRef::SF_Undefined;
159 else if (GV->hasHiddenVisibility() && !GV->hasLocalLinkage())
160 Res |= BasicSymbolRef::SF_Hidden;
161 if (const GlobalVariable *GVar = dyn_cast(GV)) {
162 if (GVar->isConstant())
163 Res |= BasicSymbolRef::SF_Const;
164 }
165 if (GV->hasPrivateLinkage())
166 Res |= BasicSymbolRef::SF_FormatSpecific;
167 if (!GV->hasLocalLinkage())
168 Res |= BasicSymbolRef::SF_Global;
169 if (GV->hasCommonLinkage())
170 Res |= BasicSymbolRef::SF_Common;
171 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
172 GV->hasExternalWeakLinkage())
173 Res |= BasicSymbolRef::SF_Weak;
174
175 if (GV->getName().startswith("llvm."))
176 Res |= BasicSymbolRef::SF_FormatSpecific;
177 else if (auto *Var = dyn_cast(GV)) {
178 if (Var->getSection() == "llvm.metadata")
179 Res |= BasicSymbolRef::SF_FormatSpecific;
180 }
181
182 return Res;
183 }
554554 // Parse inline ASM and collect the list of symbols that are not defined in
555555 // the current module.
556556 StringSet<> AsmUndefinedRefs;
557 object::IRObjectFile::CollectAsmUndefinedRefs(
557 ModuleSymbolTable::CollectAsmSymbols(
558558 Triple(TheModule.getTargetTriple()), TheModule.getModuleInlineAsm(),
559559 [&AsmUndefinedRefs](StringRef Name, object::BasicSymbolRef::Flags Flags) {
560560 if (Flags & object::BasicSymbolRef::SF_Undefined)