[flang-commits] [flang] [Flang][OpenMP] Add Semantics support for Nested OpenMPLoopConstructs (PR #145917)
via flang-commits
flang-commits at lists.llvm.org
Thu Jun 26 08:31:16 PDT 2025
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff HEAD~1 HEAD --extensions h,cpp -- flang/include/flang/Parser/parse-tree.h flang/lib/Lower/OpenMP/OpenMP.cpp flang/lib/Parser/unparse.cpp flang/lib/Semantics/canonicalize-omp.cpp flang/lib/Semantics/check-omp-structure.cpp flang/lib/Semantics/resolve-directives.cpp
``````````
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index 7aa925023..8d8735424 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -5025,7 +5025,9 @@ struct OpenMPLoopConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPLoopConstruct);
OpenMPLoopConstruct(OmpBeginLoopDirective &&a)
: t({std::move(a), std::nullopt, std::nullopt}) {}
- std::tuple<OmpBeginLoopDirective, std::optional<std::variant<DoConstruct, common::Indirection<OpenMPLoopConstruct>>>,
+ std::tuple<OmpBeginLoopDirective,
+ std::optional<
+ std::variant<DoConstruct, common::Indirection<OpenMPLoopConstruct>>>,
std::optional<OmpEndLoopDirective>>
t;
};
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index 3e6f0ff2e..c85d015b8 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -4232,8 +4232,10 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
converter.genLocation(beginLoopDirective.source);
auto &optLoopCons = std::get<1>(loopConstruct.t);
- if(optLoopCons.has_value())
- if(auto *ompNestedLoopCons{std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(&*optLoopCons)}) {
+ if (optLoopCons.has_value())
+ if (auto *ompNestedLoopCons{
+ std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
+ &*optLoopCons)}) {
genOMP(converter, symTable, semaCtx, eval, ompNestedLoopCons->value());
}
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index 276be878d..903287515 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2926,7 +2926,8 @@ public:
Walk(std::get<OmpBeginLoopDirective>(x.t));
Put("\n");
EndOpenMP();
- Walk(std::get<std::optional<std::variant<DoConstruct, common::Indirection<parser::OpenMPLoopConstruct>>>>(x.t));
+ Walk(std::get<std::optional<std::variant<DoConstruct,
+ common::Indirection<parser::OpenMPLoopConstruct>>>>(x.t));
Walk(std::get<std::optional<OmpEndLoopDirective>>(x.t));
}
void Unparse(const BasedPointer &x) {
diff --git a/flang/lib/Semantics/canonicalize-omp.cpp b/flang/lib/Semantics/canonicalize-omp.cpp
index d68274351..68ba1c594 100644
--- a/flang/lib/Semantics/canonicalize-omp.cpp
+++ b/flang/lib/Semantics/canonicalize-omp.cpp
@@ -109,8 +109,8 @@ private:
void missingDoConstruct(parser::OmpLoopDirective &dir) {
messages_.Say(dir.source,
- "A DO loop must follow the %s directive"_err_en_US,
- parser::ToUpperCaseLetters(dir.source.ToString()));
+ "A DO loop must follow the %s directive"_err_en_US,
+ parser::ToUpperCaseLetters(dir.source.ToString()));
}
void RewriteOpenMPLoopConstruct(parser::OpenMPLoopConstruct &x,
@@ -142,7 +142,8 @@ private:
if (auto *doCons{GetConstructIf<parser::DoConstruct>(*nextIt)}) {
if (doCons->GetLoopControl()) {
// move DoConstruct
- std::get<std::optional<std::variant<parser::DoConstruct, common::Indirection<parser::OpenMPLoopConstruct>>>>(x.t) =
+ std::get<std::optional<std::variant<parser::DoConstruct,
+ common::Indirection<parser::OpenMPLoopConstruct>>>>(x.t) =
std::move(*doCons);
nextIt = block.erase(nextIt);
// try to match OmpEndLoopDirective
@@ -159,34 +160,41 @@ private:
}
} else if (auto *ompLoopCons{
GetOmpIf<parser::OpenMPLoopConstruct>(*nextIt)}) {
- // We should allow UNROLL and TILE constructs to be inserted between an OpenMP Loop Construct and the DO loop itself
+ // We should allow UNROLL and TILE constructs to be inserted between an
+ // OpenMP Loop Construct and the DO loop itself
auto &beginDirective =
std::get<parser::OmpBeginLoopDirective>(ompLoopCons->t);
auto &beginLoopDirective =
- std::get<parser::OmpLoopDirective>(beginDirective.t);
- // iterate through the remaining block items to find the end directive for the unroll/tile directive.
+ std::get<parser::OmpLoopDirective>(beginDirective.t);
+ // iterate through the remaining block items to find the end directive
+ // for the unroll/tile directive.
parser::Block::iterator endIt;
endIt = nextIt;
- while(endIt != block.end()) {
+ while (endIt != block.end()) {
if (auto *endDir{
- GetConstructIf<parser::OmpEndLoopDirective>(*endIt)}) {
- auto &endLoopDirective = std::get<parser::OmpLoopDirective>(endDir->t);
- if(endLoopDirective.v == dir.v) {
- std::get<std::optional<parser::OmpEndLoopDirective>>(x.t) =
- std::move(*endDir);
- endIt = block.erase(endIt);
- continue;
- }
+ GetConstructIf<parser::OmpEndLoopDirective>(*endIt)}) {
+ auto &endLoopDirective =
+ std::get<parser::OmpLoopDirective>(endDir->t);
+ if (endLoopDirective.v == dir.v) {
+ std::get<std::optional<parser::OmpEndLoopDirective>>(x.t) =
+ std::move(*endDir);
+ endIt = block.erase(endIt);
+ continue;
}
- ++endIt;
}
+ ++endIt;
+ }
if ((beginLoopDirective.v == llvm::omp::Directive::OMPD_unroll ||
- beginLoopDirective.v == llvm::omp::Directive::OMPD_tile)) {
+ beginLoopDirective.v == llvm::omp::Directive::OMPD_tile)) {
RewriteOpenMPLoopConstruct(*ompLoopCons, block, nextIt);
- auto &ompLoop = std::get<std::optional<std::variant<parser::DoConstruct, common::Indirection<parser::OpenMPLoopConstruct>>>>(x.t);
- ompLoop = std::optional<std::variant<parser::DoConstruct, common::Indirection<parser::OpenMPLoopConstruct>>>{
- std::variant<parser::DoConstruct, common::Indirection<parser::OpenMPLoopConstruct>>{
- common::Indirection{std::move(*ompLoopCons)}}};
+ auto &ompLoop =
+ std::get<std::optional<std::variant<parser::DoConstruct,
+ common::Indirection<parser::OpenMPLoopConstruct>>>>(x.t);
+ ompLoop = std::optional<std::variant<parser::DoConstruct,
+ common::Indirection<parser::OpenMPLoopConstruct>>>{
+ std::variant<parser::DoConstruct,
+ common::Indirection<parser::OpenMPLoopConstruct>>{
+ common::Indirection{std::move(*ompLoopCons)}}};
nextIt = block.erase(nextIt);
}
} else {
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index b54cd30ec..81c1c3e76 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -763,7 +763,7 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
SetLoopInfo(x);
auto &optLoopCons = std::get<1>(x.t);
- if(optLoopCons.has_value()) {
+ if (optLoopCons.has_value()) {
if (const auto &doConstruct{
std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
const auto &doBlock{std::get<parser::Block>(doConstruct->t)};
@@ -785,7 +785,6 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
if (beginDir.v == llvm::omp::Directive::OMPD_tile) {
const auto &clauses{std::get<parser::OmpClauseList>(beginLoopDir.t)};
for (auto &clause : clauses.v) {
-
}
}
}
@@ -872,26 +871,26 @@ void OmpStructureChecker::CheckLoopItrVariableIsInt(
auto &optLoopCons = std::get<1>(x.t);
if (optLoopCons.has_value()) {
if (const auto &loopConstruct{
- std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
+ std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
- for (const parser::DoConstruct *loop{&*loopConstruct}; loop;) {
- if (loop->IsDoNormal()) {
- const parser::Name &itrVal{GetLoopIndex(loop)};
- if (itrVal.symbol) {
- const auto *type{itrVal.symbol->GetType()};
- if (!type->IsNumeric(TypeCategory::Integer)) {
- context_.Say(itrVal.source,
- "The DO loop iteration"
- " variable must be of the type integer."_err_en_US,
- itrVal.ToString());
+ for (const parser::DoConstruct *loop{&*loopConstruct}; loop;) {
+ if (loop->IsDoNormal()) {
+ const parser::Name &itrVal{GetLoopIndex(loop)};
+ if (itrVal.symbol) {
+ const auto *type{itrVal.symbol->GetType()};
+ if (!type->IsNumeric(TypeCategory::Integer)) {
+ context_.Say(itrVal.source,
+ "The DO loop iteration"
+ " variable must be of the type integer."_err_en_US,
+ itrVal.ToString());
+ }
}
}
- }
- // Get the next DoConstruct if block is not empty.
- const auto &block{std::get<parser::Block>(loop->t)};
- const auto it{block.begin()};
- loop = it != block.end() ? parser::Unwrap<parser::DoConstruct>(*it)
- : nullptr;
+ // Get the next DoConstruct if block is not empty.
+ const auto &block{std::get<parser::Block>(loop->t)};
+ const auto it{block.begin()};
+ loop = it != block.end() ? parser::Unwrap<parser::DoConstruct>(*it)
+ : nullptr;
}
}
}
@@ -1094,25 +1093,25 @@ void OmpStructureChecker::CheckDistLinear(
// clauses.
auto &optLoopCons = std::get<1>(x.t);
if (optLoopCons.has_value()) {
- if (const auto &loopConstruct{
- std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
- for (const parser::DoConstruct *loop{&*loopConstruct}; loop;) {
- if (loop->IsDoNormal()) {
- const parser::Name &itrVal{GetLoopIndex(loop)};
- if (itrVal.symbol) {
- // Remove the symbol from the collected set
- indexVars.erase(&itrVal.symbol->GetUltimate());
- }
- collapseVal--;
- if (collapseVal == 0) {
- break;
+ if (const auto &loopConstruct{
+ std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
+ for (const parser::DoConstruct *loop{&*loopConstruct}; loop;) {
+ if (loop->IsDoNormal()) {
+ const parser::Name &itrVal{GetLoopIndex(loop)};
+ if (itrVal.symbol) {
+ // Remove the symbol from the collected set
+ indexVars.erase(&itrVal.symbol->GetUltimate());
+ }
+ collapseVal--;
+ if (collapseVal == 0) {
+ break;
+ }
}
- }
- // Get the next DoConstruct if block is not empty.
- const auto &block{std::get<parser::Block>(loop->t)};
- const auto it{block.begin()};
- loop = it != block.end() ? parser::Unwrap<parser::DoConstruct>(*it)
- : nullptr;
+ // Get the next DoConstruct if block is not empty.
+ const auto &block{std::get<parser::Block>(loop->t)};
+ const auto it{block.begin()};
+ loop = it != block.end() ? parser::Unwrap<parser::DoConstruct>(*it)
+ : nullptr;
}
}
}
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 36bea4fbe..9b8686022 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -1968,10 +1968,11 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
auto &optLoopCons = std::get<1>(x.t);
if (optLoopCons.has_value()) {
if (const auto &outer{std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
- for (const parser::DoConstruct *loop{&*outer}; loop && level > 0; --level) {
+ for (const parser::DoConstruct *loop{&*outer}; loop && level > 0;
+ --level) {
if (loop->IsDoConcurrent()) {
- // DO CONCURRENT is explicitly allowed for the LOOP construct so long as
- // there isn't a COLLAPSE clause
+ // DO CONCURRENT is explicitly allowed for the LOOP construct so long
+ // as there isn't a COLLAPSE clause
if (isLoopConstruct) {
if (hasCollapseClause) {
// hasCollapseClause implies clause != nullptr
@@ -2000,16 +2001,20 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
}
}
CheckAssocLoopLevel(level, GetAssociatedClause());
- } else if (const auto &loop{std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(&*optLoopCons)}) {
+ } else if (const auto &loop{std::get_if<
+ common::Indirection<parser::OpenMPLoopConstruct>>(
+ &*optLoopCons)}) {
auto &beginDirective =
- std::get<parser::OmpBeginLoopDirective>(loop->value().t);
+ std::get<parser::OmpBeginLoopDirective>(loop->value().t);
auto &beginLoopDirective =
std::get<parser::OmpLoopDirective>(beginDirective.t);
if ((beginLoopDirective.v != llvm::omp::Directive::OMPD_unroll &&
- beginLoopDirective.v != llvm::omp::Directive::OMPD_tile)) {
+ beginLoopDirective.v != llvm::omp::Directive::OMPD_tile)) {
context_.Say(GetContext().directiveSource,
- "Only UNROLL or TILE constructs are allowed between an OpenMP Loop Construct and a DO construct"_err_en_US,
- parser::ToUpperCaseLetters(llvm::omp::getOpenMPDirectiveName(GetContext().directive, version).str()));
+ "Only UNROLL or TILE constructs are allowed between an OpenMP Loop Construct and a DO construct"_err_en_US,
+ parser::ToUpperCaseLetters(llvm::omp::getOpenMPDirectiveName(
+ GetContext().directive, version)
+ .str()));
} else {
PrivatizeAssociatedLoopIndexAndCheckLoopLevel(loop->value());
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/145917
More information about the flang-commits
mailing list