forked from OSchip/llvm-project
[OPENMP] Support for '#pragma omp taskgroup' directive.
Added parsing, sema analysis and codegen for '#pragma omp taskgroup' directive (OpenMP 4.0). The code for directive is generated the following way: #pragma omp taskgroup <body> void __kmpc_taskgroup(<loc>, thread_id); <body> void __kmpc_end_taskgroup(<loc>, thread_id); llvm-svn: 240011
This commit is contained in:
parent
22ef2c3e30
commit
c30dd2daf9
|
@ -2225,7 +2225,12 @@ enum CXCursorKind {
|
|||
*/
|
||||
CXCursor_OMPTeamsDirective = 253,
|
||||
|
||||
CXCursor_LastStmt = CXCursor_OMPTeamsDirective,
|
||||
/** \brief OpenMP taskwait directive.
|
||||
*/
|
||||
CXCursor_OMPTaskgroupDirective = 254,
|
||||
|
||||
|
||||
CXCursor_LastStmt = CXCursor_OMPTaskgroupDirective,
|
||||
|
||||
/**
|
||||
* \brief Cursor that represents the translation unit itself.
|
||||
|
|
|
@ -2355,6 +2355,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
|
|||
DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
DEF_TRAVERSE_STMT(OMPFlushDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
|
|
|
@ -2388,6 +2388,9 @@ DEF_TRAVERSE_STMT(OMPBarrierDirective,
|
|||
DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
DEF_TRAVERSE_STMT(OMPFlushDirective,
|
||||
{ TRY_TO(TraverseOMPExecutableDirective(S)); })
|
||||
|
||||
|
|
|
@ -1455,6 +1455,53 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// \brief This represents '#pragma omp taskgroup' directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp taskgroup
|
||||
/// \endcode
|
||||
///
|
||||
class OMPTaskgroupDirective : public OMPExecutableDirective {
|
||||
friend class ASTStmtReader;
|
||||
/// \brief Build directive with the given start and end location.
|
||||
///
|
||||
/// \param StartLoc Starting location of the directive kind.
|
||||
/// \param EndLoc Ending location of the directive.
|
||||
///
|
||||
OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
|
||||
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
|
||||
StartLoc, EndLoc, 0, 1) {}
|
||||
|
||||
/// \brief Build an empty directive.
|
||||
///
|
||||
explicit OMPTaskgroupDirective()
|
||||
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
|
||||
SourceLocation(), SourceLocation(), 0, 1) {}
|
||||
|
||||
public:
|
||||
/// \brief Creates directive.
|
||||
///
|
||||
/// \param C AST context.
|
||||
/// \param StartLoc Starting location of the directive kind.
|
||||
/// \param EndLoc Ending Location of the directive.
|
||||
/// \param AssociatedStmt Statement, associated with the directive.
|
||||
///
|
||||
static OMPTaskgroupDirective *Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
Stmt *AssociatedStmt);
|
||||
|
||||
/// \brief Creates an empty directive.
|
||||
///
|
||||
/// \param C AST context.
|
||||
///
|
||||
static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
|
||||
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == OMPTaskgroupDirectiveClass;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief This represents '#pragma omp flush' directive.
|
||||
///
|
||||
/// \code
|
||||
|
|
|
@ -84,6 +84,7 @@ OPENMP_DIRECTIVE(critical)
|
|||
OPENMP_DIRECTIVE(taskyield)
|
||||
OPENMP_DIRECTIVE(barrier)
|
||||
OPENMP_DIRECTIVE(taskwait)
|
||||
OPENMP_DIRECTIVE(taskgroup)
|
||||
OPENMP_DIRECTIVE(flush)
|
||||
OPENMP_DIRECTIVE(ordered)
|
||||
OPENMP_DIRECTIVE(atomic)
|
||||
|
|
|
@ -199,6 +199,7 @@ def OMPTaskDirective : DStmt<OMPExecutableDirective>;
|
|||
def OMPTaskyieldDirective : DStmt<OMPExecutableDirective>;
|
||||
def OMPBarrierDirective : DStmt<OMPExecutableDirective>;
|
||||
def OMPTaskwaitDirective : DStmt<OMPExecutableDirective>;
|
||||
def OMPTaskgroupDirective : DStmt<OMPExecutableDirective>;
|
||||
def OMPFlushDirective : DStmt<OMPExecutableDirective>;
|
||||
def OMPOrderedDirective : DStmt<OMPExecutableDirective>;
|
||||
def OMPAtomicDirective : DStmt<OMPExecutableDirective>;
|
||||
|
|
|
@ -7649,6 +7649,9 @@ public:
|
|||
/// \brief Called on well-formed '\#pragma omp taskwait'.
|
||||
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed '\#pragma omp taskgroup'.
|
||||
StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed '\#pragma omp flush'.
|
||||
StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
|
||||
SourceLocation StartLoc,
|
||||
|
|
|
@ -1396,6 +1396,7 @@ namespace clang {
|
|||
STMT_OMP_ATOMIC_DIRECTIVE,
|
||||
STMT_OMP_TARGET_DIRECTIVE,
|
||||
STMT_OMP_TEAMS_DIRECTIVE,
|
||||
STMT_OMP_TASKGROUP_DIRECTIVE,
|
||||
|
||||
// ARC
|
||||
EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr
|
||||
|
|
|
@ -1777,7 +1777,7 @@ OMPSectionDirective *OMPSectionDirective::Create(const ASTContext &C,
|
|||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
Stmt *AssociatedStmt) {
|
||||
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionsDirective),
|
||||
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPSectionDirective),
|
||||
llvm::alignOf<Stmt *>());
|
||||
void *Mem = C.Allocate(Size + sizeof(Stmt *));
|
||||
OMPSectionDirective *Dir = new (Mem) OMPSectionDirective(StartLoc, EndLoc);
|
||||
|
@ -2041,6 +2041,27 @@ OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C,
|
|||
return new (Mem) OMPTaskwaitDirective();
|
||||
}
|
||||
|
||||
OMPTaskgroupDirective *OMPTaskgroupDirective::Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
Stmt *AssociatedStmt) {
|
||||
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskgroupDirective),
|
||||
llvm::alignOf<Stmt *>());
|
||||
void *Mem = C.Allocate(Size + sizeof(Stmt *));
|
||||
OMPTaskgroupDirective *Dir =
|
||||
new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc);
|
||||
Dir->setAssociatedStmt(AssociatedStmt);
|
||||
return Dir;
|
||||
}
|
||||
|
||||
OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C,
|
||||
EmptyShell) {
|
||||
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPTaskgroupDirective),
|
||||
llvm::alignOf<Stmt *>());
|
||||
void *Mem = C.Allocate(Size + sizeof(Stmt *));
|
||||
return new (Mem) OMPTaskgroupDirective();
|
||||
}
|
||||
|
||||
OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc,
|
||||
|
|
|
@ -910,6 +910,11 @@ void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
|
|||
PrintOMPExecutableDirective(Node);
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
|
||||
Indent() << "#pragma omp taskgroup";
|
||||
PrintOMPExecutableDirective(Node);
|
||||
}
|
||||
|
||||
void StmtPrinter::VisitOMPFlushDirective(OMPFlushDirective *Node) {
|
||||
Indent() << "#pragma omp flush ";
|
||||
PrintOMPExecutableDirective(Node);
|
||||
|
|
|
@ -510,6 +510,10 @@ void StmtProfiler::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *S) {
|
|||
VisitOMPExecutableDirective(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *S) {
|
||||
VisitOMPExecutableDirective(S);
|
||||
}
|
||||
|
||||
void StmtProfiler::VisitOMPFlushDirective(const OMPFlushDirective *S) {
|
||||
VisitOMPExecutableDirective(S);
|
||||
}
|
||||
|
|
|
@ -332,6 +332,7 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
|||
case OMPD_taskyield:
|
||||
case OMPD_barrier:
|
||||
case OMPD_taskwait:
|
||||
case OMPD_taskgroup:
|
||||
case OMPD_ordered:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -741,7 +741,7 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {
|
|||
break;
|
||||
}
|
||||
case OMPRTL__kmpc_end_ordered: {
|
||||
// Build void __kmpc_ordered(ident_t *loc, kmp_int32 global_tid);
|
||||
// Build void __kmpc_end_ordered(ident_t *loc, kmp_int32 global_tid);
|
||||
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
|
||||
llvm::FunctionType *FnTy =
|
||||
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
|
||||
|
@ -756,6 +756,22 @@ CGOpenMPRuntime::createRuntimeFunction(OpenMPRTLFunction Function) {
|
|||
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_omp_taskwait");
|
||||
break;
|
||||
}
|
||||
case OMPRTL__kmpc_taskgroup: {
|
||||
// Build void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
|
||||
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
|
||||
llvm::FunctionType *FnTy =
|
||||
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
|
||||
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_taskgroup");
|
||||
break;
|
||||
}
|
||||
case OMPRTL__kmpc_end_taskgroup: {
|
||||
// Build void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
|
||||
llvm::Type *TypeParams[] = {getIdentTyPointerTy(), CGM.Int32Ty};
|
||||
llvm::FunctionType *FnTy =
|
||||
llvm::FunctionType::get(CGM.VoidTy, TypeParams, /*isVarArg=*/false);
|
||||
RTLFn = CGM.CreateRuntimeFunction(FnTy, "__kmpc_end_taskgroup");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return RTLFn;
|
||||
}
|
||||
|
@ -1240,6 +1256,25 @@ void CGOpenMPRuntime::emitTaskyieldCall(CodeGenFunction &CGF,
|
|||
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_omp_taskyield), Args);
|
||||
}
|
||||
|
||||
void CGOpenMPRuntime::emitTaskgroupRegion(CodeGenFunction &CGF,
|
||||
const RegionCodeGenTy &TaskgroupOpGen,
|
||||
SourceLocation Loc) {
|
||||
// __kmpc_taskgroup(ident_t *, gtid);
|
||||
// TaskgroupOpGen();
|
||||
// __kmpc_end_taskgroup(ident_t *, gtid);
|
||||
// Prepare arguments and build a call to __kmpc_taskgroup
|
||||
{
|
||||
CodeGenFunction::RunCleanupsScope Scope(CGF);
|
||||
llvm::Value *Args[] = {emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc)};
|
||||
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_taskgroup), Args);
|
||||
// Build a call to __kmpc_end_taskgroup
|
||||
CGF.EHStack.pushCleanup<CallEndCleanup<std::extent<decltype(Args)>::value>>(
|
||||
NormalAndEHCleanup, createRuntimeFunction(OMPRTL__kmpc_end_taskgroup),
|
||||
llvm::makeArrayRef(Args));
|
||||
emitInlinedDirective(CGF, TaskgroupOpGen);
|
||||
}
|
||||
}
|
||||
|
||||
static llvm::Value *emitCopyprivateCopyFunction(
|
||||
CodeGenModule &CGM, llvm::Type *ArgsType,
|
||||
ArrayRef<const Expr *> CopyprivateVars, ArrayRef<const Expr *> DestExprs,
|
||||
|
|
|
@ -131,6 +131,10 @@ private:
|
|||
// Call to kmp_int32 __kmpc_omp_taskwait(ident_t *loc, kmp_int32
|
||||
// global_tid);
|
||||
OMPRTL__kmpc_omp_taskwait,
|
||||
// Call to void __kmpc_taskgroup(ident_t *loc, kmp_int32 global_tid);
|
||||
OMPRTL__kmpc_taskgroup,
|
||||
// Call to void __kmpc_end_taskgroup(ident_t *loc, kmp_int32 global_tid);
|
||||
OMPRTL__kmpc_end_taskgroup,
|
||||
};
|
||||
|
||||
/// \brief Values for bit flags used in the ident_t to describe the fields.
|
||||
|
@ -388,6 +392,13 @@ public:
|
|||
/// \brief Emits code for a taskyield directive.
|
||||
virtual void emitTaskyieldCall(CodeGenFunction &CGF, SourceLocation Loc);
|
||||
|
||||
/// \brief Emit a taskgroup region.
|
||||
/// \param TaskgroupOpGen Generator for the statement associated with the
|
||||
/// given taskgroup region.
|
||||
virtual void emitTaskgroupRegion(CodeGenFunction &CGF,
|
||||
const RegionCodeGenTy &TaskgroupOpGen,
|
||||
SourceLocation Loc);
|
||||
|
||||
/// \brief Emits a single region.
|
||||
/// \param SingleOpGen Generator for the statement associated with the given
|
||||
/// single region.
|
||||
|
@ -401,7 +412,7 @@ public:
|
|||
|
||||
/// \brief Emit an ordered region.
|
||||
/// \param OrderedOpGen Generator for the statement associated with the given
|
||||
/// critical region.
|
||||
/// ordered region.
|
||||
virtual void emitOrderedRegion(CodeGenFunction &CGF,
|
||||
const RegionCodeGenTy &OrderedOpGen,
|
||||
SourceLocation Loc);
|
||||
|
|
|
@ -222,6 +222,9 @@ void CodeGenFunction::EmitStmt(const Stmt *S) {
|
|||
case Stmt::OMPTaskwaitDirectiveClass:
|
||||
EmitOMPTaskwaitDirective(cast<OMPTaskwaitDirective>(*S));
|
||||
break;
|
||||
case Stmt::OMPTaskgroupDirectiveClass:
|
||||
EmitOMPTaskgroupDirective(cast<OMPTaskgroupDirective>(*S));
|
||||
break;
|
||||
case Stmt::OMPFlushDirectiveClass:
|
||||
EmitOMPFlushDirective(cast<OMPFlushDirective>(*S));
|
||||
break;
|
||||
|
|
|
@ -1612,6 +1612,16 @@ void CodeGenFunction::EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S) {
|
|||
CGM.getOpenMPRuntime().emitTaskwaitCall(*this, S.getLocStart());
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPTaskgroupDirective(
|
||||
const OMPTaskgroupDirective &S) {
|
||||
LexicalScope Scope(*this, S.getSourceRange());
|
||||
auto &&CodeGen = [&S](CodeGenFunction &CGF) {
|
||||
CGF.EmitStmt(cast<CapturedStmt>(S.getAssociatedStmt())->getCapturedStmt());
|
||||
CGF.EnsureInsertPoint();
|
||||
};
|
||||
CGM.getOpenMPRuntime().emitTaskgroupRegion(*this, CodeGen, S.getLocStart());
|
||||
}
|
||||
|
||||
void CodeGenFunction::EmitOMPFlushDirective(const OMPFlushDirective &S) {
|
||||
CGM.getOpenMPRuntime().emitFlush(*this, [&]() -> ArrayRef<const Expr *> {
|
||||
if (auto C = S.getSingleClause(/*K*/ OMPC_flush)) {
|
||||
|
|
|
@ -2169,6 +2169,7 @@ public:
|
|||
void EmitOMPTaskyieldDirective(const OMPTaskyieldDirective &S);
|
||||
void EmitOMPBarrierDirective(const OMPBarrierDirective &S);
|
||||
void EmitOMPTaskwaitDirective(const OMPTaskwaitDirective &S);
|
||||
void EmitOMPTaskgroupDirective(const OMPTaskgroupDirective &S);
|
||||
void EmitOMPFlushDirective(const OMPFlushDirective &S);
|
||||
void EmitOMPOrderedDirective(const OMPOrderedDirective &S);
|
||||
void EmitOMPAtomicDirective(const OMPAtomicDirective &S);
|
||||
|
|
|
@ -94,6 +94,7 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
|
|||
case OMPD_taskyield:
|
||||
case OMPD_barrier:
|
||||
case OMPD_taskwait:
|
||||
case OMPD_taskgroup:
|
||||
case OMPD_flush:
|
||||
case OMPD_for:
|
||||
case OMPD_for_simd:
|
||||
|
@ -128,7 +129,8 @@ Parser::DeclGroupPtrTy Parser::ParseOpenMPDeclarativeDirective() {
|
|||
/// 'section' | 'single' | 'master' | 'critical' [ '(' <name> ')' ] |
|
||||
/// 'parallel for' | 'parallel sections' | 'task' | 'taskyield' |
|
||||
/// 'barrier' | 'taskwait' | 'flush' | 'ordered' | 'atomic' |
|
||||
/// 'for simd' | 'parallel for simd' | 'target' | 'teams' {clause}
|
||||
/// 'for simd' | 'parallel for simd' | 'target' | 'teams' | 'taskgroup'
|
||||
/// {clause}
|
||||
/// annot_pragma_openmp_end
|
||||
///
|
||||
StmtResult
|
||||
|
@ -198,7 +200,8 @@ Parser::ParseOpenMPDeclarativeOrExecutableDirective(bool StandAloneAllowed) {
|
|||
case OMPD_ordered:
|
||||
case OMPD_atomic:
|
||||
case OMPD_target:
|
||||
case OMPD_teams: {
|
||||
case OMPD_teams:
|
||||
case OMPD_taskgroup: {
|
||||
ConsumeToken();
|
||||
// Parse directive name of the 'critical' directive if any.
|
||||
if (DKind == OMPD_critical) {
|
||||
|
|
|
@ -1270,6 +1270,14 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
|
|||
Params);
|
||||
break;
|
||||
}
|
||||
case OMPD_taskgroup: {
|
||||
Sema::CapturedParamNameType Params[] = {
|
||||
std::make_pair(StringRef(), QualType()) // __context with shared vars
|
||||
};
|
||||
ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
|
||||
Params);
|
||||
break;
|
||||
}
|
||||
case OMPD_threadprivate:
|
||||
case OMPD_taskyield:
|
||||
case OMPD_barrier:
|
||||
|
@ -1335,6 +1343,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | parallel | taskyield | * |
|
||||
// | parallel | barrier | * |
|
||||
// | parallel | taskwait | * |
|
||||
// | parallel | taskgroup | * |
|
||||
// | parallel | flush | * |
|
||||
// | parallel | ordered | + |
|
||||
// | parallel | atomic | * |
|
||||
|
@ -1357,6 +1366,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | for | taskyield | * |
|
||||
// | for | barrier | + |
|
||||
// | for | taskwait | * |
|
||||
// | for | taskgroup | * |
|
||||
// | for | flush | * |
|
||||
// | for | ordered | * (if construct is ordered) |
|
||||
// | for | atomic | * |
|
||||
|
@ -1379,6 +1389,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | master | taskyield | * |
|
||||
// | master | barrier | + |
|
||||
// | master | taskwait | * |
|
||||
// | master | taskgroup | * |
|
||||
// | master | flush | * |
|
||||
// | master | ordered | + |
|
||||
// | master | atomic | * |
|
||||
|
@ -1401,6 +1412,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | critical | taskyield | * |
|
||||
// | critical | barrier | + |
|
||||
// | critical | taskwait | * |
|
||||
// | critical | taskgroup | * |
|
||||
// | critical | ordered | + |
|
||||
// | critical | atomic | * |
|
||||
// | critical | target | * |
|
||||
|
@ -1422,6 +1434,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | simd | taskyield | |
|
||||
// | simd | barrier | |
|
||||
// | simd | taskwait | |
|
||||
// | simd | taskgroup | |
|
||||
// | simd | flush | |
|
||||
// | simd | ordered | |
|
||||
// | simd | atomic | |
|
||||
|
@ -1444,6 +1457,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | for simd | taskyield | |
|
||||
// | for simd | barrier | |
|
||||
// | for simd | taskwait | |
|
||||
// | for simd | taskgroup | |
|
||||
// | for simd | flush | |
|
||||
// | for simd | ordered | |
|
||||
// | for simd | atomic | |
|
||||
|
@ -1466,6 +1480,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | parallel for simd| taskyield | |
|
||||
// | parallel for simd| barrier | |
|
||||
// | parallel for simd| taskwait | |
|
||||
// | parallel for simd| taskgroup | |
|
||||
// | parallel for simd| flush | |
|
||||
// | parallel for simd| ordered | |
|
||||
// | parallel for simd| atomic | |
|
||||
|
@ -1488,6 +1503,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | sections | taskyield | * |
|
||||
// | sections | barrier | + |
|
||||
// | sections | taskwait | * |
|
||||
// | sections | taskgroup | * |
|
||||
// | sections | flush | * |
|
||||
// | sections | ordered | + |
|
||||
// | sections | atomic | * |
|
||||
|
@ -1510,6 +1526,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | section | taskyield | * |
|
||||
// | section | barrier | + |
|
||||
// | section | taskwait | * |
|
||||
// | section | taskgroup | * |
|
||||
// | section | flush | * |
|
||||
// | section | ordered | + |
|
||||
// | section | atomic | * |
|
||||
|
@ -1532,6 +1549,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | single | taskyield | * |
|
||||
// | single | barrier | + |
|
||||
// | single | taskwait | * |
|
||||
// | single | taskgroup | * |
|
||||
// | single | flush | * |
|
||||
// | single | ordered | + |
|
||||
// | single | atomic | * |
|
||||
|
@ -1554,6 +1572,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | parallel for | taskyield | * |
|
||||
// | parallel for | barrier | + |
|
||||
// | parallel for | taskwait | * |
|
||||
// | parallel for | taskgroup | * |
|
||||
// | parallel for | flush | * |
|
||||
// | parallel for | ordered | * (if construct is ordered) |
|
||||
// | parallel for | atomic | * |
|
||||
|
@ -1576,6 +1595,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | parallel sections| taskyield | * |
|
||||
// | parallel sections| barrier | + |
|
||||
// | parallel sections| taskwait | * |
|
||||
// | parallel sections| taskgroup | * |
|
||||
// | parallel sections| flush | * |
|
||||
// | parallel sections| ordered | + |
|
||||
// | parallel sections| atomic | * |
|
||||
|
@ -1598,6 +1618,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | task | taskyield | * |
|
||||
// | task | barrier | + |
|
||||
// | task | taskwait | * |
|
||||
// | task | taskgroup | * |
|
||||
// | task | flush | * |
|
||||
// | task | ordered | + |
|
||||
// | task | atomic | * |
|
||||
|
@ -1620,6 +1641,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | ordered | taskyield | * |
|
||||
// | ordered | barrier | + |
|
||||
// | ordered | taskwait | * |
|
||||
// | ordered | taskgroup | * |
|
||||
// | ordered | flush | * |
|
||||
// | ordered | ordered | + |
|
||||
// | ordered | atomic | * |
|
||||
|
@ -1642,6 +1664,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | atomic | taskyield | |
|
||||
// | atomic | barrier | |
|
||||
// | atomic | taskwait | |
|
||||
// | atomic | taskgroup | |
|
||||
// | atomic | flush | |
|
||||
// | atomic | ordered | |
|
||||
// | atomic | atomic | |
|
||||
|
@ -1664,6 +1687,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | target | taskyield | * |
|
||||
// | target | barrier | * |
|
||||
// | target | taskwait | * |
|
||||
// | target | taskgroup | * |
|
||||
// | target | flush | * |
|
||||
// | target | ordered | * |
|
||||
// | target | atomic | * |
|
||||
|
@ -1686,6 +1710,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | teams | taskyield | + |
|
||||
// | teams | barrier | + |
|
||||
// | teams | taskwait | + |
|
||||
// | teams | taskgroup | + |
|
||||
// | teams | flush | + |
|
||||
// | teams | ordered | + |
|
||||
// | teams | atomic | + |
|
||||
|
@ -1936,6 +1961,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,
|
|||
"No associated statement allowed for 'omp taskwait' directive");
|
||||
Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
|
||||
break;
|
||||
case OMPD_taskgroup:
|
||||
assert(ClausesWithImplicit.empty() &&
|
||||
"No clauses are allowed for 'omp taskgroup' directive");
|
||||
Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc);
|
||||
break;
|
||||
case OMPD_flush:
|
||||
assert(AStmt == nullptr &&
|
||||
"No associated statement allowed for 'omp flush' directive");
|
||||
|
@ -3398,6 +3428,16 @@ StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
|
|||
return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
|
||||
}
|
||||
|
||||
StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected");
|
||||
|
||||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt);
|
||||
}
|
||||
|
||||
StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
|
|
|
@ -6870,6 +6870,17 @@ TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
|
|||
return Res;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
|
||||
OMPTaskgroupDirective *D) {
|
||||
DeclarationNameInfo DirName;
|
||||
getDerived().getSema().StartOpenMPDSABlock(OMPD_taskgroup, DirName, nullptr,
|
||||
D->getLocStart());
|
||||
StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
|
||||
getDerived().getSema().EndOpenMPDSABlock(Res.get());
|
||||
return Res;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
StmtResult
|
||||
TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
|
||||
|
|
|
@ -2189,6 +2189,11 @@ void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
|
|||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
|
||||
VisitStmt(D);
|
||||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void ASTStmtReader::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
||||
VisitStmt(D);
|
||||
// The NumClauses field was read in ReadStmtFromStream.
|
||||
|
@ -2803,6 +2808,10 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
|||
S = OMPTaskwaitDirective::CreateEmpty(Context, Empty);
|
||||
break;
|
||||
|
||||
case STMT_OMP_TASKGROUP_DIRECTIVE:
|
||||
S = OMPTaskgroupDirective::CreateEmpty(Context, Empty);
|
||||
break;
|
||||
|
||||
case STMT_OMP_FLUSH_DIRECTIVE:
|
||||
S = OMPFlushDirective::CreateEmpty(
|
||||
Context, Record[ASTStmtReader::NumStmtFields], Empty);
|
||||
|
|
|
@ -2071,6 +2071,12 @@ void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
|
|||
Code = serialization::STMT_OMP_TASKWAIT_DIRECTIVE;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
|
||||
VisitStmt(D);
|
||||
VisitOMPExecutableDirective(D);
|
||||
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
|
||||
}
|
||||
|
||||
void ASTStmtWriter::VisitOMPFlushDirective(OMPFlushDirective *D) {
|
||||
VisitStmt(D);
|
||||
Record.push_back(D->getNumClauses());
|
||||
|
|
|
@ -816,6 +816,7 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
|
|||
case Stmt::OMPTaskyieldDirectiveClass:
|
||||
case Stmt::OMPBarrierDirectiveClass:
|
||||
case Stmt::OMPTaskwaitDirectiveClass:
|
||||
case Stmt::OMPTaskgroupDirectiveClass:
|
||||
case Stmt::OMPFlushDirectiveClass:
|
||||
case Stmt::OMPOrderedDirectiveClass:
|
||||
case Stmt::OMPAtomicDirectiveClass:
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -ast-print %s | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -std=c++11 -include-pch %t -fsyntax-only -verify %s -ast-print | FileCheck %s
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
void foo() {}
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int b = argc, c, d, e, f, g;
|
||||
static int a;
|
||||
// CHECK: static int a;
|
||||
#pragma omp taskgroup
|
||||
a=2;
|
||||
// CHECK-NEXT: #pragma omp taskgroup
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: ++a;
|
||||
++a;
|
||||
#pragma omp taskgroup
|
||||
foo();
|
||||
// CHECK-NEXT: #pragma omp taskgroup
|
||||
// CHECK-NEXT: foo();
|
||||
// CHECK-NEXT: return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,56 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp -x c++ -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
|
||||
// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -fexceptions -fcxx-exceptions -gline-tables-only -x c++ -emit-llvm %s -o - | FileCheck %s --check-prefix=TERM_DEBUG
|
||||
// expected-no-diagnostics
|
||||
|
||||
#ifndef HEADER
|
||||
#define HEADER
|
||||
|
||||
// CHECK: [[IDENT_T_TY:%.+]] = type { i32, i32, i32, i32, i8* }
|
||||
|
||||
// CHECK: define void [[FOO:@.+]]()
|
||||
|
||||
void foo() {}
|
||||
|
||||
// CHECK-LABEL: @main
|
||||
// TERM_DEBUG-LABEL: @main
|
||||
int main() {
|
||||
// CHECK: [[A_ADDR:%.+]] = alloca i8
|
||||
char a;
|
||||
|
||||
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num([[IDENT_T_TY]]* [[DEFAULT_LOC:@.+]])
|
||||
// CHECK: call void @__kmpc_taskgroup([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
|
||||
// CHECK-NEXT: store i8 2, i8* [[A_ADDR]]
|
||||
// CHECK-NEXT: call void @__kmpc_end_taskgroup([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
|
||||
#pragma omp taskgroup
|
||||
a = 2;
|
||||
// CHECK: call void @__kmpc_taskgroup([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
|
||||
// CHECK-NEXT: invoke void [[FOO]]()
|
||||
// CHECK: call void @__kmpc_end_taskgroup([[IDENT_T_TY]]* [[DEFAULT_LOC]], i32 [[GTID]])
|
||||
#pragma omp taskgroup
|
||||
foo();
|
||||
// CHECK-NOT: call void @__kmpc_taskgroup
|
||||
// CHECK-NOT: call void @__kmpc_end_taskgroup
|
||||
return a;
|
||||
}
|
||||
|
||||
// CHECK-LABEL: parallel_taskgroup
|
||||
// TERM_DEBUG-LABEL: parallel_taskgroup
|
||||
void parallel_taskgroup() {
|
||||
#pragma omp parallel
|
||||
#pragma omp taskgroup
|
||||
// TERM_DEBUG-NOT: __kmpc_global_thread_num
|
||||
// TERM_DEBUG: call void @__kmpc_taskgroup({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]]
|
||||
// TERM_DEBUG: invoke void {{.*}}foo{{.*}}()
|
||||
// TERM_DEBUG: unwind label %[[TERM_LPAD:.+]],
|
||||
// TERM_DEBUG-NOT: __kmpc_global_thread_num
|
||||
// TERM_DEBUG: call void @__kmpc_end_taskgroup({{.+}}), !dbg [[DBG_LOC_END:![0-9]+]]
|
||||
// TERM_DEBUG: [[TERM_LPAD]]
|
||||
// TERM_DEBUG: call void @__clang_call_terminate
|
||||
// TERM_DEBUG: unreachable
|
||||
foo();
|
||||
}
|
||||
// TERM_DEBUG-DAG: [[DBG_LOC_START]] = !DILocation(line: [[@LINE-12]],
|
||||
// TERM_DEBUG-DAG: [[DBG_LOC_END]] = !DILocation(line: [[@LINE-3]],
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
// RUN: %clang_cc1 -verify -fopenmp %s
|
||||
|
||||
int foo();
|
||||
|
||||
int main() {
|
||||
#pragma omp taskgroup
|
||||
;
|
||||
#pragma omp taskgroup unknown // expected-warning {{extra tokens at the end of '#pragma omp taskgroup' are ignored}}
|
||||
foo();
|
||||
{
|
||||
#pragma omp taskgroup
|
||||
} // expected-error {{expected statement}}
|
||||
#pragma omp taskgroup
|
||||
#pragma omp taskgroup
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp for
|
||||
for (int j = 0; j < 10; j++) {
|
||||
foo();
|
||||
#pragma omp taskgroup
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp taskgroup
|
||||
#pragma omp taskgroup
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp for
|
||||
for (int j = 0; j < 10; j++) {
|
||||
#pragma omp taskgroup
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp taskgroup
|
||||
#pragma omp taskgroup
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
foo();
|
||||
#pragma omp parallel
|
||||
#pragma omp for
|
||||
for (int j = 0; j < 10; j++) {
|
||||
#pragma omp taskgroup
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int foo() {
|
||||
L1:
|
||||
foo();
|
||||
#pragma omp taskgroup
|
||||
{
|
||||
foo();
|
||||
goto L1; // expected-error {{use of undeclared label 'L1'}}
|
||||
}
|
||||
goto L2; // expected-error {{use of undeclared label 'L2'}}
|
||||
#pragma omp taskgroup
|
||||
{
|
||||
L2:
|
||||
foo();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1879,6 +1879,7 @@ public:
|
|||
void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
|
||||
void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
|
||||
void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
|
||||
void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
|
||||
void VisitOMPFlushDirective(const OMPFlushDirective *D);
|
||||
void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
|
||||
void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
|
||||
|
@ -2478,6 +2479,11 @@ void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
|
|||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void EnqueueVisitor::VisitOMPTaskgroupDirective(
|
||||
const OMPTaskgroupDirective *D) {
|
||||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
||||
void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
|
||||
VisitOMPExecutableDirective(D);
|
||||
}
|
||||
|
@ -4260,6 +4266,8 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
|
|||
return cxstring::createRef("OMPBarrierDirective");
|
||||
case CXCursor_OMPTaskwaitDirective:
|
||||
return cxstring::createRef("OMPTaskwaitDirective");
|
||||
case CXCursor_OMPTaskgroupDirective:
|
||||
return cxstring::createRef("OMPTaskgroupDirective");
|
||||
case CXCursor_OMPFlushDirective:
|
||||
return cxstring::createRef("OMPFlushDirective");
|
||||
case CXCursor_OMPOrderedDirective:
|
||||
|
|
|
@ -570,6 +570,9 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
|
|||
case Stmt::OMPTaskwaitDirectiveClass:
|
||||
K = CXCursor_OMPTaskwaitDirective;
|
||||
break;
|
||||
case Stmt::OMPTaskgroupDirectiveClass:
|
||||
K = CXCursor_OMPTaskgroupDirective;
|
||||
break;
|
||||
case Stmt::OMPFlushDirectiveClass:
|
||||
K = CXCursor_OMPFlushDirective;
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue