[clang] 9e239fc - [LinkerWrapper] Emit assembly files from LTO with `save-temps`

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 12 10:55:01 PST 2023


Author: Joseph Huber
Date: 2023-01-12T12:54:53-06:00
New Revision: 9e239fc487d51d6b90ad50f6ffa72203d8df3210

URL: https://github.com/llvm/llvm-project/commit/9e239fc487d51d6b90ad50f6ffa72203d8df3210
DIFF: https://github.com/llvm/llvm-project/commit/9e239fc487d51d6b90ad50f6ffa72203d8df3210.diff

LOG: [LinkerWrapper] Emit assembly files from LTO with `save-temps`

Currently in LTO mode we don't emit any `.s` files for non-NVPTX targets
during LTO. This makes it diffcult to investigate any failures in the
assembly. This patch makes the save-temps mode output an assembly file
and then assembles it separately. I decided to simply invoke `clang` for
this as it would be a lot of effort to invoke the `MCStramer` interface
directly.

Reviewed By: arsenm

Differential Revision: https://reviews.llvm.org/D141543

Added: 
    

Modified: 
    clang/test/Driver/linker-wrapper.c
    clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp

Removed: 
    


################################################################################
diff  --git a/clang/test/Driver/linker-wrapper.c b/clang/test/Driver/linker-wrapper.c
index a455c2cfba285..a313a629cae9e 100644
--- a/clang/test/Driver/linker-wrapper.c
+++ b/clang/test/Driver/linker-wrapper.c
@@ -51,6 +51,16 @@
 
 // AMDGPU-LINK: lld{{.*}}-flavor gnu --no-undefined -shared -plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx908 -o {{.*}}.out {{.*}}.o {{.*}}.o
 
+// RUN: clang-offload-packager -o %t.out \
+// RUN:   --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx1030 \
+// RUN:   --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx1030
+// RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
+// RUN: clang-linker-wrapper --host-triple=x86_64-unknown-linux-gnu --dry-run --save-temps -O2 \
+// RUN:   --linker-path=/usr/bin/ld -- %t.o -o a.out 2>&1 | FileCheck %s --check-prefix=AMDGPU-LTO-TEMPS
+
+// AMDGPU-LTO-TEMPS: clang" -o [[OBJ:.+]] -fPIC -c --target=amdgcn-amd-amdhsa -O2 -mcpu=gfx1030 {{.*}}.s
+// AMDGPU-LTO-TEMPS: lld{{.*}}-flavor gnu --no-undefined -shared -plugin-opt=-amdgpu-internalize-symbols -plugin-opt=mcpu=gfx1030 -o {{.*}}.out {{.*}}.o
+
 // RUN: clang-offload-packager -o %t.out \
 // RUN:   --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908 \
 // RUN:   --image=file=%t.amdgpu.bc,kind=openmp,triple=amdgcn-amd-amdhsa,arch=gfx908

diff  --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 294a84b929b7d..095033e0517ee 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -510,6 +510,42 @@ const char *getLDMOption(const llvm::Triple &T) {
   }
 }
 
+Expected<StringRef> assemble(StringRef InputFile, const ArgList &Args) {
+  llvm::TimeTraceScope TimeScope("Clang Assembler");
+  // Use `clang` to invoke the generic assembler.
+  Expected<std::string> ClangPath =
+      findProgram("clang", {getMainExecutable("clang")});
+  if (!ClangPath)
+    return ClangPath.takeError();
+
+  const llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ));
+  StringRef Arch = Args.getLastArgValue(OPT_arch_EQ);
+  // Create a new file to write the linked device image to. Assume that the
+  // input filename already has the device and architecture.
+  auto TempFileOrErr = createOutputFile(sys::path::stem(InputFile), "o");
+  if (!TempFileOrErr)
+    return TempFileOrErr.takeError();
+
+  StringRef OptLevel = Args.getLastArgValue(OPT_opt_level, "O2");
+  SmallVector<StringRef, 16> CmdArgs{
+      *ClangPath,
+      "-o",
+      *TempFileOrErr,
+      "-fPIC",
+      "-c",
+      Args.MakeArgString("--target=" + Triple.getTriple()),
+      Args.MakeArgString("-" + OptLevel),
+      Triple.isAMDGPU() ? Args.MakeArgString("-mcpu=" + Arch)
+                        : Args.MakeArgString("-march=" + Arch),
+      InputFile,
+  };
+
+  if (Error Err = executeCommands(*ClangPath, CmdArgs))
+    return std::move(Err);
+
+  return *TempFileOrErr;
+}
+
 Expected<StringRef> link(ArrayRef<StringRef> InputFiles, const ArgList &Args) {
   llvm::TimeTraceScope TimeScope("Generic linker");
   const llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ));
@@ -685,7 +721,8 @@ std::unique_ptr<lto::LTO> createLTO(
     };
   }
   Conf.PostOptModuleHook = Hook;
-  Conf.CGFileType = Triple.isNVPTX() ? CGFT_AssemblyFile : CGFT_ObjectFile;
+  Conf.CGFileType =
+      (Triple.isNVPTX() || SaveTemps) ? CGFT_AssemblyFile : CGFT_ObjectFile;
 
   // TODO: Handle remark files
   Conf.HasWholeProgramVisibility = Args.hasArg(OPT_whole_program);
@@ -852,7 +889,7 @@ Error linkBitcodeFiles(SmallVectorImpl<OffloadFile> &InputFiles,
           const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
     int FD = -1;
     auto &TempFile = Files[Task];
-    StringRef Extension = (Triple.isNVPTX()) ? "s" : "o";
+    StringRef Extension = (Triple.isNVPTX() || SaveTemps) ? "s" : "o";
     std::string TaskStr = Task ? "." + std::to_string(Task) : "";
     auto TempFileOrErr =
         createOutputFile(sys::path::filename(ExecutableName) + "-device-" +
@@ -885,9 +922,12 @@ Error linkBitcodeFiles(SmallVectorImpl<OffloadFile> &InputFiles,
   }
 
   // Is we are compiling for NVPTX we need to run the assembler first.
-  if (Triple.isNVPTX()) {
+  if (Triple.isNVPTX() || SaveTemps) {
     for (StringRef &File : Files) {
-      auto FileOrErr = nvptx::assemble(File, Args, !SingleOutput);
+
+      auto FileOrErr = Triple.isNVPTX()
+                           ? nvptx::assemble(File, Args, !SingleOutput)
+                           : generic::assemble(File, Args);
       if (!FileOrErr)
         return FileOrErr.takeError();
       File = *FileOrErr;


        


More information about the cfe-commits mailing list