summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGStmtOpenMP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r--clang/lib/CodeGen/CGStmtOpenMP.cpp96
1 files changed, 68 insertions, 28 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);
OpenPOWER on IntegriCloud