diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2015-06-16 13:14:42 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-06-16 13:14:42 +0000 |
commit | fc087ecc051e52229cc0af176436005d97152ef3 (patch) | |
tree | 798ee933f7a1a092e36fccf12970fd495ba5db67 /clang | |
parent | 8d8b13dc19d5f031a04ba1393be70e7be37dd561 (diff) | |
download | bcm5719-llvm-fc087ecc051e52229cc0af176436005d97152ef3.tar.gz bcm5719-llvm-fc087ecc051e52229cc0af176436005d97152ef3.zip |
[OPENMP] Support lastprivate clause in omp simd directive.
Added codegen for lastprivate clauses within simd loop-based directives.
llvm-svn: 239813
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 48 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 4 | ||||
-rw-r--r-- | clang/test/OpenMP/simd_codegen.cpp | 9 |
3 files changed, 41 insertions, 20 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index a6da3891af5..907fe93efc4 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -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. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index b3c31f61d1a..fddecbc9394 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -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. /// diff --git a/clang/test/OpenMP/simd_codegen.cpp b/clang/test/OpenMP/simd_codegen.cpp index 6b3170d5dfd..0a5b38a0ce3 100644 --- a/clang/test/OpenMP/simd_codegen.cpp +++ b/clang/test/OpenMP/simd_codegen.cpp @@ -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 } |