-
Notifications
You must be signed in to change notification settings - Fork 0
Support for declare target initializers #3
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14473,6 +14473,13 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, | |
|
|
||
| for (unsigned i = 0, e = Group.size(); i != e; ++i) { | ||
| if (Decl *D = Group[i]) { | ||
| // Check if the Decl has been declared in '#pragma omp declare target' | ||
| // directive and has static storage duration. | ||
| if (auto *VD = dyn_cast_or_null<VarDecl>(D); | ||
| LangOpts.OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() && | ||
| VD->hasGlobalStorage()) { | ||
| ActOnOpenMPImplicitDeclareTarget(D); | ||
| } | ||
|
Comment on lines
+14478
to
+14482
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you run git-clang-format on all your changes ? |
||
| // For declarators, there are some additional syntactic-ish checks we need | ||
| // to perform. | ||
| if (auto *DD = dyn_cast<DeclaratorDecl>(D)) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23094,6 +23094,59 @@ void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, | |
| checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); | ||
| } | ||
|
|
||
| class MyStmtVisitor final : public ConstStmtVisitor<MyStmtVisitor> { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggesting not to use |
||
| public: | ||
| SmallVector<Decl *> DeclVector; | ||
| Decl *TargetDecl; | ||
| void VisitDeclRefExpr(const DeclRefExpr *Node) { | ||
| Decl *DeclVar = nullptr; | ||
| if (const VarDecl *VD = dyn_cast<VarDecl>(Node->getDecl())) { | ||
| DeclVar = (Decl *)Node->getDecl(); | ||
| DeclVar->addAttr((this->TargetDecl)->getAttr<OMPDeclareTargetDeclAttr>()); | ||
| (this->DeclVector).push_back(DeclVar); | ||
| } | ||
| } | ||
| void VisitMyExpr(const Expr *Ex) { | ||
| for (Expr::const_child_iterator it = Ex->child_begin(); | ||
| it != Ex->child_end(); ++it) { | ||
| if (isa<Expr>(*it)) | ||
| VisitMyExpr(dyn_cast<Expr>(*it)); | ||
| if (isa<DeclRefExpr>(*it)) | ||
| Visit(*it); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am assuming this |
||
| } | ||
| } | ||
| }; | ||
|
|
||
| /// Adding OMPDeclareTargetDeclAttr to variables with static storage | ||
| /// duration that are referenced in the initializer expression list of | ||
| /// variables with static storage duration in declare target directive. | ||
| void Sema::ActOnOpenMPImplicitDeclareTarget(Decl *TargetDecl) { | ||
| MyStmtVisitor visitor; | ||
| visitor.TargetDecl = TargetDecl; | ||
| VarDecl *TargetVarDecl = nullptr; | ||
| if (TargetVarDecl = dyn_cast_or_null<VarDecl>(TargetDecl)) | ||
| visitor.DeclVector.push_back(TargetDecl); | ||
| while (!visitor.DeclVector.empty()) { | ||
| Decl *D = visitor.DeclVector.pop_back_val(); | ||
| TargetVarDecl = dyn_cast_or_null<VarDecl>(D); | ||
| if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>()) { | ||
| if (TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) { | ||
| Expr *Ex = TargetVarDecl->getInit(); | ||
| const DeclRefExpr *DeclRef = nullptr; | ||
| if (Ex) { | ||
| if (isa<DeclRefExpr>(Ex)) { | ||
| DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(Ex); | ||
| visitor.VisitDeclRefExpr(DeclRef); | ||
| continue; | ||
| } | ||
| visitor.VisitMyExpr(Ex); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| OMPClause *Sema::ActOnOpenMPToClause( | ||
| ArrayRef<OpenMPMotionModifierKind> MotionModifiers, | ||
| ArrayRef<SourceLocation> MotionModifiersLoc, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| // RUN: %clang_cc1 -w -verify -fopenmp -I %S/Inputs -ast-print %s | FileCheck %s --check-prefix=CHECK | ||
| // expected-no-diagnostics | ||
|
|
||
| static int variable = 100; | ||
| static float variable1 = 200; | ||
| static float variable2 = variable1; | ||
|
|
||
| static int var = 1; | ||
|
|
||
| static int var1 = 10; | ||
| static int *var2 = &var1; | ||
| static int **ptr1 = &var2; | ||
|
|
||
| int arr[2] = {1,2}; | ||
| int (*arrptr)[2] = &arr; | ||
|
|
||
| class declare{ | ||
| public: int x; | ||
| void print(); | ||
| }; | ||
| declare obj1; | ||
| declare *obj2 = &obj1; | ||
|
|
||
| struct target{ | ||
| int x; | ||
| void print(); | ||
| }; | ||
| static target S; | ||
|
|
||
| #pragma omp declare target | ||
| int target_var = variable; | ||
| float target_var1 = variable2; | ||
| int *ptr = &var; | ||
| int ***ptr2 = &ptr1; | ||
| int (**ptr3)[2] = &arrptr; | ||
| declare **obj3 = &obj2; | ||
| target *S1 = &S; | ||
| #pragma omp end declare target | ||
| // CHECK: #pragma omp declare target | ||
| // CHECK-NEXT: static int variable = 100; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
|
|
||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: static float variable1 = 200; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: static float variable2 = variable1; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
|
|
||
| // CHECK: #pragma omp declare target | ||
| // CHECK-NEXT: static int var = 1; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
|
|
||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: static int var1 = 10; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: static int *var2 = &var1; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: static int **ptr1 = &var2; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
|
|
||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: int arr[2] = {1, 2}; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: int (*arrptr)[2] = &arr; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
|
|
||
| // CHECK-NEXT: class declare { | ||
| // CHECK-NEXT: public: | ||
| // CHECK-NEXT: int x; | ||
| // CHECK-NEXT: void print(); | ||
| // CHECK-NEXT: }; | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: declare obj1; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: declare *obj2 = &obj1; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
|
|
||
| // CHECK-NEXT: struct target { | ||
| // CHECK-NEXT: int x; | ||
| // CHECK-NEXT: void print(); | ||
| // CHECK-NEXT: }; | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: static target S; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
|
|
||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: int target_var = variable; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: float target_var1 = variable2; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: int *ptr = &var; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: int ***ptr2 = &ptr1; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: int (**ptr3)[2] = &arrptr; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: declare **obj3 = &obj2; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
| // CHECK-NEXT: #pragma omp declare target | ||
| // CHECK-NEXT: target *S1 = &S; | ||
| // CHECK-NEXT: #pragma omp end declare target | ||
|
|
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.
Instead of explaining what the function does literally, a comment describing the goal of the function would be easier to understand.