forked from OSchip/llvm-project
[OPENMP 4.1] Add 'simd' clause for 'ordered' directive.
Parsing and sema analysis for 'simd' clause in 'ordered' directive. Description If the simd clause is specified, the ordered regions encountered by any thread will use only a single SIMD lane to execute the ordered regions in the order of the loop iterations. Restrictions An ordered construct with the simd clause is the only OpenMP construct that can appear in the simd region llvm-svn: 248696
This commit is contained in:
parent
f32f5f2305
commit
d14d1e6f25
|
@ -2539,6 +2539,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
template <typename T>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
|
||||
|
|
|
@ -2561,6 +2561,36 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// \brief This represents 'simd' clause in the '#pragma omp ...' directive.
|
||||
///
|
||||
/// \code
|
||||
/// #pragma omp ordered simd
|
||||
/// \endcode
|
||||
/// In this example directive '#pragma omp ordered' has simple 'simd' clause.
|
||||
///
|
||||
class OMPSIMDClause : public OMPClause {
|
||||
public:
|
||||
/// \brief Build 'simd' clause.
|
||||
///
|
||||
/// \param StartLoc Starting location of the clause.
|
||||
/// \param EndLoc Ending location of the clause.
|
||||
///
|
||||
OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
|
||||
: OMPClause(OMPC_simd, StartLoc, EndLoc) {}
|
||||
|
||||
/// \brief Build an empty clause.
|
||||
///
|
||||
OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {}
|
||||
|
||||
static bool classof(const OMPClause *T) {
|
||||
return T->getClauseKind() == OMPC_simd;
|
||||
}
|
||||
|
||||
child_range children() {
|
||||
return child_range(child_iterator(), child_iterator());
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2571,6 +2571,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
|
|||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
template <typename T>
|
||||
bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
|
||||
|
|
|
@ -145,6 +145,7 @@ OPENMP_CLAUSE(seq_cst, OMPSeqCstClause)
|
|||
OPENMP_CLAUSE(depend, OMPDependClause)
|
||||
OPENMP_CLAUSE(device, OMPDeviceClause)
|
||||
OPENMP_CLAUSE(threads, OMPThreadsClause)
|
||||
OPENMP_CLAUSE(simd, OMPSIMDClause)
|
||||
|
||||
// Clauses allowed for OpenMP directive 'parallel'.
|
||||
OPENMP_PARALLEL_CLAUSE(if)
|
||||
|
@ -318,6 +319,7 @@ OPENMP_TEAMS_CLAUSE(reduction)
|
|||
// Clauses allowed for OpenMP directive 'ordered'.
|
||||
// TODO More clauses for 'ordered' directive.
|
||||
OPENMP_ORDERED_CLAUSE(threads)
|
||||
OPENMP_ORDERED_CLAUSE(simd)
|
||||
|
||||
#undef OPENMP_LINEAR_KIND
|
||||
#undef OPENMP_DEPEND_KIND
|
||||
|
|
|
@ -7997,7 +7997,10 @@ public:
|
|||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'threads' clause.
|
||||
OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
SourceLocation EndLoc);
|
||||
/// \brief Called on well-formed 'simd' clause.
|
||||
OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc,
|
||||
SourceLocation EndLoc);
|
||||
|
||||
OMPClause *ActOnOpenMPVarListClause(
|
||||
OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr,
|
||||
|
|
|
@ -701,6 +701,8 @@ void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
|
|||
OS << "threads";
|
||||
}
|
||||
|
||||
void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }
|
||||
|
||||
void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
|
||||
OS << "device(";
|
||||
Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
|
||||
|
|
|
@ -335,6 +335,8 @@ void OMPClauseProfiler::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
|||
|
||||
void OMPClauseProfiler::VisitOMPThreadsClause(const OMPThreadsClause *) {}
|
||||
|
||||
void OMPClauseProfiler::VisitOMPSIMDClause(const OMPSIMDClause *) {}
|
||||
|
||||
template<typename T>
|
||||
void OMPClauseProfiler::VisitOMPClauseList(T *Node) {
|
||||
for (auto *E : Node->varlists()) {
|
||||
|
|
|
@ -129,6 +129,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
|
|||
case OMPC_seq_cst:
|
||||
case OMPC_device:
|
||||
case OMPC_threads:
|
||||
case OMPC_simd:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP simple clause kind");
|
||||
|
@ -214,6 +215,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
|
|||
case OMPC_seq_cst:
|
||||
case OMPC_device:
|
||||
case OMPC_threads:
|
||||
case OMPC_simd:
|
||||
break;
|
||||
}
|
||||
llvm_unreachable("Invalid OpenMP simple clause kind");
|
||||
|
|
|
@ -2210,6 +2210,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
|
|||
case OMPC_mergeable:
|
||||
case OMPC_device:
|
||||
case OMPC_threads:
|
||||
case OMPC_simd:
|
||||
llvm_unreachable("Clause is not allowed in 'omp atomic'.");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -394,7 +394,7 @@ bool Parser::ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind,
|
|||
/// schedule-clause | copyin-clause | copyprivate-clause | untied-clause |
|
||||
/// mergeable-clause | flush-clause | read-clause | write-clause |
|
||||
/// update-clause | capture-clause | seq_cst-clause | device-clause |
|
||||
/// simdlen-clause | threads-clause
|
||||
/// simdlen-clause | threads-clause | simd-clause
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
||||
OpenMPClauseKind CKind, bool FirstClause) {
|
||||
|
@ -473,6 +473,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
|
|||
case OMPC_capture:
|
||||
case OMPC_seq_cst:
|
||||
case OMPC_threads:
|
||||
case OMPC_simd:
|
||||
// OpenMP [2.7.1, Restrictions, p. 9]
|
||||
// Only one ordered clause can appear on a loop directive.
|
||||
// OpenMP [2.7.1, Restrictions, C/C++, p. 4]
|
||||
|
@ -605,6 +606,9 @@ OMPClause *Parser::ParseOpenMPSimpleClause(OpenMPClauseKind Kind) {
|
|||
/// threads-clause:
|
||||
/// 'threads'
|
||||
///
|
||||
/// simd-clause:
|
||||
/// 'simd'
|
||||
///
|
||||
OMPClause *Parser::ParseOpenMPClause(OpenMPClauseKind Kind) {
|
||||
SourceLocation Loc = Tok.getLocation();
|
||||
ConsumeAnyToken();
|
||||
|
|
|
@ -1547,7 +1547,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | simd | taskwait | |
|
||||
// | simd | taskgroup | |
|
||||
// | simd | flush | |
|
||||
// | simd | ordered | |
|
||||
// | simd | ordered | + (with simd clause) |
|
||||
// | simd | atomic | |
|
||||
// | simd | target | |
|
||||
// | simd | teams | |
|
||||
|
@ -1573,7 +1573,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | for simd | taskwait | |
|
||||
// | for simd | taskgroup | |
|
||||
// | for simd | flush | |
|
||||
// | for simd | ordered | |
|
||||
// | for simd | ordered | + (with simd clause) |
|
||||
// | for simd | atomic | |
|
||||
// | for simd | target | |
|
||||
// | for simd | teams | |
|
||||
|
@ -1599,7 +1599,7 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// | parallel for simd| taskwait | |
|
||||
// | parallel for simd| taskgroup | |
|
||||
// | parallel for simd| flush | |
|
||||
// | parallel for simd| ordered | |
|
||||
// | parallel for simd| ordered | + (with simd clause) |
|
||||
// | parallel for simd| atomic | |
|
||||
// | parallel for simd| target | |
|
||||
// | parallel for simd| teams | |
|
||||
|
@ -1877,9 +1877,12 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
ShouldBeInOrderedRegion,
|
||||
ShouldBeInTargetRegion
|
||||
} Recommend = NoRecommend;
|
||||
if (isOpenMPSimdDirective(ParentRegion)) {
|
||||
if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
|
||||
// OpenMP [2.16, Nesting of Regions]
|
||||
// OpenMP constructs may not be nested inside a simd region.
|
||||
// OpenMP [2.8.1,simd Construct, Restrictions]
|
||||
// An ordered construct with the simd clause is the only OpenMP construct
|
||||
// that can appear in the simd region.
|
||||
SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd);
|
||||
return true;
|
||||
}
|
||||
|
@ -1987,9 +1990,13 @@ static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
|
|||
// atomic, or explicit task region.
|
||||
// An ordered region must be closely nested inside a loop region (or
|
||||
// parallel loop region) with an ordered clause.
|
||||
// OpenMP [2.8.1,simd Construct, Restrictions]
|
||||
// An ordered construct with the simd clause is the only OpenMP construct
|
||||
// that can appear in the simd region.
|
||||
NestingProhibited = ParentRegion == OMPD_critical ||
|
||||
ParentRegion == OMPD_task ||
|
||||
!Stack->isParentOrderedRegion();
|
||||
!(isOpenMPSimdDirective(ParentRegion) ||
|
||||
Stack->isParentOrderedRegion());
|
||||
Recommend = ShouldBeInOrderedRegion;
|
||||
} else if (isOpenMPTeamsDirective(CurrentRegion)) {
|
||||
// OpenMP [2.16, Nesting of Regions]
|
||||
|
@ -4146,9 +4153,12 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
|
|||
getCurFunction()->setHasBranchProtectedScope();
|
||||
|
||||
OMPThreadsClause *TC = nullptr;
|
||||
OMPSIMDClause *SC = nullptr;
|
||||
for (auto *C: Clauses) {
|
||||
if (C->getClauseKind() == OMPC_threads)
|
||||
TC = cast<OMPThreadsClause>(C);
|
||||
else if (C->getClauseKind() == OMPC_simd)
|
||||
SC = cast<OMPSIMDClause>(C);
|
||||
}
|
||||
|
||||
// TODO: this must happen only if 'threads' clause specified or if no clauses
|
||||
|
@ -4159,6 +4169,13 @@ StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
|
|||
Diag(Param->getLocStart(), diag::note_omp_ordered_param);
|
||||
return StmtError();
|
||||
}
|
||||
if (!SC && isOpenMPSimdDirective(DSAStack->getParentDirective())) {
|
||||
// OpenMP [2.8.1,simd Construct, Restrictions]
|
||||
// An ordered construct with the simd clause is the only OpenMP construct
|
||||
// that can appear in the simd region.
|
||||
Diag(StartLoc, diag::err_omp_prohibited_region_simd);
|
||||
return StmtError();
|
||||
}
|
||||
|
||||
return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
|
||||
}
|
||||
|
@ -5009,6 +5026,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
|
|||
case OMPC_seq_cst:
|
||||
case OMPC_depend:
|
||||
case OMPC_threads:
|
||||
case OMPC_simd:
|
||||
case OMPC_unknown:
|
||||
llvm_unreachable("Clause is not allowed.");
|
||||
}
|
||||
|
@ -5270,6 +5288,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
|
|||
case OMPC_depend:
|
||||
case OMPC_device:
|
||||
case OMPC_threads:
|
||||
case OMPC_simd:
|
||||
case OMPC_unknown:
|
||||
llvm_unreachable("Clause is not allowed.");
|
||||
}
|
||||
|
@ -5398,6 +5417,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
|
|||
case OMPC_depend:
|
||||
case OMPC_device:
|
||||
case OMPC_threads:
|
||||
case OMPC_simd:
|
||||
case OMPC_unknown:
|
||||
llvm_unreachable("Clause is not allowed.");
|
||||
}
|
||||
|
@ -5504,6 +5524,9 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
|
|||
case OMPC_threads:
|
||||
Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_simd:
|
||||
Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
|
||||
break;
|
||||
case OMPC_if:
|
||||
case OMPC_final:
|
||||
case OMPC_num_threads:
|
||||
|
@ -5578,6 +5601,11 @@ OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
|
|||
return new (Context) OMPThreadsClause(StartLoc, EndLoc);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
|
||||
SourceLocation EndLoc) {
|
||||
return new (Context) OMPSIMDClause(StartLoc, EndLoc);
|
||||
}
|
||||
|
||||
OMPClause *Sema::ActOnOpenMPVarListClause(
|
||||
OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
|
||||
SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
|
||||
|
@ -5644,6 +5672,7 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
|
|||
case OMPC_seq_cst:
|
||||
case OMPC_device:
|
||||
case OMPC_threads:
|
||||
case OMPC_simd:
|
||||
case OMPC_unknown:
|
||||
llvm_unreachable("Clause is not allowed.");
|
||||
}
|
||||
|
|
|
@ -7372,6 +7372,12 @@ TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
|
|||
return C;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
|
||||
// No need to rebuild this clause, no template-dependent parameters.
|
||||
return C;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
OMPClause *
|
||||
TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
|
||||
|
|
|
@ -1780,6 +1780,9 @@ OMPClause *OMPClauseReader::readClause() {
|
|||
case OMPC_threads:
|
||||
C = new (Context) OMPThreadsClause();
|
||||
break;
|
||||
case OMPC_simd:
|
||||
C = new (Context) OMPSIMDClause();
|
||||
break;
|
||||
case OMPC_private:
|
||||
C = OMPPrivateClause::CreateEmpty(Context, Record[Idx++]);
|
||||
break;
|
||||
|
@ -1904,6 +1907,8 @@ void OMPClauseReader::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
|
|||
|
||||
void OMPClauseReader::VisitOMPThreadsClause(OMPThreadsClause *) {}
|
||||
|
||||
void OMPClauseReader::VisitOMPSIMDClause(OMPSIMDClause *) {}
|
||||
|
||||
void OMPClauseReader::VisitOMPPrivateClause(OMPPrivateClause *C) {
|
||||
C->setLParenLoc(Reader->ReadSourceLocation(Record, Idx));
|
||||
unsigned NumVars = C->varlist_size();
|
||||
|
|
|
@ -1812,6 +1812,8 @@ void OMPClauseWriter::VisitOMPSeqCstClause(OMPSeqCstClause *) {}
|
|||
|
||||
void OMPClauseWriter::VisitOMPThreadsClause(OMPThreadsClause *) {}
|
||||
|
||||
void OMPClauseWriter::VisitOMPSIMDClause(OMPSIMDClause *) {}
|
||||
|
||||
void OMPClauseWriter::VisitOMPPrivateClause(OMPPrivateClause *C) {
|
||||
Record.push_back(C->varlist_size());
|
||||
Writer->Writer.AddSourceLocation(C->getLParenLoc(), Record);
|
||||
|
|
|
@ -24,6 +24,24 @@ T tmain (T argc) {
|
|||
{
|
||||
a=2;
|
||||
}
|
||||
#pragma omp simd
|
||||
for (int i =0 ; i < argc; ++i)
|
||||
#pragma omp ordered simd
|
||||
{
|
||||
a=2;
|
||||
}
|
||||
#pragma omp for simd
|
||||
for (int i =0 ; i < argc; ++i)
|
||||
#pragma omp ordered simd
|
||||
{
|
||||
a=2;
|
||||
}
|
||||
#pragma omp parallel for simd
|
||||
for (int i =0 ; i < argc; ++i)
|
||||
#pragma omp ordered simd
|
||||
{
|
||||
a=2;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -40,6 +58,24 @@ T tmain (T argc) {
|
|||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp for simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp parallel for simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: static T a;
|
||||
// CHECK-NEXT: #pragma omp for ordered
|
||||
|
@ -54,6 +90,24 @@ T tmain (T argc) {
|
|||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp for simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp parallel for simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
|
||||
int main (int argc, char **argv) {
|
||||
int b = argc, c, d, e, f, g;
|
||||
|
@ -71,6 +125,24 @@ int main (int argc, char **argv) {
|
|||
{
|
||||
a=2;
|
||||
}
|
||||
#pragma omp simd
|
||||
for (int i =0 ; i < argc; ++i)
|
||||
#pragma omp ordered simd
|
||||
{
|
||||
a=2;
|
||||
}
|
||||
#pragma omp for simd
|
||||
for (int i =0 ; i < argc; ++i)
|
||||
#pragma omp ordered simd
|
||||
{
|
||||
a=2;
|
||||
}
|
||||
#pragma omp parallel for simd
|
||||
for (int i =0 ; i < argc; ++i)
|
||||
#pragma omp ordered simd
|
||||
{
|
||||
a=2;
|
||||
}
|
||||
// CHECK-NEXT: #pragma omp for ordered
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered
|
||||
|
@ -82,6 +154,24 @@ int main (int argc, char **argv) {
|
|||
// CHECK-NEXT: #pragma omp ordered threads
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp for simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: #pragma omp parallel for simd
|
||||
// CHECK-NEXT: for (int i = 0; i < argc; ++i)
|
||||
// CHECK-NEXT: #pragma omp ordered simd
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: a = 2;
|
||||
// CHECK-NEXT: }
|
||||
return tmain(argc);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,52 @@ T foo() {
|
|||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp ordered simd simd // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'simd' clause}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp parallel for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp parallel for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
return T();
|
||||
}
|
||||
|
@ -91,6 +137,52 @@ int foo() {
|
|||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp ordered simd simd // expected-error {{directive '#pragma omp ordered' cannot contain more than one 'simd' clause}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
#pragma omp simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp parallel for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
#pragma omp parallel for simd
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
#pragma omp ordered threads // expected-error {{OpenMP constructs may not be nested inside a simd region}}
|
||||
{
|
||||
foo();
|
||||
}
|
||||
}
|
||||
|
||||
return foo<int>();
|
||||
}
|
||||
|
|
|
@ -2068,6 +2068,8 @@ void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}
|
|||
|
||||
void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}
|
||||
|
||||
void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}
|
||||
|
||||
void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
|
||||
Visitor->AddStmt(C->getDevice());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue