Skip to content
Open
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
042d2f6
[flang] Draft of the work to look up COMMON declarations in the modules
eugeneepshteyn Oct 6, 2025
f31c976
Merge branch 'main' into 2-acc-common
eugeneepshteyn Oct 6, 2025
931b300
Try to handle use association, but didn't work, because no symbol
eugeneepshteyn Oct 9, 2025
0bfb06c
Merge branch 'main' into 2-acc-common
eugeneepshteyn Oct 9, 2025
86cb8b6
Searching for COMMON definition in top level modules
eugeneepshteyn Oct 9, 2025
f462bf5
Guard against null cb
eugeneepshteyn Oct 9, 2025
14ce6b6
Unit test
eugeneepshteyn Oct 9, 2025
8c344c3
Merge branch 'llvm:main' into 2-acc-common
eugeneepshteyn Oct 9, 2025
e00d8f5
Merge branch '2-acc-common' into 3-acc-common
eugeneepshteyn Oct 10, 2025
827f8f0
Merge branch 'llvm:main' into 3-acc-common
eugeneepshteyn Oct 12, 2025
430660f
Merge branch 'llvm:main' into 3-acc-common
eugeneepshteyn Oct 13, 2025
ff637dd
Updated Scope::FindCommonBlock() to be similar to Scope::FindSymbol()…
eugeneepshteyn Oct 13, 2025
9e19979
clang-format
eugeneepshteyn Oct 13, 2025
66028ef
Split FindCommonBlock() into FindCB() and FindCommonBlockInScopes(). …
eugeneepshteyn Oct 13, 2025
41336f1
Add USE association details to COMMON blocks
eugeneepshteyn Oct 13, 2025
eac75b7
Handle the case of redeclared COMMON block
eugeneepshteyn Oct 13, 2025
553a3c3
clang-format
eugeneepshteyn Oct 13, 2025
63662d8
Merge branch 'llvm:main' into 3-acc-common
eugeneepshteyn Oct 13, 2025
adcd69b
Merge branch 'llvm:main' into 2-acc-common
eugeneepshteyn Oct 13, 2025
74de636
Merge branch '3-acc-common' into 2-acc-common
eugeneepshteyn Oct 13, 2025
6527159
Merge branch 'llvm:main' into 3-acc-common
eugeneepshteyn Oct 16, 2025
c042379
Code review feedback + separated COMMON lists into COMMON in the curr…
eugeneepshteyn Oct 16, 2025
740894f
COMMON block uses renames. Extended test to using module chain
eugeneepshteyn Oct 16, 2025
ca82173
clang-format
eugeneepshteyn Oct 16, 2025
2474da0
Enabled creating of USE symbols from USE symbols of COMMON blocks
eugeneepshteyn Oct 16, 2025
68363d2
Merge branch 'llvm:main' into 3-acc-common
eugeneepshteyn Oct 16, 2025
5c84d48
clang-format
eugeneepshteyn Oct 16, 2025
cc4145c
Merge branch 'llvm:main' into 2-acc-common
eugeneepshteyn Oct 16, 2025
06b2a01
Merge branch '3-acc-common' into 2-acc-common
eugeneepshteyn Oct 16, 2025
8f802f7
Code review feedback
eugeneepshteyn Oct 16, 2025
b711009
Renamed to FindCommonBlockInVisibleScope()
eugeneepshteyn Oct 17, 2025
ee0cdde
clang-format
eugeneepshteyn Oct 17, 2025
5349a65
Merge branch 'llvm:main' into 2-acc-common
eugeneepshteyn Oct 17, 2025
b268f4e
Merge branch 'llvm:main' into 3-acc-common
eugeneepshteyn Oct 20, 2025
6c8e7a0
Code review feedback
eugeneepshteyn Oct 16, 2025
bab4e67
Renamed to FindCommonBlockInVisibleScope()
eugeneepshteyn Oct 17, 2025
ab01526
clang-format
eugeneepshteyn Oct 17, 2025
f2028c7
Code review feedback
eugeneepshteyn Oct 20, 2025
258050f
Merge branch 'llvm:main' into 3-acc-common
eugeneepshteyn Oct 20, 2025
adf6b5f
Merge branch 'llvm:main' into 2-acc-common
eugeneepshteyn Oct 20, 2025
86dc6a7
Merge branch '3-acc-common' into 2-acc-common
eugeneepshteyn Oct 20, 2025
acde775
clang-format
eugeneepshteyn Oct 20, 2025
abd2f40
[AddOrUpdateCommonBlockUse] Implemented selection of largest COMMON b…
eugeneepshteyn Oct 20, 2025
fc6beb7
[AddOrUpdateCommonBlockUse] Implemented selection of largest COMMON b…
eugeneepshteyn Oct 20, 2025
19c1534
clang-format
eugeneepshteyn Oct 20, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion flang/include/flang/Semantics/scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_; }
Copy link
Contributor

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


// Find COMMON block that is not USE-associated in the current scope
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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The name isn't consistent with the comment; will this member function detect a common block in this scope, or only in its parents?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would appreciate suggestion for a better name, otherwise it'll be FindCommonBlockInCurrentAndSurroundingScopes() :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe FindCommonBlockInLexicalScopes or VisibleScopes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with FindCommonBlockInVisibleScopes()


/// Make a Symbol but don't add it to the scope.
template <typename D>
Expand Down Expand Up @@ -283,6 +305,7 @@ class Scope {
std::list<Scope> children_;
mapType symbols_;
mapType commonBlocks_;
mapType commonBlockUses_; // USE-assocated COMMON blocks
std::list<EquivalenceSet> equivalenceSets_;
mapType crayPointers_;
std::map<SourceName, common::Reference<Scope>> submodules_;
Expand Down
22 changes: 9 additions & 13 deletions flang/lib/Semantics/resolve-directives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be more clear as if (name) { ..., I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

return nullptr;
}
if (auto *cb{GetContext().scope.FindCommonBlockInSurroundingScopes(
name->source)}) {
name->symbol = cb;
return cb;
}
return nullptr;
}
Expand Down Expand Up @@ -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());
}
},
},
Expand Down
22 changes: 22 additions & 0 deletions flang/lib/Semantics/resolve-names.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens when the same COMMON block name arrives from multiple modules?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first use will be added via AddCommonBlockUse(), but adding the second use will silently fail. What should be the behavior in such case?

Copy link
Contributor

Choose a reason for hiding this comment

The 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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

COMMON block names and sizes are already stored in SemanticsContext, available via SemanticsContext::GetCommonBlocks(). This is what lowering is using to generate correctly sized blob for COMMON.

We already have a warning for COMMON size differences. The following code

module common_multi_mod_a
  integer :: a
  common /my_common/ a
end module

module common_multi_mod_b
  integer :: b
  integer :: c
  common /my_common/ b, c
end module

subroutine s1()
  use common_multi_mod_a
  a = 1
end subroutine

subroutine s2()
  use common_multi_mod_b
  b = 2
  c = 3
end subroutine

subroutine s3()
  use common_multi_mod_b
  use common_multi_mod_a
  a = 4
  b = 5
  c = 6
end subroutine

... generates the following warning:

$ flang -c common-multi-mod.f90 -pedantic
./common-multi-mod.f90:9:11: portability: A named COMMON block should have the same size everywhere it appears (8 bytes here) [-Wdistinct-common-sizes]
    common /my_common/ b, c
            ^^^^^^^^^
./common-multi-mod.f90:3:11: Previously defined with a size of 4 bytes
    common /my_common/ a
            ^^^^^^^^^

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Note that a and b in the example above occupy the same space. We don't warn about that. Should we?)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's storage association.

Copy link
Contributor Author

@eugeneepshteyn eugeneepshteyn Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you would want to retain the largest definition of the COMMON block

I implemented that, but unfortunately in PerformStatementSemantics(), ResolveNames() is called before ComputeOffsets(), so don't know COMMON block sizes at the time of the name resolution. I undid my implementation, but kept AddCommonBlockUse() change

// 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)};
!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(
name, symbol->attrs(), UseDetails{name, symbol->GetUltimate()});
currScope().AddCommonBlockUse(name, *localCB);
}
useModuleScope_ = nullptr;
}

Expand Down
33 changes: 27 additions & 6 deletions flang/lib/Semantics/scope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,35 @@ void Scope::add_crayPointer(const SourceName &name, Symbol &pointer) {
}

Symbol &Scope::MakeCommonBlock(SourceName name, SourceName location) {
const auto it{commonBlocks_.find(name)};
if (it != commonBlocks_.end()) {
return *it->second;
if (auto *cb{FindCommonBlock(name)}) {
return *cb;
} else {
Symbol &symbol{MakeSymbol(
name, Attrs{}, CommonBlockDetails{name.empty() ? location : name})};
commonBlocks_.emplace(name, symbol);
return symbol;
}
}
Symbol *Scope::FindCommonBlock(const SourceName &name) const {
const auto it{commonBlocks_.find(name)};
return it != commonBlocks_.end() ? &*it->second : nullptr;

Symbol *Scope::FindCommonBlockInSurroundingScopes(
const SourceName &name) const {
if (Symbol * cb{FindCommonBlock(name)}) {
return cb;
} else if (Symbol * cb{FindCommonBlockUse(name)}) {
return &cb->GetUltimate();
} else if (IsSubmodule()) {
if (const Scope *parent{
symbol_ ? symbol_->get<ModuleDetails>().parent() : nullptr}) {
if (auto *cb{parent->FindCommonBlockInSurroundingScopes(name)}) {
return cb;
}
}
} else if (!IsTopLevel() && parent_) {
if (auto *cb{parent_->FindCommonBlockInSurroundingScopes(name)}) {
return cb;
}
}
return nullptr;
}

Scope *Scope::FindSubmodule(const SourceName &name) const {
Expand All @@ -167,6 +183,11 @@ Scope *Scope::FindSubmodule(const SourceName &name) const {
return &*it->second;
}
}

bool Scope::AddCommonBlockUse(const SourceName &name, Symbol &cbSymbol) {
return commonBlockUses_.emplace(name, cbSymbol).second;
}

bool Scope::AddSubmodule(const SourceName &name, Scope &submodule) {
return submodules_.emplace(name, submodule).second;
}
Expand Down
30 changes: 30 additions & 0 deletions flang/test/Semantics/OpenACC/acc-common.f90
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