itessier created this revision. The -fdestroy-globals flag can be used to disable global variable destructor registration. It is intended to be used with embedded code that never exits. Disabling registration allows the linker to garbage collect unused destructors and vtables.
https://reviews.llvm.org/D35338 Files: include/clang/Driver/Options.td include/clang/Frontend/CodeGenOptions.def lib/CodeGen/CGDeclCXX.cpp lib/Driver/ToolChains/Clang.cpp lib/Frontend/CompilerInvocation.cpp test/Driver/fdestroy-globals.cpp
Index: test/Driver/fdestroy-globals.cpp =================================================================== --- /dev/null +++ test/Driver/fdestroy-globals.cpp @@ -0,0 +1,30 @@ +// RUN: %clang -fno-destroy-globals -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-FLAG-DISABLE +// RUN: %clang -fdestroy-globals -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-FLAG-ENABLE1 +// RUN: %clang -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-FLAG-ENABLE2 + +// RUN: %clang_cc1 -fno-destroy-globals -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-CODE-DISABLE +// RUN: %clang_cc1 -fdestroy-globals -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-CODE-ENABLE + +// CHECK-FLAG-DISABLE: "-cc1" +// CHECK-FLAG-DISABLE: "-fno-destroy-globals" + +// CHECK-FLAG-ENABLE1: "-cc1" +// CHECK-FLAG-ENABLE1-NOT: "-fno-destroy-globals" + +// CHECK-FLAG-ENABLE2: "-cc1" +// CHECK-FLAG-ENABLE2-NOT: "-fno-destroy-globals" + +// CHECK-CODE-DISABLE-LABEL: define {{.*}} @__cxx_global_var_init +// CHECK-CODE-DISABLE: call void @_ZN1AC1Ev{{.*}} +// CHECK-CODE-DISABLE: ret void + +// CHECK-CODE-ENABLE-LABEL: define {{.*}} @__cxx_global_var_init +// CHECK-CODE-ENABLE: call void @_ZN1AC1Ev{{.*}} +// CHECK-CODE-ENABLE: %{{.*}} = call i32 @__cxa_atexit{{.*}}_ZN1AD1Ev +// CHECK-CODE-ENABLE: ret void + +struct A { + virtual ~A() {} +}; + +A a; Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -582,6 +582,7 @@ Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); + Opts.DestroyGlobals = !Args.hasArg(OPT_fno_destroy_globals); Opts.CodeModel = getCodeModel(Args, Diags); Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); Opts.DisableFPElim = Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3697,6 +3697,11 @@ KernelOrKext) CmdArgs.push_back("-fno-use-cxa-atexit"); + // -fdestroy-globals=1 is default. + if (!Args.hasFlag(options::OPT_fdestroy_globals, + options::OPT_fno_destroy_globals, true)) + CmdArgs.push_back("-fno-destroy-globals"); + // -fms-extensions=0 is default. if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions, IsWindowsMSVC)) Index: lib/CodeGen/CGDeclCXX.cpp =================================================================== --- lib/CodeGen/CGDeclCXX.cpp +++ lib/CodeGen/CGDeclCXX.cpp @@ -180,7 +180,7 @@ EmitDeclInit(*this, D, DeclAddr); if (CGM.isTypeConstant(D.getType(), true)) EmitDeclInvariant(*this, D, DeclPtr); - else + else if (CGM.getCodeGenOpts().DestroyGlobals) EmitDeclDestroy(*this, D, DeclAddr); return; } Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -44,6 +44,7 @@ CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors. CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker ///< aliases to base ctors when possible. +CODEGENOPT(DestroyGlobals, 1, 1) ///< -fdestroy-globals CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled. CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names. CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled. Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1235,6 +1235,7 @@ HelpText<"Don't use __cxa_atexit for calling destructors">; def fno_use_init_array : Flag<["-"], "fno-use-init-array">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Don't use .init_array instead of .ctors">; +def fno_destroy_globals : Flag<["-"], "fno-destroy-globals">, Group<f_Group>, Flags<[CC1Option]>; def fno_unit_at_a_time : Flag<["-"], "fno-unit-at-a-time">, Group<f_Group>; def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group<f_Group>; def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>; @@ -1465,6 +1466,8 @@ def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>; def fuse_init_array : Flag<["-"], "fuse-init-array">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use .init_array instead of .ctors">; +def fdestroy_globals : Flag<["-"], "fdestroy-globals">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Register global variables for destruction">; def fno_var_tracking : Flag<["-"], "fno-var-tracking">, Group<clang_ignored_f_Group>; def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>; def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>,
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits