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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits