[OpenMP] Sema and parsing for 'target simd' pragma

This patch is to implement sema and parsing for 'target simd' pragma.

Differential Revision: https://reviews.llvm.org/D22479

llvm-svn: 276203
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index d55d6ec..14029e2 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -1610,7 +1610,8 @@
   case OMPD_target:
   case OMPD_target_parallel:
   case OMPD_target_parallel_for:
-  case OMPD_target_parallel_for_simd: {
+  case OMPD_target_parallel_for_simd:
+  case OMPD_target_simd: {
     Sema::CapturedParamNameType Params[] = {
         std::make_pair(StringRef(), QualType()) // __context with shared vars
     };
@@ -1906,6 +1907,7 @@
   // | parallel         | distribute      | +                                  |
   // |                  |parallel for simd|                                    |
   // | parallel         | distribute simd | +                                  |
+  // | parallel         | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | for              | parallel        | *                                  |
   // | for              | for             | +                                  |
@@ -1949,6 +1951,7 @@
   // | for              | distribute simd | +                                  |
   // | for              | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | for              | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | master           | parallel        | *                                  |
   // | master           | for             | +                                  |
@@ -1992,6 +1995,7 @@
   // | master           | distribute simd | +                                  |
   // | master           | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | master           | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | critical         | parallel        | *                                  |
   // | critical         | for             | +                                  |
@@ -2034,6 +2038,7 @@
   // | critical         | distribute simd | +                                  |
   // | critical         | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | critical         | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | simd             | parallel        |                                    |
   // | simd             | for             |                                    |
@@ -2077,6 +2082,7 @@
   // | simd             | distribute simd |                                    |
   // | simd             | target parallel |                                    |
   // |                  | for simd        |                                    |
+  // | simd             | target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   // | for simd         | parallel        |                                    |
   // | for simd         | for             |                                    |
@@ -2120,6 +2126,7 @@
   // | for simd         | distribute simd |                                    |
   // | for simd         | target parallel |                                    |
   // |                  | for simd        |                                    |
+  // | for simd         | target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   // | parallel for simd| parallel        |                                    |
   // | parallel for simd| for             |                                    |
@@ -2162,6 +2169,7 @@
   // |                  |parallel for simd|                                    |
   // | parallel for simd| distribute simd |                                    |
   // |                  | for simd        |                                    |
+  // | parallel for simd| target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   // | sections         | parallel        | *                                  |
   // | sections         | for             | +                                  |
@@ -2205,6 +2213,7 @@
   // | sections         | distribute simd | +                                  |
   // | sections         | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | sections         | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | section          | parallel        | *                                  |
   // | section          | for             | +                                  |
@@ -2248,6 +2257,7 @@
   // | section          | distribute simd | +                                  |
   // | section          | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | section          | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | single           | parallel        | *                                  |
   // | single           | for             | +                                  |
@@ -2291,6 +2301,7 @@
   // | single           | distribute simd | +                                  |
   // | single           | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | single           | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | parallel for     | parallel        | *                                  |
   // | parallel for     | for             | +                                  |
@@ -2334,6 +2345,7 @@
   // | parallel for     | distribute simd | +                                  |
   // | parallel for     | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | parallel for     | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | parallel sections| parallel        | *                                  |
   // | parallel sections| for             | +                                  |
@@ -2377,6 +2389,7 @@
   // | parallel sections| distribute simd | +                                  |
   // | parallel sections| target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | parallel sections| target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | task             | parallel        | *                                  |
   // | task             | for             | +                                  |
@@ -2420,6 +2433,7 @@
   // | task             | distribute simd | +                                  |
   // | task             | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | task             | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | ordered          | parallel        | *                                  |
   // | ordered          | for             | +                                  |
@@ -2463,6 +2477,7 @@
   // | ordered          | distribute simd | +                                  |
   // | ordered          | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | ordered          | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | atomic           | parallel        |                                    |
   // | atomic           | for             |                                    |
@@ -2506,6 +2521,7 @@
   // | atomic           | distribute simd |                                    |
   // | atomic           | target parallel |                                    |
   // |                  | for simd        |                                    |
+  // | atomic           | target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   // | target           | parallel        | *                                  |
   // | target           | for             | *                                  |
@@ -2549,6 +2565,7 @@
   // | target           | distribute simd | +                                  |
   // | target           | target parallel |                                    |
   // |                  | for simd        |                                    |
+  // | target           | target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   // | target parallel  | parallel        | *                                  |
   // | target parallel  | for             | *                                  |
@@ -2592,6 +2609,7 @@
   // | target parallel  | distribute simd |                                    |
   // | target parallel  | target parallel |                                    |
   // |                  | for simd        |                                    |
+  // | target parallel  | target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   // | target parallel  | parallel        | *                                  |
   // | for              |                 |                                    |
@@ -2663,6 +2681,8 @@
   // | for              |                 |                                    |
   // | target parallel  | target parallel |                                    |
   // | for              | for simd        |                                    |
+  // | target parallel  | target simd     |                                    |
+  // | for              |                 |                                    |
   // +------------------+-----------------+------------------------------------+
   // | teams            | parallel        | *                                  |
   // | teams            | for             | +                                  |
@@ -2706,6 +2726,7 @@
   // | teams            | distribute simd | !                                  |
   // | teams            | target parallel | +                                  |
   // |                  | for simd        |                                    |
+  // | teams            | target simd     | +                                  |
   // +------------------+-----------------+------------------------------------+
   // | taskloop         | parallel        | *                                  |
   // | taskloop         | for             | +                                  |
@@ -2748,6 +2769,7 @@
   // | taskloop         | distribute simd | +                                  |
   // | taskloop         | target parallel | *                                  |
   // |                  | for simd        |                                    |
+  // | taskloop         | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | taskloop simd    | parallel        |                                    |
   // | taskloop simd    | for             |                                    |
@@ -2791,6 +2813,7 @@
   // | taskloop simd    | distribute simd |                                    |
   // | taskloop simd    | target parallel |                                    |
   // |                  | for simd        |                                    |
+  // | taskloop simd    | target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   // | distribute       | parallel        | *                                  |
   // | distribute       | for             | *                                  |
@@ -2834,6 +2857,7 @@
   // | distribute       | distribute simd |                                    |
   // | distribute       | target parallel |                                    |
   // |                  | for simd        |                                    |
+  // | distribute       | target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   // | distribute       | parallel        | *                                  |
   // | parallel for     |                 |                                    |
@@ -2906,6 +2930,8 @@
   // | parallel for     |                 |                                    |
   // | distribute       | target parallel |                                    |
   // | parallel for     | for simd        |                                    |
+  // | distribute       | target simd     |                                    |
+  // | parallel for     |                 |                                    |
   // +------------------+-----------------+------------------------------------+
   // | distribute       | parallel        | *                                  |
   // | parallel for simd|                 |                                    |
@@ -2977,6 +3003,8 @@
   // | parallel for simd|                 |                                    |
   // | distribute       | target parallel |                                    |
   // | parallel for simd| for simd        |                                    |
+  // | distribute       | target simd     |                                    |
+  // | parallel for simd|                 |                                    |
   // +------------------+-----------------+------------------------------------+
   // | distribute simd  | parallel        | *                                  |
   // | distribute simd  | for             | *                                  |
@@ -3020,6 +3048,7 @@
   // | distribute simd  | distribute simd | *                                  |
   // | distribute simd  | target parallel | *                                  |
   // |                  | for simd        |                                    |
+  // | distribute simd  | target simd     | *                                  |
   // +------------------+-----------------+------------------------------------+
   // | target parallel  | parallel        | *                                  |
   // | for simd         |                 |                                    |
@@ -3091,6 +3120,52 @@
   // | for simd         |                 |                                    |
   // | target parallel  | target parallel | *                                  |
   // | for simd         | for simd        |                                    |
+  // | target parallel  | target simd     | *                                  |
+  // | for simd         |                 |                                    |
+  // +------------------+-----------------+------------------------------------+
+  // | target simd      | parallel        |                                    |
+  // | target simd      | for             |                                    |
+  // | target simd      | for simd        |                                    |
+  // | target simd      | master          |                                    |
+  // | target simd      | critical        |                                    |
+  // | target simd      | simd            |                                    |
+  // | target simd      | sections        |                                    |
+  // | target simd      | section         |                                    |
+  // | target simd      | single          |                                    |
+  // | target simd      | parallel for    |                                    |
+  // | target simd      |parallel for simd|                                    |
+  // | target simd      |parallel sections|                                    |
+  // | target simd      | task            |                                    |
+  // | target simd      | taskyield       |                                    |
+  // | target simd      | barrier         |                                    |
+  // | target simd      | taskwait        |                                    |
+  // | target simd      | taskgroup       |                                    |
+  // | target simd      | flush           |                                    |
+  // | target simd      | ordered         | + (with simd clause)               |
+  // | target simd      | atomic          |                                    |
+  // | target simd      | target          |                                    |
+  // | target simd      | target parallel |                                    |
+  // | target simd      | target parallel |                                    |
+  // |                  | for             |                                    |
+  // | target simd      | target enter    |                                    |
+  // |                  | data            |                                    |
+  // | target simd      | target exit     |                                    |
+  // |                  | data            |                                    |
+  // | target simd      | teams           |                                    |
+  // | target simd      | cancellation    |                                    |
+  // |                  | point           |                                    |
+  // | target simd      | cancel          |                                    |
+  // | target simd      | taskloop        |                                    |
+  // | target simd      | taskloop simd   |                                    |
+  // | target simd      | distribute      |                                    |
+  // | target simd      | distribute      |                                    |
+  // |                  | parallel for    |                                    |
+  // | target simd      | distribute      |                                    |
+  // |                  |parallel for simd|                                    |
+  // | target simd      | distribute simd |                                    |
+  // | target simd      | target parallel |                                    |
+  // |                  | for simd        |                                    |
+  // | target simd      | target simd     |                                    |
   // +------------------+-----------------+------------------------------------+
   if (Stack->getCurScope()) {
     auto ParentRegion = Stack->getParentDirective();
@@ -3596,6 +3671,11 @@
     AllowedNameModifiers.push_back(OMPD_target);
     AllowedNameModifiers.push_back(OMPD_parallel);
     break;
+  case OMPD_target_simd:
+    Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
+                                         EndLoc, VarsWithInheritedDSA);
+    AllowedNameModifiers.push_back(OMPD_target);
+    break;
   case OMPD_declare_target:
   case OMPD_end_declare_target:
   case OMPD_threadprivate:
@@ -7201,6 +7281,53 @@
       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
 }
 
+StmtResult Sema::ActOnOpenMPTargetSimdDirective(
+    ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
+    SourceLocation EndLoc,
+    llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
+  if (!AStmt)
+    return StmtError();
+
+  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
+  // 1.2.2 OpenMP Language Terminology
+  // Structured block - An executable statement with a single entry at the
+  // top and a single exit at the bottom.
+  // The point of exit cannot be a branch out of the structured block.
+  // longjmp() and throw() must not violate the entry/exit criteria.
+  CS->getCapturedDecl()->setNothrow();
+
+  OMPLoopDirective::HelperExprs B;
+  // In presence of clause 'collapse' with number of loops, it will define the
+  // nested loops number.
+  unsigned NestedLoopCount = 
+      CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
+                      getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
+                      VarsWithImplicitDSA, B);
+  if (NestedLoopCount == 0)
+    return StmtError();
+
+  assert((CurContext->isDependentContext() || B.builtAll()) &&
+         "omp target simd loop exprs were not built");
+
+  if (!CurContext->isDependentContext()) {
+    // Finalize the clauses that need pre-built expressions for CodeGen.
+    for (auto C : Clauses) {
+      if (auto LC = dyn_cast<OMPLinearClause>(C))
+        if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
+                                     B.NumIterations, *this, CurScope,
+                                     DSAStack))
+          return StmtError();
+    }
+  }
+
+  if (checkSimdlenSafelenSpecified(*this, Clauses))
+    return StmtError();
+
+  getCurFunction()->setHasBranchProtectedScope();
+  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
+                                        NestedLoopCount, Clauses, AStmt, B);
+}
+
 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
                                              SourceLocation StartLoc,
                                              SourceLocation LParenLoc,