[cfe-commits] r159336 - in /cfe/trunk: docs/tools/clang.pod include/clang/Driver/Options.td include/clang/Frontend/CodeGenOptions.h lib/CodeGen/CGDecl.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/tls-model.c

Hans Wennborg hans at hanshq.net
Thu Jun 28 01:01:45 PDT 2012


Author: hans
Date: Thu Jun 28 03:01:44 2012
New Revision: 159336

URL: http://llvm.org/viewvc/llvm-project?rev=159336&view=rev
Log:
Add -ftls-model command-line flag.

This allows for setting the default TLS model. (PR9788)

Added:
    cfe/trunk/test/CodeGen/tls-model.c
Modified:
    cfe/trunk/docs/tools/clang.pod
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/include/clang/Frontend/CodeGenOptions.h
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp

Modified: cfe/trunk/docs/tools/clang.pod
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/tools/clang.pod?rev=159336&r1=159335&r2=159336&view=diff
==============================================================================
--- cfe/trunk/docs/tools/clang.pod (original)
+++ cfe/trunk/docs/tools/clang.pod Thu Jun 28 03:01:44 2012
@@ -303,6 +303,14 @@
 This flag specifies that variables without initializers get common linkage.  It
 can be disabled with B<-fno-common>.
 
+=item B<-ftls-model>
+
+Set the default thread-local storage (TLS) model to use for thread-local
+variables. Valid values are: "global-dynamic", "local-dynamic", "initial-exec"
+and "local-exec". The default is "global-dynamic". The default model can be
+overridden with the tls_model attribute. The compiler will try to choose a more
+efficient model if possible.
+
 =item B<-flto> B<-emit-llvm>
 
 Generate output files in LLVM formats, suitable for link time optimization. When

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=159336&r1=159335&r2=159336&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Thu Jun 28 03:01:44 2012
@@ -648,6 +648,7 @@
 def fterminated_vtables : Flag<"-fterminated-vtables">, Alias<fapple_kext>;
 def fthreadsafe_statics : Flag<"-fthreadsafe-statics">, Group<f_Group>;
 def ftime_report : Flag<"-ftime-report">, Group<f_Group>, Flags<[CC1Option]>;
+def ftlsmodel_EQ : Joined<"-ftls-model=">, Group<f_Group>, Flags<[CC1Option]>;
 def ftrapv : Flag<"-ftrapv">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Trap on integer overflow">;
 def ftrapv_handler_EQ : Joined<"-ftrapv-handler=">, Group<f_Group>,

Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.h?rev=159336&r1=159335&r2=159336&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CodeGenOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/CodeGenOptions.h Thu Jun 28 03:01:44 2012
@@ -44,6 +44,13 @@
     FullDebugInfo         // Generate complete debug info.
   };
 
+  enum TLSModel {
+    GeneralDynamicTLSModel,
+    LocalDynamicTLSModel,
+    InitialExecTLSModel,
+    LocalExecTLSModel
+  };
+
   unsigned AsmVerbose        : 1; ///< -dA, -fverbose-asm.
   unsigned ObjCAutoRefCountExceptions : 1; ///< Whether ARC should be EH-safe.
   unsigned CUDAIsDevice      : 1; ///< Set when compiling for CUDA device.
@@ -175,6 +182,9 @@
   /// The run-time penalty for bounds checking, or 0 to disable.
   unsigned char BoundsChecking;
 
+  /// The default TLS model to use.
+  TLSModel DefaultTLSModel;
+
 public:
   CodeGenOptions() {
     AsmVerbose = 0;
@@ -231,6 +241,7 @@
     DebugInfo = NoDebugInfo;
     Inlining = NoInlining;
     RelocationModel = "pic";
+    DefaultTLSModel = GeneralDynamicTLSModel;
   }
 
   ObjCDispatchMethodKind getObjCDispatchMethod() const {

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=159336&r1=159335&r2=159336&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Thu Jun 28 03:01:44 2012
@@ -183,26 +183,20 @@
   else
     Name = GetStaticDeclName(*this, D, Separator);
 
-  llvm::GlobalVariable::ThreadLocalMode TLM;
-  TLM = D.isThreadSpecified() ? llvm::GlobalVariable::GeneralDynamicTLSModel
-                              : llvm::GlobalVariable::NotThreadLocal;
-
-  // Set the TLS mode if it it's explicitly specified.
-  if (D.hasAttr<TLSModelAttr>()) {
-    assert(D.isThreadSpecified() && "Can't have TLS model on non-tls var.");
-    const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>();
-    TLM = CodeGenModule::GetLLVMTLSModel(Attr->getModel());
-  }
-
   llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(Ty);
   llvm::GlobalVariable *GV =
     new llvm::GlobalVariable(CGM.getModule(), LTy,
                              Ty.isConstant(getContext()), Linkage,
-                             CGM.EmitNullConstant(D.getType()), Name, 0, TLM,
+                             CGM.EmitNullConstant(D.getType()), Name, 0,
+                             llvm::GlobalVariable::NotThreadLocal,
                              CGM.getContext().getTargetAddressSpace(Ty));
   GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
   if (Linkage != llvm::GlobalValue::InternalLinkage)
     GV->setVisibility(CurFn->getVisibility());
+
+  if (D.isThreadSpecified())
+    CGM.setTLSMode(GV, D);
+
   return GV;
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=159336&r1=159335&r2=159336&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Jun 28 03:01:44 2012
@@ -258,6 +258,45 @@
     GV->setVisibility(GetLLVMVisibility(LV.visibility()));
 }
 
+static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
+  return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
+      .Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
+      .Case("local-dynamic", llvm::GlobalVariable::LocalDynamicTLSModel)
+      .Case("initial-exec", llvm::GlobalVariable::InitialExecTLSModel)
+      .Case("local-exec", llvm::GlobalVariable::LocalExecTLSModel);
+}
+
+static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(
+    CodeGenOptions::TLSModel M) {
+  switch (M) {
+  case CodeGenOptions::GeneralDynamicTLSModel:
+    return llvm::GlobalVariable::GeneralDynamicTLSModel;
+  case CodeGenOptions::LocalDynamicTLSModel:
+    return llvm::GlobalVariable::LocalDynamicTLSModel;
+  case CodeGenOptions::InitialExecTLSModel:
+    return llvm::GlobalVariable::InitialExecTLSModel;
+  case CodeGenOptions::LocalExecTLSModel:
+    return llvm::GlobalVariable::LocalExecTLSModel;
+  }
+  llvm_unreachable("Invalid TLS model!");
+}
+
+void CodeGenModule::setTLSMode(llvm::GlobalVariable *GV,
+                               const VarDecl &D) const {
+  assert(D.isThreadSpecified() && "setting TLS mode on non-TLS var!");
+
+  llvm::GlobalVariable::ThreadLocalMode TLM;
+  TLM = GetLLVMTLSModel(CodeGenOpts.DefaultTLSModel);
+
+  // Override the TLS model if it is explicitly specified.
+  if (D.hasAttr<TLSModelAttr>()) {
+    const TLSModelAttr *Attr = D.getAttr<TLSModelAttr>();
+    TLM = GetLLVMTLSModel(Attr->getModel());
+  }
+
+  GV->setThreadLocalMode(TLM);
+}
+
 /// Set the symbol visibility of type information (vtable and RTTI)
 /// associated with the given type.
 void CodeGenModule::setTypeVisibility(llvm::GlobalValue *GV,
@@ -1212,13 +1251,8 @@
         GV->setVisibility(GetLLVMVisibility(LV.visibility()));
     }
 
-    GV->setThreadLocal(D->isThreadSpecified());
-
-    // Set the TLS model if it it's explicitly specified.
-    if (D->hasAttr<TLSModelAttr>()) {
-      const TLSModelAttr *Attr = D->getAttr<TLSModelAttr>();
-      GV->setThreadLocalMode(GetLLVMTLSModel(Attr->getModel()));
-    }
+    if (D->isThreadSpecified())
+      setTLSMode(GV, *D);
   }
 
   if (AddrSpace != Ty->getAddressSpace())

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=159336&r1=159335&r2=159336&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Thu Jun 28 03:01:44 2012
@@ -474,6 +474,10 @@
   /// GlobalValue.
   void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
 
+  /// setTLSMode - Set the TLS mode for the given LLVM GlobalVariable
+  /// for the thread-local variable declaration D.
+  void setTLSMode(llvm::GlobalVariable *GV, const VarDecl &D) const;
+
   /// TypeVisibilityKind - The kind of global variable that is passed to 
   /// setTypeVisibility
   enum TypeVisibilityKind {
@@ -498,15 +502,6 @@
     llvm_unreachable("unknown visibility!");
   }
 
-  static llvm::GlobalVariable::ThreadLocalMode GetLLVMTLSModel(StringRef S) {
-    return llvm::StringSwitch<llvm::GlobalVariable::ThreadLocalMode>(S)
-        .Case("global-dynamic", llvm::GlobalVariable::GeneralDynamicTLSModel)
-        .Case("local-dynamic", llvm::GlobalVariable::LocalDynamicTLSModel)
-        .Case("initial-exec", llvm::GlobalVariable::InitialExecTLSModel)
-        .Case("local-exec", llvm::GlobalVariable::LocalExecTLSModel)
-        .Default(llvm::GlobalVariable::NotThreadLocal);
-  }
-
   llvm::Constant *GetAddrOfGlobal(GlobalDecl GD) {
     if (isa<CXXConstructorDecl>(GD.getDecl()))
       return GetAddrOfCXXConstructor(cast<CXXConstructorDecl>(GD.getDecl()),

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=159336&r1=159335&r2=159336&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Thu Jun 28 03:01:44 2012
@@ -2209,6 +2209,8 @@
 
   Args.AddLastArg(CmdArgs, options::OPT_fvisibility_inlines_hidden);
 
+  Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
+
   // -fhosted is default.
   if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
       KernelOrKext)

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=159336&r1=159335&r2=159336&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Thu Jun 28 03:01:44 2012
@@ -307,6 +307,20 @@
     Res.push_back("-disable-llvm-verifier");
   for (unsigned i = 0, e = Opts.BackendOptions.size(); i != e; ++i)
     Res.push_back("-backend-option", Opts.BackendOptions[i]);
+
+  switch (Opts.DefaultTLSModel) {
+  case CodeGenOptions::GeneralDynamicTLSModel:
+    break;
+  case CodeGenOptions::LocalDynamicTLSModel:
+    Res.push_back("-ftls-model=local-dynamic");
+    break;
+  case CodeGenOptions::InitialExecTLSModel:
+    Res.push_back("-ftls-model=initial-exec");
+    break;
+  case CodeGenOptions::LocalExecTLSModel:
+    Res.push_back("-ftls-model=local-exec");
+    break;
+  }
 }
 
 static void DependencyOutputOptsToArgs(const DependencyOutputOptions &Opts,
@@ -788,7 +802,7 @@
   
   if (Opts.AppleKext)
     Res.push_back("-fapple-kext");
-  
+
   if (Opts.getVisibilityMode() != DefaultVisibility) {
     Res.push_back("-fvisibility");
     if (Opts.getVisibilityMode() == HiddenVisibility) {
@@ -1256,6 +1270,22 @@
     }
   }
 
+  if (Arg *A = Args.getLastArg(OPT_ftlsmodel_EQ)) {
+    StringRef Name = A->getValue(Args);
+    unsigned Model = llvm::StringSwitch<unsigned>(Name)
+        .Case("global-dynamic", CodeGenOptions::GeneralDynamicTLSModel)
+        .Case("local-dynamic", CodeGenOptions::LocalDynamicTLSModel)
+        .Case("initial-exec", CodeGenOptions::InitialExecTLSModel)
+        .Case("local-exec", CodeGenOptions::LocalExecTLSModel)
+        .Default(~0U);
+    if (Model == ~0U) {
+      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Name;
+      Success = false;
+    } else {
+      Opts.DefaultTLSModel = static_cast<CodeGenOptions::TLSModel>(Model);
+    }
+  }
+
   return Success;
 }
 

Added: cfe/trunk/test/CodeGen/tls-model.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/tls-model.c?rev=159336&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/tls-model.c (added)
+++ cfe/trunk/test/CodeGen/tls-model.c Thu Jun 28 03:01:44 2012
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-GD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=global-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-GD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-dynamic -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LD
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=initial-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-IE
+// RUN: %clang_cc1 %s -triple x86_64-pc-linux-gnu -ftls-model=local-exec -emit-llvm -o - | FileCheck %s -check-prefix=CHECK-LE
+
+int __thread x;
+int f() {
+  static int __thread y;
+  return y++;
+}
+int __thread __attribute__((tls_model("initial-exec"))) z;
+
+// CHECK-GD: @f.y = internal thread_local global i32 0
+// CHECK-GD: @x = thread_local global i32 0
+// CHECK-GD: @z = thread_local(initialexec) global i32 0
+
+// CHECK-LD: @f.y = internal thread_local(localdynamic) global i32 0
+// CHECK-LD: @x = thread_local(localdynamic) global i32 0
+// CHECK-LD: @z = thread_local(initialexec) global i32 0
+
+// CHECK-IE: @f.y = internal thread_local(initialexec) global i32 0
+// CHECK-IE: @x = thread_local(initialexec) global i32 0
+// CHECK-IE: @z = thread_local(initialexec) global i32 0
+
+// CHECK-LE: @f.y = internal thread_local(localexec) global i32 0
+// CHECK-LE: @x = thread_local(localexec) global i32 0
+// CHECK-LE: @z = thread_local(initialexec) global i32 0





More information about the cfe-commits mailing list