diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2016-03-09 09:49:09 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2016-03-09 09:49:09 +0000 |
commit | ef549a89559c1038f2cc8fbdf62a49ec78ef5aa7 (patch) | |
tree | 3b1ff5749eb4106bc5db32c6a9865ca53c3de187 /clang/lib | |
parent | 78849fb464ce63bd701e07d607d4c70ceec897f4 (diff) | |
download | bcm5719-llvm-ef549a89559c1038f2cc8fbdf62a49ec78ef5aa7.tar.gz bcm5719-llvm-ef549a89559c1038f2cc8fbdf62a49ec78ef5aa7.zip |
[OPENMP 4.5] Codegen for data members in 'linear' clause
OpenMP 4.5 allows privatization of non-static data members in OpenMP
constructs. Patch adds proper codegen support for data members in
'linear' clause
llvm-svn: 263003
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 96 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 4 |
2 files changed, 71 insertions, 29 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 211155edd23..808af527a39 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -1114,17 +1114,19 @@ void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { for (auto Init : C->inits()) { auto *VD = cast<VarDecl>(cast<DeclRefExpr>(Init)->getDecl()); - auto *OrigVD = cast<VarDecl>( - cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())->getDecl()); - DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), - CapturedStmtInfo->lookup(OrigVD) != nullptr, - VD->getInit()->getType(), VK_LValue, - VD->getInit()->getExprLoc()); - AutoVarEmission Emission = EmitAutoVarAlloca(*VD); - EmitExprAsInit(&DRE, VD, - MakeAddrLValue(Emission.getAllocatedAddress(), VD->getType()), - /*capturedByInit=*/false); - EmitAutoVarCleanups(Emission); + if (auto *Ref = dyn_cast<DeclRefExpr>(VD->getInit()->IgnoreImpCasts())) { + AutoVarEmission Emission = EmitAutoVarAlloca(*VD); + auto *OrigVD = cast<VarDecl>(Ref->getDecl()); + DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), + CapturedStmtInfo->lookup(OrigVD) != nullptr, + VD->getInit()->getType(), VK_LValue, + VD->getInit()->getExprLoc()); + EmitExprAsInit(&DRE, VD, MakeAddrLValue(Emission.getAllocatedAddress(), + VD->getType()), + /*capturedByInit=*/false); + EmitAutoVarCleanups(Emission); + } else + EmitVarDecl(*VD); } // Emit the linear steps for the linear clauses. // If a step is not constant, it is pre-calculated before the loop. @@ -1137,14 +1139,26 @@ void CodeGenFunction::EmitOMPLinearClauseInit(const OMPLoopDirective &D) { } } -static void emitLinearClauseFinal(CodeGenFunction &CGF, - const OMPLoopDirective &D) { +static void emitLinearClauseFinal( + CodeGenFunction &CGF, const OMPLoopDirective &D, + const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) { if (!CGF.HaveInsertPoint()) return; + llvm::BasicBlock *DoneBB = nullptr; // Emit the final values of the linear variables. for (const auto *C : D.getClausesOfKind<OMPLinearClause>()) { auto IC = C->varlist_begin(); for (auto F : C->finals()) { + if (!DoneBB) { + if (auto *Cond = CondGen(CGF)) { + // If the first post-update expression is found, emit conditional + // block if it was requested. + auto *ThenBB = CGF.createBasicBlock(".omp.linear.pu"); + DoneBB = CGF.createBasicBlock(".omp.linear.pu.done"); + CGF.Builder.CreateCondBr(Cond, ThenBB, DoneBB); + CGF.EmitBlock(ThenBB); + } + } auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(*IC)->getDecl()); DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr, @@ -1158,8 +1172,10 @@ static void emitLinearClauseFinal(CodeGenFunction &CGF, ++IC; } if (auto *PostUpdate = C->getPostUpdateExpr()) - EmitIgnoredExpr(PostUpdate); + CGF.EmitIgnoredExpr(PostUpdate); } + if (DoneBB) + CGF.EmitBlock(DoneBB, /*IsFinished=*/true); } static void emitAlignedClause(CodeGenFunction &CGF, @@ -1296,13 +1312,26 @@ void CodeGenFunction::EmitOMPSimdInit(const OMPLoopDirective &D, emitSimdlenSafelenClause(*this, D, IsMonotonic); } -void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &D) { +void CodeGenFunction::EmitOMPSimdFinal( + const OMPLoopDirective &D, + const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen) { if (!HaveInsertPoint()) return; + llvm::BasicBlock *DoneBB = nullptr; auto IC = D.counters().begin(); for (auto F : D.finals()) { auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>((*IC))->getDecl()); if (LocalDeclMap.count(OrigVD) || CapturedStmtInfo->lookup(OrigVD)) { + if (!DoneBB) { + if (auto *Cond = CondGen(*this)) { + // If the first post-update expression is found, emit conditional + // block if it was requested. + auto *ThenBB = createBasicBlock(".omp.final.then"); + DoneBB = createBasicBlock(".omp.final.done"); + Builder.CreateCondBr(Cond, ThenBB, DoneBB); + EmitBlock(ThenBB); + } + } DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD), CapturedStmtInfo->lookup(OrigVD) != nullptr, (*IC)->getType(), VK_LValue, (*IC)->getExprLoc()); @@ -1315,7 +1344,8 @@ void CodeGenFunction::EmitOMPSimdFinal(const OMPLoopDirective &D) { } ++IC; } - emitLinearClauseFinal(*this, D); + if (DoneBB) + EmitBlock(DoneBB, /*IsFinished=*/true); } void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { @@ -1387,7 +1417,10 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) { emitPostUpdateForReductionClause( CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); } - CGF.EmitOMPSimdFinal(S); + CGF.EmitOMPSimdFinal( + S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); + emitLinearClauseFinal( + CGF, S, [](CodeGenFunction &) -> llvm::Value * { return nullptr; }); // Emit: if (PreCond) - end. if (ContBlock) { CGF.EmitBranch(ContBlock); @@ -1651,18 +1684,18 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { emitAlignedClause(*this, S); EmitOMPLinearClauseInit(S); + // Emit helper vars inits. + LValue LB = + EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable())); + LValue UB = + EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable())); + LValue ST = + EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); + LValue IL = + EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); + // Emit 'then' code. { - // Emit helper vars inits. - LValue LB = - EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getLowerBoundVariable())); - LValue UB = - EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getUpperBoundVariable())); - LValue ST = - EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getStrideVariable())); - LValue IL = - EmitOMPHelperVar(*this, cast<DeclRefExpr>(S.getIsLastIterVariable())); - OMPPrivateScope LoopScope(*this); if (EmitOMPFirstprivateClause(S, LoopScope)) { // Emit implicit barrier to synchronize threads and avoid data races on @@ -1759,8 +1792,15 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { S, Builder.CreateIsNotNull(EmitLoadOfScalar(IL, S.getLocStart()))); } if (isOpenMPSimdDirective(S.getDirectiveKind())) { - EmitOMPSimdFinal(S); + EmitOMPSimdFinal(S, [&](CodeGenFunction &CGF) -> llvm::Value * { + return CGF.Builder.CreateIsNotNull( + CGF.EmitLoadOfScalar(IL, S.getLocStart())); + }); } + emitLinearClauseFinal(*this, S, [&](CodeGenFunction &CGF) -> llvm::Value * { + return CGF.Builder.CreateIsNotNull( + CGF.EmitLoadOfScalar(IL, S.getLocStart())); + }); // We're now done with the loop, so jump to the continuation block. if (ContBlock) { EmitBranch(ContBlock); diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index a84a0f0e73c..13a3acbaeda 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -2389,7 +2389,9 @@ private: /// Helpers for the OpenMP loop directives. void EmitOMPLoopBody(const OMPLoopDirective &D, JumpDest LoopExit); void EmitOMPSimdInit(const OMPLoopDirective &D, bool IsMonotonic = false); - void EmitOMPSimdFinal(const OMPLoopDirective &D); + void EmitOMPSimdFinal( + const OMPLoopDirective &D, + const llvm::function_ref<llvm::Value *(CodeGenFunction &)> &CondGen); /// \brief Emit code for the worksharing loop-based directive. /// \return true, if this construct has any lastprivate clause, false - /// otherwise. |