forked from OSchip/llvm-project
Object: Simplify the IRObjectFile symbol iterator implementation.
Change the IRObjectFile symbol iterator to be a pointer into a vector of PointerUnions representing either IR symbols or asm symbols. This change is in preparation for a future change for supporting multiple modules in an IRObjectFile. Although it causes an increase in memory consumption, we can deal with that issue separately by introducing a bitcode symbol table. Differential Revision: https://reviews.llvm.org/D26928 llvm-svn: 287845
This commit is contained in:
parent
7b54dd039e
commit
e32baa0c3e
|
@ -14,6 +14,7 @@
|
|||
#ifndef LLVM_OBJECT_IROBJECTFILE_H
|
||||
#define LLVM_OBJECT_IROBJECTFILE_H
|
||||
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/Object/SymbolicFile.h"
|
||||
|
||||
namespace llvm {
|
||||
|
@ -28,7 +29,14 @@ class ObjectFile;
|
|||
class IRObjectFile : public SymbolicFile {
|
||||
std::unique_ptr<Module> M;
|
||||
std::unique_ptr<Mangler> Mang;
|
||||
std::vector<std::pair<std::string, uint32_t>> AsmSymbols;
|
||||
typedef std::pair<std::string, uint32_t> AsmSymbol;
|
||||
SpecificBumpPtrAllocator<AsmSymbol> AsmSymbols;
|
||||
|
||||
typedef PointerUnion<GlobalValue *, AsmSymbol *> Sym;
|
||||
std::vector<Sym> SymTab;
|
||||
static Sym getSym(DataRefImpl &Symb) {
|
||||
return *reinterpret_cast<Sym *>(Symb.p);
|
||||
}
|
||||
|
||||
public:
|
||||
IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> M);
|
||||
|
|
|
@ -38,9 +38,18 @@ using namespace object;
|
|||
IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
|
||||
: SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) {
|
||||
Mang.reset(new Mangler());
|
||||
|
||||
for (Function &F : *M)
|
||||
SymTab.push_back(&F);
|
||||
for (GlobalVariable &GV : M->globals())
|
||||
SymTab.push_back(&GV);
|
||||
for (GlobalAlias &GA : M->aliases())
|
||||
SymTab.push_back(&GA);
|
||||
|
||||
CollectAsmUndefinedRefs(Triple(M->getTargetTriple()), M->getModuleInlineAsm(),
|
||||
[this](StringRef Name, BasicSymbolRef::Flags Flags) {
|
||||
AsmSymbols.emplace_back(Name, std::move(Flags));
|
||||
SymTab.push_back(new (AsmSymbols.Allocate())
|
||||
AsmSymbol(Name, Flags));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -124,91 +133,21 @@ void IRObjectFile::CollectAsmUndefinedRefs(
|
|||
}
|
||||
}
|
||||
|
||||
IRObjectFile::~IRObjectFile() {
|
||||
}
|
||||
|
||||
static GlobalValue *getGV(DataRefImpl &Symb) {
|
||||
if ((Symb.p & 3) == 3)
|
||||
return nullptr;
|
||||
|
||||
return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3));
|
||||
}
|
||||
|
||||
static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) {
|
||||
if (I == M.alias_end())
|
||||
return 3;
|
||||
const GlobalValue *GV = &*I;
|
||||
return reinterpret_cast<uintptr_t>(GV) | 2;
|
||||
}
|
||||
|
||||
static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) {
|
||||
if (I == M.global_end())
|
||||
return skipEmpty(M.alias_begin(), M);
|
||||
const GlobalValue *GV = &*I;
|
||||
return reinterpret_cast<uintptr_t>(GV) | 1;
|
||||
}
|
||||
|
||||
static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) {
|
||||
if (I == M.end())
|
||||
return skipEmpty(M.global_begin(), M);
|
||||
const GlobalValue *GV = &*I;
|
||||
return reinterpret_cast<uintptr_t>(GV) | 0;
|
||||
}
|
||||
|
||||
static unsigned getAsmSymIndex(DataRefImpl Symb) {
|
||||
assert((Symb.p & uintptr_t(3)) == 3);
|
||||
uintptr_t Index = Symb.p & ~uintptr_t(3);
|
||||
Index >>= 2;
|
||||
return Index;
|
||||
}
|
||||
IRObjectFile::~IRObjectFile() {}
|
||||
|
||||
void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const {
|
||||
const GlobalValue *GV = getGV(Symb);
|
||||
uintptr_t Res;
|
||||
|
||||
switch (Symb.p & 3) {
|
||||
case 0: {
|
||||
Module::const_iterator Iter(static_cast<const Function*>(GV));
|
||||
++Iter;
|
||||
Res = skipEmpty(Iter, *M);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV));
|
||||
++Iter;
|
||||
Res = skipEmpty(Iter, *M);
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV));
|
||||
++Iter;
|
||||
Res = skipEmpty(Iter, *M);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
unsigned Index = getAsmSymIndex(Symb);
|
||||
assert(Index < AsmSymbols.size());
|
||||
++Index;
|
||||
Res = (Index << 2) | 3;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
llvm_unreachable("unreachable case");
|
||||
}
|
||||
|
||||
Symb.p = Res;
|
||||
Symb.p += sizeof(Sym);
|
||||
}
|
||||
|
||||
std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
|
||||
DataRefImpl Symb) const {
|
||||
const GlobalValue *GV = getGV(Symb);
|
||||
if (!GV) {
|
||||
unsigned Index = getAsmSymIndex(Symb);
|
||||
assert(Index <= AsmSymbols.size());
|
||||
OS << AsmSymbols[Index].first;
|
||||
Sym S = getSym(Symb);
|
||||
if (S.is<AsmSymbol *>()) {
|
||||
OS << S.get<AsmSymbol *>()->first;
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
auto *GV = S.get<GlobalValue *>();
|
||||
if (GV->hasDLLImportStorageClass())
|
||||
OS << "__imp_";
|
||||
|
||||
|
@ -221,13 +160,11 @@ std::error_code IRObjectFile::printSymbolName(raw_ostream &OS,
|
|||
}
|
||||
|
||||
uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
|
||||
const GlobalValue *GV = getGV(Symb);
|
||||
Sym S = getSym(Symb);
|
||||
if (S.is<AsmSymbol *>())
|
||||
return S.get<AsmSymbol *>()->second;
|
||||
|
||||
if (!GV) {
|
||||
unsigned Index = getAsmSymIndex(Symb);
|
||||
assert(Index <= AsmSymbols.size());
|
||||
return AsmSymbols[Index].second;
|
||||
}
|
||||
auto *GV = S.get<GlobalValue *>();
|
||||
|
||||
uint32_t Res = BasicSymbolRef::SF_None;
|
||||
if (GV->isDeclarationForLinker())
|
||||
|
@ -258,22 +195,21 @@ uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
|
|||
return Res;
|
||||
}
|
||||
|
||||
GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); }
|
||||
GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) {
|
||||
return getSym(Symb).dyn_cast<GlobalValue *>();
|
||||
}
|
||||
|
||||
std::unique_ptr<Module> IRObjectFile::takeModule() { return std::move(M); }
|
||||
|
||||
basic_symbol_iterator IRObjectFile::symbol_begin() const {
|
||||
Module::const_iterator I = M->begin();
|
||||
DataRefImpl Ret;
|
||||
Ret.p = skipEmpty(I, *M);
|
||||
Ret.p = reinterpret_cast<uintptr_t>(SymTab.data());
|
||||
return basic_symbol_iterator(BasicSymbolRef(Ret, this));
|
||||
}
|
||||
|
||||
basic_symbol_iterator IRObjectFile::symbol_end() const {
|
||||
DataRefImpl Ret;
|
||||
uint64_t NumAsm = AsmSymbols.size();
|
||||
NumAsm <<= 2;
|
||||
Ret.p = 3 | NumAsm;
|
||||
Ret.p = reinterpret_cast<uintptr_t>(SymTab.data() + SymTab.size());
|
||||
return basic_symbol_iterator(BasicSymbolRef(Ret, this));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue