diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-11-11 04:05:39 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-11-11 04:05:39 +0000 |
commit | 9772000a2250e81654b97f8e54904a96a20c4a86 (patch) | |
tree | 881270747aa7216946f88c594a00a732009cd784 /clang/lib/CodeGen/CGExpr.cpp | |
parent | ea97e36dfc4b3203a7490844e12c2450a170584c (diff) | |
download | bcm5719-llvm-9772000a2250e81654b97f8e54904a96a20c4a86.tar.gz bcm5719-llvm-9772000a2250e81654b97f8e54904a96a20c4a86.zip |
[OPENMP] Codegen for threadprivate variables
For all threadprivate variables which have constructor/destructor emit call to void __kmpc_threadprivate_register(ident_t * <Current Location>, void *<Original Global Addr>, kmpc_ctor <Constructor>, kmpc_cctor NULL, kmpc_dtor <Destructor>);
In expressions all references to such variables are replaced by calls to void *__kmpc_threadprivate_cached(ident_t *<Current Location>, kmp_int32 <Current Thread Id>, void *<Original Global Addr>, size_t <Size of Data>, void ***<Pointer to autogenerated cache – array of private copies of threadprivate variable>);
Test test/OpenMP/threadprivate_codegen.cpp checks that codegen is correct. Also it checks that codegen is correct after serialization/deserialization and one of passes verifies debug info.
Differential Revision: http://reviews.llvm.org/D4002
llvm-svn: 221663
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index b433a6454eb..877323bf926 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -16,6 +16,7 @@ #include "CGCall.h" #include "CGDebugInfo.h" #include "CGObjCRuntime.h" +#include "CGOpenMPRuntime.h" #include "CGRecordLayout.h" #include "CodeGenModule.h" #include "TargetInfo.h" @@ -1802,6 +1803,14 @@ EmitBitCastOfLValueToProperType(CodeGenFunction &CGF, return CGF.Builder.CreateBitCast(V, IRType->getPointerTo(AS), Name); } +static LValue EmitThreadPrivateVarDeclLValue( + CodeGenFunction &CGF, const VarDecl *VD, QualType T, llvm::Value *V, + llvm::Type *RealVarTy, CharUnits Alignment, SourceLocation Loc) { + V = CGF.CGM.getOpenMPRuntime().getOMPAddrOfThreadPrivate(CGF, VD, V, Loc); + V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy); + return CGF.MakeAddrLValue(V, T, Alignment); +} + static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, const Expr *E, const VarDecl *VD) { QualType T = E->getType(); @@ -1816,6 +1825,11 @@ static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, V = EmitBitCastOfLValueToProperType(CGF, V, RealVarTy); CharUnits Alignment = CGF.getContext().getDeclAlign(VD); LValue LV; + // Emit reference to the private copy of the variable if it is an OpenMP + // threadprivate variable. + if (CGF.getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>()) + return EmitThreadPrivateVarDeclLValue(CGF, VD, T, V, RealVarTy, Alignment, + E->getExprLoc()); if (VD->getType()->isReferenceType()) { llvm::LoadInst *LI = CGF.Builder.CreateLoad(V); LI->setAlignment(Alignment.getQuantity()); @@ -1929,6 +1943,12 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { V = CGM.getOrCreateStaticVarDecl( *VD, CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false)); + // Check if variable is threadprivate. + if (V && getLangOpts().OpenMP && VD->hasAttr<OMPThreadPrivateDeclAttr>()) + return EmitThreadPrivateVarDeclLValue( + *this, VD, T, V, getTypes().ConvertTypeForMem(VD->getType()), + Alignment, E->getExprLoc()); + // Use special handling for lambdas. if (!V) { if (FieldDecl *FD = LambdaCaptureFields.lookup(VD)) { |