diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2015-09-15 12:52:43 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2015-09-15 12:52:43 +0000 |
commit | 25e5b4465494ff106fec9b5623e9d74e6b242e79 (patch) | |
tree | b9e0e6b8773322f22b9c385b4e1c4783a5f95717 /clang/lib/CodeGen/CGStmtOpenMP.cpp | |
parent | 7d4038dc5a0a6095324d3f1462fc4402a8a6eac3 (diff) | |
download | bcm5719-llvm-25e5b4465494ff106fec9b5623e9d74e6b242e79.tar.gz bcm5719-llvm-25e5b4465494ff106fec9b5623e9d74e6b242e79.zip |
[OPENMP] Emit __kmpc_cancel_barrier() and code for 'cancellation point' only if 'cancel' is found.
Patch improves codegen for OpenMP constructs. If the OpenMP region does not have internal 'cancel' construct, a call to 'void __kmpc_barrier()' runtime function is generated for all implicit/explicit barriers. If the region has inner 'cancel' directive, then
```
if (__kmpc_cancel_barrier())
exit from outer construct;
```
code is generated.
Also, the code for 'canellation point' directive is not generated if parent directive does not have 'cancel' directive.
llvm-svn: 247681
Diffstat (limited to 'clang/lib/CodeGen/CGStmtOpenMP.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGStmtOpenMP.cpp | 60 |
1 files changed, 38 insertions, 22 deletions
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp index 03f473631e0..70f86385d57 100644 --- a/clang/lib/CodeGen/CGStmtOpenMP.cpp +++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp @@ -624,8 +624,9 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { // initialization of firstprivate variables or propagation master's thread // values of threadprivate variables to local instances of that variables // of all other implicit threads. - CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), - OMPD_unknown); + CGF.CGM.getOpenMPRuntime().emitBarrierCall( + CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); } CGF.EmitOMPPrivateClause(S, PrivateScope); CGF.EmitOMPReductionClauseInit(S, PrivateScope); @@ -633,8 +634,9 @@ void CodeGenFunction::EmitOMPParallelDirective(const OMPParallelDirective &S) { CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EmitOMPReductionClauseFinal(S); // Emit implicit barrier at the end of the 'parallel' directive. - CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), - OMPD_unknown); + CGF.CGM.getOpenMPRuntime().emitBarrierCall( + CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); }; emitCommonOMPParallelDirective(*this, S, OMPD_parallel, CodeGen); } @@ -1238,8 +1240,9 @@ bool CodeGenFunction::EmitOMPWorksharingLoop(const OMPLoopDirective &S) { if (EmitOMPFirstprivateClause(S, LoopScope)) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables. - CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), - OMPD_unknown); + CGM.getOpenMPRuntime().emitBarrierCall( + *this, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); } EmitOMPPrivateClause(S, LoopScope); HasLastprivateClause = EmitOMPLastprivateClauseInit(S, LoopScope); @@ -1321,7 +1324,8 @@ void CodeGenFunction::EmitOMPForDirective(const OMPForDirective &S) { auto &&CodeGen = [&S, &HasLastprivates](CodeGenFunction &CGF) { HasLastprivates = CGF.EmitOMPWorksharingLoop(S); }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_for, CodeGen, + S.hasCancel()); // Emit an implicit barrier at the end. if (!S.getSingleClause<OMPNowaitClause>() || HasLastprivates) { @@ -1416,8 +1420,9 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { if (CGF.EmitOMPFirstprivateClause(S, LoopScope)) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables. - CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), - OMPD_unknown); + CGF.CGM.getOpenMPRuntime().emitBarrierCall( + CGF, S.getLocStart(), OMPD_unknown, /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); } CGF.EmitOMPPrivateClause(S, LoopScope); HasLastprivates = CGF.EmitOMPLastprivateClauseInit(S, LoopScope); @@ -1450,7 +1455,13 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { CGF.EmitLoadOfScalar(IL, S.getLocStart()))); }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen); + bool HasCancel = false; + if (auto *OSD = dyn_cast<OMPSectionsDirective>(&S)) + HasCancel = OSD->hasCancel(); + else if (auto *OPSD = dyn_cast<OMPParallelSectionsDirective>(&S)) + HasCancel = OPSD->hasCancel(); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_sections, CodeGen, + HasCancel); // Emit barrier for lastprivates only if 'sections' directive has 'nowait' // clause. Otherwise the barrier will be generated by the codegen for the // directive. @@ -1490,7 +1501,9 @@ CodeGenFunction::EmitSections(const OMPExecutableDirective &S) { S.getSingleClause<OMPNowaitClause>()) { // Emit implicit barrier to synchronize threads and avoid data races on // initialization of firstprivate variables. - CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown); + CGM.getOpenMPRuntime().emitBarrierCall(*this, S.getLocStart(), OMPD_unknown, + /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); } return OMPD_single; } @@ -1510,7 +1523,8 @@ void CodeGenFunction::EmitOMPSectionDirective(const OMPSectionDirective &S) { CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt()); CGF.EnsureInsertPoint(); }; - CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen); + CGM.getOpenMPRuntime().emitInlinedDirective(*this, OMPD_section, CodeGen, + S.hasCancel()); } void CodeGenFunction::EmitOMPSingleDirective(const OMPSingleDirective &S) { @@ -1586,8 +1600,9 @@ void CodeGenFunction::EmitOMPParallelForDirective( // Emit implicit barrier at the end of parallel region, but this barrier // is at the end of 'for' directive, so emit it as the implicit barrier for // this 'for' directive. - CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), - OMPD_parallel); + CGF.CGM.getOpenMPRuntime().emitBarrierCall( + CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); }; emitCommonOMPParallelDirective(*this, S, OMPD_for, CodeGen); } @@ -1603,8 +1618,9 @@ void CodeGenFunction::EmitOMPParallelForSimdDirective( // Emit implicit barrier at the end of parallel region, but this barrier // is at the end of 'for' directive, so emit it as the implicit barrier for // this 'for' directive. - CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), - OMPD_parallel); + CGF.CGM.getOpenMPRuntime().emitBarrierCall( + CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); }; emitCommonOMPParallelDirective(*this, S, OMPD_simd, CodeGen); } @@ -1617,8 +1633,9 @@ void CodeGenFunction::EmitOMPParallelSectionsDirective( auto &&CodeGen = [&S](CodeGenFunction &CGF) { (void)CGF.EmitSections(S); // Emit implicit barrier at the end of parallel region. - CGF.CGM.getOpenMPRuntime().emitBarrierCall(CGF, S.getLocStart(), - OMPD_parallel); + CGF.CGM.getOpenMPRuntime().emitBarrierCall( + CGF, S.getLocStart(), OMPD_parallel, /*EmitChecks=*/false, + /*ForceSimpleCall=*/true); }; emitCommonOMPParallelDirective(*this, S, OMPD_sections, CodeGen); } @@ -2253,10 +2270,9 @@ CodeGenFunction::JumpDest CodeGenFunction::getOMPCancelDestination(OpenMPDirectiveKind Kind) { if (Kind == OMPD_parallel || Kind == OMPD_task) return ReturnBlock; - else if (Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections) - return BreakContinueStack.empty() ? JumpDest() - : BreakContinueStack.back().BreakBlock; - return JumpDest(); + assert(Kind == OMPD_for || Kind == OMPD_section || Kind == OMPD_sections || + Kind == OMPD_parallel_sections || Kind == OMPD_parallel_for); + return BreakContinueStack.back().BreakBlock; } // Generate the instructions for '#pragma omp target data' directive. |