Skip to content

Commit 9facbf7

Browse files
committed
R8: converting string refs to symbol* and merging the new changes
1 parent b10a198 commit 9facbf7

File tree

7 files changed

+116
-54
lines changed

7 files changed

+116
-54
lines changed

flang/lib/Semantics/check-directive-structure.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,10 +201,6 @@ class DirectiveStructureChecker : public virtual BaseChecker {
201201
ClauseMapTy clauseInfo;
202202
std::list<C> actualClauses;
203203
std::list<C> crtGroup;
204-
std::set<std::string> usedInScanDirective;
205-
206-
using ReductionModifier = parser::OmpReductionClause::ReductionModifier;
207-
std::map<const std::string, ReductionModifier> reductionMod;
208204
Symbol *loopIV{nullptr};
209205
};
210206

flang/lib/Semantics/check-omp-structure.cpp

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,12 @@ void OmpStructureChecker::CheckDistLinear(
976976
void OmpStructureChecker::Leave(const parser::OpenMPLoopConstruct &x) {
977977
const auto &beginLoopDir{std::get<parser::OmpBeginLoopDirective>(x.t)};
978978
const auto &clauseList{std::get<parser::OmpClauseList>(beginLoopDir.t)};
979+
980+
// A few semantic checks for InScan reduction are performed below as SCAN
981+
// constructs inside LOOP may add the relevant information. Scan reduction is
982+
// supported only in loop constructs, so same checks are not applicable to
983+
// other directives.
984+
979985
for (const auto &clause : clauseList.v) {
980986
if (const auto *reductionClause{
981987
std::get_if<parser::OmpClause::Reduction>(&clause.u)}) {
@@ -987,14 +993,13 @@ void OmpStructureChecker::Leave(const parser::OpenMPLoopConstruct &x) {
987993
std::get<parser::OmpObjectList>(reductionClause->v.t)};
988994
auto checkReductionSymbolInScan = [&](const parser::Name *name) {
989995
if (name->symbol) {
990-
std::string nameStr = name->symbol->name().ToString();
991-
if (GetContext().usedInScanDirective.find(nameStr) ==
992-
GetContext().usedInScanDirective.end()) {
996+
if (!scanReductionInfoStack.top().findSymbolInScanConstruct(
997+
name->symbol)) {
993998
context_.Say(name->source,
994-
"List item %s must appear in 'inclusive' or "
995-
"'exclusive' clause of an "
996-
"enclosed scan directive"_err_en_US,
997-
nameStr);
999+
"List item %s must appear in EXCLUSIVE or "
1000+
"INCLUSIVE clause of an "
1001+
"enclosed SCAN directive"_err_en_US,
1002+
name->ToString());
9981003
}
9991004
}
10001005
};
@@ -1011,6 +1016,7 @@ void OmpStructureChecker::Leave(const parser::OpenMPLoopConstruct &x) {
10111016
},
10121017
ompObj.u);
10131018
}
1019+
scanReductionInfoStack.pop();
10141020
}
10151021
}
10161022
}
@@ -1690,14 +1696,14 @@ void OmpStructureChecker::CheckScan(
16901696
const parser::OpenMPSimpleStandaloneConstruct &x) {
16911697
if (std::get<parser::OmpClauseList>(x.t).v.size() != 1) {
16921698
context_.Say(x.source,
1693-
"Exactly one of `exclusive` or `inclusive` clause is expected"_err_en_US);
1699+
"Exactly one of EXCLUSIVE or INCLUSIVE clause is expected"_err_en_US);
16941700
}
16951701
if (!CurrentDirectiveIsNested() ||
16961702
!llvm::omp::scanParentAllowedSet.test(GetContextParent().directive)) {
16971703
context_.Say(x.source,
1698-
"Orphaned `omp scan` directives are prohibited; perhaps you forgot "
1699-
"to enclose the directive in to a worksharing loop, a worksharing "
1700-
"loop simd or a simd directive."_err_en_US);
1704+
"Orphaned SCAN directives are prohibited; perhaps you forgot "
1705+
"to enclose the directive in to a WORKSHARING LOOP, a WORKSHARING "
1706+
"LOOP SIMD or a SIMD directive."_err_en_US);
17011707
}
17021708
}
17031709

@@ -2838,20 +2844,24 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) {
28382844
if (const auto &maybeModifier{
28392845
std::get<std::optional<ReductionModifier>>(x.v.t)}) {
28402846
const ReductionModifier modifier{*maybeModifier};
2841-
const auto &ompObjectList{std::get<parser::OmpObjectList>(x.v.t)};
2842-
AddModifierToMap(ompObjectList, modifier);
2847+
if (modifier == ReductionModifier::Inscan) {
2848+
scanReductionInfoStack.emplace();
2849+
const auto &ompObjectList{std::get<parser::OmpObjectList>(x.v.t)};
2850+
scanReductionInfoStack.top().mapSymbolsToReductionModifiers(
2851+
ompObjectList, modifier);
2852+
}
28432853
CheckReductionModifier(modifier);
28442854
}
28452855
}
28462856

28472857
void OmpStructureChecker::Enter(const parser::OmpClause::Inclusive &x) {
28482858
CheckAllowed(llvm::omp::Clause::OMPC_inclusive);
2849-
CheckAndAddSymbolsToUsedInScanList(x.v);
2859+
CheckAndMarkSymbolsUsedInScan(x.v);
28502860
}
28512861

28522862
void OmpStructureChecker::Enter(const parser::OmpClause::Exclusive &x) {
28532863
CheckAllowed(llvm::omp::Clause::OMPC_exclusive);
2854-
CheckAndAddSymbolsToUsedInScanList(x.v);
2864+
CheckAndMarkSymbolsUsedInScan(x.v);
28552865
}
28562866

28572867
bool OmpStructureChecker::CheckReductionOperators(
@@ -2895,34 +2905,24 @@ bool OmpStructureChecker::CheckReductionOperators(
28952905
return ok;
28962906
}
28972907

2898-
void OmpStructureChecker::AddModifierToMap(
2899-
const parser::OmpObjectList &x, const ReductionModifier &modifier) {
2900-
for (const auto &ompObject : x.v) {
2901-
if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
2902-
if (const auto *symbol{name->symbol}) {
2903-
GetContext().reductionMod[symbol->name().ToString()] = modifier;
2904-
}
2905-
}
2906-
}
2907-
}
2908-
2909-
void OmpStructureChecker::CheckAndAddSymbolsToUsedInScanList(
2908+
void OmpStructureChecker::CheckAndMarkSymbolsUsedInScan(
29102909
const parser::OmpObjectList &x) {
29112910
for (const auto &ompObj : x.v) {
2912-
auto checkScanSymbolInReduction = [&](const parser::Name *name) {
2911+
auto checkAndMark = [&](const parser::Name *name) {
29132912
if (name->symbol) {
29142913
if (CurrentDirectiveIsNested()) {
2915-
std::string nameStr = name->symbol->name().ToString();
2916-
if (GetContextParent().reductionMod.find(nameStr) ==
2917-
GetContextParent().reductionMod.end()) {
2918-
2914+
ScanReductionInfo &scanReductionInfo = scanReductionInfoStack.top();
2915+
std::optional<ReductionModifier> reductionMod =
2916+
scanReductionInfo.findReductionModifier(name->symbol);
2917+
if (!reductionMod.has_value() ||
2918+
reductionMod.value() != ReductionModifier::Inscan) {
29192919
context_.Say(name->source,
2920-
"List item %s must appear in 'reduction' clause "
2921-
"with the 'inscan' modifier of the parent "
2920+
"List item %s must appear in REDUCTION clause "
2921+
"with the INSCAN modifier of the parent "
29222922
"directive"_err_en_US,
2923-
nameStr);
2923+
name->ToString());
29242924
}
2925-
GetContextParent().usedInScanDirective.insert(nameStr);
2925+
scanReductionInfo.markSymbolAsUsedInScanConstruct(name->symbol);
29262926
}
29272927
}
29282928
};
@@ -2931,10 +2931,10 @@ void OmpStructureChecker::CheckAndAddSymbolsToUsedInScanList(
29312931
[&](const parser::Designator &designator) {
29322932
if (const auto *name{
29332933
semantics::getDesignatorNameIfDataRef(designator)}) {
2934-
checkScanSymbolInReduction(name);
2934+
checkAndMark(name);
29352935
}
29362936
},
2937-
[&](const auto &name) { checkScanSymbolInReduction(&name); },
2937+
[&](const auto &name) { checkAndMark(&name); },
29382938
},
29392939
ompObj.u);
29402940
}
@@ -3112,7 +3112,7 @@ void OmpStructureChecker::CheckReductionModifier(
31123112
if (!llvm::omp::scanParentAllowedSet.test(dirCtx.directive)) {
31133113
context_.Say(GetContext().clauseSource,
31143114
"Modifier 'INSCAN' on REDUCTION clause is only allowed with "
3115-
"worksharing-loop, worksharing-loop simd, "
3115+
"WORKSHARING LOOP, WORKSHARING LOOP SIMD, "
31163116
"or SIMD directive"_err_en_US);
31173117
}
31183118
} else {

flang/lib/Semantics/check-omp-structure.h

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "flang/Semantics/openmp-directive-sets.h"
2121
#include "flang/Semantics/semantics.h"
2222
#include "llvm/Frontend/OpenMP/OMPConstants.h"
23+
#include <optional>
24+
#include <stack>
2325

2426
using OmpClauseSet =
2527
Fortran::common::EnumSet<llvm::omp::Clause, llvm::omp::Clause_enumSize>;
@@ -71,6 +73,43 @@ class OmpStructureChecker
7173
}
7274
using llvmOmpClause = const llvm::omp::Clause;
7375
using ReductionModifier = parser::OmpReductionClause::ReductionModifier;
76+
using Symbol = Fortran::semantics::Symbol;
77+
class ScanReductionInfo {
78+
79+
public:
80+
std::set<Symbol *> usedInScanDirective;
81+
std::map<Symbol *, ReductionModifier> reductionMod;
82+
83+
void mapSymbolsToReductionModifiers(
84+
const parser::OmpObjectList &x, const ReductionModifier &modifier) {
85+
for (const auto &ompObject : x.v) {
86+
if (const auto *name{parser::Unwrap<parser::Name>(ompObject)}) {
87+
if (const auto &symbol{name->symbol}) {
88+
reductionMod[symbol] = modifier;
89+
}
90+
}
91+
}
92+
}
93+
94+
void markSymbolAsUsedInScanConstruct(Symbol *sym) {
95+
usedInScanDirective.insert(sym);
96+
}
97+
98+
bool findSymbolInScanConstruct(Symbol *sym) {
99+
if (usedInScanDirective.find(sym) != usedInScanDirective.end()) {
100+
return true;
101+
}
102+
return false;
103+
}
104+
105+
std::optional<ReductionModifier> findReductionModifier(Symbol *sym) {
106+
if (reductionMod.find(sym) != reductionMod.end()) {
107+
return reductionMod[sym];
108+
}
109+
return std::nullopt;
110+
}
111+
};
112+
std::stack<class ScanReductionInfo> scanReductionInfoStack;
74113

75114
void Enter(const parser::OpenMPConstruct &);
76115
void Leave(const parser::OpenMPConstruct &);
@@ -249,9 +288,7 @@ class OmpStructureChecker
249288
const parser::OmpObjectList &ompObjectList);
250289
void CheckPredefinedAllocatorRestriction(
251290
const parser::CharBlock &source, const parser::Name &name);
252-
void CheckAndAddSymbolsToUsedInScanList(const parser::OmpObjectList &x);
253-
void AddModifierToMap(
254-
const parser::OmpObjectList &x, const ReductionModifier &modifier);
291+
void CheckAndMarkSymbolsUsedInScan(const parser::OmpObjectList &x);
255292
bool isPredefinedAllocator{false};
256293

257294
void CheckAllowedRequiresClause(llvmOmpClause clause);

flang/lib/Semantics/resolve-directives.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "flang/Semantics/expression.h"
2222
#include "flang/Semantics/symbol.h"
2323
#include "flang/Semantics/tools.h"
24+
#include <iostream>
2425
#include <list>
2526
#include <map>
2627
#include <sstream>
@@ -458,6 +459,18 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor<llvm::omp::Directive> {
458459
}
459460

460461
// 2.15.3 Data-Sharing Attribute Clauses
462+
void ResolveNames(const parser::OmpObjectList &objList);
463+
464+
bool Pre(const parser::OmpClause::Inclusive &x) {
465+
const auto &objectList{x.v};
466+
ResolveNames(objectList);
467+
return false;
468+
}
469+
bool Pre(const parser::OmpClause::Exclusive &x) {
470+
const auto &objectList{x.v};
471+
ResolveNames(objectList);
472+
return false;
473+
}
461474
void Post(const parser::OmpDefaultClause &);
462475
bool Pre(const parser::OmpClause::Shared &x) {
463476
ResolveOmpObjectList(x.v, Symbol::Flag::OmpShared);
@@ -2957,4 +2970,19 @@ void OmpAttributeVisitor::IssueNonConformanceWarning(
29572970
context_.Warn(common::UsageWarning::OpenMPUsage, source, "%s"_warn_en_US,
29582971
warnStrOS.str());
29592972
}
2973+
void OmpAttributeVisitor::ResolveNames(const parser::OmpObjectList &objList) {
2974+
for (const auto &ompObj : objList.v) {
2975+
common::visit(
2976+
common::visitors{
2977+
[&](const parser::Designator &designator) {
2978+
if (const auto *name{
2979+
semantics::getDesignatorNameIfDataRef(designator)}) {
2980+
ResolveName(name);
2981+
}
2982+
},
2983+
[&](const auto &name) { ResolveName(&name); },
2984+
},
2985+
ompObj.u);
2986+
}
2987+
}
29602988
} // namespace Fortran::semantics

flang/test/Lower/OpenMP/Todo/reduction-inscan.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ subroutine reduction_inscan()
88

99
!$omp do reduction(inscan, +:i)
1010
do j=1,10
11+
!$omp scan inclusive(i)
1112
i = i + 1
1213
end do
1314
!$omp end do

flang/test/Semantics/OpenMP/reduction-modifiers.f90

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ subroutine mod_inscan3(x)
7272
subroutine mod_inscan4(x)
7373
integer, intent(inout) :: x
7474

75-
!ERROR: Modifier 'INSCAN' on REDUCTION clause is only allowed with worksharing-loop, worksharing-loop simd, or SIMD directive
75+
!ERROR: Modifier 'INSCAN' on REDUCTION clause is only allowed with WORKSHARING LOOP, WORKSHARING LOOP SIMD, or SIMD directive
7676
!$omp parallel reduction(inscan, +:x)
7777
do i = 1, 100
7878
x = foo(i)
@@ -83,7 +83,7 @@ subroutine mod_inscan4(x)
8383
subroutine mod_inscan5(x)
8484
integer, intent(inout) :: x
8585

86-
!ERROR: Modifier 'INSCAN' on REDUCTION clause is only allowed with worksharing-loop, worksharing-loop simd, or SIMD directive
86+
!ERROR: Modifier 'INSCAN' on REDUCTION clause is only allowed with WORKSHARING LOOP, WORKSHARING LOOP SIMD, or SIMD directive
8787
!$omp sections reduction(inscan, +:x)
8888
do i = 1, 100
8989
x = foo(i)

flang/test/Semantics/OpenMP/scan.f90

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
subroutine test_scan()
44
integer x, y, k, z
55

6-
!ERROR: Orphaned `omp scan` directives are prohibited; perhaps you forgot to enclose the directive in to a worksharing loop, a worksharing loop simd or a simd directive.
6+
!ERROR: Orphaned SCAN directives are prohibited; perhaps you forgot to enclose the directive in to a WORKSHARING LOOP, a WORKSHARING LOOP SIMD or a SIMD directive.
77
!$omp scan inclusive(x)
88
!$omp parallel do simd
99
do k = 1, n
@@ -13,21 +13,21 @@ subroutine test_scan()
1313

1414
!$omp parallel do simd
1515
do k = 1, n
16-
!ERROR: Exactly one of `exclusive` or `inclusive` clause is expected
16+
!ERROR: Exactly one of EXCLUSIVE or INCLUSIVE clause is expected
1717
!$omp scan
1818
end do
1919

2020
!$omp parallel do simd reduction(inscan,+: x, y)
2121
do k = 1, n
22-
!ERROR: Exactly one of `exclusive` or `inclusive` clause is expected
22+
!ERROR: Exactly one of EXCLUSIVE or INCLUSIVE clause is expected
2323
!$omp scan inclusive(x) exclusive(y)
2424
end do
2525

26-
!ERROR: List item y must appear in 'inclusive' or 'exclusive' clause of an enclosed scan directive
26+
!ERROR: List item y must appear in EXCLUSIVE or INCLUSIVE clause of an enclosed SCAN directive
2727
!$omp parallel do simd reduction(inscan,+: x, y)
2828
do k = 1, n
29-
!ERROR: Exactly one of `exclusive` or `inclusive` clause is expected
30-
!ERROR: List item z must appear in 'reduction' clause with the 'inscan' modifier of the parent directive
29+
!ERROR: Exactly one of EXCLUSIVE or INCLUSIVE clause is expected
30+
!ERROR: List item z must appear in REDUCTION clause with the INSCAN modifier of the parent directive
3131
!$omp scan inclusive(x) exclusive(z)
3232
end do
3333
end subroutine

0 commit comments

Comments
 (0)