[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
This commit is contained in:
Alexey Bataev
2014-11-11 04:05:39 +00:00
parent ea97e36dfc
commit 9772000a22
19 changed files with 1109 additions and 20 deletions

View File

@@ -3230,6 +3230,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
break;
}
case Decl::OMPThreadPrivate:
EmitOMPThreadPrivateDecl(cast<OMPThreadPrivateDecl>(D));
break;
case Decl::ClassTemplateSpecialization: {
const auto *Spec = cast<ClassTemplateSpecializationDecl>(D);
if (DebugInfo &&
@@ -3506,3 +3510,18 @@ llvm::Constant *CodeGenModule::GetAddrOfRTTIDescriptor(QualType Ty,
return getCXXABI().getAddrOfRTTIDescriptor(Ty);
}
void CodeGenModule::EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
for (auto RefExpr : D->varlists()) {
auto *VD = cast<VarDecl>(cast<DeclRefExpr>(RefExpr)->getDecl());
bool PerformInit =
VD->getAnyInitializer() &&
!VD->getAnyInitializer()->isConstantInitializer(getContext(),
/*ForRef=*/false);
if (auto InitFunction =
getOpenMPRuntime().EmitOMPThreadPrivateVarDefinition(
VD, GetAddrOfGlobalVar(VD), RefExpr->getLocStart(),
PerformInit))
CXXGlobalInits.push_back(InitFunction);
}
}