-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[flang][OpenACC] Relax COMMON block usage restriction in OpenACC directives #162659
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 29 commits
042d2f6
f31c976
931b300
0bfb06c
86cb8b6
f462bf5
14ce6b6
8c344c3
e00d8f5
827f8f0
430660f
ff637dd
9e19979
66028ef
41336f1
eac75b7
553a3c3
63662d8
adcd69b
74de636
6527159
c042379
740894f
ca82173
2474da0
68363d2
5c84d48
cc4145c
06b2a01
8f802f7
b711009
ee0cdde
5349a65
b268f4e
6c8e7a0
bab4e67
ab01526
f2028c7
258050f
adf6b5f
86dc6a7
acde775
abd2f40
fc6beb7
19c1534
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 |
---|---|---|
|
@@ -189,7 +189,29 @@ class Scope { | |
mapType &commonBlocks() { return commonBlocks_; } | ||
const mapType &commonBlocks() const { return commonBlocks_; } | ||
Symbol &MakeCommonBlock(SourceName, SourceName location); | ||
Symbol *FindCommonBlock(const SourceName &) const; | ||
bool AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol); | ||
mapType &commonBlockUses() { return commonBlockUses_; } | ||
|
||
// Find COMMON block that is not USE-associated in the current scope | ||
eugeneepshteyn marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
Symbol *FindCommonBlock(const SourceName &name) const { | ||
if (const auto it{commonBlocks_.find(name)}; it != commonBlocks_.end()) { | ||
return &*it->second; | ||
} | ||
return nullptr; | ||
} | ||
|
||
// Find USE-associated COMMON block in the current scope | ||
Symbol *FindCommonBlockUse(const SourceName &name) const { | ||
if (const auto it{commonBlockUses_.find(name)}; | ||
it != commonBlockUses_.end()) { | ||
return &*it->second; | ||
} | ||
return nullptr; | ||
} | ||
|
||
// Find COMMON block in current and surrounding scopes, follow USE | ||
// associations | ||
Symbol *FindCommonBlockInSurroundingScopes(const SourceName &) const; | ||
|
||
|
||
/// Make a Symbol but don't add it to the scope. | ||
template <typename D> | ||
|
@@ -283,6 +305,7 @@ class Scope { | |
std::list<Scope> children_; | ||
mapType symbols_; | ||
mapType commonBlocks_; | ||
mapType commonBlockUses_; // USE-assocated COMMON blocks | ||
eugeneepshteyn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
std::list<EquivalenceSet> equivalenceSets_; | ||
mapType crayPointers_; | ||
std::map<SourceName, common::Reference<Scope>> submodules_; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1729,17 +1729,13 @@ void AccAttributeVisitor::Post(const parser::Name &name) { | |
|
||
Symbol *AccAttributeVisitor::ResolveAccCommonBlockName( | ||
const parser::Name *name) { | ||
if (auto *prev{name | ||
? GetContext().scope.parent().FindCommonBlock(name->source) | ||
: nullptr}) { | ||
name->symbol = prev; | ||
return prev; | ||
} | ||
// Check if the Common Block is declared in the current scope | ||
if (auto *commonBlockSymbol{ | ||
name ? GetContext().scope.FindCommonBlock(name->source) : nullptr}) { | ||
name->symbol = commonBlockSymbol; | ||
return commonBlockSymbol; | ||
if (!name) { | ||
|
||
return nullptr; | ||
} | ||
if (auto *cb{GetContext().scope.FindCommonBlockInSurroundingScopes( | ||
name->source)}) { | ||
name->symbol = cb; | ||
return cb; | ||
} | ||
return nullptr; | ||
} | ||
|
@@ -1789,8 +1785,8 @@ void AccAttributeVisitor::ResolveAccObject( | |
} | ||
} else { | ||
context_.Say(name.source, | ||
"COMMON block must be declared in the same scoping unit " | ||
"in which the OpenACC directive or clause appears"_err_en_US); | ||
"Could not find COMMON block '%s' used in OpenACC directive"_err_en_US, | ||
name.ToString()); | ||
} | ||
}, | ||
}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3627,6 +3627,28 @@ void ModuleVisitor::Post(const parser::UseStmt &x) { | |
} | ||
} | ||
} | ||
// Go through the list of COMMON block symbols in the module scope and add | ||
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. What happens when the same COMMON block name arrives from multiple modules? 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 first use will be added via 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 don't know. Maybe you would want to retain the largest definition of the COMMON block, and perhaps warn if their sizes differ. 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. COMMON block names and sizes are already stored in We already have a warning for COMMON size differences. The following code
... generates the following warning:
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. (Note that 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. No, it's storage association. 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 implemented that, but unfortunately in |
||
// their USE association to the current scope's USE-associated COMMON blocks. | ||
for (const auto &[name, symbol] : useModuleScope_->commonBlocks()) { | ||
if (Symbol *localCB{currScope().FindCommonBlockInSurroundingScopes(name)}; | ||
eugeneepshteyn marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
!localCB) { | ||
// Make a symbol, but don't add it to the Scope, since it needs to | ||
// be added to the USE-associated COMMON blocks | ||
localCB = &currScope().MakeSymbol( | ||
name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()}); | ||
currScope().AddCommonBlockUse(name, *localCB); | ||
} | ||
} | ||
// Go through the list of USE-associated COMMON block symbols in the module | ||
// scope and add USE associations to their ultimate symbols to the current | ||
// scope's USE-associated COMMON blocks. | ||
for (const auto &[name, symbol] : useModuleScope_->commonBlockUses()) { | ||
// Make a symbol, but don't add it to the Scope, since it needs to | ||
// be added to the USE-associated COMMON blocks | ||
Symbol *localCB = &currScope().MakeSymbol( | ||
eugeneepshteyn marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()}); | ||
currScope().AddCommonBlockUse(name, *localCB); | ||
} | ||
useModuleScope_ = nullptr; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
! RUN: %python %S/../test_errors.py %s %flang -fopenacc | ||
module acc_common_decl | ||
implicit none | ||
integer a | ||
common /a_common/ a | ||
!$acc declare create (/a_common/) | ||
data a/42/ | ||
end module acc_common_decl | ||
|
||
module acc_common_intermediate | ||
use acc_common_decl | ||
implicit none | ||
integer b | ||
common /b_common/ b | ||
!$acc declare create (/b_common/) | ||
end module acc_common_intermediate | ||
|
||
program acc_decl_test | ||
use acc_common_intermediate | ||
implicit none | ||
|
||
a = 1 | ||
b = 10 | ||
!$acc update device (/a_common/) | ||
a = 2 | ||
!$acc update device (/b_common/) | ||
b = 20 | ||
!ERROR: Could not find COMMON block 'a_common_bad' used in OpenACC directive | ||
!$acc update device (/a_common_bad/) | ||
end program |
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.
Consider adding a
const
accessor as well, and moving this up to be with the other accessors.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.
Done.