-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[Flang][OpenMP] Add frontend support for declare variant #130578
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
Changes from 1 commit
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 |
---|---|---|
|
@@ -3755,6 +3755,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, | |
TODO(converter.getCurrentLocation(), "OpenMP ASSUMES declaration"); | ||
} | ||
|
||
static void | ||
genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, | ||
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, | ||
const parser::OmpDeclareVariantDirective &declareVariantDirective) { | ||
TODO(converter.getCurrentLocation(), "OpenMPDeclareVariantDirective"); | ||
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. The class is actually called 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. Done. |
||
} | ||
|
||
static void genOMP( | ||
lower::AbstractConverter &converter, lower::SymMap &symTable, | ||
semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1511,6 +1511,25 @@ class OmpVisitor : public virtual DeclarationVisitor { | |
return true; | ||
} | ||
|
||
bool Pre(const parser::OmpDeclareVariantDirective &x) { | ||
AddOmpSourceRange(x.source); | ||
auto FindSymbolOrError = [&](const parser::Name &procName) { | ||
auto *symbol{FindSymbol(NonDerivedTypeScope(), procName)}; | ||
if (!symbol) { | ||
context().Say(procName.source, | ||
"Implicit subroutine declaration '%s' in !$OMP DECLARE VARIANT"_err_en_US, | ||
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. Is there a test for this? 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. Added test |
||
procName.source); | ||
} | ||
}; | ||
auto &baseProcName = std::get<std::optional<parser::Name>>(x.t); | ||
if (baseProcName) { | ||
FindSymbolOrError(*baseProcName); | ||
} | ||
auto &varProcName = std::get<parser::Name>(x.t); | ||
FindSymbolOrError(varProcName); | ||
return true; | ||
} | ||
|
||
bool Pre(const parser::OpenMPDeclareReductionConstruct &x) { | ||
AddOmpSourceRange(x.source); | ||
ProcessReductionSpecifier( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s | ||
|
||
! CHECK: not yet implemented: OpenMPDeclareVariantDirective | ||
|
||
subroutine sb1 | ||
integer :: x | ||
x = 1 | ||
call sub(x) | ||
contains | ||
subroutine vsub (v1) | ||
integer, value :: v1 | ||
end | ||
subroutine sub (v1) | ||
!$omp declare variant(vsub), match(construct={dispatch}) | ||
integer, value :: v1 | ||
end | ||
end subroutine |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
! RUN: %flang_fc1 -fdebug-unparse-no-sema -fopenmp %s | FileCheck --ignore-case %s | ||
! RUN: %flang_fc1 -fdebug-dump-parse-tree-no-sema -fopenmp %s | FileCheck --check-prefix="PARSE-TREE" %s | ||
|
||
subroutine sub0 | ||
!CHECK: !$OMP DECLARE VARIANT (sub:vsub) MATCH(CONSTRUCT={PARALLEL}) | ||
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective | ||
!PARSE-TREE: | Verbatim | ||
!PARSE-TREE: | Name = 'sub' | ||
!PARSE-TREE: | Name = 'vsub' | ||
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector | ||
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct | ||
!PARSE-TREE: | | OmpTraitSelector | ||
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = parallel | ||
!$omp declare variant (sub:vsub) match (construct={parallel}) | ||
contains | ||
subroutine vsub | ||
end subroutine | ||
|
||
subroutine sub () | ||
end subroutine | ||
end subroutine | ||
|
||
subroutine sb1 | ||
integer :: x | ||
x = 1 | ||
!$omp dispatch device(1) | ||
call sub(x) | ||
contains | ||
subroutine vsub (v1) | ||
integer, value :: v1 | ||
end | ||
subroutine sub (v1) | ||
!CHECK: !$OMP DECLARE VARIANT (vsub) MATCH(CONSTRUCT={DISPATCH} | ||
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective | ||
!PARSE-TREE: | Verbatim | ||
!PARSE-TREE: | Name = 'vsub' | ||
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector | ||
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct | ||
!PARSE-TREE: | | OmpTraitSelector | ||
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = dispatch | ||
!$omp declare variant(vsub), match(construct={dispatch}) | ||
integer, value :: v1 | ||
end | ||
end subroutine | ||
|
||
subroutine sb2 (x1, x2) | ||
use omp_lib, only: omp_interop_kind | ||
integer :: x | ||
x = 1 | ||
!$omp dispatch device(1) | ||
call sub(x) | ||
contains | ||
subroutine vsub (v1, a1, a2) | ||
integer, value :: v1 | ||
integer(omp_interop_kind) :: a1 | ||
integer(omp_interop_kind), value :: a2 | ||
end | ||
subroutine sub (v1) | ||
!CHECK: !$OMP DECLARE VARIANT (vsub) MATCH(CONSTRUCT={DISPATCH}) APPEND_ARGS(INTEROP(T& | ||
!CHECK: !$OMP&ARGET),INTEROP(TARGET)) | ||
!PARSE-TREE: OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective | ||
!PARSE-TREE: | Verbatim | ||
!PARSE-TREE: | Name = 'vsub' | ||
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector | ||
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct | ||
!PARSE-TREE: | | OmpTraitSelector | ||
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = dispatch | ||
!PARSE-TREE: | OmpClause -> AppendArgs -> OmpAppendArgsClause -> OmpAppendOp -> OmpInteropType -> Value = Target | ||
!PARSE-TREE: | OmpAppendOp -> OmpInteropType -> Value = Target | ||
!$omp declare variant(vsub), match(construct={dispatch}), append_args (interop(target), interop(target)) | ||
integer, value :: v1 | ||
end | ||
end subroutine | ||
|
||
subroutine sb3 (x1, x2) | ||
use iso_c_binding, only: c_ptr | ||
type(c_ptr), value :: x1, x2 | ||
|
||
!$omp dispatch device(1) | ||
call sub(x1, x2) | ||
contains | ||
subroutine sub (v1, v2) | ||
type(c_ptr), value :: v1, v2 | ||
!CHECK: !$OMP DECLARE VARIANT (vsub) MATCH(CONSTRUCT={DISPATCH}) ADJUST_ARGS(NOTHING:v& | ||
!CHECK: !$OMP&1) ADJUST_ARGS(NEED_DEVICE_PTR:v2) | ||
!PARSE-TREE: DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OmpDeclareVariantDirective | ||
!PARSE-TREE: | Verbatim | ||
!PARSE-TREE: | Name = 'vsub' | ||
!PARSE-TREE: | OmpClauseList -> OmpClause -> Match -> OmpMatchClause -> OmpContextSelectorSpecification -> OmpTraitSetSelector | ||
!PARSE-TREE: | | OmpTraitSetSelectorName -> Value = Construct | ||
!PARSE-TREE: | | OmpTraitSelector | ||
!PARSE-TREE: | | | OmpTraitSelectorName -> llvm::omp::Directive = dispatch | ||
!PARSE-TREE: | OmpClause -> AdjustArgs -> OmpAdjustArgsClause | ||
!PARSE-TREE: | | OmpAdjustOp -> Value = Nothing | ||
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'v1' | ||
!PARSE-TREE: | OmpClause -> AdjustArgs -> OmpAdjustArgsClause | ||
!PARSE-TREE: | | OmpAdjustOp -> Value = Need_Device_Ptr | ||
!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'v2' | ||
!$omp declare variant(vsub) match ( construct = { dispatch } ) adjust_args(nothing : v1 ) adjust_args(need_device_ptr : v2) | ||
end | ||
subroutine vsub(v1, v2) | ||
type(c_ptr), value :: v1, v2 | ||
end | ||
end subroutine |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51 | ||
|
||
subroutine sub0 | ||
!ERROR: Implicit subroutine declaration 'vsub1' in !$OMP DECLARE VARIANT | ||
!$omp declare variant (sub:vsub1) match (construct={parallel}) | ||
!ERROR: Implicit subroutine declaration 'sub1' in !$OMP DECLARE VARIANT | ||
!$omp declare variant (sub1:vsub) match (construct={parallel}) | ||
contains | ||
subroutine vsub | ||
end subroutine | ||
|
||
subroutine sub () | ||
end subroutine | ||
end subroutine |
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.
Nit: Is there a reason this directive is called "Omp" and the others are "OpenMP"?
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.
In the standard it is listed as a directive.