[clang] [llvm] Assume (PR #97535)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 3 00:29:12 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-flang-openmp

Author: None (SunilKuravinakop)

<details>
<summary>Changes</summary>

Support for assume directive : Parse and AST modules

---
Full diff: https://github.com/llvm/llvm-project/pull/97535.diff


7 Files Affected:

- (modified) clang/include/clang/Parse/Parser.h (+2-2) 
- (modified) clang/include/clang/Sema/SemaOpenMP.h (+3) 
- (modified) clang/lib/Basic/OpenMPKinds.cpp (+3) 
- (modified) clang/lib/Parse/ParseOpenMP.cpp (+31-2) 
- (modified) clang/lib/Sema/SemaOpenMP.cpp (+65-1) 
- (added) clang/test/OpenMP/assume_ast.cpp (+43) 
- (modified) llvm/include/llvm/Frontend/OpenMP/OMP.td (+4) 


``````````diff
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 6880fa4bb0b03..e9083e98e2baa 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -3434,8 +3434,8 @@ class Parser : public CodeCompletionHandler {
                                      SourceLocation Loc);
 
   /// Parse 'omp [begin] assume[s]' directive.
-  void ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
-                                   SourceLocation Loc);
+  StmtResult ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
+                                         SourceLocation Loc);
 
   /// Parse 'omp end assumes' directive.
   void ParseOpenMPEndAssumesDirective(SourceLocation Loc);
diff --git a/clang/include/clang/Sema/SemaOpenMP.h b/clang/include/clang/Sema/SemaOpenMP.h
index 3edf1cc7c12f2..1831d417877b5 100644
--- a/clang/include/clang/Sema/SemaOpenMP.h
+++ b/clang/include/clang/Sema/SemaOpenMP.h
@@ -106,6 +106,9 @@ class SemaOpenMP : public SemaBase {
   /// Act on \p D, a function definition inside of an `omp [begin/end] assumes`.
   void ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D);
 
+  /// Act on \p D, Associated statements of `omp assume`.
+  StmtResult ActOnFinishedStatementInOpenMPAssumeScope(Stmt *);
+
   /// Can we exit an OpenMP declare variant scope at the moment.
   bool isInOpenMPDeclareVariantScope() const {
     return !OMPDeclareVariantScopes.empty();
diff --git a/clang/lib/Basic/OpenMPKinds.cpp b/clang/lib/Basic/OpenMPKinds.cpp
index 766d6a8418a6a..696a819086af1 100644
--- a/clang/lib/Basic/OpenMPKinds.cpp
+++ b/clang/lib/Basic/OpenMPKinds.cpp
@@ -760,6 +760,9 @@ void clang::getOpenMPCaptureRegions(
     case OMPD_parallel:
       CaptureRegions.push_back(OMPD_parallel);
       break;
+    case OMPD_assume:
+      CaptureRegions.push_back(OMPD_assume);
+      break;
     case OMPD_target:
       CaptureRegions.push_back(OMPD_task);
       CaptureRegions.push_back(OMPD_target);
diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp
index 326cd22ff9005..9267e8792f0bf 100644
--- a/clang/lib/Parse/ParseOpenMP.cpp
+++ b/clang/lib/Parse/ParseOpenMP.cpp
@@ -1682,8 +1682,8 @@ void Parser::ParseOpenMPClauses(OpenMPDirectiveKind DKind,
 ///     'no_openmp_routines'
 ///     'no_parallelism'
 ///
-void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
-                                         SourceLocation Loc) {
+StmtResult Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
+                                               SourceLocation Loc) {
   SmallVector<std::string, 4> Assumptions;
   bool SkippedClauses = false;
 
@@ -1759,8 +1759,34 @@ void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind,
     Assumptions.push_back(Assumption);
   }
 
+  StmtResult AssociatedStmt;
+
+  // Fix the scope for assume.
+  if (DKind == llvm::omp::Directive::OMPD_assume) {
+
+    if (Tok.getKind() == clang::tok::annot_pragma_openmp_end)
+      ConsumeAnyToken();
+
+    DeclarationNameInfo DirName;
+    Actions.OpenMP().StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope(), Loc);
+  }
+
   Actions.OpenMP().ActOnOpenMPAssumesDirective(Loc, DKind, Assumptions,
                                                SkippedClauses);
+
+  if (DKind == llvm::omp::Directive::OMPD_assume) {
+
+    AssociatedStmt = ParseStatement();
+    AssociatedStmt =
+        Actions.OpenMP().ActOnFinishedStatementInOpenMPAssumeScope(AssociatedStmt.get());
+
+    // End the scope for assume.
+    ParseOpenMPEndAssumesDirective(Loc);
+    Actions.OpenMP().EndOpenMPDSABlock(nullptr);
+    if (Tok.getKind() == clang::tok::annot_pragma_openmp_end)
+      ConsumeAnyToken();
+  }
+  return AssociatedStmt;
 }
 
 void Parser::ParseOpenMPEndAssumesDirective(SourceLocation Loc) {
@@ -2885,6 +2911,9 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
     }
     break;
   }
+  case OMPD_assume:
+    Directive = ParseOpenMPAssumesDirective(DKind, ConsumeToken());
+    break;
   case OMPD_declare_target: {
     SourceLocation DTLoc = ConsumeAnyToken();
     bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 86666f064f35d..043559c052d57 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -3536,7 +3536,8 @@ void SemaOpenMP::ActOnOpenMPAssumesDirective(SourceLocation Loc,
 
   auto *AA =
       OMPAssumeAttr::Create(getASTContext(), llvm::join(Assumptions, ","), Loc);
-  if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
+  if (DKind == llvm::omp::Directive::OMPD_begin_assumes ||
+      DKind == llvm::omp::Directive::OMPD_assume) {
     OMPAssumeScoped.push_back(AA);
     return;
   }
@@ -7323,6 +7324,69 @@ void SemaOpenMP::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
     FD->addAttr(AA);
 }
 
+class OMPAssumeStmtVisitor : public StmtVisitor<OMPAssumeStmtVisitor> {
+  SmallVector<OMPAssumeAttr *, 4> *OMPAssumeScoped;
+
+public:
+  OMPAssumeStmtVisitor(SmallVector<OMPAssumeAttr *, 4> *OMPAssumeScoped) {
+    this->OMPAssumeScoped = OMPAssumeScoped;
+  }
+
+  void VisitCapturedStmt(CapturedStmt *CS) {
+    // To find the CaptureDecl for the CaptureStmt
+    CapturedDecl *CD = CS->getCapturedDecl();
+    if (CD) {
+      for (OMPAssumeAttr *AA : *OMPAssumeScoped)
+        CD->addAttr(AA);
+    }
+  }
+
+  void VisitCompoundStmt(CompoundStmt *CS) {
+    // Handle CompoundStmt
+    // Visit each statement in the CompoundStmt
+    for (Stmt *SubStmt : CS->body()) {
+      if (Expr *CE = dyn_cast<Expr>(SubStmt)) {
+        // If the statement is a Expr, process it
+        VisitExpr(CE);
+      }
+    }
+  }
+
+  void VisitExpr(Expr *CE) {
+    // Handle all Expr
+    for (auto *Child : CE->children()) {
+      Visit(Child);
+    }
+  }
+
+  void Visit(Stmt *S) {
+    const char *CName = S->getStmtClassName();
+    if ((strstr(CName, "OMP") != NULL) &&
+        (strstr(CName, "Directive") != NULL)) {
+      for (Stmt *Child : S->children()) {
+        auto *CS = dyn_cast<CapturedStmt>(Child);
+        if (CS)
+          VisitCapturedStmt(CS);
+        else
+          StmtVisitor<OMPAssumeStmtVisitor>::Visit(Child);
+      }
+    } else {
+      StmtVisitor<OMPAssumeStmtVisitor>::Visit(S);
+    }
+  }
+};
+
+StmtResult
+SemaOpenMP::ActOnFinishedStatementInOpenMPAssumeScope(Stmt *AssociatedStmt) {
+
+  if (AssociatedStmt) {
+    // Add the AssumeAttr to the Directive associated with the Assume Directive.
+    OMPAssumeStmtVisitor Visitor(&OMPAssumeScoped);
+    Visitor.Visit(AssociatedStmt);
+  }
+  return AssociatedStmt;
+}
+
 SemaOpenMP::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
     : TI(&TI), NameSuffix(TI.getMangledName()) {}
 
diff --git a/clang/test/OpenMP/assume_ast.cpp b/clang/test/OpenMP/assume_ast.cpp
new file mode 100644
index 0000000000000..9f63ac87391a5
--- /dev/null
+++ b/clang/test/OpenMP/assume_ast.cpp
@@ -0,0 +1,43 @@
+// Check no warnings/errors
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -fsyntax-only -verify %s
+// expected-no-diagnostics
+
+// Check AST and unparsing
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -ast-dump  %s | FileCheck %s --check-prefix=DUMP
+
+// Check same results after serialization round-trip
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -emit-pch -o %t %s
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -fopenmp -include-pch %t -ast-dump-all %s | FileCheck %s --check-prefix=DUMP
+
+#ifndef HEADER
+#define HEADER
+
+#define N 12
+int A[N];
+int B[N];
+
+
+// DUMP-LABEL:  FunctionDecl {{.*}} main
+int
+main() {
+
+  for (int i = 0; i < N; ++i) {
+    A[i] = 0;
+  }
+
+
+  // assume is for the "simd" region
+  // DUMP:      OMPSimdDirective
+  // DUMP-NEXT:   CapturedStmt
+  // DUMP-NEXT:   CapturedDecl
+  #pragma omp assume no_openmp
+  #pragma omp simd
+  for (int i = 0; i < N; ++i){
+    A[i] += B[i];
+  }
+  // DUMP:  OMPAssumeAttr {{.*}} "omp_no_openmp"
+
+  return 0;
+}
+
+#endif
diff --git a/llvm/include/llvm/Frontend/OpenMP/OMP.td b/llvm/include/llvm/Frontend/OpenMP/OMP.td
index 005c678302b27..aac86bc8d7bc4 100644
--- a/llvm/include/llvm/Frontend/OpenMP/OMP.td
+++ b/llvm/include/llvm/Frontend/OpenMP/OMP.td
@@ -502,6 +502,10 @@ def OMP_Allocators : Directive<"allocators"> {
   let association = AS_Block;
   let category = CA_Executable;
 }
+def OMP_Assume : Directive<"assume"> {
+  let association = AS_None;
+  let category = CA_Informational;
+}
 def OMP_Assumes : Directive<"assumes"> {
   let association = AS_None;
   let category = CA_Informational;

``````````

</details>


https://github.com/llvm/llvm-project/pull/97535


More information about the cfe-commits mailing list