[llvm] 66b4095 - llvm-link: Add support for archive files as inputs
Richard Smith via llvm-commits
llvm-commits at lists.llvm.org
Tue Jul 14 17:08:15 PDT 2020
Fixed in f49edafd9abf75aaa7d9254c345026620e69b5ce. Please double-check
that's what you intended.
On Tue, 14 Jul 2020 at 15:29, Richard Smith <richard at metafoo.co.uk> wrote:
> On Tue, 14 Jul 2020 at 12:32, Jan Sjodin via llvm-commits <
> llvm-commits at lists.llvm.org> wrote:
>
>>
>> Author: Jan Sjodin
>> Date: 2020-07-14T15:30:59-04:00
>> New Revision: 66b409582a1d349a3ce5480237aeab92dd5ebde1
>>
>> URL:
>> https://github.com/llvm/llvm-project/commit/66b409582a1d349a3ce5480237aeab92dd5ebde1
>> DIFF:
>> https://github.com/llvm/llvm-project/commit/66b409582a1d349a3ce5480237aeab92dd5ebde1.diff
>>
>> LOG: llvm-link: Add support for archive files as inputs
>>
>> This patch adds support for archive files as inputs to llvm-link. One
>> of the use-cases is for OpenMP, where device specific libraries need
>> to be extracted from libraries containing bundled object files. The
>> clang-offload-bundler will support extracting these archives, which
>> will be passed into llvm-link, see https://reviews.llvm.org/D80816.
>>
>> Reviewed By: jdoerfert
>>
>> Differential Revision: https://reviews.llvm.org/D81109
>>
>> Added:
>> llvm/test/tools/llvm-link/Inputs/f.ll
>> llvm/test/tools/llvm-link/Inputs/g.ll
>> llvm/test/tools/llvm-link/Inputs/h.ll
>> llvm/test/tools/llvm-link/archive-bad.ll
>> llvm/test/tools/llvm-link/archive.ll
>> llvm/test/tools/llvm-link/archivell.ll
>>
>> Modified:
>> llvm/tools/llvm-link/llvm-link.cpp
>>
>> Removed:
>>
>>
>>
>>
>> ################################################################################
>> diff --git a/llvm/test/tools/llvm-link/Inputs/f.ll
>> b/llvm/test/tools/llvm-link/Inputs/f.ll
>> new file mode 100644
>> index 000000000000..a7cdacea82fb
>> --- /dev/null
>> +++ b/llvm/test/tools/llvm-link/Inputs/f.ll
>> @@ -0,0 +1,6 @@
>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>> +
>> +define void @f() {
>> +entry:
>> + ret void
>> +}
>>
>> diff --git a/llvm/test/tools/llvm-link/Inputs/g.ll
>> b/llvm/test/tools/llvm-link/Inputs/g.ll
>> new file mode 100644
>> index 000000000000..b81de922b4da
>> --- /dev/null
>> +++ b/llvm/test/tools/llvm-link/Inputs/g.ll
>> @@ -0,0 +1,6 @@
>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>> +
>> +define void @g() {
>> +entry:
>> + ret void
>> +}
>>
>> diff --git a/llvm/test/tools/llvm-link/Inputs/h.ll
>> b/llvm/test/tools/llvm-link/Inputs/h.ll
>> new file mode 100644
>> index 000000000000..c2bda1712a40
>> --- /dev/null
>> +++ b/llvm/test/tools/llvm-link/Inputs/h.ll
>> @@ -0,0 +1,6 @@
>> +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>> +
>> +define void @h() {
>> +entry:
>> + ret void
>> +}
>>
>> diff --git a/llvm/test/tools/llvm-link/archive-bad.ll
>> b/llvm/test/tools/llvm-link/archive-bad.ll
>> new file mode 100644
>> index 000000000000..80ce6fc1fe0d
>> --- /dev/null
>> +++ b/llvm/test/tools/llvm-link/archive-bad.ll
>> @@ -0,0 +1,7 @@
>> +# RUN: cp %S/Inputs/f.ll %t.fg.a
>> +# RUN: not llvm-link %S/Inputs/h.ll %t.fg.a -o %t.linked.bc 2>&1 |
>> FileCheck %s
>> +
>> +# RUN: rm -f %t.fg.a
>> +# RUN: rm -f %t.linked.bc
>> +
>> +# CHECK: file too small to be an archive
>>
>> diff --git a/llvm/test/tools/llvm-link/archive.ll
>> b/llvm/test/tools/llvm-link/archive.ll
>> new file mode 100644
>> index 000000000000..10ab83a3d5be
>> --- /dev/null
>> +++ b/llvm/test/tools/llvm-link/archive.ll
>> @@ -0,0 +1,17 @@
>> +# RUN: llvm-as %S/Inputs/f.ll -o %t.f.bc
>> +# RUN: llvm-as %S/Inputs/g.ll -o %t.g.bc
>> +# RUN: llvm-ar cr %t.fg.a %t.f.bc %t.g.bc
>> +# RUN: llvm-ar cr %t.empty.a
>> +# RUN: llvm-link %S/Inputs/h.ll %t.fg.a %t.empty.a -o %t.linked.bc
>> +
>> +# RUN: llvm-nm %t.linked.bc | FileCheck %s
>> +
>> +# RUN: rm -f %t.f.bc
>> +# RUN: rm -f %t.g.bc
>> +# RUN: rm -f %t.fg.a
>> +# RUN: rm -f %t.empty.a
>> +# RUN: rm -f %t.linked.bc
>> +
>> +# CHECK: -------- T f
>> +# CHECK: -------- T g
>> +# CHECK: -------- T h
>>
>> diff --git a/llvm/test/tools/llvm-link/archivell.ll
>> b/llvm/test/tools/llvm-link/archivell.ll
>> new file mode 100644
>> index 000000000000..7474df14e907
>> --- /dev/null
>> +++ b/llvm/test/tools/llvm-link/archivell.ll
>> @@ -0,0 +1,7 @@
>> +# RUN: llvm-ar cr %t.fg.a %S/Inputs/f.ll llvm-as %S/Inputs/g.ll
>>
>
> Did you really mean to include the 'llvm-as' binary in the archive here?
> This is causing this test to break in our test environment.
>
>
>> +# RUN: not llvm-link %S/Inputs/h.ll %t.fg.a -o %t.linked.bc 2>&1 |
>> FileCheck %s
>> +
>> +# RUN: rm -f %t.fg.a
>> +# RUN: rm -f %t.linked.bc
>> +
>> +# CHECK: error: member of archive is not a bitcode file
>>
>> diff --git a/llvm/tools/llvm-link/llvm-link.cpp
>> b/llvm/tools/llvm-link/llvm-link.cpp
>> index a7cda24bbe0a..7141bd1ca7a1 100644
>> --- a/llvm/tools/llvm-link/llvm-link.cpp
>> +++ b/llvm/tools/llvm-link/llvm-link.cpp
>> @@ -11,6 +11,7 @@
>> //
>>
>> //===----------------------------------------------------------------------===//
>>
>> +#include "llvm/Object/Archive.h"
>> #include "llvm/ADT/STLExtras.h"
>> #include "llvm/Bitcode/BitcodeReader.h"
>> #include "llvm/Bitcode/BitcodeWriter.h"
>> @@ -139,6 +140,73 @@ static std::unique_ptr<Module> loadFile(const char
>> *argv0,
>> return Result;
>> }
>>
>> +static std::unique_ptr<Module> loadArFile(const char *Argv0,
>> + const std::string &ArchiveName,
>> + LLVMContext &Context, Linker
>> &L,
>> + unsigned OrigFlags,
>> + unsigned ApplicableFlags) {
>> + std::unique_ptr<Module> Result(new Module("ArchiveModule", Context));
>> + if (Verbose)
>> + errs() << "Reading library archive file '" << ArchiveName
>> + << "' to memory\n";
>> + ErrorOr<std::unique_ptr<MemoryBuffer>> Buf =
>> + MemoryBuffer::getFile(ArchiveName, -1, false);
>> + ExitOnErr(errorCodeToError(Buf.getError()));
>> + Error Err = Error::success();
>> + object::Archive Archive(Buf.get()->getMemBufferRef(), Err);
>> + ExitOnErr(std::move(Err));
>> + for (const object::Archive::Child &C : Archive.children(Err)) {
>> + Expected<StringRef> Ename = C.getName();
>> + if (Error E = Ename.takeError()) {
>> + errs() << Argv0 << ": ";
>> + WithColor::error()
>> + << " failed to read name of archive member"
>> + << ArchiveName << "'\n";
>> + return nullptr;
>> + };
>> + std::string ChildName = Ename.get().str();
>> + if (Verbose)
>> + errs() << "Parsing member '" << ChildName
>> + << "' of archive library to module.\n";
>> + SMDiagnostic ParseErr;
>> + Expected<MemoryBufferRef> MemBuf = C.getMemoryBufferRef();
>> + if (Error E = MemBuf.takeError()) {
>> + errs() << Argv0 << ": ";
>> + WithColor::error() << " loading memory for member '" << ChildName
>> + << "' of archive library failed'" << ArchiveName
>> + << "'\n";
>> + return nullptr;
>> + };
>> +
>> + if (!isBitcode(reinterpret_cast<const unsigned char *>
>> + (MemBuf.get().getBufferStart()),
>> + reinterpret_cast<const unsigned char *>
>> + (MemBuf.get().getBufferEnd()))) {
>> + errs() << Argv0 << ": ";
>> + WithColor::error() << " member of archive is not a bitcode file:
>> '"
>> + << ChildName << "'\n";
>> + return nullptr;
>> + }
>> +
>> + std::unique_ptr<Module> M = parseIR(MemBuf.get(), ParseErr, Context);
>> +
>> + if (!M.get()) {
>> + errs() << Argv0 << ": ";
>> + WithColor::error() << " parsing member '" << ChildName
>> + << "' of archive library failed'" << ArchiveName
>> + << "'\n";
>> + return nullptr;
>> + }
>> + if (Verbose)
>> + errs() << "Linking member '" << ChildName << "' of archive
>> library.\n";
>> + if (L.linkModules(*Result, std::move(M), ApplicableFlags))
>> + return nullptr;
>> + ApplicableFlags = OrigFlags;
>> + } // end for each child
>> + ExitOnErr(std::move(Err));
>> + return Result;
>> +}
>> +
>> namespace {
>>
>> /// Helper to load on demand a Module from file and cache it for
>> subsequent
>> @@ -281,7 +349,10 @@ static bool linkFiles(const char *argv0, LLVMContext
>> &Context, Linker &L,
>> // Similar to some flags, internalization doesn't apply to the first
>> file.
>> bool InternalizeLinkedSymbols = false;
>> for (const auto &File : Files) {
>> - std::unique_ptr<Module> M = loadFile(argv0, File, Context);
>> + std::unique_ptr<Module> M =
>> + (llvm::sys::path::extension(File) == ".a")
>> + ? loadArFile(argv0, File, Context, L, Flags, ApplicableFlags)
>> + : loadFile(argv0, File, Context);
>> if (!M.get()) {
>> errs() << argv0 << ": ";
>> WithColor::error() << " loading file '" << File << "'\n";
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200714/a3e77626/attachment.html>
More information about the llvm-commits
mailing list