summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorSamuel Antao <sfantao@us.ibm.com>2015-07-13 22:54:53 +0000
committerSamuel Antao <sfantao@us.ibm.com>2015-07-13 22:54:53 +0000
commitf8b5012dfb5210d616d838a558a5dccd7f8f6aae (patch)
treefa1748382ae9c4e1ba45546c3504fa93d73b9a55 /clang/lib
parent6c40c5e0311539fcfea9bd5ef6e2330d5c4f2199 (diff)
downloadbcm5719-llvm-f8b5012dfb5210d616d838a558a5dccd7f8f6aae.tar.gz
bcm5719-llvm-f8b5012dfb5210d616d838a558a5dccd7f8f6aae.zip
[OpenMP] Add TLS-based implementation for threadprivate directive.
llvm-svn: 242080
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp12
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp10
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp5
-rw-r--r--clang/lib/Driver/Tools.cpp10
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--clang/lib/Sema/SemaOpenMP.cpp14
6 files changed, 46 insertions, 7 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 74c0e2dc69d..ea4b2f517cd 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1803,15 +1803,19 @@ void VarDecl::setStorageClass(StorageClass SC) {
VarDecl::TLSKind VarDecl::getTLSKind() const {
switch (VarDeclBits.TSCSpec) {
case TSCS_unspecified:
- if (!hasAttr<ThreadAttr>())
+ if (!hasAttr<ThreadAttr>() &&
+ !(getASTContext().getLangOpts().OpenMPUseTLS &&
+ getASTContext().getTargetInfo().isTLSSupported() &&
+ hasAttr<OMPThreadPrivateDeclAttr>()))
return TLS_None;
- return getASTContext().getLangOpts().isCompatibleWithMSVC(
- LangOptions::MSVC2015)
+ return ((getASTContext().getLangOpts().isCompatibleWithMSVC(
+ LangOptions::MSVC2015)) ||
+ hasAttr<OMPThreadPrivateDeclAttr>())
? TLS_Dynamic
: TLS_Static;
case TSCS___thread: // Fall through.
case TSCS__Thread_local:
- return TLS_Static;
+ return TLS_Static;
case TSCS_thread_local:
return TLS_Dynamic;
}
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index 8c534846cf9..81488398bb8 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -932,6 +932,8 @@ llvm::Constant *CGOpenMPRuntime::createDispatchNextFunction(unsigned IVSize,
llvm::Constant *
CGOpenMPRuntime::getOrCreateThreadPrivateCache(const VarDecl *VD) {
+ assert(!CGM.getLangOpts().OpenMPUseTLS ||
+ !CGM.getContext().getTargetInfo().isTLSSupported());
// Lookup the entry, lazily creating it if necessary.
return getOrCreateInternalVariable(CGM.Int8PtrPtrTy,
Twine(CGM.getMangledName(VD)) + ".cache.");
@@ -941,6 +943,10 @@ llvm::Value *CGOpenMPRuntime::getAddrOfThreadPrivate(CodeGenFunction &CGF,
const VarDecl *VD,
llvm::Value *VDAddr,
SourceLocation Loc) {
+ if (CGM.getLangOpts().OpenMPUseTLS &&
+ CGM.getContext().getTargetInfo().isTLSSupported())
+ return VDAddr;
+
auto VarTy = VDAddr->getType()->getPointerElementType();
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
CGF.Builder.CreatePointerCast(VDAddr, CGM.Int8PtrTy),
@@ -970,6 +976,10 @@ void CGOpenMPRuntime::emitThreadPrivateVarInit(
llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
const VarDecl *VD, llvm::Value *VDAddr, SourceLocation Loc,
bool PerformInit, CodeGenFunction *CGF) {
+ if (CGM.getLangOpts().OpenMPUseTLS &&
+ CGM.getContext().getTargetInfo().isTLSSupported())
+ return nullptr;
+
VD = VD->getDefinition(CGM.getContext());
if (VD && ThreadPrivateWithDefinition.count(VD) == 0) {
ThreadPrivateWithDefinition.insert(VD);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index b905bd2b36b..a179ad42eac 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1262,6 +1262,11 @@ bool CodeGenModule::MayBeEmittedEagerly(const ValueDecl *Global) {
// Implicit template instantiations may change linkage if they are later
// explicitly instantiated, so they should not be emitted eagerly.
return false;
+ // If OpenMP is enabled and threadprivates must be generated like TLS, delay
+ // codegen for global variables, because they may be marked as threadprivate.
+ if (LangOpts.OpenMP && LangOpts.OpenMPUseTLS &&
+ getContext().getTargetInfo().isTLSSupported() && isa<VarDecl>(Global))
+ return false;
return true;
}
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 180533396c1..bf9b4baeb3b 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -3954,6 +3954,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
case OMPRT_IOMP5:
// Clang can generate useful OpenMP code for these two runtime libraries.
CmdArgs.push_back("-fopenmp");
+
+ // If no option regarding the use of TLS in OpenMP codegeneration is
+ // given, decide a default based on the target. Otherwise rely on the
+ // options and pass the right information to the frontend.
+ if (!Args.hasFlag(options::OPT_fopenmp_use_tls,
+ options::OPT_fnoopenmp_use_tls,
+ getToolChain().getArch() == llvm::Triple::ppc ||
+ getToolChain().getArch() == llvm::Triple::ppc64 ||
+ getToolChain().getArch() == llvm::Triple::ppc64le))
+ CmdArgs.push_back("-fnoopenmp-use-tls");
break;
default:
// By default, if Clang doesn't know how to generate useful OpenMP code
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index baee1190595..6f13faf573b 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1651,6 +1651,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
// Check if -fopenmp is specified.
Opts.OpenMP = Args.hasArg(options::OPT_fopenmp);
+ Opts.OpenMPUseTLS =
+ Opts.OpenMP && !Args.hasArg(options::OPT_fnoopenmp_use_tls);
// Record whether the __DEPRECATED define was requested.
Opts.Deprecated = Args.hasFlag(OPT_fdeprecated_macro,
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 867cb9f3c83..4030d9e66e0 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/StmtOpenMP.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/OpenMPKinds.h"
+#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Initialization.h"
#include "clang/Sema/Lookup.h"
@@ -472,7 +473,10 @@ DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) {
// OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
// in a Construct, C/C++, predetermined, p.1]
// Variables appearing in threadprivate directives are threadprivate.
- if (D->getTLSKind() != VarDecl::TLS_None ||
+ if ((D->getTLSKind() != VarDecl::TLS_None &&
+ !(D->hasAttr<OMPThreadPrivateDeclAttr>() &&
+ SemaRef.getLangOpts().OpenMPUseTLS &&
+ SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
(D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() &&
!D->isLocalVarDecl())) {
addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(),
@@ -959,8 +963,12 @@ Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
continue;
}
- // Check if this is a TLS variable.
- if (VD->getTLSKind() != VarDecl::TLS_None ||
+ // Check if this is a TLS variable. If TLS is not being supported, produce
+ // the corresponding diagnostic.
+ if ((VD->getTLSKind() != VarDecl::TLS_None &&
+ !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
+ getLangOpts().OpenMPUseTLS &&
+ getASTContext().getTargetInfo().isTLSSupported())) ||
(VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
!VD->isLocalVarDecl())) {
Diag(ILoc, diag::err_omp_var_thread_local)
OpenPOWER on IntegriCloud