From: Peter Collingbourne Date: Fri, 14 Apr 2017 02:55:06 +0000 (+0000) Subject: Object, LTO: Add target triple to irsymtab and LTO API. X-Git-Tag: llvmorg-5.0.0-rc1~7706 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8446f1fe6a5afd89c0f24e5500fce675390ce87b;p=platform%2Fupstream%2Fllvm.git Object, LTO: Add target triple to irsymtab and LTO API. Start using it in LLD to avoid needing to read bitcode again just to get the target triple, and in llvm-lto2 to avoid printing symbol table information that is inappropriate for the target. Differential Revision: https://reviews.llvm.org/D32038 llvm-svn: 300300 --- diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp index f9befa3..cb56e13 100644 --- a/lld/COFF/InputFiles.cpp +++ b/lld/COFF/InputFiles.cpp @@ -19,7 +19,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" -#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/Object/Binary.h" #include "llvm/Object/COFF.h" #include "llvm/Support/COFF.h" @@ -364,10 +363,7 @@ void BitcodeFile::parse() { } MachineTypes BitcodeFile::getMachineType() { - Expected ET = getBitcodeTargetTriple(MB); - if (!ET) - return IMAGE_FILE_MACHINE_UNKNOWN; - switch (Triple(*ET).getArch()) { + switch (Triple(Obj->getTargetTriple()).getArch()) { case Triple::x86_64: return AMD64; case Triple::x86: diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 8c8905a..d651fbc 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -16,7 +16,6 @@ #include "Symbols.h" #include "SyntheticSections.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Bitcode/BitcodeReader.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/IR/LLVMContext.h" @@ -760,15 +759,13 @@ template void SharedFile::parseRest() { } } -static ELFKind getBitcodeELFKind(MemoryBufferRef MB) { - Triple T(check(getBitcodeTargetTriple(MB), MB.getBufferIdentifier())); +static ELFKind getBitcodeELFKind(const Triple &T) { if (T.isLittleEndian()) return T.isArch64Bit() ? ELF64LEKind : ELF32LEKind; return T.isArch64Bit() ? ELF64BEKind : ELF32BEKind; } -static uint8_t getBitcodeMachineKind(MemoryBufferRef MB) { - Triple T(check(getBitcodeTargetTriple(MB), MB.getBufferIdentifier())); +static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) { switch (T.getArch()) { case Triple::aarch64: return EM_AARCH64; @@ -789,15 +786,32 @@ static uint8_t getBitcodeMachineKind(MemoryBufferRef MB) { case Triple::x86_64: return EM_X86_64; default: - fatal(MB.getBufferIdentifier() + - ": could not infer e_machine from bitcode target triple " + T.str()); + fatal(Path + ": could not infer e_machine from bitcode target triple " + + T.str()); } } -BitcodeFile::BitcodeFile(MemoryBufferRef MB, uint64_t OffsetInArchive) - : InputFile(BitcodeKind, MB), OffsetInArchive(OffsetInArchive) { - EKind = getBitcodeELFKind(MB); - EMachine = getBitcodeMachineKind(MB); +BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName, + uint64_t OffsetInArchive) + : InputFile(BitcodeKind, MB) { + this->ArchiveName = ArchiveName; + + // Here we pass a new MemoryBufferRef which is identified by ArchiveName + // (the fully resolved path of the archive) + member name + offset of the + // member in the archive. + // ThinLTO uses the MemoryBufferRef identifier to access its internal + // data structures and if two archives define two members with the same name, + // this causes a collision which result in only one of the objects being + // taken into consideration at LTO time (which very likely causes undefined + // symbols later in the link stage). + MemoryBufferRef MBRef(MB.getBuffer(), + Saver.save(ArchiveName + MB.getBufferIdentifier() + + utostr(OffsetInArchive))); + Obj = check(lto::InputFile::create(MBRef), toString(this)); + + Triple T(Obj->getTargetTriple()); + EKind = getBitcodeELFKind(T); + EMachine = getBitcodeMachineKind(MB.getBufferIdentifier(), T); } static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) { @@ -845,20 +859,6 @@ static Symbol *createBitcodeSymbol(const std::vector &KeptComdats, template void BitcodeFile::parse(DenseSet &ComdatGroups) { - - // Here we pass a new MemoryBufferRef which is identified by ArchiveName - // (the fully resolved path of the archive) + member name + offset of the - // member in the archive. - // ThinLTO uses the MemoryBufferRef identifier to access its internal - // data structures and if two archives define two members with the same name, - // this causes a collision which result in only one of the objects being - // taken into consideration at LTO time (which very likely causes undefined - // symbols later in the link stage). - MemoryBufferRef MBRef(MB.getBuffer(), - Saver.save(ArchiveName + MB.getBufferIdentifier() + - utostr(OffsetInArchive))); - Obj = check(lto::InputFile::create(MBRef), toString(this)); - std::vector KeptComdats; for (StringRef S : Obj->getComdatTable()) KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second); @@ -931,8 +931,9 @@ static bool isBitcode(MemoryBufferRef MB) { InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName, uint64_t OffsetInArchive) { - InputFile *F = isBitcode(MB) ? make(MB, OffsetInArchive) - : createELFFile(MB); + InputFile *F = isBitcode(MB) + ? make(MB, ArchiveName, OffsetInArchive) + : createELFFile(MB); F->ArchiveName = ArchiveName; return F; } diff --git a/lld/ELF/InputFiles.h b/lld/ELF/InputFiles.h index 975f9b4..40a8b23 100644 --- a/lld/ELF/InputFiles.h +++ b/lld/ELF/InputFiles.h @@ -260,19 +260,14 @@ private: class BitcodeFile : public InputFile { public: - BitcodeFile(MemoryBufferRef M, uint64_t OffsetInArchive); + BitcodeFile(MemoryBufferRef M, StringRef ArchiveName, + uint64_t OffsetInArchive); static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; } template void parse(llvm::DenseSet &ComdatGroups); ArrayRef getSymbols() { return Symbols; } std::unique_ptr Obj; - // If this file is in an archive, the member contains the offset of - // the file in the archive. Otherwise, it's just zero. We store this - // field so that we can pass it to lib/LTO in order to disambiguate - // between objects. - uint64_t OffsetInArchive; - private: std::vector Symbols; }; diff --git a/llvm/include/llvm/LTO/LTO.h b/llvm/include/llvm/LTO/LTO.h index 8c08394..3772592 100644 --- a/llvm/include/llvm/LTO/LTO.h +++ b/llvm/include/llvm/LTO/LTO.h @@ -97,7 +97,7 @@ private: // [begin, end) for each module std::vector> ModuleSymIndices; - StringRef SourceFileName, COFFLinkerOpts; + StringRef TargetTriple, SourceFileName, COFFLinkerOpts; std::vector ComdatTable; public: @@ -138,6 +138,9 @@ public: /// Returns the path to the InputFile. StringRef getName() const; + /// Returns the input file's target triple. + StringRef getTargetTriple() const { return TargetTriple; } + /// Returns the source file path specified at compile time. StringRef getSourceFileName() const { return SourceFileName; } diff --git a/llvm/include/llvm/Object/IRSymtab.h b/llvm/include/llvm/Object/IRSymtab.h index 98ef3ff..cde6f3b 100644 --- a/llvm/include/llvm/Object/IRSymtab.h +++ b/llvm/include/llvm/Object/IRSymtab.h @@ -116,7 +116,7 @@ struct Header { Range Symbols; Range Uncommons; - Str SourceFileName; + Str TargetTriple, SourceFileName; /// COFF-specific: linker directives. Str COFFLinkerOpts; @@ -227,6 +227,8 @@ public: /// copied into an irsymtab::Symbol object. symbol_range module_symbols(unsigned I) const; + StringRef getTargetTriple() const { return str(header().TargetTriple); } + /// Returns the source file path specified at compile time. StringRef getSourceFileName() const { return str(header().SourceFileName); } diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index e6fc8cc..9782c89 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -351,6 +351,7 @@ Expected> InputFile::create(MemoryBufferRef Object) { irsymtab::Reader R({Symtab.data(), Symtab.size()}, {File->Strtab.data(), File->Strtab.size()}); + File->TargetTriple = R.getTargetTriple(); File->SourceFileName = R.getSourceFileName(); File->COFFLinkerOpts = R.getCOFFLinkerOpts(); File->ComdatTable = R.getComdatTable(); diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp index f78b84b..da1ef99 100644 --- a/llvm/lib/Object/IRSymtab.cpp +++ b/llvm/lib/Object/IRSymtab.cpp @@ -190,6 +190,7 @@ Error Builder::build(ArrayRef IRMods) { storage::Header Hdr; assert(!IRMods.empty()); + setStr(Hdr.TargetTriple, IRMods[0]->getTargetTriple()); setStr(Hdr.SourceFileName, IRMods[0]->getSourceFileName()); TT = Triple(IRMods[0]->getTargetTriple()); diff --git a/llvm/test/LTO/Resolution/X86/symtab-elf.ll b/llvm/test/LTO/Resolution/X86/symtab-elf.ll new file mode 100644 index 0000000..1683b06 --- /dev/null +++ b/llvm/test/LTO/Resolution/X86/symtab-elf.ll @@ -0,0 +1,15 @@ +; RUN: llvm-as -o %t %s +; RUN: llvm-lto2 dump-symtab %t | FileCheck %s + +; CHECK: target triple: x86_64-unknown-linux-gnu +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +; CHECK-NOT: linker opts: +!0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}} +!llvm.module.flags = !{ !0 } + +@g1 = global i32 0 + +; CHECK-NOT: fallback g1 +@g2 = weak alias i32, i32* @g1 diff --git a/llvm/test/LTO/Resolution/X86/symtab.ll b/llvm/test/LTO/Resolution/X86/symtab.ll index e2729ac..b7bc117 100644 --- a/llvm/test/LTO/Resolution/X86/symtab.ll +++ b/llvm/test/LTO/Resolution/X86/symtab.ll @@ -1,13 +1,14 @@ ; RUN: llvm-as -o %t %s ; RUN: llvm-lto2 dump-symtab %t | FileCheck %s +; CHECK: target triple: i686-pc-windows-msvc18.0.0 target triple = "i686-pc-windows-msvc18.0.0" target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32" ; CHECK: source filename: src.c source_filename = "src.c" -; CHECK: linker opts (COFF only): /include:foo +; CHECK: linker opts: /include:foo !0 = !{i32 6, !"Linker Options", !{!{!"/include:foo"}}} !llvm.module.flags = !{ !0 } diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp index 7a8d405..3d2643d 100644 --- a/llvm/tools/llvm-lto2/llvm-lto2.cpp +++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp @@ -293,8 +293,13 @@ static int dumpSymtab(int argc, char **argv) { std::unique_ptr Input = check(InputFile::create(MB->getMemBufferRef()), F); + outs() << "target triple: " << Input->getTargetTriple() << '\n'; + Triple TT(Input->getTargetTriple()); + outs() << "source filename: " << Input->getSourceFileName() << '\n'; - outs() << "linker opts (COFF only): " << Input->getCOFFLinkerOpts() << '\n'; + + if (TT.isOSBinFormatCOFF()) + outs() << "linker opts: " << Input->getCOFFLinkerOpts() << '\n'; std::vector ComdatTable = Input->getComdatTable(); for (const InputFile::Symbol &Sym : Input->symbols()) { @@ -328,7 +333,7 @@ static int dumpSymtab(int argc, char **argv) { if (Comdat != -1) outs() << " comdat " << ComdatTable[Comdat] << '\n'; - if (Sym.isWeak() && Sym.isIndirect()) + if (TT.isOSBinFormatCOFF() && Sym.isWeak() && Sym.isIndirect()) outs() << " fallback " << Sym.getCOFFWeakExternalFallback() << '\n'; }