forked from OSchip/llvm-project
[flang][openacc] Semantic check for cache directive
Add semantic check for the cache directive. According to section 2.10 from the specification: A var in a cache directive must be a single array element or a simple subarray. Reviewed By: kiranchandramohan Differential Revision: https://reviews.llvm.org/D90184
This commit is contained in:
parent
0637dfe88b
commit
e73d8c793a
|
@ -238,6 +238,15 @@ void AccStructureChecker::Leave(const parser::OpenACCAtomicConstruct &x) {
|
|||
dirContext_.pop_back();
|
||||
}
|
||||
|
||||
void AccStructureChecker::Enter(const parser::OpenACCCacheConstruct &x) {
|
||||
const auto &verbatim = std::get<parser::Verbatim>(x.t);
|
||||
PushContextAndClauseSets(verbatim.source, llvm::acc::Directive::ACCD_cache);
|
||||
SetContextDirectiveSource(verbatim.source);
|
||||
}
|
||||
void AccStructureChecker::Leave(const parser::OpenACCCacheConstruct &x) {
|
||||
dirContext_.pop_back();
|
||||
}
|
||||
|
||||
// Clause checkers
|
||||
CHECK_REQ_SCALAR_INT_CONSTANT_CLAUSE(Collapse, ACCC_collapse)
|
||||
|
||||
|
|
|
@ -59,6 +59,8 @@ public:
|
|||
void Leave(const parser::OpenACCWaitConstruct &);
|
||||
void Enter(const parser::OpenACCAtomicConstruct &);
|
||||
void Leave(const parser::OpenACCAtomicConstruct &);
|
||||
void Enter(const parser::OpenACCCacheConstruct &);
|
||||
void Leave(const parser::OpenACCCacheConstruct &);
|
||||
|
||||
// Clauses
|
||||
void Leave(const parser::AccClauseList &);
|
||||
|
|
|
@ -140,6 +140,9 @@ public:
|
|||
GetContext().withinConstruct = true;
|
||||
}
|
||||
|
||||
bool Pre(const parser::OpenACCCacheConstruct &);
|
||||
void Post(const parser::OpenACCCacheConstruct &) { PopContext(); }
|
||||
|
||||
void Post(const parser::AccDefaultClause &);
|
||||
|
||||
bool Pre(const parser::AccClause::Copy &x) {
|
||||
|
@ -209,6 +212,7 @@ private:
|
|||
Symbol *DeclareOrMarkOtherAccessEntity(Symbol &, Symbol::Flag);
|
||||
void CheckMultipleAppearances(
|
||||
const parser::Name &, const Symbol &, Symbol::Flag);
|
||||
void AllowOnlyArrayAndSubArray(const parser::AccObjectList &objectList);
|
||||
};
|
||||
|
||||
// Data-sharing and Data-mapping attributes for data-refs in OpenMP construct
|
||||
|
@ -450,7 +454,6 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCLoopConstruct &x) {
|
|||
bool AccAttributeVisitor::Pre(const parser::OpenACCStandaloneConstruct &x) {
|
||||
const auto &standaloneDir{std::get<parser::AccStandaloneDirective>(x.t)};
|
||||
switch (standaloneDir.v) {
|
||||
case llvm::acc::Directive::ACCD_cache:
|
||||
case llvm::acc::Directive::ACCD_enter_data:
|
||||
case llvm::acc::Directive::ACCD_exit_data:
|
||||
case llvm::acc::Directive::ACCD_init:
|
||||
|
@ -483,6 +486,64 @@ bool AccAttributeVisitor::Pre(const parser::OpenACCCombinedConstruct &x) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool IsLastNameArray(const parser::Designator &designator) {
|
||||
const auto &name{GetLastName(designator)};
|
||||
const evaluate::DataRef dataRef{*(name.symbol)};
|
||||
return std::visit(
|
||||
common::visitors{
|
||||
[](const evaluate::SymbolRef &ref) { return ref->Rank() > 0; },
|
||||
[](const evaluate::ArrayRef &aref) {
|
||||
return aref.base().IsSymbol() ||
|
||||
aref.base().GetComponent().base().Rank() == 0;
|
||||
},
|
||||
[](const auto &) { return false; },
|
||||
},
|
||||
dataRef.u);
|
||||
}
|
||||
|
||||
void AccAttributeVisitor::AllowOnlyArrayAndSubArray(
|
||||
const parser::AccObjectList &objectList) {
|
||||
for (const auto &accObject : objectList.v) {
|
||||
std::visit(
|
||||
common::visitors{
|
||||
[&](const parser::Designator &designator) {
|
||||
if (!IsLastNameArray(designator))
|
||||
context_.Say(designator.source,
|
||||
"Only array element or subarray are allowed in %s directive"_err_en_US,
|
||||
parser::ToUpperCaseLetters(
|
||||
llvm::acc::getOpenACCDirectiveName(
|
||||
GetContext().directive)
|
||||
.str()));
|
||||
},
|
||||
[&](const auto &name) {
|
||||
context_.Say(name.source,
|
||||
"Only array element or subarray are allowed in %s directive"_err_en_US,
|
||||
parser::ToUpperCaseLetters(
|
||||
llvm::acc::getOpenACCDirectiveName(GetContext().directive)
|
||||
.str()));
|
||||
},
|
||||
},
|
||||
accObject.u);
|
||||
}
|
||||
}
|
||||
|
||||
bool AccAttributeVisitor::Pre(const parser::OpenACCCacheConstruct &x) {
|
||||
const auto &verbatim{std::get<parser::Verbatim>(x.t)};
|
||||
PushContext(verbatim.source, llvm::acc::Directive::ACCD_cache);
|
||||
ClearDataSharingAttributeObjects();
|
||||
|
||||
const auto &objectListWithModifier =
|
||||
std::get<parser::AccObjectListWithModifier>(x.t);
|
||||
const auto &objectList =
|
||||
std::get<Fortran::parser::AccObjectList>(objectListWithModifier.t);
|
||||
|
||||
// 2.10 Cache directive restriction: A var in a cache directive must be a
|
||||
// single array element or a simple subarray.
|
||||
AllowOnlyArrayAndSubArray(objectList);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::int64_t AccAttributeVisitor::GetAssociatedLoopLevelFromClauses(
|
||||
const parser::AccClauseList &x) {
|
||||
std::int64_t collapseLevel{0};
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
! 2.14.3 Set
|
||||
! 2.14.4 Update
|
||||
! 2.15.1 Routine
|
||||
! 2.10 Cache
|
||||
! 2.11 Parallel Loop
|
||||
! 2.11 Kernels Loop
|
||||
! 2.11 Serial Loop
|
||||
|
@ -21,6 +22,11 @@ program openacc_clause_validity
|
|||
|
||||
implicit none
|
||||
|
||||
type atype
|
||||
real(8), dimension(10) :: arr
|
||||
real(8) :: s
|
||||
end type atype
|
||||
|
||||
integer :: i, j, b, gang_size, vector_size, worker_size
|
||||
integer, parameter :: N = 256
|
||||
integer, dimension(N) :: c
|
||||
|
@ -31,6 +37,8 @@ program openacc_clause_validity
|
|||
logical :: reduction_l
|
||||
real(8), dimension(N, N) :: aa, bb, cc
|
||||
logical :: ifCondition = .TRUE.
|
||||
type(atype) :: t
|
||||
type(atype), dimension(10) :: ta
|
||||
|
||||
!ERROR: At least one clause is required on the DECLARE directive
|
||||
!$acc declare
|
||||
|
@ -646,6 +654,28 @@ program openacc_clause_validity
|
|||
i = i + 1
|
||||
!$acc end atomic
|
||||
!$acc end parallel
|
||||
t%arr(i) = 2.0
|
||||
|
||||
!$acc cache(a(i))
|
||||
!$acc cache(a(1:2,3:4))
|
||||
!$acc cache(a)
|
||||
!$acc cache(readonly: a, aa)
|
||||
!$acc cache(readonly: a(i), aa(i, i))
|
||||
!$acc cache(t%arr)
|
||||
!$acc cache(ta(1:2)%arr)
|
||||
!$acc cache(ta(1:2)%arr(1:4))
|
||||
|
||||
!ERROR: Only array element or subarray are allowed in CACHE directive
|
||||
!$acc cache(ta(1:2)%s)
|
||||
|
||||
!ERROR: Only array element or subarray are allowed in CACHE directive
|
||||
!$acc cache(i)
|
||||
|
||||
!ERROR: Only array element or subarray are allowed in CACHE directive
|
||||
!$acc cache(t%s)
|
||||
|
||||
!ERROR: Only array element or subarray are allowed in CACHE directive
|
||||
!$acc cache(/i/)
|
||||
|
||||
contains
|
||||
|
||||
|
|
Loading…
Reference in New Issue