[PATCH] D52296: [Clang] - Add '-gsplit-dwarf[=split, =single]' version for '-gsplit-dwarf' option.

2020-07-21 Thread David Blaikie via Phabricator via cfe-commits
dblaikie added a comment.

In D52296#2165370 , @Trass3r wrote:

> In D52296#1285328 , @grimar wrote:
>
> > In D52296#1284130 , @probinson 
> > wrote:
> >
> > > Only DWARF supports this, correct?
> >
> >
> > I am not aware of any kind of debug information splitting except DWARF 
> > splitting.
>
>
> Just for the record, msvc does something very similar to this 
> -gsplit-dwarf=single option (using a linker option /DEBUG:FASTLINK instead of 
> this SHF_EXCLUDE approach).
>
> Some questions:
>
> - How is this handled by dwp/llvm-dwp? I guess not yet since neither supports 
> DWARF5 atm.
> - How does it interact with -gdwarf-5? Should it?


This functionality should be pretty orthogonal to -gdwarf-5 and dwp - though it 
may not be currently, I haven't looked/checked. But seems to me this sort of 
functionality should work with pre-standard/DWARFv4 Split DWARF as well as it 
does with DWARFv5 Split DWARF, unless I'm missing something.

And dwp tools should be made to ignore the non-.dwo-suffixed sections, but they 
may not be made that way currently, I haven't checked.

> - There is some deeply buried information about how gdb requires 
> .debug_gnu_pubnames in the case of split dwarf: 
> https://reviews.llvm.org/D54497?id=173943#1299461. Is this still true for 
> this single split case? I'm asking cause these sections are huge and I wonder 
> if they defeat the split dwarf link time gains.

I believe it still is the case, yes. Though GDB startup times are much better 
with an index with or without Split DWARF - so if you want an index anyway, the 
split (single split, or split split) might still be a good thing independent of 
that. If you have to tradeoff one or the other, yeah, that may be more 
complicated (lld, at least, last I heard, uses more memory to make gdb-index 
than gold does, so while lld's memory usage is less than gold's (& certainly 
less than bfd's) usually, with gdb-index it's a bit worse - so the tradeoffs 
might be more complicated depending on which linker you're using, etc)


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D52296/new/

https://reviews.llvm.org/D52296



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52296: [Clang] - Add '-gsplit-dwarf[=split, =single]' version for '-gsplit-dwarf' option.

2020-07-21 Thread Trass3r via Phabricator via cfe-commits
Trass3r added a comment.
Herald added a subscriber: dang.

In D52296#1285328 , @grimar wrote:

> In D52296#1284130 , @probinson wrote:
>
> > Only DWARF supports this, correct?
>
>
> I am not aware of any kind of debug information splitting except DWARF 
> splitting.


Just for the record, msvc does something very similar to this 
-gsplit-dwarf=single option (using a linker option /DEBUG:FASTLINK instead of 
this SHF_EXCLUDE approach).

Some questions:

- How is this handled by dwp/llvm-dwp? I guess not yet since neither supports 
DWARF5 atm.
- How does it interact with -gdwarf-5? Should it?
- There is some deeply buried information about how gdb requires 
.debug_gnu_pubnames in the case of split dwarf: 
https://reviews.llvm.org/D54497?id=173943#1299461. Is this still true for this 
single split case? I'm asking cause these sections are huge and I wonder if 
they defeat the split dwarf link time gains.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D52296/new/

https://reviews.llvm.org/D52296



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52296: [Clang] - Add '-gsplit-dwarf[=split, =single]' version for '-gsplit-dwarf' option.

2018-11-14 Thread George Rimar via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC346837: [Clang] - Add 
-gsplit-dwarf[=split,=single] version for 
-gsplit-dwarf… (authored by grimar, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D52296?vs=173643=173998#toc

Repository:
  rC Clang

https://reviews.llvm.org/D52296

Files:
  include/clang/Driver/CC1Options.td
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.def
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Driver/ToolChains/CommonArgs.cpp
  lib/Driver/ToolChains/CommonArgs.h
  lib/Driver/ToolChains/Gnu.cpp
  lib/Driver/ToolChains/MinGW.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/split-debug-single-file.c
  test/Driver/split-debug.c
  test/Driver/split-debug.s

Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -596,9 +596,25 @@
   Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro);
   Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables);
   Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std);
-  Opts.EnableSplitDwarf = Args.hasArg(OPT_enable_split_dwarf);
   Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
   Opts.SplitDwarfInlining = !Args.hasArg(OPT_fno_split_dwarf_inlining);
+
+  if (Arg *A =
+  Args.getLastArg(OPT_enable_split_dwarf, OPT_enable_split_dwarf_EQ)) {
+if (A->getOption().matches(options::OPT_enable_split_dwarf)) {
+  Opts.setSplitDwarfMode(CodeGenOptions::SplitFileFission);
+} else {
+  StringRef Name = A->getValue();
+  if (Name == "single")
+Opts.setSplitDwarfMode(CodeGenOptions::SingleFileFission);
+  else if (Name == "split")
+Opts.setSplitDwarfMode(CodeGenOptions::SplitFileFission);
+  else
+Diags.Report(diag::err_drv_invalid_value)
+<< A->getAsString(Args) << Name;
+}
+  }
+
   Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
   Opts.DebugExplicitImport = Args.hasArg(OPT_dwarf_explicit_import);
   Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params);
Index: lib/CodeGen/BackendUtil.cpp
===
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -468,7 +468,7 @@
   Options.EmitStackSizeSection = CodeGenOpts.StackSizeSection;
   Options.EmitAddrsig = CodeGenOpts.Addrsig;
 
-  if (CodeGenOpts.EnableSplitDwarf)
+  if (CodeGenOpts.getSplitDwarfMode() != CodeGenOptions::NoFission)
 Options.MCOptions.SplitDwarfFile = CodeGenOpts.SplitDwarfFile;
   Options.MCOptions.MCRelaxAll = CodeGenOpts.RelaxAll;
   Options.MCOptions.MCSaveTempLabels = CodeGenOpts.SaveTempLabels;
@@ -832,7 +832,8 @@
 break;
 
   default:
-if (!CodeGenOpts.SplitDwarfFile.empty()) {
+if (!CodeGenOpts.SplitDwarfFile.empty() &&
+(CodeGenOpts.getSplitDwarfMode() == CodeGenOptions::SplitFileFission)) {
   DwoOS = openOutputFile(CodeGenOpts.SplitDwarfFile);
   if (!DwoOS)
 return;
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -581,8 +581,11 @@
   CGOpts.EmitVersionIdentMetadata ? Producer : "",
   LO.Optimize || CGOpts.PrepareForLTO || CGOpts.PrepareForThinLTO,
   CGOpts.DwarfDebugFlags, RuntimeVers,
-  CGOpts.EnableSplitDwarf ? "" : CGOpts.SplitDwarfFile, EmissionKind,
-  0 /* DWOid */, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling,
+  (CGOpts.getSplitDwarfMode() != CodeGenOptions::NoFission)
+  ? ""
+  : CGOpts.SplitDwarfFile,
+  EmissionKind, 0 /* DWOid */, CGOpts.SplitDwarfInlining,
+  CGOpts.DebugInfoForProfiling,
   CGM.getTarget().getTriple().isNVPTX()
   ? llvm::DICompileUnit::DebugNameTableKind::None
   : static_cast(
Index: lib/Driver/ToolChains/CommonArgs.cpp
===
--- lib/Driver/ToolChains/CommonArgs.cpp
+++ lib/Driver/ToolChains/CommonArgs.cpp
@@ -808,7 +808,12 @@
   return false;
 }
 
-const char *tools::SplitDebugName(const ArgList , const InputInfo ) {
+const char *tools::SplitDebugName(const ArgList , const InputInfo ,
+  const InputInfo ) {
+  if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
+if (StringRef(A->getValue()) == "single")
+  return Args.MakeArgString(Output.getFilename());
+
   Arg *FinalOutput = Args.getLastArg(options::OPT_o);
   if (FinalOutput && Args.hasArg(options::OPT_c)) {
 SmallString<128> T(FinalOutput->getValue());
Index: lib/Driver/ToolChains/MinGW.cpp
===
--- 

[PATCH] D52296: [Clang] - Add '-gsplit-dwarf[=split, =single]' version for '-gsplit-dwarf' option.

2018-11-13 Thread David Blaikie via Phabricator via cfe-commits
dblaikie accepted this revision.
dblaikie added inline comments.
This revision is now accepted and ready to land.



Comment at: lib/Driver/ToolChains/CommonArgs.cpp:813-830
+  if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
+if (StringRef(A->getValue()) == "single")
+  return Args.MakeArgString(Output.getFilename());
+
   Arg *FinalOutput = Args.getLastArg(options::OPT_o);
   if (FinalOutput && Args.hasArg(options::OPT_c)) {
 SmallString<128> T(FinalOutput->getValue());

grimar wrote:
> grimar wrote:
> > dblaikie wrote:
> > > If this function now takes the output file name - could it be simplified 
> > > to just always use that, rather than the conditional code that follows 
> > > and tests whether -o is specified and builds up something like the output 
> > > file name & uses the dwo suffix?
> > I am investigating this.
> So what I see now is that when the function becomes:
> 
> ```
> const char *tools::SplitDebugName(const ArgList , const InputInfo ,
>   const InputInfo ) {
>   SmallString<128> T(Output.getFilename());
>   llvm::sys::path::replace_extension(T, "dwo");
>   return Args.MakeArgString(T);
> }
> ```
> 
> Then no clang tests (check-clang) fail. This does not seem normal to me.
> I would expect that such a change should break some `-fdebug-compilation-dir` 
> relative 
> logic at least and I suspect we just have no test(s) atm.
> 
> What about if I add test case(s) and post a follow-up refactor patch for this 
> place?
> (I started work on it, but it will take some time).
Sounds good - thanks!



Comment at: test/CodeGen/split-debug-single-file.c:12
+//  RUN:   -enable-split-dwarf=split -split-dwarf-file %t.o -emit-obj -o %t.o 
%s
+//  RUN: llvm-objdump -section-headers %t.o | FileCheck 
--check-prefix=MODE-SPLIT %s
+//  MODE-SPLIT-NOT: .dwo

grimar wrote:
> dblaikie wrote:
> > This looks like an end-to-end test, which we don't usually do in Clang (or 
> > in the LLVM project in general).
> > 
> > For example, the previous testing for split-dwarf had a driver test (that 
> > tested only that the driver produced the right cc1 invocation) and a 
> > CodeGen test (that tested that the right IR was produced), but I don't see 
> > any test like this (that tested the resulting object file)?
> > 
> > I know there's a narrow gap in IR testing - things that don't go in the IR, 
> > but instead go through MCOptions  & that the SplitDwarfFile is one of those.
> > 
> > So, yeah, in this case it's a bit of a test hole - if you're going to keep 
> > this test, perhaps it could test assembly, rather than the object file? 
> > Since it doesn't need complex parsing, etc, perhaps?
> > So, yeah, in this case it's a bit of a test hole - if you're going to keep 
> > this test, perhaps it could test assembly, rather than the object file? 
> > Since it doesn't need complex parsing, etc, perhaps?
> 
> I am not sure assembly can help here. For example
> `clang main.c -S -g -gsplit-dwarf` would create single asm file output anyways
> and what I tried to check here is that we can either place .dwo sections into 
> the
> same output or into a different one depending on new option.
> 
> > For example, the previous testing for split-dwarf had a driver test (that 
> > tested only that the driver produced the right cc1 invocation) and a 
> > CodeGen test (that tested that the right IR was produced), but I don't see 
> > any test like this (that tested the resulting object file)?
> 
> I think `split-debug-filename.c` do that?
> See: 
> https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/split-debug-filename.c#L18
> 
> Also, `relax.c`: 
> https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/relax.c
> And `mips-inline-asm-abi.c`:  
> https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/mips-inline-asm-abi.c
> 
> Seems it is not common, but still acceptable?
Ah, I see/good point, split-debug-filename.c tests both the IR & then also 
tests the object headers.

Sounds good


https://reviews.llvm.org/D52296



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52296: [Clang] - Add '-gsplit-dwarf[=split, =single]' version for '-gsplit-dwarf' option.

2018-11-13 Thread George Rimar via Phabricator via cfe-commits
grimar added inline comments.



Comment at: lib/Driver/ToolChains/CommonArgs.cpp:813-830
+  if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
+if (StringRef(A->getValue()) == "single")
+  return Args.MakeArgString(Output.getFilename());
+
   Arg *FinalOutput = Args.getLastArg(options::OPT_o);
   if (FinalOutput && Args.hasArg(options::OPT_c)) {
 SmallString<128> T(FinalOutput->getValue());

grimar wrote:
> dblaikie wrote:
> > If this function now takes the output file name - could it be simplified to 
> > just always use that, rather than the conditional code that follows and 
> > tests whether -o is specified and builds up something like the output file 
> > name & uses the dwo suffix?
> I am investigating this.
So what I see now is that when the function becomes:

```
const char *tools::SplitDebugName(const ArgList , const InputInfo ,
  const InputInfo ) {
  SmallString<128> T(Output.getFilename());
  llvm::sys::path::replace_extension(T, "dwo");
  return Args.MakeArgString(T);
}
```

Then no clang tests (check-clang) fail. This does not seem normal to me.
I would expect that such a change should break some `-fdebug-compilation-dir` 
relative 
logic at least and I suspect we just have no test(s) atm.

What about if I add test case(s) and post a follow-up refactor patch for this 
place?
(I started work on it, but it will take some time).


https://reviews.llvm.org/D52296



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52296: [Clang] - Add '-gsplit-dwarf[=split, =single]' version for '-gsplit-dwarf' option.

2018-11-13 Thread George Rimar via Phabricator via cfe-commits
grimar added inline comments.



Comment at: lib/Driver/ToolChains/CommonArgs.cpp:813-830
+  if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
+if (StringRef(A->getValue()) == "single")
+  return Args.MakeArgString(Output.getFilename());
+
   Arg *FinalOutput = Args.getLastArg(options::OPT_o);
   if (FinalOutput && Args.hasArg(options::OPT_c)) {
 SmallString<128> T(FinalOutput->getValue());

dblaikie wrote:
> If this function now takes the output file name - could it be simplified to 
> just always use that, rather than the conditional code that follows and tests 
> whether -o is specified and builds up something like the output file name & 
> uses the dwo suffix?
I am investigating this.



Comment at: test/CodeGen/split-debug-single-file.c:12
+//  RUN:   -enable-split-dwarf=split -split-dwarf-file %t.o -emit-obj -o %t.o 
%s
+//  RUN: llvm-objdump -section-headers %t.o | FileCheck 
--check-prefix=MODE-SPLIT %s
+//  MODE-SPLIT-NOT: .dwo

dblaikie wrote:
> This looks like an end-to-end test, which we don't usually do in Clang (or in 
> the LLVM project in general).
> 
> For example, the previous testing for split-dwarf had a driver test (that 
> tested only that the driver produced the right cc1 invocation) and a CodeGen 
> test (that tested that the right IR was produced), but I don't see any test 
> like this (that tested the resulting object file)?
> 
> I know there's a narrow gap in IR testing - things that don't go in the IR, 
> but instead go through MCOptions  & that the SplitDwarfFile is one of those.
> 
> So, yeah, in this case it's a bit of a test hole - if you're going to keep 
> this test, perhaps it could test assembly, rather than the object file? Since 
> it doesn't need complex parsing, etc, perhaps?
> So, yeah, in this case it's a bit of a test hole - if you're going to keep 
> this test, perhaps it could test assembly, rather than the object file? Since 
> it doesn't need complex parsing, etc, perhaps?

I am not sure assembly can help here. For example
`clang main.c -S -g -gsplit-dwarf` would create single asm file output anyways
and what I tried to check here is that we can either place .dwo sections into 
the
same output or into a different one depending on new option.

> For example, the previous testing for split-dwarf had a driver test (that 
> tested only that the driver produced the right cc1 invocation) and a CodeGen 
> test (that tested that the right IR was produced), but I don't see any test 
> like this (that tested the resulting object file)?

I think `split-debug-filename.c` do that?
See: 
https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/split-debug-filename.c#L18

Also, `relax.c`: 
https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/relax.c
And `mips-inline-asm-abi.c`:  
https://github.com/llvm-mirror/clang/blob/master/test/CodeGen/mips-inline-asm-abi.c

Seems it is not common, but still acceptable?


https://reviews.llvm.org/D52296



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52296: [Clang] - Add '-gsplit-dwarf[=split, =single]' version for '-gsplit-dwarf' option.

2018-11-12 Thread David Blaikie via Phabricator via cfe-commits
dblaikie added inline comments.



Comment at: lib/Driver/ToolChains/CommonArgs.cpp:813-830
+  if (Arg *A = Args.getLastArg(options::OPT_gsplit_dwarf_EQ))
+if (StringRef(A->getValue()) == "single")
+  return Args.MakeArgString(Output.getFilename());
+
   Arg *FinalOutput = Args.getLastArg(options::OPT_o);
   if (FinalOutput && Args.hasArg(options::OPT_c)) {
 SmallString<128> T(FinalOutput->getValue());

If this function now takes the output file name - could it be simplified to 
just always use that, rather than the conditional code that follows and tests 
whether -o is specified and builds up something like the output file name & 
uses the dwo suffix?



Comment at: test/CodeGen/split-debug-single-file.c:12
+//  RUN:   -enable-split-dwarf=split -split-dwarf-file %t.o -emit-obj -o %t.o 
%s
+//  RUN: llvm-objdump -section-headers %t.o | FileCheck 
--check-prefix=MODE-SPLIT %s
+//  MODE-SPLIT-NOT: .dwo

This looks like an end-to-end test, which we don't usually do in Clang (or in 
the LLVM project in general).

For example, the previous testing for split-dwarf had a driver test (that 
tested only that the driver produced the right cc1 invocation) and a CodeGen 
test (that tested that the right IR was produced), but I don't see any test 
like this (that tested the resulting object file)?

I know there's a narrow gap in IR testing - things that don't go in the IR, but 
instead go through MCOptions  & that the SplitDwarfFile is one of those.

So, yeah, in this case it's a bit of a test hole - if you're going to keep this 
test, perhaps it could test assembly, rather than the object file? Since it 
doesn't need complex parsing, etc, perhaps?


https://reviews.llvm.org/D52296



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52296: [Clang] - Add '-gsplit-dwarf[=split, =single]' version for '-gsplit-dwarf' option.

2018-11-12 Thread George Rimar via Phabricator via cfe-commits
grimar updated this revision to Diff 173643.
grimar retitled this revision from "[Clang] - Add -fdwarf-fission=split,single 
option." to "[Clang] - Add '-gsplit-dwarf[=split,=single]' version for 
'-gsplit-dwarf' option.".
grimar edited the summary of this revision.
grimar added a comment.

Thanks, David!

Changed:

- Introduced a -gsplit-dwarf[=split,=single] version for '-gsplit-dwarf' option


https://reviews.llvm.org/D52296

Files:
  include/clang/Driver/CC1Options.td
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.def
  include/clang/Frontend/CodeGenOptions.h
  lib/CodeGen/BackendUtil.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Driver/ToolChains/CommonArgs.cpp
  lib/Driver/ToolChains/CommonArgs.h
  lib/Driver/ToolChains/Gnu.cpp
  lib/Driver/ToolChains/MinGW.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGen/split-debug-single-file.c
  test/Driver/split-debug.c
  test/Driver/split-debug.s

Index: test/Driver/split-debug.s
===
--- test/Driver/split-debug.s
+++ test/Driver/split-debug.s
@@ -5,6 +5,13 @@
 //
 // CHECK-ACTIONS: "-split-dwarf-file" "split-debug.dwo"
 
+// Check we pass -split-dwarf-file to `as` if -gsplit-dwarf=split.
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf=split -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-ACTIONS < %t %s
+
+// Check we do not pass any -split-dwarf* commands to `as` if -gsplit-dwarf=single.
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf=single -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-NO-ACTIONS < %t %s
 
 // RUN: %clang -target x86_64-macosx -gsplit-dwarf -c -### %s 2> %t
 // RUN: FileCheck -check-prefix=CHECK-NO-ACTIONS < %t %s
Index: test/Driver/split-debug.c
===
--- test/Driver/split-debug.c
+++ test/Driver/split-debug.c
@@ -5,6 +5,21 @@
 //
 // CHECK-ACTIONS: "-split-dwarf-file" "split-debug.dwo"
 
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-ACTIONS < %t %s
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf=split -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-ACTIONS < %t %s
+
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf=single -c -### %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-ACTIONS-SINGLE-SPLIT < %t %s
+//
+// CHECK-ACTIONS-SINGLE-SPLIT: "-enable-split-dwarf=single"
+// CHECK-ACTIONS-SINGLE-SPLIT: "-split-dwarf-file" "split-debug.o"
+
+// RUN: %clang -target x86_64-unknown-linux-gnu -gsplit-dwarf=single -c -### -o %tfoo.o %s 2> %t
+// RUN: FileCheck -check-prefix=CHECK-SINGLE-SPLIT-FILENAME < %t %s
+//
+// CHECK-SINGLE-SPLIT-FILENAME: "-split-dwarf-file" "{{.*}}foo.o"
 
 // RUN: %clang -target x86_64-macosx -gsplit-dwarf -c -### %s 2> %t
 // RUN: FileCheck -check-prefix=CHECK-NO-ACTIONS < %t %s
Index: test/CodeGen/split-debug-single-file.c
===
--- test/CodeGen/split-debug-single-file.c
+++ test/CodeGen/split-debug-single-file.c
@@ -0,0 +1,17 @@
+// REQUIRES: x86-registered-target
+
+// Testing to ensure -enable-split-dwarf=single allows to place .dwo sections into regular output object.
+//  RUN: %clang_cc1 -debug-info-kind=limited -triple x86_64-unknown-linux \
+//  RUN:   -enable-split-dwarf=single -split-dwarf-file %t.o -emit-obj -o %t.o %s
+//  RUN: llvm-objdump -section-headers %t.o | FileCheck --check-prefix=MODE-SINGLE %s
+//  MODE-SINGLE: .dwo
+
+// Testing to ensure -enable-split-dwarf=single allows to place .dwo sections into regular output object.
+//  RUN: %clang_cc1 -debug-info-kind=limited -triple x86_64-unknown-linux \
+//  RUN:   -enable-split-dwarf=split -split-dwarf-file %t.o -emit-obj -o %t.o %s
+//  RUN: llvm-objdump -section-headers %t.o | FileCheck --check-prefix=MODE-SPLIT %s
+//  MODE-SPLIT-NOT: .dwo
+
+int main (void) {
+  return 0;
+}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -596,9 +596,25 @@
   Opts.MacroDebugInfo = Args.hasArg(OPT_debug_info_macro);
   Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables);
   Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std);
-  Opts.EnableSplitDwarf = Args.hasArg(OPT_enable_split_dwarf);
   Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
   Opts.SplitDwarfInlining = !Args.hasArg(OPT_fno_split_dwarf_inlining);
+
+  if (Arg *A =
+  Args.getLastArg(OPT_enable_split_dwarf, OPT_enable_split_dwarf_EQ)) {
+if (A->getOption().matches(options::OPT_enable_split_dwarf)) {
+  Opts.setSplitDwarfMode(CodeGenOptions::SplitFileFission);
+} else {
+  StringRef Name = A->getValue();
+  if (Name == "single")
+