HaohaiWen created this revision.
Herald added subscribers: ormris, steven_wu, hiraditya, inglorion.
Herald added a project: All.
HaohaiWen requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay.
Herald added a project: clang.

This patch added /dwodir to lld/COFF which is equivalent to lld/ELF
option -plugin-opt=dwo_dir=. This option tells LTO backend to create
dwo directory and files and all dwo files will be in it. Otherwise all
dwarf sections will be embeded into image even if -gsplit-dwarf is
specified when using LTO.
For Driver, when user specify -gsplit-dwarf and LTO, /dwodir will be
automatically added.

A simple use case:
$clang-cl -c -flto -gdwarf main.c -o main.o
$clang-cl -c -flto -gdwarf a.c -o a.o
$clang-cl -flto -fuse-ld=lld -gdwarf -gsplit-dwarf main.o a.o

This'll generate a dwo file: main.exe_dwo/0.dwo


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154070

Files:
  clang/lib/Driver/ToolChains/MSVC.cpp
  clang/test/Driver/lto-dwo.c
  lld/COFF/Config.h
  lld/COFF/Driver.cpp
  lld/COFF/LTO.cpp
  lld/COFF/Options.td
  lld/test/COFF/lto-debug-fission.ll

Index: lld/test/COFF/lto-debug-fission.ll
===================================================================
--- /dev/null
+++ lld/test/COFF/lto-debug-fission.ll
@@ -0,0 +1,18 @@
+; REQUIRES: x86
+
+; RUN: opt %s -o %t1.o
+; RUN: rm -rf %t.dir
+
+; Test to ensure that -dwodir:$DIR creates .dwo files under $DIR
+; RUN: lld-link -dwodir:%t.dir -noentry -dll %t1.o -out:%t.dll
+; RUN: llvm-readobj -h %t.dir/0.dwo | FileCheck %s
+
+; CHECK: Format: COFF-x86-64
+
+target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-windows-msvc"
+
+define void @f() {
+entry:
+  ret void
+}
Index: lld/COFF/Options.td
===================================================================
--- lld/COFF/Options.td
+++ lld/COFF/Options.td
@@ -42,6 +42,8 @@
 def defaultlib : P<"defaultlib", "Add the library to the list of input files">;
 def delayload : P<"delayload", "Delay loaded DLL name">;
 def diasdkdir : P<"diasdkdir", "Set the location of the DIA SDK">;
+def dwodir : P<"dwodir",
+    "Directory to store .dwo files when LTO and debug fission are used">;
 def entry   : P<"entry", "Name of entry point symbol">;
 def errorlimit : P<"errorlimit",
     "Maximum number of errors to emit before stopping (0 = no limit)">;
Index: lld/COFF/LTO.cpp
===================================================================
--- lld/COFF/LTO.cpp
+++ lld/COFF/LTO.cpp
@@ -84,6 +84,7 @@
   c.DisableVerify = true;
 #endif
   c.DiagHandler = diagnosticHandler;
+  c.DwoDir = ctx.config.dwoDir.str();
   c.OptLevel = ctx.config.ltoo;
   c.CPU = getCPUStr();
   c.MAttrs = getMAttrs();
Index: lld/COFF/Driver.cpp
===================================================================
--- lld/COFF/Driver.cpp
+++ lld/COFF/Driver.cpp
@@ -1910,6 +1910,9 @@
     fatal("/manifestinput: requires /manifest:embed");
   }
 
+  // Handle /dwodir
+  config->dwoDir = args.getLastArgValue(OPT_dwodir);
+
   config->thinLTOEmitImportsFiles = args.hasArg(OPT_thinlto_emit_imports_files);
   config->thinLTOIndexOnly = args.hasArg(OPT_thinlto_index_only) ||
                              args.hasArg(OPT_thinlto_index_only_arg);
Index: lld/COFF/Config.h
===================================================================
--- lld/COFF/Config.h
+++ lld/COFF/Config.h
@@ -203,6 +203,9 @@
   StringRef manifestUIAccess = "'false'";
   StringRef manifestFile;
 
+  // used for /dwodir
+  StringRef dwoDir;
+
   // Used for /aligncomm.
   std::map<std::string, int> alignComm;
 
Index: clang/test/Driver/lto-dwo.c
===================================================================
--- clang/test/Driver/lto-dwo.c
+++ clang/test/Driver/lto-dwo.c
@@ -1,6 +1,9 @@
 // Confirm that -gsplit-dwarf=DIR is passed to linker
 
 // RUN: %clang --target=x86_64-unknown-linux -### %s -flto=thin -gsplit-dwarf -o a.out 2> %t
-// RUN: FileCheck -check-prefix=CHECK-LINK-DWO-DIR-DEFAULT < %t %s
+// RUN: FileCheck -check-prefix=CHECK-LINK-ELF-DWO-DIR-DEFAULT < %t %s
+// RUN: %clang_cl --target=x86_64-unknown-windows-msvc -### -fuse-ld=lld -flto -gsplit-dwarf -o a.out -- %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-LINK-COFF-DWO-DIR-DEFAULT < %t %s
 //
-// CHECK-LINK-DWO-DIR-DEFAULT: "-plugin-opt=dwo_dir=a.out_dwo"
+// CHECK-LINK-ELF-DWO-DIR-DEFAULT:  "-plugin-opt=dwo_dir=a.out_dwo"
+// CHECK-LINK-COFF-DWO-DIR-DEFAULT: "/dwodir:a.out_dwo"
Index: clang/lib/Driver/ToolChains/MSVC.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MSVC.cpp
+++ clang/lib/Driver/ToolChains/MSVC.cpp
@@ -269,6 +269,26 @@
     AddRunTimeLibs(TC, TC.getDriver(), CmdArgs, Args);
   }
 
+  StringRef Linker =
+      Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER);
+  if (Linker.empty())
+    Linker = "link";
+  // We need to translate 'lld' into 'lld-link'.
+  else if (Linker.equals_insensitive("lld"))
+    Linker = "lld-link";
+
+  if (Linker == "lld-link") {
+    for (Arg *A : Args.filtered(options::OPT_vfsoverlay))
+      CmdArgs.push_back(
+          Args.MakeArgString(std::string("/vfsoverlay:") + A->getValue()));
+
+    if (C.getDriver().isUsingLTO() &&
+        Args.hasFlag(options::OPT_gsplit_dwarf, options::OPT_gno_split_dwarf,
+                     false))
+      CmdArgs.push_back(Args.MakeArgString(Twine("/dwodir:") +
+                                           Output.getFilename() + "_dwo"));
+  }
+
   // Add filenames, libraries, and other linker inputs.
   for (const auto &Input : Inputs) {
     if (Input.isFilename()) {
@@ -301,22 +321,9 @@
 
   std::vector<const char *> Environment;
 
-  // We need to special case some linker paths.  In the case of lld, we need to
-  // translate 'lld' into 'lld-link', and in the case of the regular msvc
+  // We need to special case some linker paths. in the case of the regular msvc
   // linker, we need to use a special search algorithm.
   llvm::SmallString<128> linkPath;
-  StringRef Linker
-    = Args.getLastArgValue(options::OPT_fuse_ld_EQ, CLANG_DEFAULT_LINKER);
-  if (Linker.empty())
-    Linker = "link";
-  if (Linker.equals_insensitive("lld"))
-    Linker = "lld-link";
-
-  if (Linker == "lld-link")
-    for (Arg *A : Args.filtered(options::OPT_vfsoverlay))
-      CmdArgs.push_back(
-          Args.MakeArgString(std::string("/vfsoverlay:") + A->getValue()));
-
   if (Linker.equals_insensitive("link")) {
     // If we're using the MSVC linker, it's not sufficient to just use link
     // from the program PATH, because other environments like GnuWin32 install
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to