diff options
| author | Adrian Prantl <aprantl@apple.com> | 2014-01-07 01:19:08 +0000 |
|---|---|---|
| committer | Adrian Prantl <aprantl@apple.com> | 2014-01-07 01:19:08 +0000 |
| commit | a763447124ba107870865b1c7ba8ad97f0cf78d8 (patch) | |
| tree | 7265d3d7bb8bfc79362b21bdb1e9bd280fa98932 /clang | |
| parent | 0b8e3b2cb41e105a39b9d9b21d6ece18942581cb (diff) | |
| download | bcm5719-llvm-a763447124ba107870865b1c7ba8ad97f0cf78d8.tar.gz bcm5719-llvm-a763447124ba107870865b1c7ba8ad97f0cf78d8.zip | |
Implement a new -fstandalone-debug option. rdar://problem/15685848
It controls everything that -flimit-debug-info used to, plus the
vtable type optimization. The old -fno-limit-debug-info option is now an
alias to -fstandalone-debug and vice versa.
Standalone is the default on Darwin until dtrace is updated to work with
non-standalone debug info (rdar://problem/15758808).
Note: I kept the LimitedDebugInfo name in CodeGenOptions::DebugInfoKind
because NoStandaloneDebugInfo sounded even more confusing.
llvm-svn: 198655
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/docs/tools/clang.pod | 19 | ||||
| -rw-r--r-- | clang/include/clang/Driver/Options.td | 10 | ||||
| -rw-r--r-- | clang/include/clang/Frontend/CodeGenOptions.h | 20 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGDebugInfo.cpp | 12 | ||||
| -rw-r--r-- | clang/lib/Driver/Tools.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 22 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-class-limited.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-class-nolimit.cpp | 4 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-method2.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-namespace.cpp | 6 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-pubtypes.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-template-limit.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-template-member.cpp | 2 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/debug-info-vtable-optzn.cpp | 21 |
15 files changed, 88 insertions, 42 deletions
diff --git a/clang/docs/tools/clang.pod b/clang/docs/tools/clang.pod index c051005c904..1f3a3ec0ac6 100644 --- a/clang/docs/tools/clang.pod +++ b/clang/docs/tools/clang.pod @@ -312,12 +312,19 @@ Currently equivalent to B<-O3> Generate debug information. Note that Clang debug information works best at B<-O0>. -=item B<-flimit-debug-info> B<-fno-limit-debug-info> - -By default Clang does not emit type definitions for types that are not -needed by the module and could be replaced with a forward -declaration. By specifying B<-fno-limit-debug-info> this optimization -can be turned off. Note that Clang will never emit type information +=item B<-fstandalone-debug> B<-fno-standalone-debug> + +Clang supports a number of optimizations to reduce the size of debug +information in the binary. They work based on the assumption that the +debug type information can be spread out over multiple compilation +units. For instance, Clang will not emit type definitions for types +that are not needed by a module and could be replaced with a forward +declaration. Further, Clang will only emit type info for a dynamic +C++ class in the module that contains the vtable for the class. + +The B<-fstandalone-debug> option turns off these optimizations. This +is useful when working with 3rd-party libraries that don't come with +debug information. Note that Clang will never emit type information for types that are not referenced at all by the program. =item B<-fexceptions> diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index b0f0588b343..e1930a2e956 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -559,8 +559,6 @@ def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group> def fkeep_inline_functions : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>; def flat__namespace : Flag<["-"], "flat_namespace">; def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>; -def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Limit debug information produced to reduce size of debug binary">; def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>; def flto : Flag<["-"], "flto">, Group<f_Group>; def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>; @@ -654,8 +652,6 @@ def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Opti def fno_keep_inline_functions : Flag<["-"], "fno-keep-inline-functions">, Group<clang_ignored_f_Group>; def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, Group<f_Group>, HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">, Flags<[CC1Option]>; -def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Do not limit debug information produced to reduce size of debug binary">; def fno_merge_all_constants : Flag<["-"], "fno-merge-all-constants">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disallow merging of constants">; def fno_modules : Flag <["-"], "fno-modules">, Group<f_Group>, @@ -783,6 +779,12 @@ def fno_signed_char : Flag<["-"], "fno-signed-char">, Flags<[CC1Option]>, def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>; def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>; +def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Emit full debug info for all types used by the program">; +def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Limit debug information produced to reduce size of debug binary">; +def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Alias<fno_standalone_debug>; +def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Alias<fstandalone_debug>; def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>; def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable optimizations based on the strict definition of an enum's " diff --git a/clang/include/clang/Frontend/CodeGenOptions.h b/clang/include/clang/Frontend/CodeGenOptions.h index 6c5d399f1e7..da97e5c956b 100644 --- a/clang/include/clang/Frontend/CodeGenOptions.h +++ b/clang/include/clang/Frontend/CodeGenOptions.h @@ -50,12 +50,20 @@ public: }; enum DebugInfoKind { - NoDebugInfo, // Don't generate debug info. - DebugLineTablesOnly, // Emit only debug info necessary for generating - // line number tables (-gline-tables-only). - LimitedDebugInfo, // Limit generated debug info to reduce size - // (-flimit-debug-info). - FullDebugInfo // Generate complete debug info. + NoDebugInfo, /// Don't generate debug info. + + DebugLineTablesOnly, /// Emit only debug info necessary for generating + /// line number tables (-gline-tables-only). + + LimitedDebugInfo, /// Limit generated debug info to reduce size + /// (-fno-standalone-debug). This emits + /// forward decls for types that could be + /// replaced with forward decls in the source + /// code. For dynamic C++ classes type info + /// is only emitted int the module that + /// contains the classe's vtable. + + FullDebugInfo /// Generate complete debug info. }; enum TLSModel { diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index c12e2949bf1..1897627f932 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1464,13 +1464,13 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty) { // declaration. The completeType, completeRequiredType, and completeClassData // callbacks will handle promoting the declaration to a definition. if (T || + // Under -flimit-debug-info: (DebugKind <= CodeGenOptions::LimitedDebugInfo && - // Under -flimit-debug-info, emit only a declaration unless the type is - // required to be complete. - !RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) || - // If the class is dynamic, only emit a declaration. A definition will be - // emitted whenever the vtable is emitted. - (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())) { + // Emit only a forward declaration unless the type is required. + ((!RD->isCompleteDefinitionRequired() && CGM.getLangOpts().CPlusPlus) || + // If the class is dynamic, only emit a declaration. A definition will be + // emitted whenever the vtable is emitted. + (CXXDecl && CXXDecl->hasDefinition() && CXXDecl->isDynamicClass())))) { llvm::DIDescriptor FDContext = getContextDescriptor(cast<Decl>(RD->getDeclContext())); if (!T) diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp index dd2d507a4d5..1ee5e563a2d 100644 --- a/clang/lib/Driver/Tools.cpp +++ b/clang/lib/Driver/Tools.cpp @@ -2945,8 +2945,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // Forward -f (flag) options which we can pass directly. Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); - Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info); - Args.AddLastArg(CmdArgs, options::OPT_fno_limit_debug_info); + Args.AddLastArg(CmdArgs, options::OPT_fstandalone_debug); + Args.AddLastArg(CmdArgs, options::OPT_fno_standalone_debug); Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names); // AltiVec language extensions aren't relevant for assembling. if (!isa<PreprocessJobAction>(JA) || diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 3065e1769b0..dc4aad74b94 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -296,7 +296,8 @@ static void ParseCommentArgs(CommentOptions &Opts, ArgList &Args) { } static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, - DiagnosticsEngine &Diags) { + DiagnosticsEngine &Diags, + const TargetOptions &TargetOpts) { using namespace options; bool Success = true; @@ -323,10 +324,16 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.setDebugInfo(CodeGenOptions::DebugLineTablesOnly); } else if (Args.hasArg(OPT_g_Flag) || Args.hasArg(OPT_gdwarf_2) || Args.hasArg(OPT_gdwarf_3) || Args.hasArg(OPT_gdwarf_4)) { - if (Args.hasFlag(OPT_flimit_debug_info, OPT_fno_limit_debug_info, true)) - Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo); - else + bool Default = false; + // Until dtrace (via CTF) can deal with distributed debug info, + // Darwin defaults to standalone/full debug info. + if (llvm::Triple(TargetOpts.Triple).isOSDarwin()) + Default = true; + + if (Args.hasFlag(OPT_fstandalone_debug, OPT_fno_standalone_debug, Default)) Opts.setDebugInfo(CodeGenOptions::FullDebugInfo); + else + Opts.setDebugInfo(CodeGenOptions::LimitedDebugInfo); } Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info); Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file); @@ -1662,8 +1669,9 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, ParseFileSystemArgs(Res.getFileSystemOpts(), *Args); // FIXME: We shouldn't have to pass the DashX option around here InputKind DashX = ParseFrontendArgs(Res.getFrontendOpts(), *Args, Diags); - Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags) - && Success; + ParseTargetArgs(Res.getTargetOpts(), *Args); + Success = ParseCodeGenArgs(Res.getCodeGenOpts(), *Args, DashX, Diags, + Res.getTargetOpts()) && Success; ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), *Args); if (DashX != IK_AST && DashX != IK_LLVM_IR) { ParseLangArgs(*Res.getLangOpts(), *Args, DashX, Diags); @@ -1678,8 +1686,6 @@ bool CompilerInvocation::CreateFromArgs(CompilerInvocation &Res, ParsePreprocessorArgs(Res.getPreprocessorOpts(), *Args, FileMgr, Diags); ParsePreprocessorOutputArgs(Res.getPreprocessorOutputOpts(), *Args, Res.getFrontendOpts().ProgramAction); - ParseTargetArgs(Res.getTargetOpts(), *Args); - return Success; } diff --git a/clang/test/CodeGenCXX/debug-info-class-limited.cpp b/clang/test/CodeGenCXX/debug-info-class-limited.cpp index a4b9f46ec65..9bf295e9b95 100644 --- a/clang/test/CodeGenCXX/debug-info-class-limited.cpp +++ b/clang/test/CodeGenCXX/debug-info-class-limited.cpp @@ -1,4 +1,4 @@ -// RUN: %clang -emit-llvm -g -S %s -o - | FileCheck %s +// RUN: %clang -emit-llvm -fno-standalone-debug -g -S %s -o - | FileCheck %s namespace PR16214_1 { // CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def] diff --git a/clang/test/CodeGenCXX/debug-info-class-nolimit.cpp b/clang/test/CodeGenCXX/debug-info-class-nolimit.cpp index ce72bd347ca..7a6ee4d441a 100644 --- a/clang/test/CodeGenCXX/debug-info-class-nolimit.cpp +++ b/clang/test/CodeGenCXX/debug-info-class-nolimit.cpp @@ -1,4 +1,6 @@ -// RUN: %clang_cc1 -triple x86_64-unk-unk -fno-limit-debug-info -o - -emit-llvm -g %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unk-unk -fstandalone-debug -o - -emit-llvm -g %s | FileCheck %s +// On Darwin, this should be the default: +// RUN: %clang_cc1 -triple x86_64-apple-darwin -o - -emit-llvm -g %s | FileCheck %s namespace rdar14101097_1 { // see also PR16214 // Check that we emit debug info for the definition of a struct if the diff --git a/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp index 04fe7a03e16..1b9a055527d 100644 --- a/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp +++ b/clang/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -fno-limit-debug-info %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin -fstandalone-debug %s -o - | FileCheck %s class Test { diff --git a/clang/test/CodeGenCXX/debug-info-method2.cpp b/clang/test/CodeGenCXX/debug-info-method2.cpp index a927c49d307..a365312b258 100644 --- a/clang/test/CodeGenCXX/debug-info-method2.cpp +++ b/clang/test/CodeGenCXX/debug-info-method2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -flimit-debug-info -x c++ -g -S -emit-llvm < %s | FileCheck %s +// RUN: %clang_cc1 -fno-standalone-debug -x c++ -g -S -emit-llvm < %s | FileCheck %s // rdar://10336845 // Preserve type qualifiers in -flimit-debug-info mode. diff --git a/clang/test/CodeGenCXX/debug-info-namespace.cpp b/clang/test/CodeGenCXX/debug-info-namespace.cpp index a2d7ede1643..0fec2e45674 100644 --- a/clang/test/CodeGenCXX/debug-info-namespace.cpp +++ b/clang/test/CodeGenCXX/debug-info-namespace.cpp @@ -1,6 +1,6 @@ -// RUN: %clang -g -S -emit-llvm %s -o - | FileCheck %s -// RUN: %clang -g -gline-tables-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s -// RUN: %clang -g -fno-limit-debug-info -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s +// RUN: %clang -g -fno-standalone-debug -S -emit-llvm %s -o - | FileCheck %s +// RUN: %clang -g -gline-tables-only -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-GMLT %s +// RUN: %clang -g -fstandalone-debug -S -emit-llvm %s -o - | FileCheck -check-prefix=CHECK-NOLIMIT %s namespace A { #line 1 "foo.cpp" diff --git a/clang/test/CodeGenCXX/debug-info-pubtypes.cpp b/clang/test/CodeGenCXX/debug-info-pubtypes.cpp index 192a99435bb..4643db0a499 100644 --- a/clang/test/CodeGenCXX/debug-info-pubtypes.cpp +++ b/clang/test/CodeGenCXX/debug-info-pubtypes.cpp @@ -1,5 +1,5 @@ // REQUIRES: x86-registered-target -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -fno-limit-debug-info -S -mllvm -generate-dwarf-pub-sections=Enable %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -g -fstandalone-debug -S -mllvm -generate-dwarf-pub-sections=Enable %s -o - | FileCheck %s // FIXME: This testcase shouldn't rely on assembly emission. //CHECK: Lpubtypes_begin[[SECNUM:[0-9]:]] diff --git a/clang/test/CodeGenCXX/debug-info-template-limit.cpp b/clang/test/CodeGenCXX/debug-info-template-limit.cpp index 34e4373a753..6b158573c00 100644 --- a/clang/test/CodeGenCXX/debug-info-template-limit.cpp +++ b/clang/test/CodeGenCXX/debug-info-template-limit.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -flimit-debug-info -cxx-abi itanium -g %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -fno-standalone-debug -cxx-abi itanium -g %s -o - | FileCheck %s // Check that this pointer type is TC<int> // CHECK: ![[LINE:[0-9]+]] = {{.*}}"TC<int>", {{.*}} metadata !"_ZTS2TCIiE"} ; [ DW_TAG_class_type ] diff --git a/clang/test/CodeGenCXX/debug-info-template-member.cpp b/clang/test/CodeGenCXX/debug-info-template-member.cpp index 9ac1befc101..7a2b4c2b54f 100644 --- a/clang/test/CodeGenCXX/debug-info-template-member.cpp +++ b/clang/test/CodeGenCXX/debug-info-template-member.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s +// RUN: %clang_cc1 -emit-llvm -g -fno-standalone-debug -triple x86_64-apple-darwin %s -o - | FileCheck %s struct MyClass { template <int i> int add(int j) { diff --git a/clang/test/CodeGenCXX/debug-info-vtable-optzn.cpp b/clang/test/CodeGenCXX/debug-info-vtable-optzn.cpp new file mode 100644 index 00000000000..8a6d4ff3e0f --- /dev/null +++ b/clang/test/CodeGenCXX/debug-info-vtable-optzn.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s +// +// This tests that the "emit debug info for a C++ class only in the +// module that has its vtable" optimization is disabled by default on +// Darwin. +// +// CHECK: [ DW_TAG_member ] [lost] +class A +{ + virtual bool f() = 0; + int lost; +}; + +class B : public A +{ + B *g(); +}; + +B *B::g() { + return this; +} |

