[OPENMP 4.0] Add 'if' clause for 'cancel' directive.
Add parsing, sema analysis and codegen for 'if' clause in 'cancel' directive. llvm-svn: 247976
This commit is contained in:
parent
fbbc0b8cec
commit
87933c7ced
|
@ -2127,17 +2127,21 @@ class OMPCancelDirective : public OMPExecutableDirective {
|
||||||
///
|
///
|
||||||
/// \param StartLoc Starting location of the directive kind.
|
/// \param StartLoc Starting location of the directive kind.
|
||||||
/// \param EndLoc Ending location of the directive.
|
/// \param EndLoc Ending location of the directive.
|
||||||
|
/// \param NumClauses Number of clauses.
|
||||||
///
|
///
|
||||||
OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
|
OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
|
||||||
|
unsigned NumClauses)
|
||||||
: OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
|
: OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
|
||||||
StartLoc, EndLoc, 0, 0),
|
StartLoc, EndLoc, NumClauses, 0),
|
||||||
CancelRegion(OMPD_unknown) {}
|
CancelRegion(OMPD_unknown) {}
|
||||||
|
|
||||||
/// \brief Build an empty directive.
|
/// \brief Build an empty directive.
|
||||||
///
|
///
|
||||||
explicit OMPCancelDirective()
|
/// \param NumClauses Number of clauses.
|
||||||
|
explicit OMPCancelDirective(unsigned NumClauses)
|
||||||
: OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
|
: OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
|
||||||
SourceLocation(), SourceLocation(), 0, 0),
|
SourceLocation(), SourceLocation(), NumClauses,
|
||||||
|
0),
|
||||||
CancelRegion(OMPD_unknown) {}
|
CancelRegion(OMPD_unknown) {}
|
||||||
|
|
||||||
/// \brief Set cancel region for current cancellation point.
|
/// \brief Set cancel region for current cancellation point.
|
||||||
|
@ -2150,17 +2154,19 @@ public:
|
||||||
/// \param C AST context.
|
/// \param C AST context.
|
||||||
/// \param StartLoc Starting location of the directive kind.
|
/// \param StartLoc Starting location of the directive kind.
|
||||||
/// \param EndLoc Ending Location of the directive.
|
/// \param EndLoc Ending Location of the directive.
|
||||||
|
/// \param Clauses List of clauses.
|
||||||
///
|
///
|
||||||
static OMPCancelDirective *Create(const ASTContext &C,
|
static OMPCancelDirective *
|
||||||
SourceLocation StartLoc,
|
Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
|
||||||
SourceLocation EndLoc,
|
ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
|
||||||
OpenMPDirectiveKind CancelRegion);
|
|
||||||
|
|
||||||
/// \brief Creates an empty directive.
|
/// \brief Creates an empty directive.
|
||||||
///
|
///
|
||||||
/// \param C AST context.
|
/// \param C AST context.
|
||||||
|
/// \param NumClauses Number of clauses.
|
||||||
///
|
///
|
||||||
static OMPCancelDirective *CreateEmpty(const ASTContext &C, EmptyShell);
|
static OMPCancelDirective *CreateEmpty(const ASTContext &C,
|
||||||
|
unsigned NumClauses, EmptyShell);
|
||||||
|
|
||||||
/// \brief Get cancellation region for the current cancellation point.
|
/// \brief Get cancellation region for the current cancellation point.
|
||||||
OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
|
OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
|
||||||
|
|
|
@ -63,6 +63,9 @@
|
||||||
#ifndef OPENMP_TEAMS_CLAUSE
|
#ifndef OPENMP_TEAMS_CLAUSE
|
||||||
# define OPENMP_TEAMS_CLAUSE(Name)
|
# define OPENMP_TEAMS_CLAUSE(Name)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef OPENMP_CANCEL_CLAUSE
|
||||||
|
# define OPENMP_CANCEL_CLAUSE(Name)
|
||||||
|
#endif
|
||||||
#ifndef OPENMP_DEFAULT_KIND
|
#ifndef OPENMP_DEFAULT_KIND
|
||||||
# define OPENMP_DEFAULT_KIND(Name)
|
# define OPENMP_DEFAULT_KIND(Name)
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,6 +200,9 @@ OPENMP_SINGLE_CLAUSE(firstprivate)
|
||||||
OPENMP_SINGLE_CLAUSE(copyprivate)
|
OPENMP_SINGLE_CLAUSE(copyprivate)
|
||||||
OPENMP_SINGLE_CLAUSE(nowait)
|
OPENMP_SINGLE_CLAUSE(nowait)
|
||||||
|
|
||||||
|
// Clauses allowed for OpenMP directive 'cancel'.
|
||||||
|
OPENMP_CANCEL_CLAUSE(if)
|
||||||
|
|
||||||
// Static attributes for 'default' clause.
|
// Static attributes for 'default' clause.
|
||||||
OPENMP_DEFAULT_KIND(none)
|
OPENMP_DEFAULT_KIND(none)
|
||||||
OPENMP_DEFAULT_KIND(shared)
|
OPENMP_DEFAULT_KIND(shared)
|
||||||
|
@ -313,6 +319,7 @@ OPENMP_TEAMS_CLAUSE(reduction)
|
||||||
#undef OPENMP_DIRECTIVE
|
#undef OPENMP_DIRECTIVE
|
||||||
#undef OPENMP_DIRECTIVE_EXT
|
#undef OPENMP_DIRECTIVE_EXT
|
||||||
#undef OPENMP_CLAUSE
|
#undef OPENMP_CLAUSE
|
||||||
|
#undef OPENMP_CANCEL_CLAUSE
|
||||||
#undef OPENMP_SINGLE_CLAUSE
|
#undef OPENMP_SINGLE_CLAUSE
|
||||||
#undef OPENMP_SECTIONS_CLAUSE
|
#undef OPENMP_SECTIONS_CLAUSE
|
||||||
#undef OPENMP_PARALLEL_CLAUSE
|
#undef OPENMP_PARALLEL_CLAUSE
|
||||||
|
|
|
@ -7884,7 +7884,8 @@ public:
|
||||||
SourceLocation EndLoc,
|
SourceLocation EndLoc,
|
||||||
OpenMPDirectiveKind CancelRegion);
|
OpenMPDirectiveKind CancelRegion);
|
||||||
/// \brief Called on well-formed '\#pragma omp cancel'.
|
/// \brief Called on well-formed '\#pragma omp cancel'.
|
||||||
StmtResult ActOnOpenMPCancelDirective(SourceLocation StartLoc,
|
StmtResult ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
|
||||||
|
SourceLocation StartLoc,
|
||||||
SourceLocation EndLoc,
|
SourceLocation EndLoc,
|
||||||
OpenMPDirectiveKind CancelRegion);
|
OpenMPDirectiveKind CancelRegion);
|
||||||
|
|
||||||
|
|
|
@ -2128,22 +2128,27 @@ OMPCancellationPointDirective::CreateEmpty(const ASTContext &C, EmptyShell) {
|
||||||
|
|
||||||
OMPCancelDirective *
|
OMPCancelDirective *
|
||||||
OMPCancelDirective::Create(const ASTContext &C, SourceLocation StartLoc,
|
OMPCancelDirective::Create(const ASTContext &C, SourceLocation StartLoc,
|
||||||
SourceLocation EndLoc,
|
SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses,
|
||||||
OpenMPDirectiveKind CancelRegion) {
|
OpenMPDirectiveKind CancelRegion) {
|
||||||
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCancelDirective),
|
unsigned Size = llvm::RoundUpToAlignment(
|
||||||
llvm::alignOf<Stmt *>());
|
sizeof(OMPCancelDirective) + sizeof(OMPClause *) * Clauses.size(),
|
||||||
|
llvm::alignOf<Stmt *>());
|
||||||
void *Mem = C.Allocate(Size);
|
void *Mem = C.Allocate(Size);
|
||||||
OMPCancelDirective *Dir = new (Mem) OMPCancelDirective(StartLoc, EndLoc);
|
OMPCancelDirective *Dir =
|
||||||
|
new (Mem) OMPCancelDirective(StartLoc, EndLoc, Clauses.size());
|
||||||
|
Dir->setClauses(Clauses);
|
||||||
Dir->setCancelRegion(CancelRegion);
|
Dir->setCancelRegion(CancelRegion);
|
||||||
return Dir;
|
return Dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
OMPCancelDirective *OMPCancelDirective::CreateEmpty(const ASTContext &C,
|
OMPCancelDirective *OMPCancelDirective::CreateEmpty(const ASTContext &C,
|
||||||
|
unsigned NumClauses,
|
||||||
EmptyShell) {
|
EmptyShell) {
|
||||||
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCancelDirective),
|
unsigned Size = llvm::RoundUpToAlignment(sizeof(OMPCancelDirective) +
|
||||||
|
sizeof(OMPClause *) * NumClauses,
|
||||||
llvm::alignOf<Stmt *>());
|
llvm::alignOf<Stmt *>());
|
||||||
void *Mem = C.Allocate(Size);
|
void *Mem = C.Allocate(Size);
|
||||||
return new (Mem) OMPCancelDirective();
|
return new (Mem) OMPCancelDirective(NumClauses);
|
||||||
}
|
}
|
||||||
|
|
||||||
OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C,
|
OMPFlushDirective *OMPFlushDirective::Create(const ASTContext &C,
|
||||||
|
|
|
@ -991,7 +991,7 @@ void StmtPrinter::VisitOMPCancellationPointDirective(
|
||||||
|
|
||||||
void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
|
void StmtPrinter::VisitOMPCancelDirective(OMPCancelDirective *Node) {
|
||||||
Indent() << "#pragma omp cancel "
|
Indent() << "#pragma omp cancel "
|
||||||
<< getOpenMPDirectiveName(Node->getCancelRegion());
|
<< getOpenMPDirectiveName(Node->getCancelRegion()) << " ";
|
||||||
PrintOMPExecutableDirective(Node);
|
PrintOMPExecutableDirective(Node);
|
||||||
}
|
}
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -360,6 +360,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
||||||
#define OPENMP_TEAMS_CLAUSE(Name) \
|
#define OPENMP_TEAMS_CLAUSE(Name) \
|
||||||
case OMPC_##Name: \
|
case OMPC_##Name: \
|
||||||
return true;
|
return true;
|
||||||
|
#include "clang/Basic/OpenMPKinds.def"
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OMPD_cancel:
|
||||||
|
switch (CKind) {
|
||||||
|
#define OPENMP_CANCEL_CLAUSE(Name) \
|
||||||
|
case OMPC_##Name: \
|
||||||
|
return true;
|
||||||
#include "clang/Basic/OpenMPKinds.def"
|
#include "clang/Basic/OpenMPKinds.def"
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -375,7 +385,6 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
|
||||||
case OMPD_taskwait:
|
case OMPD_taskwait:
|
||||||
case OMPD_taskgroup:
|
case OMPD_taskgroup:
|
||||||
case OMPD_cancellation_point:
|
case OMPD_cancellation_point:
|
||||||
case OMPD_cancel:
|
|
||||||
case OMPD_ordered:
|
case OMPD_ordered:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2914,6 +2914,7 @@ void CGOpenMPRuntime::emitCancellationPointCall(
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
|
void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
|
const Expr *IfCond,
|
||||||
OpenMPDirectiveKind CancelRegion) {
|
OpenMPDirectiveKind CancelRegion) {
|
||||||
// Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
|
// Build call kmp_int32 __kmpc_cancel(ident_t *loc, kmp_int32 global_tid,
|
||||||
// kmp_int32 cncl_kind);
|
// kmp_int32 cncl_kind);
|
||||||
|
@ -2921,27 +2922,34 @@ void CGOpenMPRuntime::emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
|
dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) {
|
||||||
if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
|
if (OMPRegionInfo->getDirectiveKind() == OMPD_single)
|
||||||
return;
|
return;
|
||||||
llvm::Value *Args[] = {
|
auto &&ThenGen = [this, Loc, CancelRegion,
|
||||||
emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
|
OMPRegionInfo](CodeGenFunction &CGF) {
|
||||||
CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
|
llvm::Value *Args[] = {
|
||||||
// Ignore return result until untied tasks are supported.
|
emitUpdateLocation(CGF, Loc), getThreadID(CGF, Loc),
|
||||||
auto *Result =
|
CGF.Builder.getInt32(getCancellationKind(CancelRegion))};
|
||||||
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
|
// Ignore return result until untied tasks are supported.
|
||||||
// if (__kmpc_cancel()) {
|
auto *Result =
|
||||||
// __kmpc_cancel_barrier();
|
CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_cancel), Args);
|
||||||
// exit from construct;
|
// if (__kmpc_cancel()) {
|
||||||
// }
|
// __kmpc_cancel_barrier();
|
||||||
auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
|
// exit from construct;
|
||||||
auto *ContBB = CGF.createBasicBlock(".cancel.continue");
|
// }
|
||||||
auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
|
auto *ExitBB = CGF.createBasicBlock(".cancel.exit");
|
||||||
CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
|
auto *ContBB = CGF.createBasicBlock(".cancel.continue");
|
||||||
CGF.EmitBlock(ExitBB);
|
auto *Cmp = CGF.Builder.CreateIsNotNull(Result);
|
||||||
// __kmpc_cancel_barrier();
|
CGF.Builder.CreateCondBr(Cmp, ExitBB, ContBB);
|
||||||
emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
|
CGF.EmitBlock(ExitBB);
|
||||||
// exit from construct;
|
// __kmpc_cancel_barrier();
|
||||||
auto CancelDest =
|
emitBarrierCall(CGF, Loc, OMPD_unknown, /*EmitChecks=*/false);
|
||||||
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
|
// exit from construct;
|
||||||
CGF.EmitBranchThroughCleanup(CancelDest);
|
auto CancelDest =
|
||||||
CGF.EmitBlock(ContBB, /*IsFinished=*/true);
|
CGF.getOMPCancelDestination(OMPRegionInfo->getDirectiveKind());
|
||||||
|
CGF.EmitBranchThroughCleanup(CancelDest);
|
||||||
|
CGF.EmitBlock(ContBB, /*IsFinished=*/true);
|
||||||
|
};
|
||||||
|
if (IfCond)
|
||||||
|
emitOMPIfClause(CGF, IfCond, ThenGen, [](CodeGenFunction &) {});
|
||||||
|
else
|
||||||
|
ThenGen(CGF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -718,9 +718,12 @@ public:
|
||||||
OpenMPDirectiveKind CancelRegion);
|
OpenMPDirectiveKind CancelRegion);
|
||||||
|
|
||||||
/// \brief Emit code for 'cancel' construct.
|
/// \brief Emit code for 'cancel' construct.
|
||||||
|
/// \param IfCond Condition in the associated 'if' clause, if it was
|
||||||
|
/// specified, nullptr otherwise.
|
||||||
/// \param CancelRegion Region kind for which the cancel must be emitted.
|
/// \param CancelRegion Region kind for which the cancel must be emitted.
|
||||||
///
|
///
|
||||||
virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
|
virtual void emitCancelCall(CodeGenFunction &CGF, SourceLocation Loc,
|
||||||
|
const Expr *IfCond,
|
||||||
OpenMPDirectiveKind CancelRegion);
|
OpenMPDirectiveKind CancelRegion);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2262,7 +2262,15 @@ void CodeGenFunction::EmitOMPCancellationPointDirective(
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
|
void CodeGenFunction::EmitOMPCancelDirective(const OMPCancelDirective &S) {
|
||||||
CGM.getOpenMPRuntime().emitCancelCall(*this, S.getLocStart(),
|
const Expr *IfCond = nullptr;
|
||||||
|
for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
|
||||||
|
if (C->getNameModifier() == OMPD_unknown ||
|
||||||
|
C->getNameModifier() == OMPD_cancel) {
|
||||||
|
IfCond = C->getCondition();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CGM.getOpenMPRuntime().emitCancelCall(*this, S.getLocStart(), IfCond,
|
||||||
S.getCancelRegion());
|
S.getCancelRegion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2245,11 +2245,11 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
|
||||||
Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
|
Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
|
||||||
break;
|
break;
|
||||||
case OMPD_cancel:
|
case OMPD_cancel:
|
||||||
assert(ClausesWithImplicit.empty() &&
|
|
||||||
"No clauses are allowed for 'omp cancel' directive");
|
|
||||||
assert(AStmt == nullptr &&
|
assert(AStmt == nullptr &&
|
||||||
"No associated statement allowed for 'omp cancel' directive");
|
"No associated statement allowed for 'omp cancel' directive");
|
||||||
Res = ActOnOpenMPCancelDirective(StartLoc, EndLoc, CancelRegion);
|
Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
|
||||||
|
CancelRegion);
|
||||||
|
AllowedNameModifiers.push_back(OMPD_cancel);
|
||||||
break;
|
break;
|
||||||
case OMPD_target_data:
|
case OMPD_target_data:
|
||||||
Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
|
Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
|
||||||
|
@ -4909,7 +4909,8 @@ Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
|
||||||
CancelRegion);
|
CancelRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
StmtResult Sema::ActOnOpenMPCancelDirective(SourceLocation StartLoc,
|
StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
|
||||||
|
SourceLocation StartLoc,
|
||||||
SourceLocation EndLoc,
|
SourceLocation EndLoc,
|
||||||
OpenMPDirectiveKind CancelRegion) {
|
OpenMPDirectiveKind CancelRegion) {
|
||||||
if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
|
if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for &&
|
||||||
|
@ -4927,7 +4928,8 @@ StmtResult Sema::ActOnOpenMPCancelDirective(SourceLocation StartLoc,
|
||||||
return StmtError();
|
return StmtError();
|
||||||
}
|
}
|
||||||
DSAStack->setParentCancelRegion(/*Cancel=*/true);
|
DSAStack->setParentCancelRegion(/*Cancel=*/true);
|
||||||
return OMPCancelDirective::Create(Context, StartLoc, EndLoc, CancelRegion);
|
return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
|
||||||
|
CancelRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
||||||
|
|
|
@ -2317,6 +2317,8 @@ void ASTStmtReader::VisitOMPCancellationPointDirective(
|
||||||
|
|
||||||
void ASTStmtReader::VisitOMPCancelDirective(OMPCancelDirective *D) {
|
void ASTStmtReader::VisitOMPCancelDirective(OMPCancelDirective *D) {
|
||||||
VisitStmt(D);
|
VisitStmt(D);
|
||||||
|
// The NumClauses field was read in ReadStmtFromStream.
|
||||||
|
++Idx;
|
||||||
VisitOMPExecutableDirective(D);
|
VisitOMPExecutableDirective(D);
|
||||||
D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record[Idx++]));
|
D->setCancelRegion(static_cast<OpenMPDirectiveKind>(Record[Idx++]));
|
||||||
}
|
}
|
||||||
|
@ -2938,7 +2940,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STMT_OMP_CANCEL_DIRECTIVE:
|
case STMT_OMP_CANCEL_DIRECTIVE:
|
||||||
S = OMPCancelDirective::CreateEmpty(Context, Empty);
|
S = OMPCancelDirective::CreateEmpty(
|
||||||
|
Context, Record[ASTStmtReader::NumStmtFields], Empty);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EXPR_CXX_OPERATOR_CALL:
|
case EXPR_CXX_OPERATOR_CALL:
|
||||||
|
|
|
@ -2169,6 +2169,7 @@ void ASTStmtWriter::VisitOMPCancellationPointDirective(
|
||||||
|
|
||||||
void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
|
void ASTStmtWriter::VisitOMPCancelDirective(OMPCancelDirective *D) {
|
||||||
VisitStmt(D);
|
VisitStmt(D);
|
||||||
|
Record.push_back(D->getNumClauses());
|
||||||
VisitOMPExecutableDirective(D);
|
VisitOMPExecutableDirective(D);
|
||||||
Record.push_back(D->getCancelRegion());
|
Record.push_back(D->getCancelRegion());
|
||||||
Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
|
Code = serialization::STMT_OMP_CANCEL_DIRECTIVE;
|
||||||
|
|
|
@ -10,11 +10,11 @@ int main (int argc, char **argv) {
|
||||||
// CHECK: int main(int argc, char **argv) {
|
// CHECK: int main(int argc, char **argv) {
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
{
|
{
|
||||||
#pragma omp cancel parallel
|
#pragma omp cancel parallel if(argc)
|
||||||
}
|
}
|
||||||
// CHECK: #pragma omp parallel
|
// CHECK: #pragma omp parallel
|
||||||
// CHECK-NEXT: {
|
// CHECK-NEXT: {
|
||||||
// CHECK-NEXT: #pragma omp cancel parallel
|
// CHECK-NEXT: #pragma omp cancel parallel if(argc)
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
#pragma omp sections
|
#pragma omp sections
|
||||||
{
|
{
|
||||||
|
@ -26,11 +26,11 @@ int main (int argc, char **argv) {
|
||||||
// CHECK: }
|
// CHECK: }
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
for (int i = 0; i < argc; ++i) {
|
for (int i = 0; i < argc; ++i) {
|
||||||
#pragma omp cancel for
|
#pragma omp cancel for if(cancel:argc)
|
||||||
}
|
}
|
||||||
// CHECK: #pragma omp for
|
// CHECK: #pragma omp for
|
||||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i) {
|
// CHECK-NEXT: for (int i = 0; i < argc; ++i) {
|
||||||
// CHECK-NEXT: #pragma omp cancel for
|
// CHECK-NEXT: #pragma omp cancel for if(cancel: argc)
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
#pragma omp task
|
#pragma omp task
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,11 +6,12 @@
|
||||||
#ifndef HEADER
|
#ifndef HEADER
|
||||||
#define HEADER
|
#define HEADER
|
||||||
|
|
||||||
|
float flag;
|
||||||
int main (int argc, char **argv) {
|
int main (int argc, char **argv) {
|
||||||
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(
|
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(
|
||||||
#pragma omp parallel
|
#pragma omp parallel
|
||||||
{
|
{
|
||||||
#pragma omp cancel parallel
|
#pragma omp cancel parallel if(flag)
|
||||||
argv[0][0] = argc;
|
argv[0][0] = argc;
|
||||||
}
|
}
|
||||||
// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
|
// CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(
|
||||||
|
@ -50,9 +51,13 @@ int main (int argc, char **argv) {
|
||||||
// CHECK: call void @__kmpc_for_static_fini(
|
// CHECK: call void @__kmpc_for_static_fini(
|
||||||
#pragma omp for
|
#pragma omp for
|
||||||
for (int i = 0; i < argc; ++i) {
|
for (int i = 0; i < argc; ++i) {
|
||||||
#pragma omp cancel for
|
#pragma omp cancel for if(cancel: flag)
|
||||||
}
|
}
|
||||||
// CHECK: call void @__kmpc_for_static_init_4(
|
// CHECK: call void @__kmpc_for_static_init_4(
|
||||||
|
// CHECK: [[FLAG:%.+]] = load float, float* @{{.+}},
|
||||||
|
// CHECK: [[BOOL:%.+]] = fcmp une float [[FLAG]], 0.000000e+00
|
||||||
|
// CHECK: br i1 [[BOOL]], label %[[THEN:[^,]+]], label %[[ELSE:[^,]+]]
|
||||||
|
// CHECK: [[THEN]]
|
||||||
// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 2)
|
// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 [[GTID]], i32 2)
|
||||||
// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
|
// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
|
||||||
// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
|
// CHECK: br i1 [[CMP]], label %[[EXIT:[^,].+]], label %[[CONTINUE:.+]]
|
||||||
|
@ -61,6 +66,8 @@ for (int i = 0; i < argc; ++i) {
|
||||||
// CHECK: br label
|
// CHECK: br label
|
||||||
// CHECK: [[CONTINUE]]
|
// CHECK: [[CONTINUE]]
|
||||||
// CHECK: br label
|
// CHECK: br label
|
||||||
|
// CHECK: [[ELSE]]
|
||||||
|
// CHECK: br label
|
||||||
// CHECK: call void @__kmpc_for_static_fini(
|
// CHECK: call void @__kmpc_for_static_fini(
|
||||||
// CHECK: call void @__kmpc_barrier(%ident_t*
|
// CHECK: call void @__kmpc_barrier(%ident_t*
|
||||||
#pragma omp task
|
#pragma omp task
|
||||||
|
@ -92,12 +99,19 @@ for (int i = 0; i < argc; ++i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}},
|
// CHECK: define internal void @{{[^(]+}}(i32* {{[^,]+}}, i32* {{[^,]+}},
|
||||||
|
// CHECK: [[FLAG:%.+]] = load float, float* @{{.+}},
|
||||||
|
// CHECK: [[BOOL:%.+]] = fcmp une float [[FLAG]], 0.000000e+00
|
||||||
|
// CHECK: br i1 [[BOOL]], label %[[THEN:[^,]+]], label %[[ELSE:[^,]+]]
|
||||||
|
// CHECK: [[THEN]]
|
||||||
// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 1)
|
// CHECK: [[RES:%.+]] = call i32 @__kmpc_cancel(%ident_t* {{[^,]+}}, i32 {{[^,]+}}, i32 1)
|
||||||
// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
|
// CHECK: [[CMP:%.+]] = icmp ne i32 [[RES]], 0
|
||||||
// CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]],
|
// CHECK: br i1 [[CMP]], label %[[EXIT:[^,]+]],
|
||||||
// CHECK: [[EXIT]]
|
// CHECK: [[EXIT]]
|
||||||
// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
|
// CHECK: call i32 @__kmpc_cancel_barrier(%ident_t*
|
||||||
// CHECK: br label %[[RETURN:.+]]
|
// CHECK: br label %[[RETURN:.+]]
|
||||||
|
// CHECK: [[ELSE]]
|
||||||
|
// CHECK: br label
|
||||||
|
// CHECK: call void @__kmpc_barrier
|
||||||
// CHECK: [[RETURN]]
|
// CHECK: [[RETURN]]
|
||||||
// CHECK: ret void
|
// CHECK: ret void
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 %s
|
||||||
|
|
||||||
|
void foo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool foobool(int argc) {
|
||||||
|
return argc;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct S1; // expected-note {{declared here}}
|
||||||
|
|
||||||
|
template <class T, class S> // expected-note {{declared here}}
|
||||||
|
int tmain(T argc, S **argv) {
|
||||||
|
#pragma omp parallel
|
||||||
|
{
|
||||||
|
#pragma omp cancel parallel if // expected-error {{expected '(' after 'if'}}
|
||||||
|
#pragma omp cancel parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if () // expected-error {{expected expression}}
|
||||||
|
#pragma omp cancel parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
|
||||||
|
#pragma omp cancel parallel if (argc > 0 ? argv[1] : argv[2])
|
||||||
|
#pragma omp cancel parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp cancel' cannot contain more than one 'if' clause}}
|
||||||
|
#pragma omp cancel parallel if (S) // expected-error {{'S' does not refer to a value}}
|
||||||
|
#pragma omp cancel parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(argc)
|
||||||
|
#pragma omp cancel parallel if(cancel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(cancel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(cancel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(cancel : argc)
|
||||||
|
#pragma omp cancel parallel if(cancel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp cancel'}}
|
||||||
|
#pragma omp cancel parallel if(cancel : argc) if (cancel:argc) // expected-error {{directive '#pragma omp cancel' cannot contain more than one 'if' clause with 'cancel' name modifier}}
|
||||||
|
#pragma omp cancel parallel if(cancel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
#pragma omp parallel
|
||||||
|
{
|
||||||
|
#pragma omp cancel parallel if // expected-error {{expected '(' after 'if'}}
|
||||||
|
#pragma omp cancel parallel if ( // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if () // expected-error {{expected expression}}
|
||||||
|
#pragma omp cancel parallel if (argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if (argc)) // expected-warning {{extra tokens at the end of '#pragma omp cancel' are ignored}}
|
||||||
|
#pragma omp cancel parallel if (argc > 0 ? argv[1] : argv[2])
|
||||||
|
#pragma omp cancel parallel if (foobool(argc)), if (true) // expected-error {{directive '#pragma omp cancel' cannot contain more than one 'if' clause}}
|
||||||
|
#pragma omp cancel parallel if (S1) // expected-error {{'S1' does not refer to a value}}
|
||||||
|
#pragma omp cancel parallel if (argv[1]=2) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if (argc argc) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if (1 0) // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(if(tmain(argc, argv) // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(cancel // expected-warning {{missing ':' after directive name modifier - ignoring}} expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(cancel : // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(cancel : argc // expected-error {{expected ')'}} expected-note {{to match this '('}}
|
||||||
|
#pragma omp cancel parallel if(cancel : argc)
|
||||||
|
#pragma omp cancel parallel if(cancel : argc) if (for:argc) // expected-error {{directive name modifier 'for' is not allowed for '#pragma omp cancel'}}
|
||||||
|
#pragma omp cancel parallel if(cancel : argc) if (cancel:argc) // expected-error {{directive '#pragma omp cancel' cannot contain more than one 'if' clause with 'cancel' name modifier}}
|
||||||
|
#pragma omp cancel parallel if(cancel : argc) if (argc) // expected-error {{no more 'if' clause is allowed}} expected-note {{previous clause with directive name modifier specified here}}
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmain(argc, argv);
|
||||||
|
}
|
Loading…
Reference in New Issue