[LinkerWrapper] Emit assembly files from LTO with `save-temps`
authorJoseph Huber <jhuber6@vols.utk.edu>
Wed, 11 Jan 2023 20:57:39 +0000 (14:57 -0600)
committerJoseph Huber <jhuber6@vols.utk.edu>
Thu, 12 Jan 2023 18:54:53 +0000 (12:54 -0600)
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

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

index a455c2c..a313a62 100644 (file)
 // 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
 // RUN: %clang -cc1 %s -triple x86_64-unknown-linux-gnu -emit-obj -o %t.o -fembed-offload-object=%t.out
index 294a84b..095033e 100644 (file)
@@ -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;