forked from OSchip/llvm-project
[OPENMP] Support lastprivate clause in omp simd directive.
Added codegen for lastprivate clauses within simd loop-based directives. llvm-svn: 239813
This commit is contained in:
parent
8d8b13dc19
commit
fc087ecc05
|
@ -316,26 +316,32 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
|
|||
// ...
|
||||
// orig_varn = private_orig_varn;
|
||||
// }
|
||||
auto *ThenBB = createBasicBlock(".omp.lastprivate.then");
|
||||
auto *DoneBB = createBasicBlock(".omp.lastprivate.done");
|
||||
Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
|
||||
EmitBlock(ThenBB);
|
||||
llvm::BasicBlock *ThenBB = nullptr;
|
||||
llvm::BasicBlock *DoneBB = nullptr;
|
||||
if (IsLastIterCond) {
|
||||
ThenBB = createBasicBlock(".omp.lastprivate.then");
|
||||
DoneBB = createBasicBlock(".omp.lastprivate.done");
|
||||
Builder.CreateCondBr(IsLastIterCond, ThenBB, DoneBB);
|
||||
EmitBlock(ThenBB);
|
||||
}
|
||||
llvm::DenseMap<const Decl *, const Expr *> LoopCountersAndUpdates;
|
||||
const Expr *LastIterVal = nullptr;
|
||||
const Expr *IVExpr = nullptr;
|
||||
const Expr *IncExpr = nullptr;
|
||||
if (auto *LoopDirective = dyn_cast<OMPLoopDirective>(&D)) {
|
||||
LastIterVal =
|
||||
cast<VarDecl>(cast<DeclRefExpr>(LoopDirective->getUpperBoundVariable())
|
||||
->getDecl())
|
||||
->getAnyInitializer();
|
||||
IVExpr = LoopDirective->getIterationVariable();
|
||||
IncExpr = LoopDirective->getInc();
|
||||
auto IUpdate = LoopDirective->updates().begin();
|
||||
for (auto *E : LoopDirective->counters()) {
|
||||
auto *D = cast<DeclRefExpr>(E)->getDecl()->getCanonicalDecl();
|
||||
LoopCountersAndUpdates[D] = *IUpdate;
|
||||
++IUpdate;
|
||||
if (isOpenMPWorksharingDirective(D.getDirectiveKind())) {
|
||||
LastIterVal = cast<VarDecl>(cast<DeclRefExpr>(
|
||||
LoopDirective->getUpperBoundVariable())
|
||||
->getDecl())
|
||||
->getAnyInitializer();
|
||||
IVExpr = LoopDirective->getIterationVariable();
|
||||
IncExpr = LoopDirective->getInc();
|
||||
auto IUpdate = LoopDirective->updates().begin();
|
||||
for (auto *E : LoopDirective->counters()) {
|
||||
auto *D = cast<DeclRefExpr>(E)->getDecl()->getCanonicalDecl();
|
||||
LoopCountersAndUpdates[D] = *IUpdate;
|
||||
++IUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
|
@ -355,7 +361,7 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
|
|||
// directive, update its value before copyin back to original
|
||||
// variable.
|
||||
if (auto *UpExpr = LoopCountersAndUpdates.lookup(CanonicalVD)) {
|
||||
if (FirstLCV) {
|
||||
if (FirstLCV && LastIterVal) {
|
||||
EmitAnyExprToMem(LastIterVal, EmitLValue(IVExpr).getAddress(),
|
||||
IVExpr->getType().getQualifiers(),
|
||||
/*IsInitializer=*/false);
|
||||
|
@ -379,7 +385,9 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
|
|||
}
|
||||
}
|
||||
}
|
||||
EmitBlock(DoneBB, /*IsFinished=*/true);
|
||||
if (IsLastIterCond) {
|
||||
EmitBlock(DoneBB, /*IsFinished=*/true);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPReductionClauseInit(
|
||||
|
@ -793,11 +801,13 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
|
|||
}
|
||||
}
|
||||
|
||||
bool HasLastprivateClause;
|
||||
{
|
||||
OMPPrivateScope LoopScope(CGF);
|
||||
EmitPrivateLoopCounters(CGF, LoopScope, S.counters());
|
||||
EmitPrivateLinearVars(CGF, S, LoopScope);
|
||||
CGF.EmitOMPPrivateClause(S, LoopScope);
|
||||
HasLastprivateClause = CGF.EmitOMPLastprivateClauseInit(S, LoopScope);
|
||||
(void)LoopScope.Privatize();
|
||||
CGF.EmitOMPInnerLoop(S, LoopScope.requiresCleanups(),
|
||||
S.getCond(), S.getInc(),
|
||||
|
@ -806,6 +816,10 @@ void CodeGenFunction::EmitOMPSimdDirective(const OMPSimdDirective &S) {
|
|||
CGF.EmitStopPoint(&S);
|
||||
},
|
||||
[](CodeGenFunction &) {});
|
||||
// Emit final copy of the lastprivate variables at the end of loops.
|
||||
if (HasLastprivateClause) {
|
||||
CGF.EmitOMPLastprivateClauseFinal(S);
|
||||
}
|
||||
}
|
||||
CGF.EmitOMPSimdFinal(S);
|
||||
// Emit: if (PreCond) - end.
|
||||
|
|
|
@ -2130,9 +2130,9 @@ public:
|
|||
/// \param D Directive that has at least one 'lastprivate' directives.
|
||||
/// \param IsLastIterCond Boolean condition that must be set to 'i1 true' if
|
||||
/// it is the last iteration of the loop code in associated directive, or to
|
||||
/// 'i1 false' otherwise.
|
||||
/// 'i1 false' otherwise. If this item is nullptr, no final check is required.
|
||||
void EmitOMPLastprivateClauseFinal(const OMPExecutableDirective &D,
|
||||
llvm::Value *IsLastIterCond);
|
||||
llvm::Value *IsLastIterCond = nullptr);
|
||||
/// \brief Emit initial code for reduction variables. Creates reduction copies
|
||||
/// and initializes them with the values according to OpenMP standard.
|
||||
///
|
||||
|
|
|
@ -182,6 +182,8 @@ void simple(float *a, float *b, float *c, float *d) {
|
|||
}
|
||||
|
||||
int A;
|
||||
// CHECK: store i32 -1, i32* [[A:%.+]],
|
||||
A = -1;
|
||||
#pragma omp simd lastprivate(A)
|
||||
// Clause 'lastprivate' implementation is not completed yet.
|
||||
// Test checks that one iteration is separated in presence of lastprivate.
|
||||
|
@ -198,13 +200,18 @@ void simple(float *a, float *b, float *c, float *d) {
|
|||
// CHECK: [[IV7_0:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
|
||||
// CHECK-NEXT: [[LC_IT_1:%.+]] = mul nsw i64 [[IV7_0]], 3
|
||||
// CHECK-NEXT: [[LC_IT_2:%.+]] = add nsw i64 -10, [[LC_IT_1]]
|
||||
// CHECK-NEXT: store i64 [[LC_IT_2]], i64* {{.+}}, !llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
|
||||
// CHECK-NEXT: store i64 [[LC_IT_2]], i64* [[LC:%[^,]+]],{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
|
||||
// CHECK-NEXT: [[LC_VAL:%.+]] = load i64, i64* [[LC]]{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
|
||||
// CHECK-NEXT: [[CONV:%.+]] = trunc i64 [[LC_VAL]] to i32
|
||||
// CHECK-NEXT: store i32 [[CONV]], i32* [[A_PRIV:%[^,]+]],{{.+}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
|
||||
A = i;
|
||||
// CHECK: [[IV7_2:%.+]] = load i64, i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
|
||||
// CHECK-NEXT: [[ADD7_2:%.+]] = add nsw i64 [[IV7_2]], 1
|
||||
// CHECK-NEXT: store i64 [[ADD7_2]], i64* [[OMP_IV7]]{{.*}}!llvm.mem.parallel_loop_access ![[SIMPLE_LOOP7_ID]]
|
||||
}
|
||||
// CHECK: [[SIMPLE_LOOP7_END]]
|
||||
// CHECK-NEXT: [[A_PRIV_VAL:%.+]] = load i32, i32* [[A_PRIV]],
|
||||
// CHECK-NEXT: store i32 [[A_PRIV_VAL]], i32* [[A]],
|
||||
// CHECK-NEXT: ret void
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue