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:
Peter Collingbourne 2016-11-24 00:41:05 +00:00
parent 7b54dd039e
commit e32baa0c3e
2 changed files with 34 additions and 90 deletions

View File

@ -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);

View File

@ -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));
}