Index: llvm/include/llvm/Object/IRObjectFile.h =================================================================== --- llvm/include/llvm/Object/IRObjectFile.h +++ llvm/include/llvm/Object/IRObjectFile.h @@ -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 IRObjectFile : public SymbolicFile { std::unique_ptr M; std::unique_ptr Mang; - std::vector> AsmSymbols; + typedef std::pair AsmSymbol; + SpecificBumpPtrAllocator AsmSymbols; + + typedef PointerUnion Sym; + std::vector SymTab; + static Sym getSym(DataRefImpl &Symb) { + return *reinterpret_cast(Symb.p); + } public: IRObjectFile(MemoryBufferRef Object, std::unique_ptr M); Index: llvm/lib/Object/IRObjectFile.cpp =================================================================== --- llvm/lib/Object/IRObjectFile.cpp +++ llvm/lib/Object/IRObjectFile.cpp @@ -38,9 +38,20 @@ IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr 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); + for (GlobalIFunc &GIF : M->ifuncs()) + SymTab.push_back(&GIF); + 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 +135,21 @@ } } -IRObjectFile::~IRObjectFile() { - } - -static GlobalValue *getGV(DataRefImpl &Symb) { - if ((Symb.p & 3) == 3) - return nullptr; - - return reinterpret_cast(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(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(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(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(GV)); - ++Iter; - Res = skipEmpty(Iter, *M); - break; - } - case 1: { - Module::const_global_iterator Iter(static_cast(GV)); - ++Iter; - Res = skipEmpty(Iter, *M); - break; - } - case 2: { - Module::const_alias_iterator Iter(static_cast(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()) { + OS << S.get()->first; return std::error_code(); } + auto *GV = S.get(); if (GV->hasDLLImportStorageClass()) OS << "__imp_"; @@ -221,13 +162,11 @@ } uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { - const GlobalValue *GV = getGV(Symb); + Sym S = getSym(Symb); + if (S.is()) + return S.get()->second; - if (!GV) { - unsigned Index = getAsmSymIndex(Symb); - assert(Index <= AsmSymbols.size()); - return AsmSymbols[Index].second; - } + auto *GV = S.get(); uint32_t Res = BasicSymbolRef::SF_None; if (GV->isDeclarationForLinker()) @@ -258,22 +197,21 @@ return Res; } -GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); } +GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { + return getSym(Symb).dyn_cast(); +} std::unique_ptr IRObjectFile::takeModule() { return std::move(M); } basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { - Module::const_iterator I = M->begin(); DataRefImpl Ret; - Ret.p = skipEmpty(I, *M); + Ret.p = reinterpret_cast(SymTab.data()); return basic_symbol_iterator(BasicSymbolRef(Ret, this)); } basic_symbol_iterator IRObjectFile::symbol_end_impl() const { DataRefImpl Ret; - uint64_t NumAsm = AsmSymbols.size(); - NumAsm <<= 2; - Ret.p = 3 | NumAsm; + Ret.p = reinterpret_cast(SymTab.data() + SymTab.size()); return basic_symbol_iterator(BasicSymbolRef(Ret, this)); } Index: llvm/test/Object/ifunc.ll =================================================================== --- /dev/null +++ llvm/test/Object/ifunc.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as -o - %s | llvm-nm - | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" + +; CHECK: U f +; CHECK: T g + +@g = ifunc void (), void ()* @f +declare void @f()