[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 15:29:54 PDT 2020


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/e645ab5d/attachment.html>


More information about the llvm-commits mailing list