diff options
author | Arpith Chacko Jacob <acjacob@us.ibm.com> | 2017-01-18 18:18:53 +0000 |
---|---|---|
committer | Arpith Chacko Jacob <acjacob@us.ibm.com> | 2017-01-18 18:18:53 +0000 |
commit | 19b911cb75f2c37e1e16ea4e7b2046df96c8e5e4 (patch) | |
tree | f6f997fb17a7a5c696ca5010efaaac0dae6ca903 /clang/lib/Sema | |
parent | 8829e961e6e3946972a14a69d44eaf92826af22c (diff) | |
download | bcm5719-llvm-19b911cb75f2c37e1e16ea4e7b2046df96c8e5e4.tar.gz bcm5719-llvm-19b911cb75f2c37e1e16ea4e7b2046df96c8e5e4.zip |
[OpenMP] Codegen support for 'target parallel' on the host.
This patch adds support for codegen of 'target parallel' on the host.
It is also the first combined directive that requires two or more
captured statements. Support for this functionality is included in
the patch.
A combined directive such as 'target parallel' has two captured
statements, one for the 'target' and the other for the 'parallel'
region. Two captured statements are required because each has
different implicit parameters (see SemaOpenMP.cpp). For example,
the 'parallel' has 'global_tid' and 'bound_tid' while the 'target'
does not. The patch adds support for handling multiple captured
statements based on the combined directive.
When codegen'ing the 'target parallel' directive, the 'target'
outlined function is created using the outer captured statement
and the 'parallel' outlined function is created using the inner
captured statement.
Reviewers: ABataev
Differential Revision: https://reviews.llvm.org/D28753
llvm-svn: 292419
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaOpenMP.cpp | 70 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 8 |
2 files changed, 71 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp index dcd19c8d817..5b21f580125 100644 --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -1608,6 +1608,26 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { Params); break; } + case OMPD_target_parallel: { + Sema::CapturedParamNameType ParamsTarget[] = { + std::make_pair(StringRef(), QualType()) // __context with shared vars + }; + // Start a captured region for 'target' with no implicit parameters. + ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, + ParamsTarget); + QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); + QualType KmpInt32PtrTy = + Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); + Sema::CapturedParamNameType ParamsParallel[] = { + std::make_pair(".global_tid.", KmpInt32PtrTy), + std::make_pair(".bound_tid.", KmpInt32PtrTy), + std::make_pair(StringRef(), QualType()) // __context with shared vars + }; + // Start a captured region for 'parallel'. + ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, + ParamsParallel); + break; + } case OMPD_simd: case OMPD_for: case OMPD_for_simd: @@ -1622,7 +1642,6 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { case OMPD_atomic: case OMPD_target_data: case OMPD_target: - case OMPD_target_parallel: case OMPD_target_parallel_for: case OMPD_target_parallel_for_simd: case OMPD_target_simd: { @@ -1737,6 +1756,12 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { } } +int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { + SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; + getOpenMPCaptureRegions(CaptureRegions, DKind); + return CaptureRegions.size(); +} + static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression) { @@ -1796,10 +1821,42 @@ static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); } +namespace { +// OpenMP directives parsed in this section are represented as a +// CapturedStatement with an associated statement. If a syntax error +// is detected during the parsing of the associated statement, the +// compiler must abort processing and close the CapturedStatement. +// +// Combined directives such as 'target parallel' have more than one +// nested CapturedStatements. This RAII ensures that we unwind out +// of all the nested CapturedStatements when an error is found. +class CaptureRegionUnwinderRAII { +private: + Sema &S; + bool &ErrorFound; + OpenMPDirectiveKind DKind; + +public: + CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, + OpenMPDirectiveKind DKind) + : S(S), ErrorFound(ErrorFound), DKind(DKind) {} + ~CaptureRegionUnwinderRAII() { + if (ErrorFound) { + int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); + while (--ThisCaptureLevel >= 0) + S.ActOnCapturedRegionError(); + } + } +}; +} // namespace + StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, ArrayRef<OMPClause *> Clauses) { + bool ErrorFound = false; + CaptureRegionUnwinderRAII CaptureRegionUnwinder( + *this, ErrorFound, DSAStack->getCurrentDirective()); if (!S.isUsable()) { - ActOnCapturedRegionError(); + ErrorFound = true; return StmtError(); } @@ -1843,7 +1900,6 @@ StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, else if (Clause->getClauseKind() == OMPC_linear) LCs.push_back(cast<OMPLinearClause>(Clause)); } - bool ErrorFound = false; // OpenMP, 2.7.1 Loop Construct, Restrictions // The nonmonotonic modifier cannot be specified if an ordered clause is // specified. @@ -1874,10 +1930,14 @@ StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, ErrorFound = true; } if (ErrorFound) { - ActOnCapturedRegionError(); return StmtError(); } - return ActOnCapturedRegionEnd(S.get()); + StmtResult SR = S; + int ThisCaptureLevel = + getOpenMPCaptureLevels(DSAStack->getCurrentDirective()); + while (--ThisCaptureLevel >= 0) + SR = ActOnCapturedRegionEnd(SR.get()); + return SR; } static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index c2aa3fef67c..1d620bb6394 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7238,8 +7238,12 @@ StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective( StmtResult Body; { Sema::CompoundScopeRAII CompoundScope(getSema()); - Body = getDerived().TransformStmt( - cast<CapturedStmt>(D->getAssociatedStmt())->getCapturedStmt()); + int ThisCaptureLevel = + Sema::getOpenMPCaptureLevels(D->getDirectiveKind()); + Stmt *CS = D->getAssociatedStmt(); + while (--ThisCaptureLevel >= 0) + CS = cast<CapturedStmt>(CS)->getCapturedStmt(); + Body = getDerived().TransformStmt(CS); } AssociatedStmt = getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses); |