[cfe-commits] r95508 - in /cfe/trunk: include/clang/Basic/LangOptions.h include/clang/Driver/CC1Options.td include/clang/Driver/Options.td lib/CodeGen/CGDeclCXX.cpp lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp lib/Sema/SemaInit.cpp te
Chandler Carruth
chandlerc at google.com
Sat Feb 6 16:53:50 PST 2010
On Sat, Feb 6, 2010 at 3:23 PM, Anders Carlsson <andersca at mac.com> wrote:
> Author: andersca
> Date: Sat Feb 6 17:23:06 2010
> New Revision: 95508
>
> URL: http://llvm.org/viewvc/llvm-project?rev=95508&view=rev
> Log:
> Add support for threadsafe statics, and make them the default (matching gcc).
Awesome. =D
>
> Daniel, I'd appreciate a review of the driver/cc1 parts.
>
> Added:
> cfe/trunk/test/CodeGenCXX/threadsafe-statics.cpp
> Modified:
> cfe/trunk/include/clang/Basic/LangOptions.h
> cfe/trunk/include/clang/Driver/CC1Options.td
> cfe/trunk/include/clang/Driver/Options.td
> cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
> cfe/trunk/lib/Driver/Tools.cpp
> cfe/trunk/lib/Frontend/CompilerInvocation.cpp
> cfe/trunk/lib/Sema/SemaInit.cpp
>
> Modified: cfe/trunk/include/clang/Basic/LangOptions.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=95508&r1=95507&r2=95508&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/LangOptions.h (original)
> +++ cfe/trunk/include/clang/Basic/LangOptions.h Sat Feb 6 17:23:06 2010
> @@ -136,8 +136,7 @@
>
> SymbolVisibility = (unsigned) Default;
>
> - // FIXME: The default should be 1.
> - ThreadsafeStatics = 0;
> + ThreadsafeStatics = 1;
> POSIXThreads = 0;
> Blocks = 0;
> BlockIntrospection = 0;
>
> Modified: cfe/trunk/include/clang/Driver/CC1Options.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=95508&r1=95507&r2=95508&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Driver/CC1Options.td (original)
> +++ cfe/trunk/include/clang/Driver/CC1Options.td Sat Feb 6 17:23:06 2010
> @@ -115,6 +115,8 @@
> HelpText<"Don't generate implicit floating point instructions (x86-only)">;
> def fno_merge_all_constants : Flag<"-fno-merge-all-constants">,
> HelpText<"Disallow merging of constants.">;
> +def fno_threadsafe_statics : Flag<"-fno-threadsafe-statics">,
> + HelpText<"Do not emit code to make initialization of local statics thread safe">;
> def masm_verbose : Flag<"-masm-verbose">,
> HelpText<"Generate verbose assembly output">;
> def mcode_model : Separate<"-mcode-model">,
>
> Modified: cfe/trunk/include/clang/Driver/Options.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=95508&r1=95507&r2=95508&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Driver/Options.td (original)
> +++ cfe/trunk/include/clang/Driver/Options.td Sat Feb 6 17:23:06 2010
> @@ -311,6 +311,7 @@
> def fno_show_source_location : Flag<"-fno-show-source-location">, Group<f_Group>;
> 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_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>;
> @@ -351,6 +352,7 @@
> def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
> def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
> def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>;
> +def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
> def ftime_report : Flag<"-ftime-report">, Group<f_Group>;
> def ftrapv : Flag<"-ftrapv">, Group<f_Group>;
> def funit_at_a_time : Flag<"-funit-at-a-time">, Group<f_Group>;
>
> Modified: cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDeclCXX.cpp?rev=95508&r1=95507&r2=95508&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGDeclCXX.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDeclCXX.cpp Sat Feb 6 17:23:06 2010
> @@ -184,42 +184,100 @@
> FinishFunction();
> }
>
> +static llvm::Constant *getGuardAcquireFn(CodeGenFunction &CGF) {
> + // int __cxa_guard_acquire(__int64_t *guard_object);
> +
> + const llvm::Type *Int64PtrTy =
> + llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
> +
> + std::vector<const llvm::Type*> Args(1, Int64PtrTy);
> +
> + const llvm::FunctionType *FTy =
> + llvm::FunctionType::get(CGF.ConvertType(CGF.getContext().IntTy),
> + Args, /*isVarArg=*/false);
> +
> + return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_acquire");
> +}
> +
> +static llvm::Constant *getGuardReleaseFn(CodeGenFunction &CGF) {
> + // void __cxa_guard_release(__int64_t *guard_object);
> +
> + const llvm::Type *Int64PtrTy =
> + llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
> +
> + std::vector<const llvm::Type*> Args(1, Int64PtrTy);
> +
> + const llvm::FunctionType *FTy =
> + llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
> + Args, /*isVarArg=*/false);
> +
> + return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_release");
> +}
> +
> +static llvm::Constant *getGuardAbortFn(CodeGenFunction &CGF) {
> + // void __cxa_guard_abort(__int64_t *guard_object);
> +
> + const llvm::Type *Int64PtrTy =
> + llvm::Type::getInt64PtrTy(CGF.getLLVMContext());
> +
> + std::vector<const llvm::Type*> Args(1, Int64PtrTy);
> +
> + const llvm::FunctionType *FTy =
> + llvm::FunctionType::get(llvm::Type::getVoidTy(CGF.getLLVMContext()),
> + Args, /*isVarArg=*/false);
> +
> + return CGF.CGM.CreateRuntimeFunction(FTy, "__cxa_guard_abort");
> +}
> +
> void
> CodeGenFunction::EmitStaticCXXBlockVarDeclInit(const VarDecl &D,
> llvm::GlobalVariable *GV) {
> - // FIXME: This should use __cxa_guard_{acquire,release}?
> -
> - assert(!getContext().getLangOptions().ThreadsafeStatics &&
> - "thread safe statics are currently not supported!");
> -
> + bool ThreadsafeStatics = getContext().getLangOptions().ThreadsafeStatics;
> +
> llvm::SmallString<256> GuardVName;
> CGM.getMangleContext().mangleGuardVariable(&D, GuardVName);
>
> // Create the guard variable.
> - llvm::GlobalValue *GuardV =
> - new llvm::GlobalVariable(CGM.getModule(), llvm::Type::getInt64Ty(VMContext),
> + const llvm::Type *Int64Ty = llvm::Type::getInt64Ty(VMContext);
> + llvm::GlobalValue *GuardVariable =
> + new llvm::GlobalVariable(CGM.getModule(), Int64Ty,
> false, GV->getLinkage(),
> - llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext)),
> + llvm::Constant::getNullValue(Int64Ty),
> GuardVName.str());
>
> // Load the first byte of the guard variable.
> const llvm::Type *PtrTy
> = llvm::PointerType::get(llvm::Type::getInt8Ty(VMContext), 0);
> - llvm::Value *V = Builder.CreateLoad(Builder.CreateBitCast(GuardV, PtrTy),
> - "tmp");
> + llvm::Value *V =
> + Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy), "tmp");
>
> - // Compare it against 0.
> - llvm::Value *nullValue
> - = llvm::Constant::getNullValue(llvm::Type::getInt8Ty(VMContext));
> - llvm::Value *ICmp = Builder.CreateICmpEQ(V, nullValue , "tobool");
> -
> - llvm::BasicBlock *InitBlock = createBasicBlock("init");
> + llvm::BasicBlock *InitCheckBlock = createBasicBlock("init.check");
> llvm::BasicBlock *EndBlock = createBasicBlock("init.end");
>
> - // If the guard variable is 0, jump to the initializer code.
> - Builder.CreateCondBr(ICmp, InitBlock, EndBlock);
> -
> - EmitBlock(InitBlock);
> + // Check if the first byte of the guard variable is zero.
> + Builder.CreateCondBr(Builder.CreateIsNull(V, "tobool"),
> + InitCheckBlock, EndBlock);
> +
> + EmitBlock(InitCheckBlock);
> +
> + if (ThreadsafeStatics) {
> + // Call __cxa_guard_acquire.
> + V = Builder.CreateCall(getGuardAcquireFn(*this), GuardVariable);
> +
> + llvm::BasicBlock *InitBlock = createBasicBlock("init");
> +
> + Builder.CreateCondBr(Builder.CreateIsNotNull(V, "tobool"),
> + InitBlock, EndBlock);
> +
> + EmitBlock(InitBlock);
> +
> + if (Exceptions) {
> + EHCleanupBlock Cleanup(*this);
> +
> + // Call __cxa_guard_abort.
> + Builder.CreateCall(getGuardAbortFn(*this), GuardVariable);
> + }
> + }
>
> if (D.getType()->isReferenceType()) {
> QualType T = D.getType();
> @@ -232,9 +290,14 @@
> } else
> EmitDeclInit(*this, D, GV);
>
> - Builder.CreateStore(llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext),
> - 1),
> - Builder.CreateBitCast(GuardV, PtrTy));
> + if (ThreadsafeStatics) {
> + // Call __cxa_guard_release.
> + Builder.CreateCall(getGuardReleaseFn(*this), GuardVariable);
> + } else {
> + llvm::Value *One =
> + llvm::ConstantInt::get(llvm::Type::getInt8Ty(VMContext), 1);
> + Builder.CreateStore(One, Builder.CreateBitCast(GuardVariable, PtrTy));
> + }
>
> EmitBlock(EndBlock);
> }
>
> Modified: cfe/trunk/lib/Driver/Tools.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=95508&r1=95507&r2=95508&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Driver/Tools.cpp (original)
> +++ cfe/trunk/lib/Driver/Tools.cpp Sat Feb 6 17:23:06 2010
> @@ -1013,6 +1013,11 @@
> isSignedCharDefault(getToolChain().getTriple())))
> CmdArgs.push_back("-fno-signed-char");
>
> + // -fthreadsafe-static is default.
> + if (!Args.hasFlag(options::OPT_fthreadsafe_statics,
> + options::OPT_fno_threadsafe_statics))
> + CmdArgs.push_back("-fno-threadsafe-statics");
> +
> // -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=95508&r1=95507&r2=95508&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
> +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Sat Feb 6 17:23:06 2010
> @@ -480,8 +480,8 @@
> Res.push_back("-fno-builtin");
> if (!Opts.AssumeSaneOperatorNew)
> Res.push_back("-fno-assume-sane-operator-new");
> - if (Opts.ThreadsafeStatics)
> - llvm::llvm_report_error("FIXME: Not yet implemented!");
> + if (!Opts.ThreadsafeStatics)
> + Res.push_back("-fno-threadsafe-statics");
> if (Opts.POSIXThreads)
> Res.push_back("-pthread");
> if (Opts.Blocks)
> @@ -1155,7 +1155,9 @@
> Opts.Microsoft = Args.hasArg(OPT_fms_extensions);
> Opts.WritableStrings = Args.hasArg(OPT_fwritable_strings);
> if (Args.hasArg(OPT_fno_lax_vector_conversions))
> - Opts.LaxVectorConversions = 0;
> + Opts.LaxVectorConversions = 0;
> + if (Args.hasArg(OPT_fno_threadsafe_statics))
> + Opts.ThreadsafeStatics = 0;
> Opts.Exceptions = Args.hasArg(OPT_fexceptions);
> Opts.RTTI = !Args.hasArg(OPT_fno_rtti);
> Opts.Blocks = Args.hasArg(OPT_fblocks);
>
> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=95508&r1=95507&r2=95508&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaInit.cpp Sat Feb 6 17:23:06 2010
> @@ -3005,7 +3005,6 @@
> bool IsCopy) {
> switch (Entity.getKind()) {
> case InitializedEntity::EK_Result:
> - case InitializedEntity::EK_Exception:
> case InitializedEntity::EK_ArrayElement:
> case InitializedEntity::EK_Member:
> return !IsCopy;
> @@ -3014,6 +3013,7 @@
> case InitializedEntity::EK_Variable:
> case InitializedEntity::EK_Base:
> case InitializedEntity::EK_VectorElement:
> + case InitializedEntity::EK_Exception:
> return false;
>
> case InitializedEntity::EK_Parameter:
>
> Added: cfe/trunk/test/CodeGenCXX/threadsafe-statics.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/threadsafe-statics.cpp?rev=95508&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/CodeGenCXX/threadsafe-statics.cpp (added)
> +++ cfe/trunk/test/CodeGenCXX/threadsafe-statics.cpp Sat Feb 6 17:23:06 2010
> @@ -0,0 +1,17 @@
> +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck -check-prefix=WITH-TSS %s
> +// RUN: %clang_cc1 -emit-llvm -o - %s -fno-threadsafe-statics | FileCheck -check-prefix=NO-TSS %s
> +
> +int f();
> +
> +// WITH-TSS: define void @_Z1gv() nounwind
> +// WITH-TSS: call i32 @__cxa_guard_acquire
> +// WITH-TSS: call void @__cxa_guard_release
> +// WITH-TSS: ret void
> +void g() {
> + static int a = f();
> +}
> +
> +// NO-TSS: define void @_Z1gv() nounwind
> +// NO-TSS-NOT: call i32 @__cxa_guard_acquire
> +// NO-TSS-NOT: call void @__cxa_guard_release
> +// NO-TSS: ret void
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list