abidmalikwaterloo created this revision.
Herald added a project: All.
abidmalikwaterloo requested review of this revision.
Herald added a reviewer: jdoerfert.
Herald added subscribers: llvm-commits, cfe-commits, sstefan1.
Herald added projects: clang, LLVM.

The patch  provides otherwise support introduced in
OpenMP 5.2 for metadirective. TODO AST support pending
on D122255 <https://reviews.llvm.org/D122255> patch.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D124040

Files:
  clang/include/clang/AST/OpenMPClause.h
  clang/include/clang/Sema/Sema.h
  clang/lib/Basic/OpenMPKinds.cpp
  clang/lib/CodeGen/CGStmtOpenMP.cpp
  clang/lib/Parse/ParseOpenMP.cpp
  clang/test/OpenMP/metadirective_otherwise_ast_print.c
  llvm/include/llvm/Frontend/OpenMP/OMP.td

Index: llvm/include/llvm/Frontend/OpenMP/OMP.td
===================================================================
--- llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -367,7 +367,12 @@
 def OMPC_Align : Clause<"align"> {
   let clangClass = "OMPAlignClause";
 }
-def OMPC_When: Clause<"when"> {}
+def OMPC_When: Clause<"when"> {
+  //let clangClass = "OMPWhenClause";			
+}
+
+def OMPC_Otherwise: Clause<"otherwise">{}
+
 
 def OMPC_Bind : Clause<"bind"> {
   let clangClass = "OMPBindClause";
@@ -1858,6 +1863,7 @@
 def OMP_Metadirective : Directive<"metadirective"> {
   let allowedClauses = [VersionedClause<OMPC_When>];
   let allowedOnceClauses = [VersionedClause<OMPC_Default>];
+  let allowedOnceClauses = [VersionedClause<OMPC_Otherwise>]; 
 }
 def OMP_Unknown : Directive<"unknown"> {
   let isDefault = true;
Index: clang/test/OpenMP/metadirective_otherwise_ast_print.c
===================================================================
--- /dev/null
+++ clang/test/OpenMP/metadirective_otherwise_ast_print.c
@@ -0,0 +1,87 @@
+// RUN: %clang_cc1 -verify -fopenmp -triple x86_64-unknown-linux-gnu -x c -std=c99 -ast-print %s -o - | FileCheck %s
+
+// RUN: %clang_cc1 -verify -fopenmp-simd -triple x86_64-unknown-linux-gnu -x c -std=c99 -ast-print %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+
+void bar(void);
+
+#define N 10
+void foo(void) {
+#pragma omp metadirective when(device = {kind(cpu)} \
+                               : parallel) otherwise()
+  bar();
+#pragma omp metadirective when(implementation = {vendor(score(0)  \
+                                                        : llvm)}, \
+                               device = {kind(cpu)}               \
+                               : parallel) otherwise (target teams)
+  bar();
+#pragma omp metadirective when(device = {kind(gpu)}                                 \
+                               : target teams) when(implementation = {vendor(llvm)} \
+                                                    : parallel) otherwise ()
+  bar();
+#pragma omp metadirective otherwise (target) when(implementation = {vendor(score(5)  \
+                                                                        : llvm)}, \
+                                               device = {kind(cpu, host)}         \
+                                               : parallel)
+  bar();
+#pragma omp metadirective when(user = {condition(N > 10)}                 \
+                               : target) when(user = {condition(N == 10)} \
+                                              : parallel)
+  bar();
+#pragma omp metadirective when(device = {kind(host)} \
+                               : parallel for)
+  for (int i = 0; i < 100; i++)
+    ;
+#pragma omp metadirective when(implementation = {extension(match_all)} \
+                               : parallel) otherwise(parallel for)
+  for (int i = 0; i < 100; i++)
+    ;
+#pragma omp metadirective when(implementation = {extension(match_any)} \
+                               : parallel) otherwise(parallel for)
+  for (int i = 0; i < 100; i++)
+    ;
+#pragma omp metadirective when(implementation = {extension(match_none)} \
+                               : parallel) otherwise(parallel for)
+  for (int i = 0; i < 100; i++)
+    ;
+
+// Test metadirective with nested OpenMP directive.
+  int array[16];
+  #pragma omp metadirective when(user = {condition(1)} \
+                                 : parallel for)
+  for (int i = 0; i < 16; i++) {
+    #pragma omp simd
+    for (int j = 0; j < 16; j++)
+      array[i] = i;
+  }
+}
+
+// CHECK: void bar(void);
+// CHECK: void foo(void)
+// CHECK-NEXT: #pragma omp parallel
+// CHECK-NEXT: bar()
+// CHECK-NEXT: #pragma omp parallel
+// CHECK-NEXT: bar()
+// CHECK-NEXT: #pragma omp parallel
+// CHECK-NEXT: bar()
+// CHECK-NEXT: #pragma omp parallel
+// CHECK-NEXT: bar()
+// CHECK-NEXT: #pragma omp parallel
+// CHECK-NEXT: bar()
+// CHECK-NEXT: #pragma omp parallel for
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK: #pragma omp parallel
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK: #pragma omp parallel for
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK: #pragma omp parallel
+// CHECK-NEXT: for (int i = 0; i < 100; i++)
+// CHECK: #pragma omp parallel for
+// CHECK-NEXT: for (int i = 0; i < 16; i++) {
+// CHECK-NEXT: #pragma omp simd
+// CHECK-NEXT: for (int j = 0; j < 16; j++)
+
+#endif
Index: clang/lib/Parse/ParseOpenMP.cpp
===================================================================
--- clang/lib/Parse/ParseOpenMP.cpp
+++ clang/lib/Parse/ParseOpenMP.cpp
@@ -2486,12 +2486,6 @@
   DeclarationNameInfo DirName;
   StmtResult Directive = StmtError();
   bool HasAssociatedStatement = true;
-  
-  //
-  if (DKind == OMPD_target){
-  	llvm::errs() << " We have target  " << PP.getSpelling(Tok) << "\n";
-  } else {llvm::errs() << " We have   " << PP.getSpelling(Tok) << "\n";}
-  //
 
   switch (DKind) {
   case OMPD_metadirective: {
@@ -2835,7 +2829,6 @@
       // If we are parsing for a directive within a metadirective, the directive
       // ends with a ')'.
       if (ReadDirectiveWithinMetadirective && Tok.is(tok::r_paren)) {
-        llvm::errs() << "We are reading meta directive\n";
         while (Tok.isNot(tok::annot_pragma_openmp_end))
           ConsumeAnyToken();
         break;
Index: clang/lib/CodeGen/CGStmtOpenMP.cpp
===================================================================
--- clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -6081,6 +6081,7 @@
                               bool IsXLHSInRHSPart, bool IsCompareCapture,
                               SourceLocation Loc) {
   switch (Kind) {
+  case OMPC_otherwise:
   case OMPC_read:
     emitOMPAtomicReadExpr(CGF, AO, X, V, Loc);
     break;
Index: clang/lib/Basic/OpenMPKinds.cpp
===================================================================
--- clang/lib/Basic/OpenMPKinds.cpp
+++ clang/lib/Basic/OpenMPKinds.cpp
@@ -201,6 +201,7 @@
   case OMPC_uses_allocators:
   case OMPC_affinity:
   case OMPC_when:
+  case OMPC_otherwise:
   case OMPC_append_args:
     break;
   default:
@@ -467,6 +468,7 @@
   case OMPC_uses_allocators:
   case OMPC_affinity:
   case OMPC_when:
+  case OMPC_otherwise:
   case OMPC_append_args:
     break;
   default:
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -11229,6 +11229,11 @@
   OMPClause *ActOnOpenMPWhenClause(OMPTraitInfo &TI, SourceLocation StartLoc,
                                    SourceLocation LParenLoc,
                                    SourceLocation EndLoc);
+  /// Called on well-formed 'otherwise' clause.
+  OMPClause *ActOnOpenMPOtherWiseClause(StmtResult Directive, SourceLocation StartLoc,
+                                        SourceLocation LParenLoc,
+                                        SourceLocation EndLoc);                               
+   
   /// Called on well-formed 'default' clause.
   OMPClause *ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind,
                                       SourceLocation KindLoc,
Index: clang/include/clang/AST/OpenMPClause.h
===================================================================
--- clang/include/clang/AST/OpenMPClause.h
+++ clang/include/clang/AST/OpenMPClause.h
@@ -1139,6 +1139,62 @@
   }
 };
 
+/// New Work in progress
+class OMPOtherWiseClause final : public OMPClause {
+  friend class OMPClauseReader;
+
+  Stmt *Directive;
+  
+  /// Location of '('.
+  SourceLocation LParenLoc;
+  
+public:
+  
+  OMPOtherWiseClause (Stmt *D, SourceLocation StartLoc, SourceLocation LParenLoc,
+                   SourceLocation EndLoc)
+      : OMPClause(llvm::omp::OMPC_otherwise, StartLoc, EndLoc),
+        Directive(D), LParenLoc(LParenLoc)  {}
+
+  /// Build an empty clause.
+  OMPOtherWiseClause()
+      : OMPClause(llvm::omp::OMPC_otherwise, SourceLocation(), SourceLocation()) {
+  }
+  
+  /// Sets the location of '('.
+  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
+
+  /// Returns the location of '('.
+  SourceLocation getLParenLoc() const { return LParenLoc; }
+
+  /// Returns the associated OpenMP directive
+  Stmt *getDirective() const { return Directive; }
+  
+  /// Set the associated OpenMP directive
+  void setDirective(Stmt *S) { Directive = S; }	
+  
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
+  child_range used_children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range used_children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+
+  static bool classof(const OMPClause *T) {
+    return T->getClauseKind() == llvm::omp::OMPC_otherwise;
+  }
+
+};
+
+/// New work in progress here
+
 /// This represents 'default' clause in the '#pragma omp ...' directive.
 ///
 /// \code
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to