llvm.org GIT mirror llvm / 050bf6c
Make the LTO comdat api more symbol table friendly. In an IR symbol table I would expect the comdats to be represented as: - A table of strings, one for each comdat name. - Each symbol has an optional index into that table. The natural api for accessing that would be InputFile: ArrayRef<StringRef> getComdatTable() const; Symbol: int getComdatIndex() const; This patch implements an API as close to that as possible. The implementation on top of the current IRObjectFile is a bit hackish, but should map just fine over a symbol table and is very convenient to use. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285061 91177308-0d34-0410-b5e6-96231b3b80d8 Rafael Espindola 4 years ago
3 changed file(s) with 54 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
105105 // FIXME: Remove the LLVMContext once we have bitcode symbol tables.
106106 LLVMContext Ctx;
107107 std::unique_ptr Obj;
108 std::vector Comdats;
109 DenseMap ComdatMap;
108110
109111 public:
110112 /// Create an InputFile.
123125 friend LTO;
124126
125127 object::basic_symbol_iterator I;
128 const InputFile *File;
126129 const GlobalValue *GV;
127130 uint32_t Flags;
128131 SmallString<64> Name;
153156 }
154157
155158 public:
156 Symbol(object::basic_symbol_iterator I) : I(I) { skip(); }
159 Symbol(object::basic_symbol_iterator I, const InputFile *File)
160 : I(I), File(File) {
161 skip();
162 }
157163
158164 StringRef getName() const { return Name; }
159165 StringRef getIRName() const {
175181 return GV && GV->isThreadLocal();
176182 }
177183
178 Expected getComdat() const {
179 if (!GV)
180 return "";
181 const GlobalObject *GO;
182 if (auto *GA = dyn_cast(GV)) {
183 GO = GA->getBaseObject();
184 if (!GO)
185 return make_error("Unable to determine comdat of alias!",
186 inconvertibleErrorCode());
187 } else {
188 GO = cast(GV);
189 }
190 if (const Comdat *C = GO->getComdat())
191 return C->getName();
192 return "";
193 }
184 // Returns the index of the comdat this symbol is in or -1 if the symbol
185 // is not in a comdat.
186 // FIXME: We have to return Expected because aliases point to an
187 // arbitrary ConstantExpr and that might not actually be a constant. That
188 // means we might not be able to find what an alias is aliased to and
189 // so find its comdat.
190 Expected getComdatIndex() const;
194191
195192 uint64_t getCommonSize() const {
196193 assert(Flags & object::BasicSymbolRef::SF_Common);
211208 Symbol Sym;
212209
213210 public:
214 symbol_iterator(object::basic_symbol_iterator I) : Sym(I) {}
211 symbol_iterator(object::basic_symbol_iterator I, const InputFile *File)
212 : Sym(I, File) {}
215213
216214 symbol_iterator &operator++() {
217215 ++Sym.I;
235233
236234 /// A range over the symbols in this InputFile.
237235 iterator_range symbols() {
238 return llvm::make_range(symbol_iterator(Obj->symbol_begin()),
239 symbol_iterator(Obj->symbol_end()));
236 return llvm::make_range(symbol_iterator(Obj->symbol_begin(), this),
237 symbol_iterator(Obj->symbol_end(), this));
240238 }
241239
242240 StringRef getDataLayoutStr() const {
250248 MemoryBufferRef getMemoryBufferRef() const {
251249 return Obj->getMemoryBufferRef();
252250 }
251
252 // Returns a table with all the comdats used by this file.
253 ArrayRef getComdatTable() const { return Comdats; }
253254 };
254255
255256 /// This class wraps an output stream for a native object. Most clients should
217217
218218 File->Ctx.setDiagnosticHandler(nullptr, nullptr);
219219
220 for (const auto &C : File->Obj->getModule().getComdatSymbolTable()) {
221 auto P =
222 File->ComdatMap.insert(std::make_pair(&C.second, File->Comdats.size()));
223 assert(P.second);
224 File->Comdats.push_back(C.first());
225 }
226
220227 return std::move(File);
228 }
229
230 Expected InputFile::Symbol::getComdatIndex() const {
231 if (!GV)
232 return -1;
233 const GlobalObject *GO;
234 if (auto *GA = dyn_cast(GV)) {
235 GO = GA->getBaseObject();
236 if (!GO)
237 return make_error("Unable to determine comdat of alias!",
238 inconvertibleErrorCode());
239 } else {
240 GO = cast(GV);
241 }
242 if (const Comdat *C = GO->getComdat()) {
243 auto I = File->ComdatMap.find(C);
244 assert(I != File->ComdatMap.end());
245 return I->second;
246 }
247 return -1;
221248 }
222249
223250 LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel,
331358
332359 auto ResI = Res.begin();
333360 for (const InputFile::Symbol &Sym :
334 make_range(InputFile::symbol_iterator(Obj->symbol_begin()),
335 InputFile::symbol_iterator(Obj->symbol_end()))) {
361 make_range(InputFile::symbol_iterator(Obj->symbol_begin(), nullptr),
362 InputFile::symbol_iterator(Obj->symbol_end(), nullptr))) {
336363 assert(ResI != Res.end());
337364 SymbolResolution Res = *ResI++;
338365 addSymbolToGlobalRes(Obj.get(), Used, Sym, Res, 0);
525525
526526 sym.size = 0;
527527 sym.comdat_key = nullptr;
528 StringRef C = check(Sym.getComdat());
529 if (!C.empty())
528 int CI = check(Sym.getComdatIndex());
529 if (CI != -1) {
530 StringRef C = Obj->getComdatTable()[CI];
530531 sym.comdat_key = strdup(C.str().c_str());
532 }
531533
532534 sym.resolution = LDPR_UNKNOWN;
533535 }