[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

Daniel Dunbar daniel at zuster.org
Sun Feb 7 22:10:31 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).
>
> Daniel, I'd appreciate a review of the driver/cc1 parts.

Looks good to me.

 - Daniel

> 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