-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Support for assume directive : Parse & AST modules #97535
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Changes to be committed: modified: clang/include/clang/Parse/Parser.h modified: clang/include/clang/Sema/Sema.h modified: clang/lib/Basic/OpenMPKinds.cpp modified: clang/lib/Parse/ParseOpenMP.cpp modified: clang/lib/Sema/SemaOpenMP.cpp modified: llvm/include/llvm/Frontend/OpenMP/OMP.td
Changes to be committed: new file: clang/test/OpenMP/assume_ast.cpp
@llvm/pr-subscribers-clang @llvm/pr-subscribers-flang-openmp Author: None (SunilKuravinakop) ChangesSupport for assume directive : Parse and AST modules Full diff: https://github.com/llvm/llvm-project/pull/97535.diff 7 Files Affected:
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;
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Changes to be committed: modified: clang/lib/Parse/ParseOpenMP.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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assume ends up with a simple assume intrinsic, right? Most probably non need to emit captured function, so it should be OMPD_unknown
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have corrected this. Thank you.
clang/lib/Parse/ParseOpenMP.cpp
Outdated
@@ -1759,8 +1759,35 @@ void Parser::ParseOpenMPAssumesDirective(OpenMPDirectiveKind DKind, | |||
Assumptions.push_back(Assumption); | |||
} | |||
|
|||
StmtResult AssociatedStmt; | |||
|
|||
// Fix the scope for assume. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong with the scope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error was in the wording in the comment. I have corrected it to "Begin marking the scope for assume."
clang/lib/Sema/SemaOpenMP.cpp
Outdated
OMPAssumeStmtVisitor Visitor(&OMPAssumeScoped); | ||
Visitor.Visit(AssociatedStmt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why need to do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the code which ensures that :
-OMPAssumeAttr
with the accompanying clauses of assume
is added to the statement associated with the assume directive. The test case attached with this upload checks for the OMPAssumeAttr.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need the visitor?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the example is :
// assume is for the "simd" region
#pragma omp assume no_openmp
#pragma omp simd
for (int i = 0; i < N; ++i){
A[i] += B[i];
}
then in -ast-dump for:
|-OMPSimdDirective 0x15cc6a0 <line:22:3, col:19>
| `-CapturedStmt 0x15b0d98 <line:23:3, line:25:3>
| `-CapturedDecl 0x15b0960 <<invalid sloc>> <invalid sloc>
| |
| |-OMPAssumeAttr 0x15b07b0 <line:21:15> "omp_no_openmp"
needs to be added. Also, according to the spec :
The scope of the assume directive is the code executed in the corresponding region or in any region that is nested in the corresponding region.
Is there a better way to add this other than having
OMPAssumeStmtVisitor::VisitCapturedStmt( )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why it is not enough to mark just the outer region? The fact that it is applied to nested regions can be hanf]dled in the codegen
1) assume ends up with a simple assume intrinsic, right? Most probably non need to emit captured function, so it should be OMPD_unknown 2) "Fix the scope for assume" reworded to "Begin marking the scope for assume." modified: clang/lib/Basic/OpenMPKinds.cpp modified: clang/lib/Parse/ParseOpenMP.cpp modified: clang/test/OpenMP/assume_ast.cpp
clang/lib/Parse/ParseOpenMP.cpp
Outdated
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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introduce RAAI class for this and use it instead
clang/lib/Sema/SemaOpenMP.cpp
Outdated
OMPAssumeStmtVisitor Visitor(&OMPAssumeScoped); | ||
Visitor.Visit(AssociatedStmt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why it is not enough to mark just the outer region? The fact that it is applied to nested regions can be hanf]dled in the codegen
Can we get a more specific title for this PR? thanks! |
clang/lib/Basic/OpenMPKinds.cpp
Outdated
case OMPD_assume: | ||
CaptureRegions.push_back(OMPD_unknown); | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please don't push OMPD_unknown here, instead add OMPD_assume to the directives at lines 790+.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, please add OMPD_assume to isOpenMPCapturingDirective
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? We usually add OMPD_unknown to the directives that do nit require outlining to a standalone function, here should be the same behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is what happens with the directives at lines 790+ (before these changes). We don't want to be adding OMPD_unknown as we go, because it can end up intermingled with other directives (in case of combined directives). I understand that OMPD_assume may be standalone, but we should treat it the same as the combinable ones for consistency.
Edit: typo OMPD_assumes -> OMPD_assume.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may affect codegen + may add some memory overhead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The final output from this (global) function will be the same, so it shouldn't affect codegen.
2) returning OMPD_assume in clang/lib/Basic/OpenMPKinds.cpp. Changes to be committed: modified: clang/include/clang/Parse/Parser.h modified: clang/lib/Basic/OpenMPKinds.cpp modified: clang/lib/Parse/ParseOpenMP.cpp
In clang/lib/Sema/SemaOpenMP.cpp I have retained the marking of the inner regions of the associated statements with AssumeAttr. This will make the work in Codegen easier. |
clang/include/clang/Parse/Parser.h
Outdated
@@ -488,6 +488,49 @@ class Parser : public CodeCompletionHandler { | |||
/// a statement expression and builds a suitable expression statement. | |||
StmtResult handleExprStmt(ExprResult E, ParsedStmtContext StmtCtx); | |||
|
|||
class AssumeParseAssociatedStmtRAII { | |||
Parser *parent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Parser *parent; | |
Parser &Parent; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I am creating instance of AssumeParseAssociatedStmtRAII
in Parser::ParseOpenMPAssumesDirective()
I have to store Parent as a pointer. The creation of the instance is done as :
AssumeParseAssociatedStmtRAII AssumeParseAssocRAII(this, Loc, DKind);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass it as *this
clang/include/clang/Parse/Parser.h
Outdated
AssumeParseAssociatedStmtRAII(Parser *parent, SourceLocation Loc, | ||
OpenMPDirectiveKind DKind) | ||
: parent(parent), DKind(DKind) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AssumeParseAssociatedStmtRAII(Parser *parent, SourceLocation Loc, | |
OpenMPDirectiveKind DKind) | |
: parent(parent), DKind(DKind) { | |
AssumeParseAssociatedStmtRAII(Parser &Parent, SourceLocation Loc, | |
OpenMPDirectiveKind DKind) | |
: Parent(Parent), DKind(DKind) { |
modified: clang/include/clang/Parse/Parser.h
2) Changing "Parent" to "&Parent". modified: clang/include/clang/Parse/Parser.h modified: clang/lib/Parse/ParseOpenMP.cpp
How it will make the codegen easier? It is better to try to avoid post-building attribute assignment, if possible. If possible to add attribute on the region build, better to do it. |
executed in the corresponding region or in any region that is nested in the corresponding region". Moving the marking of the nested regions into Codegen. Marking the outer Associated Statement provides sufficient information. Changes to be committed: modified: clang/lib/Sema/SemaOpenMP.cpp
Changes to
Hence closing this pull request. |
Support for assume directive : Parse and AST modules