Skip to content

Commit 6e975ec

Browse files
committed
Reapply "[DebugInfo] Add flag to only emit referenced member functions" (#93767)
This reverts commit 02c6845, reapplying bfabc95. The patch was reverted due to the test failing on MacOS and Windows where type units aren't supported. This is addressed by limiting type unit flag/test coverage to Linux. Complete C++ type information can be quite expensive - and there's limited value in representing every member function, even those that can't be called (we don't do similarly for every non-member function anyway). So add a flag to opt out of this behavior for experimenting with this more terse behavior. I think Sony already does this by default, so perhaps with a change to the defaults, Sony can migrate to this rather than a downstream patch. This breaks current debuggers in some expected ways - but those breakages are visible without this feature too. Consider member function template instantiations - they can't be consistently enumerated in every translation unit: a.h: ``` struct t1 { template <int i> static int f1() { return i; } }; namespace ns { template <int i> int f1() { return i; } } // namespace ns ``` a.cpp: ``` void f1() { t1::f1<0>(); ns::f1<0>(); } ``` b.cpp: ``` void f1(); int main() { f1(); t1::f1<1>(); ns::f1<1>(); } ``` ``` (gdb) p ns::f1<0>() $1 = 0 (gdb) p ns::f1<1>() $2 = 1 (gdb) p t1::f1<0>() Couldn't find method t1::f1<0> (gdb) p t1::f1<1>() $3 = 1 (gdb) s f1 () at a.cpp:3 3 t1::f1<0>(); (gdb) p t1::f1<0>() $4 = 0 (gdb) p t1::f1<1>() Couldn't find method t1::f1<1> (gdb) ``` (other similar non-canonical features are implicit special members (copy/move ctor/assignment operator, default ctor) and nested types (eg: pimpl idiom, where the nested type is declared-but-not-defined in one TU, and defined in another TU)) lldb can't parse the template expressions above, so I'm not sure how to test it there, but I'd guess it has similar problems. ( https://stackoverflow.com/questions/64602475/how-to-print-value-returned-by-template-member-function-in-gdb-lldb-debugging so... I guess that's just totally not supported in lldb, how unfortunate. And implicit special members are instantiated implicitly by lldb, so missing those doesn't tickle the same issue) Some very rudimentary numbers for a clang debug build: .debug_info section size: -g: 476MiB -g -fdebug-types-section: 357MiB -g -gomit-unreferenced-members: 340MiB Though it also means a major reduction in .debug_str size, -fdebug-types-section doesn't reduce string usage (so the first two examples have the same .debug_str size, 247MiB), down to 175MiB. So for total clang binary size (I don't have a quick "debug section size reduction" on-hand): 1.45 (no type units) GiB -> 1.34 -> 1.22, so it saves about 120MiB of binary size. Original Differential Revision: https://reviews.llvm.org/D152017
1 parent d471860 commit 6e975ec

File tree

6 files changed

+43
-1
lines changed

6 files changed

+43
-1
lines changed

clang/include/clang/Basic/DebugOptions.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ BENIGN_DEBUGOPT(NoInlineLineTables, 1, 0) ///< Whether debug info should contain
6868
///< inline line tables.
6969

7070
DEBUGOPT(DebugStrictDwarf, 1, 1) ///< Whether or not to use strict DWARF info.
71+
DEBUGOPT(DebugOmitUnreferencedMethods, 1, 0) ///< Omit unreferenced member
72+
///< functions in type debug info.
7173

7274
/// Control the Assignment Tracking debug info feature.
7375
BENIGN_ENUM_DEBUGOPT(AssignmentTrackingMode, AssignmentTrackingOpts, 2,

clang/include/clang/Driver/Options.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4345,6 +4345,10 @@ defm strict_dwarf : BoolOption<"g", "strict-dwarf",
43454345
"the specified version, avoiding features from later versions.">,
43464346
NegFlag<SetFalse>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>,
43474347
Group<g_flags_Group>;
4348+
defm omit_unreferenced_methods : BoolGOption<"omit-unreferenced-methods",
4349+
CodeGenOpts<"DebugOmitUnreferencedMethods">, DefaultFalse,
4350+
NegFlag<SetFalse>,
4351+
PosFlag<SetTrue, [], [CC1Option]>, BothFlags<[], [ClangOption, CLOption, DXCOption]>>;
43484352
defm column_info : BoolOption<"g", "column-info",
43494353
CodeGenOpts<"DebugColumnInfo">, DefaultTrue,
43504354
NegFlag<SetFalse, [], [ClangOption, CC1Option]>,

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2836,7 +2836,7 @@ CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
28362836

28372837
// Collect data fields (including static variables and any initializers).
28382838
CollectRecordFields(RD, DefUnit, EltTys, FwdDecl);
2839-
if (CXXDecl)
2839+
if (CXXDecl && !CGM.getCodeGenOpts().DebugOmitUnreferencedMethods)
28402840
CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
28412841

28422842
LexicalBlockStack.pop_back();

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "llvm/ADT/StringExtras.h"
4646
#include "llvm/BinaryFormat/Magic.h"
4747
#include "llvm/Config/llvm-config.h"
48+
#include "llvm/Frontend/Debug/Options.h"
4849
#include "llvm/Object/ObjectFile.h"
4950
#include "llvm/Option/ArgList.h"
5051
#include "llvm/Support/CodeGen.h"
@@ -4642,6 +4643,7 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T,
46424643
Args.addOptInFlag(CmdArgs, options::OPT_fforce_dwarf_frame,
46434644
options::OPT_fno_force_dwarf_frame);
46444645

4646+
bool EnableTypeUnits = false;
46454647
if (Args.hasFlag(options::OPT_fdebug_types_section,
46464648
options::OPT_fno_debug_types_section, false)) {
46474649
if (!(T.isOSBinFormatELF() || T.isOSBinFormatWasm())) {
@@ -4652,11 +4654,24 @@ renderDebugOptions(const ToolChain &TC, const Driver &D, const llvm::Triple &T,
46524654
} else if (checkDebugInfoOption(
46534655
Args.getLastArg(options::OPT_fdebug_types_section), Args, D,
46544656
TC)) {
4657+
EnableTypeUnits = true;
46554658
CmdArgs.push_back("-mllvm");
46564659
CmdArgs.push_back("-generate-type-units");
46574660
}
46584661
}
46594662

4663+
if (const Arg *A =
4664+
Args.getLastArg(options::OPT_gomit_unreferenced_methods,
4665+
options::OPT_gno_omit_unreferenced_methods))
4666+
(void)checkDebugInfoOption(A, Args, D, TC);
4667+
if (Args.hasFlag(options::OPT_gomit_unreferenced_methods,
4668+
options::OPT_gno_omit_unreferenced_methods, false) &&
4669+
(DebugInfoKind == llvm::codegenoptions::DebugInfoConstructor ||
4670+
DebugInfoKind == llvm::codegenoptions::LimitedDebugInfo) &&
4671+
!EnableTypeUnits) {
4672+
CmdArgs.push_back("-gomit-unreferenced-methods");
4673+
}
4674+
46604675
// To avoid join/split of directory+filename, the integrated assembler prefers
46614676
// the directory form of .file on all DWARF versions. GNU as doesn't allow the
46624677
// form before DWARF v5.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -debug-info-kind=limited -gomit-unreferenced-methods %s -emit-llvm -o - | FileCheck %s
2+
3+
struct t1 {
4+
void f1();
5+
void f2();
6+
};
7+
8+
void t1::f1() { }
9+
10+
// CHECK: distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1"
11+
// CHECK-SAME: elements: [[ELEMENTS:![0-9]+]]
12+
// CHECK: [[ELEMENTS]] = !{}

clang/test/Driver/debug-options.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@
242242
// RUN: %clang -### -c %s 2>&1 | FileCheck -check-prefix=NORNGBSE %s
243243
// RUN: %clang -### -c -fdebug-ranges-base-address -fno-debug-ranges-base-address %s 2>&1 | FileCheck -check-prefix=NORNGBSE %s
244244
//
245+
// RUN: %clang -### -c -gomit-unreferenced-methods %s 2>&1 | FileCheck -check-prefix=INCTYPES %s
246+
// RUN: %clang -### -c %s 2>&1 | FileCheck -check-prefix=NOINCTYPES %s
247+
// RUN: %clang -### -c -gomit-unreferenced-methods -fdebug-types-section -target x86_64-unknown-linux %s 2>&1 \
248+
// RUN: | FileCheck -check-prefix=NOINCTYPES %s
249+
// RUN: %clang -### -c -gomit-unreferenced-methods -fstandalone-debug %s 2>&1 | FileCheck -check-prefix=NOINCTYPES %s
250+
//
245251
// RUN: %clang -### -c -glldb %s 2>&1 | FileCheck -check-prefix=NOPUB %s
246252
// RUN: %clang -### -c -glldb -gno-pubnames %s 2>&1 | FileCheck -check-prefix=NOPUB %s
247253
//
@@ -381,6 +387,9 @@
381387
// RNGBSE: -fdebug-ranges-base-address
382388
// NORNGBSE-NOT: -fdebug-ranges-base-address
383389
//
390+
// INCTYPES: -gomit-unreferenced-methods
391+
// NOINCTYPES-NOT: -gomit-unreferenced-methods
392+
//
384393
// GARANGE-DAG: -generate-arange-section
385394
//
386395
// FDTS: "-mllvm" "-generate-type-units"

0 commit comments

Comments
 (0)