Skip to content

Commit 18f8e23

Browse files
authored
[flang][OpenMP] Make static duration variables default to shared DSA (#142783)
According to the OpenMP standard, variables with static storage duration are predetermined as shared. Add a check when creating implicit symbols for OpenMP to fix them erroneously getting set to firstprivate. Fixes #140732. --------- Signed-off-by: Kajetan Puchalski <kajetan.puchalski@arm.com>
1 parent de96199 commit 18f8e23

File tree

10 files changed

+111
-31
lines changed

10 files changed

+111
-31
lines changed

flang/include/flang/Semantics/symbol.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ class Symbol {
792792
LocalityShared, // named in SHARED locality-spec
793793
InDataStmt, // initialized in a DATA statement, =>object, or /init/
794794
InNamelist, // in a Namelist group
795+
InCommonBlock, // referenced in a common block
795796
EntryDummyArgument,
796797
CompilerCreated, // A compiler created symbol
797798
// For compiler created symbols that are constant but cannot legally have

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2217,6 +2217,20 @@ static bool IsPrivatizable(const Symbol *sym) {
22172217
misc->kind() != MiscDetails::Kind::ConstructName));
22182218
}
22192219

2220+
static bool IsSymbolStaticStorageDuration(const Symbol &symbol) {
2221+
LLVM_DEBUG(llvm::dbgs() << "IsSymbolStaticStorageDuration(" << symbol.name()
2222+
<< "):\n");
2223+
auto ultSym = symbol.GetUltimate();
2224+
// Module-scope variable
2225+
return (ultSym.owner().kind() == Scope::Kind::Module) ||
2226+
// Data statement variable
2227+
(ultSym.flags().test(Symbol::Flag::InDataStmt)) ||
2228+
// Save attribute variable
2229+
(ultSym.attrs().test(Attr::SAVE)) ||
2230+
// Referenced in a common block
2231+
(ultSym.flags().test(Symbol::Flag::InCommonBlock));
2232+
}
2233+
22202234
void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {
22212235
if (!IsPrivatizable(symbol)) {
22222236
return;
@@ -2310,6 +2324,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {
23102324
bool targetDir = llvm::omp::allTargetSet.test(dirContext.directive);
23112325
bool parallelDir = llvm::omp::allParallelSet.test(dirContext.directive);
23122326
bool teamsDir = llvm::omp::allTeamsSet.test(dirContext.directive);
2327+
bool isStaticStorageDuration = IsSymbolStaticStorageDuration(*symbol);
23132328

23142329
if (dsa.any()) {
23152330
if (parallelDir || taskGenDir || teamsDir) {
@@ -2367,7 +2382,7 @@ void OmpAttributeVisitor::CreateImplicitSymbols(const Symbol *symbol) {
23672382
dsa = prevDSA;
23682383
} else if (taskGenDir) {
23692384
// TODO 5) dummy arg in orphaned taskgen construct -> firstprivate
2370-
if (prevDSA.test(Symbol::Flag::OmpShared)) {
2385+
if (prevDSA.test(Symbol::Flag::OmpShared) || isStaticStorageDuration) {
23712386
// 6) shared in enclosing context -> shared
23722387
dsa = {Symbol::Flag::OmpShared};
23732388
makeSymbol(dsa);
@@ -2886,20 +2901,6 @@ void ResolveOmpTopLevelParts(
28862901
});
28872902
}
28882903

2889-
static bool IsSymbolInCommonBlock(const Symbol &symbol) {
2890-
// TODO Improve the performance of this predicate function.
2891-
// Going through all symbols sequentially, in all common blocks, can be
2892-
// slow when there are many symbols. A possible optimization is to add
2893-
// an OmpInCommonBlock flag to Symbol, to make it possible to quickly
2894-
// test if a given symbol is in a common block.
2895-
for (const auto &cb : symbol.owner().commonBlocks()) {
2896-
if (IsCommonBlockContaining(cb.second.get(), symbol)) {
2897-
return true;
2898-
}
2899-
}
2900-
return false;
2901-
}
2902-
29032904
static bool IsSymbolThreadprivate(const Symbol &symbol) {
29042905
if (const auto *details{symbol.detailsIf<HostAssocDetails>()}) {
29052906
return details->symbol().test(Symbol::Flag::OmpThreadprivate);
@@ -2928,7 +2929,7 @@ static bool IsSymbolPrivate(const Symbol &symbol) {
29282929
case Scope::Kind::BlockConstruct:
29292930
return !symbol.attrs().test(Attr::SAVE) &&
29302931
!symbol.attrs().test(Attr::PARAMETER) && !IsAssumedShape(symbol) &&
2931-
!IsSymbolInCommonBlock(symbol);
2932+
!symbol.flags().test(Symbol::Flag::InCommonBlock);
29322933
default:
29332934
return false;
29342935
}

flang/lib/Semantics/resolve-names.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6920,6 +6920,9 @@ bool DeclarationVisitor::Pre(const parser::CommonBlockObject &) {
69206920

69216921
void DeclarationVisitor::Post(const parser::CommonBlockObject &x) {
69226922
const auto &name{std::get<parser::Name>(x.t)};
6923+
if (auto *symbol{FindSymbol(name)}) {
6924+
symbol->set(Symbol::Flag::InCommonBlock);
6925+
}
69236926
DeclareObjectEntity(name);
69246927
auto pair{specPartState_.commonBlockObjects.insert(name.source)};
69256928
if (!pair.second) {

flang/test/Semantics/OpenMP/common-block.f90

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s
22

33
program main
4-
!CHECK: a size=4 offset=0: ObjectEntity type: REAL(4)
5-
!CHECK: b size=8 offset=4: ObjectEntity type: INTEGER(4) shape: 1_8:2_8
6-
!CHECK: c size=4 offset=12: ObjectEntity type: REAL(4)
4+
!CHECK: a (InCommonBlock) size=4 offset=0: ObjectEntity type: REAL(4)
5+
!CHECK: b (InCommonBlock) size=8 offset=4: ObjectEntity type: INTEGER(4) shape: 1_8:2_8
6+
!CHECK: c (InCommonBlock) size=4 offset=12: ObjectEntity type: REAL(4)
77
!CHECK: blk size=16 offset=0: CommonBlockDetails alignment=4: a b c
88
real :: a, c
99
integer :: b(2)

flang/test/Semantics/OpenMP/declare-target-common-block.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
! RUN: %flang_fc1 -fopenmp -fdebug-dump-symbols %s | FileCheck %s
22

33
PROGRAM main
4-
!CHECK: one (OmpDeclareTarget) size=4 offset=0: ObjectEntity type: REAL(4)
5-
!CHECK: two (OmpDeclareTarget) size=4 offset=4: ObjectEntity type: REAL(4)
4+
!CHECK: one (InCommonBlock, OmpDeclareTarget) size=4 offset=0: ObjectEntity type: REAL(4)
5+
!CHECK: two (InCommonBlock, OmpDeclareTarget) size=4 offset=4: ObjectEntity type: REAL(4)
66
!CHECK: numbers size=8 offset=0: CommonBlockDetails alignment=4: one two
77
REAL :: one, two
88
COMMON /numbers/ one, two

flang/test/Semantics/OpenMP/implicit-dsa.f90

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,3 +169,78 @@ subroutine implicit_dsa_test8
169169
end do
170170
!$omp end task
171171
end subroutine
172+
173+
! Test variables defined in modules default to shared DSA
174+
!DEF: /implicit_dsa_test9_mod Module
175+
module implicit_dsa_test9_mod
176+
!DEF: /implicit_dsa_test9_mod/tm3a PUBLIC (InDataStmt) ObjectEntity COMPLEX(4)
177+
complex tm3a/(0,0)/
178+
!DEF: /implicit_dsa_test9_mod/tm4a PUBLIC ObjectEntity COMPLEX(4)
179+
complex tm4a
180+
contains
181+
!DEF: /implicit_dsa_test9_mod/implict_dsa_test9 PUBLIC (Subroutine) Subprogram
182+
subroutine implict_dsa_test9
183+
!$omp task
184+
!$omp task
185+
!DEF: /implicit_dsa_test9_mod/implict_dsa_test9/OtherConstruct1/OtherConstruct1/tm3a (OmpShared) HostAssoc COMPLEX(4)
186+
tm3a = (1, 2)
187+
!DEF: /implicit_dsa_test9_mod/implict_dsa_test9/OtherConstruct1/OtherConstruct1/tm4a (OmpShared) HostAssoc COMPLEX(4)
188+
tm4a = (3, 4)
189+
!$omp end task
190+
!$omp end task
191+
!$omp taskwait
192+
!REF: /implicit_dsa_test9_mod/tm3a
193+
print *,tm3a
194+
end subroutine
195+
end module
196+
197+
! Test variables in data statement default to shared DSA
198+
!DEF: /implicit_dsa_test10 (Subroutine) Subprogram
199+
subroutine implicit_dsa_test10
200+
!DEF: /implicit_dsa_test10/tm3a (Implicit, InDataStmt) ObjectEntity REAL(4)
201+
data tm3a /3/
202+
!$omp task
203+
!$omp task
204+
!DEF: /implicit_dsa_test10/OtherConstruct1/OtherConstruct1/tm3a (OmpShared) HostAssoc REAL(4)
205+
tm3a = 5
206+
!$omp end task
207+
!$omp end task
208+
!$omp taskwait
209+
!REF: /implicit_dsa_test10/tm3a
210+
print *,tm3a
211+
end subroutine
212+
213+
! Test variables with the SAVE attrtibute default to shared DSA
214+
!DEF: /implicit_dsa_test_11 (Subroutine) Subprogram
215+
subroutine implicit_dsa_test_11
216+
!DEF: /implicit_dsa_test_11/tm3a SAVE ObjectEntity COMPLEX(4)
217+
complex, save :: tm3a
218+
!$omp task
219+
!$omp task
220+
!DEF: /implicit_dsa_test_11/OtherConstruct1/OtherConstruct1/tm3a (OmpShared) HostAssoc COMPLEX(4)
221+
tm3a = (1, 2)
222+
!$omp end task
223+
!$omp end task
224+
!$omp taskwait
225+
!REF: /implicit_dsa_test_11/tm3a
226+
print *,tm3a
227+
end subroutine
228+
229+
! Test variables referenced in a common block default to shared DSA
230+
!DEF: /implicit_dsa_test_12 (Subroutine) Subprogram
231+
subroutine implicit_dsa_test_12
232+
!DEF: /implicit_dsa_test_12/tm3a (InCommonBlock) ObjectEntity COMPLEX(4)
233+
complex tm3a
234+
!DEF: /implicit_dsa_test_12/tcom CommonBlockDetails
235+
!REF: /implicit_dsa_test_12/tm3a
236+
common /tcom/ tm3a
237+
!$omp task
238+
!$omp task
239+
!DEF: /implicit_dsa_test_12/OtherConstruct1/OtherConstruct1/tm3a (OmpShared) HostAssoc COMPLEX(4)
240+
tm3a = (1, 2)
241+
!$omp end task
242+
!$omp end task
243+
!$omp taskwait
244+
!REF: /implicit_dsa_test_12/tm3a
245+
print *,tm3a
246+
end subroutine

flang/test/Semantics/OpenMP/symbol01.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ program mm
2121
!REF: /md
2222
use :: md
2323
!DEF: /mm/c CommonBlockDetails
24-
!DEF: /mm/x ObjectEntity REAL(4)
25-
!DEF: /mm/y ObjectEntity REAL(4)
24+
!DEF: /mm/x (InCommonBlock) ObjectEntity REAL(4)
25+
!DEF: /mm/y (InCommonBlock) ObjectEntity REAL(4)
2626
common /c/x, y
2727
!REF: /mm/x
2828
!REF: /mm/y

flang/test/Semantics/offsets03.f90

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ subroutine mc !CHECK: Subprogram scope: mc size=12 alignment=1
3030
! Common block: objects are in order from COMMON statement and not part of module
3131
module md !CHECK: Module scope: md size=1 alignment=1
3232
integer(1) :: i
33-
integer(2) :: d1 !CHECK: d1, PUBLIC size=2 offset=8:
34-
integer(4) :: d2 !CHECK: d2, PUBLIC size=4 offset=4:
35-
integer(1) :: d3 !CHECK: d3, PUBLIC size=1 offset=0:
36-
real(2) :: d4 !CHECK: d4, PUBLIC size=2 offset=0:
33+
integer(2) :: d1 !CHECK: d1, PUBLIC (InCommonBlock) size=2 offset=8:
34+
integer(4) :: d2 !CHECK: d2, PUBLIC (InCommonBlock) size=4 offset=4:
35+
integer(1) :: d3 !CHECK: d3, PUBLIC (InCommonBlock) size=1 offset=0:
36+
real(2) :: d4 !CHECK: d4, PUBLIC (InCommonBlock) size=2 offset=0:
3737
common /common1/ d3,d2,d1 !CHECK: common1 size=10 offset=0: CommonBlockDetails alignment=4:
3838
common /common2/ d4 !CHECK: common2 size=2 offset=0: CommonBlockDetails alignment=2:
3939
end
@@ -71,7 +71,7 @@ module me
7171
subroutine host1
7272
contains
7373
subroutine internal
74-
common /b/ x(4) ! CHECK: x (Implicit) size=16 offset=0: ObjectEntity type: REAL(4) shape: 1_8:4_8
74+
common /b/ x(4) ! CHECK: x (Implicit, InCommonBlock) size=16 offset=0: ObjectEntity type: REAL(4) shape: 1_8:4_8
7575
equivalence(x,y) ! CHECK: y (Implicit) size=4 offset=0: ObjectEntity type: REAL(4)
7676
end
7777
end

flang/test/Semantics/resolve121.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ subroutine test3()
2525
! CHECK-LABEL: Subprogram scope: test3
2626
! CHECK: i1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
2727
! CHECK: j1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
28-
! CHECK: k1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
28+
! CHECK: k1, SAVE (InCommonBlock) size=4 offset=0: ObjectEntity type: INTEGER(4)
2929
integer :: i1
3030
integer :: j1, k1
3131
common /blk/ k1
@@ -37,7 +37,7 @@ subroutine test4()
3737
! CHECK-LABEL: Subprogram scope: test4
3838
! CHECK: i1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4) init:1_4
3939
! CHECK: j1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
40-
! CHECK: k1, SAVE size=4 offset=0: ObjectEntity type: INTEGER(4)
40+
! CHECK: k1, SAVE (InCommonBlock) size=4 offset=0: ObjectEntity type: INTEGER(4)
4141
integer :: i1 = 1
4242
integer :: j1, k1
4343
common /blk/ k1

flang/test/Semantics/symbol33.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
! array element reference still applies implicit typing, &c.
44
!DEF: /subr (Subroutine) Subprogram
55
subroutine subr
6-
!DEF: /subr/moo (Implicit) ObjectEntity INTEGER(4)
6+
!DEF: /subr/moo (Implicit, InCommonBlock) ObjectEntity INTEGER(4)
77
common //moo(1)
88
!DEF: /subr/a ObjectEntity REAL(4)
99
!REF: /subr/moo

0 commit comments

Comments
 (0)