[cfe-commits] r99039 - in /cfe/trunk: include/clang/CodeGen/CodeGenOptions.h include/clang/Driver/CC1Options.td include/clang/Driver/Options.td lib/CodeGen/CGDeclCXX.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGenCXX/deferred-global-init.cpp test/CodeGenCXX/global-dtor-no-atexit.cpp test/CodeGenCXX/global-init.cpp
Daniel Dunbar
daniel at zuster.org
Fri Mar 19 21:15:41 PDT 2010
Author: ddunbar
Date: Fri Mar 19 23:15:41 2010
New Revision: 99039
URL: http://llvm.org/viewvc/llvm-project?rev=99039&view=rev
Log:
C++: Add support for -fno-use-cxa-atexit.
- So much typing, so little gain...
Also, rename the __cxx_global_initialization function just to match llvm-gcc.
Added:
cfe/trunk/test/CodeGenCXX/global-dtor-no-atexit.cpp
Modified:
cfe/trunk/include/clang/CodeGen/CodeGenOptions.h
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/test/CodeGenCXX/deferred-global-init.cpp
cfe/trunk/test/CodeGenCXX/global-init.cpp
Modified: cfe/trunk/include/clang/CodeGen/CodeGenOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CodeGenOptions.h?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/include/clang/CodeGen/CodeGenOptions.h (original)
+++ cfe/trunk/include/clang/CodeGen/CodeGenOptions.h Fri Mar 19 23:15:41 2010
@@ -30,6 +30,9 @@
};
unsigned AsmVerbose : 1; /// -dA, -fverbose-asm.
+ unsigned CXAAtExit : 1; /// Use __cxa_atexit for calling destructors.
+ unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
+ /// aliases to base ctors when possible.
unsigned DebugInfo : 1; /// Should generate deubg info (-g).
unsigned DisableFPElim : 1; /// Set when -fomit-frame-pointer is enabled.
unsigned DisableLLVMOpts : 1; /// Don't run any optimizations, for use in
@@ -53,8 +56,6 @@
unsigned UnwindTables : 1; /// Emit unwind tables.
unsigned VerifyModule : 1; /// Control whether the module should be run
/// through the LLVM Verifier.
- unsigned CXXCtorDtorAliases: 1; /// Emit complete ctors/dtors as linker
- /// aliases to base ctors when possible.
/// The code model to use (-mcmodel).
std::string CodeModel;
@@ -86,6 +87,8 @@
public:
CodeGenOptions() {
AsmVerbose = 0;
+ CXAAtExit = 1;
+ CXXCtorDtorAliases = 0;
DebugInfo = 0;
DisableFPElim = 0;
DisableLLVMOpts = 0;
@@ -103,7 +106,6 @@
UnrollLoops = 0;
UnwindTables = 0;
VerifyModule = 1;
- CXXCtorDtorAliases = 0;
Inlining = NoInlining;
RelocationModel = "pic";
Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Fri Mar 19 23:15:41 2010
@@ -355,10 +355,12 @@
HelpText<"Disable C++ copy constructor elision">;
def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">,
HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">;
-def fno_signed_char : Flag<"-fno-signed-char">,
- HelpText<"Char is unsigned">;
def fno_operator_names : Flag<"-fno-operator-names">,
HelpText<"Do not treat C++ operator name keywords as synonyms for operators">;
+def fno_signed_char : Flag<"-fno-signed-char">,
+ HelpText<"Char is unsigned">;
+def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">,
+ HelpText<"Don't use __cxa_atexit for calling destructors">;
def fconstant_string_class : Separate<"-fconstant-string-class">,
MetaVarName<"<class name>">,
HelpText<"Specify the class to use for constant Objective-C string objects.">;
Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Fri Mar 19 23:15:41 2010
@@ -263,6 +263,7 @@
def fencoding_EQ : Joined<"-fencoding=">, Group<f_Group>;
def fexceptions : Flag<"-fexceptions">, Group<f_Group>;
def fextdirs_EQ : Joined<"-fextdirs=">, Group<f_Group>;
+def fhosted : Flag<"-fhosted">, Group<f_Group>;
def ffreestanding : Flag<"-ffreestanding">, Group<f_Group>;
def fgnu_runtime : Flag<"-fgnu-runtime">, Group<f_Group>;
def fheinous_gnu_extensions : Flag<"-fheinous-gnu-extensions">;
@@ -315,6 +316,7 @@
def fno_stack_protector : Flag<"-fno-stack-protector">, Group<f_Group>;
def fno_strict_aliasing : Flag<"-fno-strict-aliasing">, Group<clang_ignored_f_Group>;
def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">, Group<f_Group>;
+def fno_use_cxa_atexit : Flag<"-fno-use-cxa-atexit">, Group<f_Group>;
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_working_directory : Flag<"-fno-working-directory">, Group<f_Group>;
@@ -363,6 +365,7 @@
def funsigned_bitfields : Flag<"-funsigned-bitfields">, Group<f_Group>;
def funsigned_char : Flag<"-funsigned-char">, Group<f_Group>;
def funwind_tables : Flag<"-funwind-tables">, Group<f_Group>;
+def fuse_cxa_atexit : Flag<"-fuse-cxa-atexit">, Group<f_Group>;
def fverbose_asm : Flag<"-fverbose-asm">, Group<f_Group>;
def fvisibility_EQ : Joined<"-fvisibility=">, Group<f_Group>;
def fwritable_strings : Flag<"-fwritable-strings">, Group<f_Group>;
Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Fri Mar 19 23:15:41 2010
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "CodeGenFunction.h"
+#include "clang/CodeGen/CodeGenOptions.h"
using namespace clang;
using namespace CodeGen;
@@ -89,8 +90,15 @@
"global variable that binds reference to a non-lvalue");
}
-void CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
- llvm::Constant *DeclPtr) {
+void
+CodeGenFunction::EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
+ llvm::Constant *DeclPtr) {
+ // Generate a global destructor entry if not using __cxa_atexit.
+ if (!CGM.getCodeGenOpts().CXAAtExit) {
+ CGM.AddCXXDtorEntry(DtorFn, DeclPtr);
+ return;
+ }
+
const llvm::Type *Int8PtrTy =
llvm::Type::getInt8Ty(VMContext)->getPointerTo();
@@ -123,7 +131,8 @@
Builder.CreateCall(AtExitFn, &Args[0], llvm::array_endof(Args));
}
-void CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) {
+void
+CodeGenModule::EmitCXXGlobalVarDeclInitFunc(const VarDecl *D) {
const llvm::FunctionType *FTy
= llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
false);
@@ -133,18 +142,13 @@
llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
"__cxx_global_var_init", &TheModule);
- StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
- SourceLocation());
-
- llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D);
- EmitCXXGlobalVarDeclInit(*D, DeclPtr);
-
- FinishFunction();
+ CodeGenFunction(*this).GenerateCXXGlobalVarDeclInitFunc(Fn, D);
CXXGlobalInits.push_back(Fn);
}
-void CodeGenModule::EmitCXXGlobalInitFunc() {
+void
+CodeGenModule::EmitCXXGlobalInitFunc() {
if (CXXGlobalInits.empty())
return;
@@ -153,20 +157,73 @@
false);
// Create our global initialization function.
- // FIXME: Should this be tweakable by targets?
llvm::Function *Fn =
llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
- "__cxx_global_initialization", &TheModule);
+ "_GLOBAL__I_a", &TheModule);
+
+ CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn,
+ &CXXGlobalInits[0],
+ CXXGlobalInits.size());
+ AddGlobalCtor(Fn);
+}
+
+void CodeGenModule::AddCXXDtorEntry(llvm::Constant *DtorFn,
+ llvm::Constant *Object) {
+ CXXGlobalDtors.push_back(std::make_pair(DtorFn, Object));
+}
+
+void CodeGenModule::EmitCXXGlobalDtorFunc() {
+ if (CXXGlobalDtors.empty())
+ return;
+
+ const llvm::FunctionType *FTy
+ = llvm::FunctionType::get(llvm::Type::getVoidTy(VMContext),
+ false);
+
+ // Create our global destructor function.
+ llvm::Function *Fn =
+ llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage,
+ "_GLOBAL__D_a", &TheModule);
+
+ CodeGenFunction(*this).GenerateCXXGlobalDtorFunc(Fn, CXXGlobalDtors);
+ AddGlobalDtor(Fn);
+}
+void CodeGenFunction::GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn,
+ const VarDecl *D) {
StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
SourceLocation());
- for (unsigned i = 0, e = CXXGlobalInits.size(); i != e; ++i)
- Builder.CreateCall(CXXGlobalInits[i]);
+ llvm::Constant *DeclPtr = CGM.GetAddrOfGlobalVar(D);
+ EmitCXXGlobalVarDeclInit(*D, DeclPtr);
FinishFunction();
+}
- AddGlobalCtor(Fn);
+void CodeGenFunction::GenerateCXXGlobalInitFunc(llvm::Function *Fn,
+ llvm::Constant **Decls,
+ unsigned NumDecls) {
+ StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
+ SourceLocation());
+
+ for (unsigned i = 0; i != NumDecls; ++i)
+ Builder.CreateCall(Decls[i]);
+
+ FinishFunction();
+}
+
+void CodeGenFunction::GenerateCXXGlobalDtorFunc(llvm::Function *Fn,
+ const std::vector<std::pair<llvm::Constant*, llvm::Constant*> >
+ &DtorsAndObjects) {
+ StartFunction(GlobalDecl(), getContext().VoidTy, Fn, FunctionArgList(),
+ SourceLocation());
+
+ // Emit the dtors, in reverse order from construction.
+ for (unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i)
+ Builder.CreateCall(DtorsAndObjects[e - i - 1].first,
+ DtorsAndObjects[e - i - 1].second);
+
+ FinishFunction();
}
static llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) {
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Fri Mar 19 23:15:41 2010
@@ -1225,6 +1225,20 @@
void EmitCXXGlobalDtorRegistration(llvm::Constant *DtorFn,
llvm::Constant *DeclPtr);
+ /// GenerateCXXGlobalInitFunc - Generates code for initializing global
+ /// variables.
+ void GenerateCXXGlobalInitFunc(llvm::Function *Fn,
+ llvm::Constant **Decls,
+ unsigned NumDecls);
+
+ /// GenerateCXXGlobalDtorFunc - Generates code for destroying global
+ /// variables.
+ void GenerateCXXGlobalDtorFunc(llvm::Function *Fn,
+ const std::vector<std::pair<llvm::Constant*,
+ llvm::Constant*> > &DtorsAndObjects);
+
+ void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D);
+
void EmitCXXConstructExpr(llvm::Value *Dest, const CXXConstructExpr *E);
RValue EmitCXXExprWithTemporaries(const CXXExprWithTemporaries *E,
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Mar 19 23:15:41 2010
@@ -81,6 +81,7 @@
void CodeGenModule::Release() {
EmitDeferred();
EmitCXXGlobalInitFunc();
+ EmitCXXGlobalDtorFunc();
if (Runtime)
if (llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction())
AddGlobalCtor(ObjCInitFunction);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Mar 19 23:15:41 2010
@@ -138,10 +138,14 @@
llvm::StringMap<llvm::Constant*> CFConstantStringMap;
llvm::StringMap<llvm::Constant*> ConstantStringMap;
- /// CXXGlobalInits - Variables with global initializers that need to run
+ /// CXXGlobalInits - Global variables with initializers that need to run
/// before main.
std::vector<llvm::Constant*> CXXGlobalInits;
+ /// CXXGlobalDtors - Global destructor functions and arguments that need to
+ /// run on termination.
+ std::vector<std::pair<llvm::Constant*,llvm::Constant*> > CXXGlobalDtors;
+
/// CFConstantStringClassRef - Cached reference to the class for constant
/// strings. This value has type int * but is actually an Obj-C class pointer.
llvm::Constant *CFConstantStringClassRef;
@@ -321,6 +325,10 @@
void AddAnnotation(llvm::Constant *C) { Annotations.push_back(C); }
+ /// AddCXXDtorEntry - Add a destructor and object to add to the C++ global
+ /// destructor function.
+ void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object);
+
/// CreateRuntimeFunction - Create a new runtime function with the specified
/// type and name.
llvm::Constant *CreateRuntimeFunction(const llvm::FunctionType *Ty,
@@ -496,9 +504,12 @@
/// a C++ destructor Decl.
void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type);
- /// EmitCXXGlobalInitFunc - Emit a function that initializes C++ globals.
+ /// EmitCXXGlobalInitFunc - Emit the function that initializes C++ globals.
void EmitCXXGlobalInitFunc();
+ /// EmitCXXGlobalDtorFunc - Emit the function that destroys C++ globals.
+ void EmitCXXGlobalDtorFunc();
+
void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D);
// FIXME: Hardcoding priority here is gross.
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Fri Mar 19 23:15:41 2010
@@ -1118,6 +1118,11 @@
options::OPT_fno_threadsafe_statics))
CmdArgs.push_back("-fno-threadsafe-statics");
+ // -fuse-cxa-atexit is default.
+ if (!Args.hasFlag(options::OPT_fuse_cxa_atexit,
+ options::OPT_fno_use_cxa_atexit))
+ CmdArgs.push_back("-fno-use-cxa-atexit");
+
// -fms-extensions=0 is default.
if (Args.hasFlag(options::OPT_fms_extensions, options::OPT_fno_ms_extensions,
getToolChain().getTriple().getOS() == llvm::Triple::Win32))
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Mar 19 23:15:41 2010
@@ -154,6 +154,10 @@
Res.push_back("-mcode-model");
Res.push_back(Opts.CodeModel);
}
+ if (!Opts.CXAAtExit)
+ Res.push_back("-fno-use-cxa-atexit");
+ if (Opts.CXXCtorDtorAliases)
+ Res.push_back("-mconstructor-aliases");
if (!Opts.DebugPass.empty()) {
Res.push_back("-mdebug-pass");
Res.push_back(Opts.DebugPass);
@@ -180,8 +184,6 @@
Res.push_back("-mrelocation-model");
Res.push_back(Opts.RelocationModel);
}
- if (Opts.CXXCtorDtorAliases)
- Res.push_back("-mconstructor-aliases");
if (!Opts.VerifyModule)
Res.push_back("-disable-llvm-verifier");
}
@@ -784,6 +786,8 @@
Opts.UnrollLoops = (Opts.OptimizationLevel > 1 && !Opts.OptimizeSize);
Opts.AsmVerbose = Args.hasArg(OPT_masm_verbose);
+ Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit);
+ Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
Opts.CodeModel = getLastArgValue(Args, OPT_mcode_model);
Opts.DebugPass = getLastArgValue(Args, OPT_mdebug_pass);
Opts.DisableFPElim = Args.hasArg(OPT_mdisable_fp_elim);
@@ -794,7 +798,6 @@
Opts.SoftFloat = Args.hasArg(OPT_msoft_float);
Opts.UnwindTables = Args.hasArg(OPT_munwind_tables);
Opts.RelocationModel = getLastArgValue(Args, OPT_mrelocation_model, "pic");
- Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases);
Opts.MainFileName = getLastArgValue(Args, OPT_main_file_name);
Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier);
Modified: cfe/trunk/test/CodeGenCXX/deferred-global-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/deferred-global-init.cpp?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/deferred-global-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/deferred-global-init.cpp Fri Mar 19 23:15:41 2010
@@ -11,6 +11,6 @@
// CHECK: load i8** @foo
// CHECK: ret void
-// CHECK: define internal void @__cxx_global_initialization
+// CHECK: define internal void @_GLOBAL__I_a
// CHECK: call void @__cxx_global_var_init()
// CHECK: ret void
Added: cfe/trunk/test/CodeGenCXX/global-dtor-no-atexit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/global-dtor-no-atexit.cpp?rev=99039&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/global-dtor-no-atexit.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/global-dtor-no-atexit.cpp Fri Mar 19 23:15:41 2010
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64 %s -fno-use-cxa-atexit -emit-llvm -o - | FileCheck %s
+
+// CHECK: define internal void @_GLOBAL__D_a()
+// CHECK: call void @_ZN1AD1Ev(%class.A* @b)
+// CHECK: call void @_ZN1AD1Ev(%class.A* @a)
+// CHECK: }
+
+class A {
+public:
+ A();
+ ~A();
+};
+
+A a, b;
Modified: cfe/trunk/test/CodeGenCXX/global-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/global-init.cpp?rev=99039&r1=99038&r2=99039&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/global-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/global-init.cpp Fri Mar 19 23:15:41 2010
@@ -28,4 +28,4 @@
// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @d, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
D d;
-// CHECK: define internal void @__cxx_global_initialization() {
+// CHECK: define internal void @_GLOBAL__I_a() {
More information about the cfe-commits
mailing list