[flang-commits] [flang] [flang][OpenMP] Turn IsStrictlyStructuredBlock into utility function,… (PR #158111)
via flang-commits
flang-commits at lists.llvm.org
Thu Sep 11 09:36:15 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-openmp
Author: Krzysztof Parzyszek (kparzysz)
<details>
<summary>Changes</summary>
… NFC
---
Full diff: https://github.com/llvm/llvm-project/pull/158111.diff
6 Files Affected:
- (modified) flang/include/flang/Parser/openmp-utils.h (+2)
- (modified) flang/include/flang/Semantics/openmp-utils.h (+1)
- (modified) flang/lib/Parser/openmp-parsers.cpp (+3-11)
- (modified) flang/lib/Parser/openmp-utils.cpp (+13)
- (modified) flang/lib/Semantics/check-omp-structure.cpp (+2-16)
- (modified) flang/lib/Semantics/openmp-utils.cpp (+14-7)
``````````diff
diff --git a/flang/include/flang/Parser/openmp-utils.h b/flang/include/flang/Parser/openmp-utils.h
index 3d3dfae290d96..8205d25647916 100644
--- a/flang/include/flang/Parser/openmp-utils.h
+++ b/flang/include/flang/Parser/openmp-utils.h
@@ -155,6 +155,8 @@ template <typename T> OmpDirectiveName GetOmpDirectiveName(const T &x) {
}
const OmpObjectList *GetOmpObjectList(const OmpClause &clause);
+const BlockConstruct *GetFortranBlockConstruct(
+ const ExecutionPartConstruct &epc);
} // namespace Fortran::parser::omp
diff --git a/flang/include/flang/Semantics/openmp-utils.h b/flang/include/flang/Semantics/openmp-utils.h
index 1c54124a5738a..68318d6093a1e 100644
--- a/flang/include/flang/Semantics/openmp-utils.h
+++ b/flang/include/flang/Semantics/openmp-utils.h
@@ -83,6 +83,7 @@ const SomeExpr *HasStorageOverlap(
bool IsAssignment(const parser::ActionStmt *x);
bool IsPointerAssignment(const evaluate::Assignment &x);
const parser::Block &GetInnermostExecPart(const parser::Block &block);
+bool IsStrictlyStructuredBlock(const parser::Block &block);
} // namespace omp
} // namespace Fortran::semantics
diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp
index 68e0acdf91fe2..78a5746bb0bf8 100644
--- a/flang/lib/Parser/openmp-parsers.cpp
+++ b/flang/lib/Parser/openmp-parsers.cpp
@@ -15,6 +15,7 @@
#include "stmt-parser.h"
#include "token-parsers.h"
#include "type-parser-implementation.h"
+#include "flang/Parser/openmp-utils.h"
#include "flang/Parser/parse-tree.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
@@ -24,6 +25,7 @@
// OpenMP Directives and Clauses
namespace Fortran::parser {
+using namespace Fortran::parser::omp;
// Helper function to print the buffer contents starting at the current point.
[[maybe_unused]] static std::string ahead(const ParseState &state) {
@@ -1280,16 +1282,6 @@ TYPE_PARSER(sourced(
maybe(Parser<OmpClauseList>{}),
pure(OmpDirectiveSpecification::Flags::None))))
-static bool IsFortranBlockConstruct(const ExecutionPartConstruct &epc) {
- // ExecutionPartConstruct -> ExecutableConstruct
- // -> Indirection<BlockConstruct>
- if (auto *ec{std::get_if<ExecutableConstruct>(&epc.u)}) {
- return std::holds_alternative<common::Indirection<BlockConstruct>>(ec->u);
- } else {
- return false;
- }
-}
-
static bool IsStandaloneOrdered(const OmpDirectiveSpecification &dirSpec) {
// An ORDERED construct is standalone if it has DOACROSS or DEPEND clause.
return dirSpec.DirId() == llvm::omp::Directive::OMPD_ordered &&
@@ -1307,7 +1299,7 @@ struct StrictlyStructuredBlockParser {
// Detect BLOCK construct without parsing the entire thing.
if (lookAhead(skipStuffBeforeStatement >> "BLOCK"_tok).Parse(state)) {
if (auto epc{Parser<ExecutionPartConstruct>{}.Parse(state)}) {
- if (IsFortranBlockConstruct(*epc)) {
+ if (GetFortranBlockConstruct(*epc) != nullptr) {
Block body;
body.emplace_back(std::move(*epc));
return std::move(body);
diff --git a/flang/lib/Parser/openmp-utils.cpp b/flang/lib/Parser/openmp-utils.cpp
index ef7e4fcdbbd07..937a17f29f221 100644
--- a/flang/lib/Parser/openmp-utils.cpp
+++ b/flang/lib/Parser/openmp-utils.cpp
@@ -12,6 +12,7 @@
#include "flang/Parser/openmp-utils.h"
+#include "flang/Common/indirection.h"
#include "flang/Common/template.h"
#include "flang/Common/visit.h"
@@ -61,4 +62,16 @@ const OmpObjectList *GetOmpObjectList(const OmpClause &clause) {
clause.u);
}
+const BlockConstruct *GetFortranBlockConstruct(
+ const ExecutionPartConstruct &epc) {
+ // ExecutionPartConstruct -> ExecutableConstruct
+ // -> Indirection<BlockConstruct>
+ if (auto *ec{std::get_if<ExecutableConstruct>(&epc.u)}) {
+ if (auto *ind{std::get_if<common::Indirection<BlockConstruct>>(&ec->u)}) {
+ return &ind->value();
+ }
+ }
+ return nullptr;
+}
+
} // namespace Fortran::parser::omp
diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp
index d1654a3adcc9c..b7f72756c9530 100644
--- a/flang/lib/Semantics/check-omp-structure.cpp
+++ b/flang/lib/Semantics/check-omp-structure.cpp
@@ -874,22 +874,8 @@ void OmpStructureChecker::Enter(const parser::OmpBlockConstruct &x) {
// Missing mandatory end block: this is checked in semantics because that
// makes it easier to control the error messages.
// The end block is mandatory when the construct is not applied to a strictly
- // structured block (aka it is applied to a loosely structured block). In
- // other words, the body doesn't contain exactly one parser::BlockConstruct.
- auto isStrictlyStructuredBlock{[](const parser::Block &block) -> bool {
- if (block.size() != 1) {
- return false;
- }
- const parser::ExecutionPartConstruct &contents{block.front()};
- auto *executableConstruct{
- std::get_if<parser::ExecutableConstruct>(&contents.u)};
- if (!executableConstruct) {
- return false;
- }
- return std::holds_alternative<common::Indirection<parser::BlockConstruct>>(
- executableConstruct->u);
- }};
- if (!endSpec && !isStrictlyStructuredBlock(block)) {
+ // structured block (aka it is applied to a loosely structured block).
+ if (!endSpec && !IsStrictlyStructuredBlock(block)) {
llvm::omp::Directive dirId{beginSpec.DirId()};
auto &msg{context_.Say(beginSpec.source,
"Expected OpenMP END %s directive"_err_en_US,
diff --git a/flang/lib/Semantics/openmp-utils.cpp b/flang/lib/Semantics/openmp-utils.cpp
index e8df346ccdc3e..2980f827d3ef3 100644
--- a/flang/lib/Semantics/openmp-utils.cpp
+++ b/flang/lib/Semantics/openmp-utils.cpp
@@ -21,6 +21,7 @@
#include "flang/Evaluate/traverse.h"
#include "flang/Evaluate/type.h"
#include "flang/Evaluate/variable.h"
+#include "flang/Parser/openmp-utils.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/expression.h"
#include "flang/Semantics/semantics.h"
@@ -37,6 +38,7 @@
#include <vector>
namespace Fortran::semantics::omp {
+using namespace Fortran::parser::omp;
SourcedActionStmt GetActionStmt(const parser::ExecutionPartConstruct *x) {
if (x == nullptr) {
@@ -397,16 +399,21 @@ const parser::Block &GetInnermostExecPart(const parser::Block &block) {
const parser::Block *iter{&block};
while (iter->size() == 1) {
const parser::ExecutionPartConstruct &ep{iter->front()};
- if (auto *exec{std::get_if<parser::ExecutableConstruct>(&ep.u)}) {
- using BlockConstruct = common::Indirection<parser::BlockConstruct>;
- if (auto *bc{std::get_if<BlockConstruct>(&exec->u)}) {
- iter = &std::get<parser::Block>(bc->value().t);
- continue;
- }
+ if (auto *bc{GetFortranBlockConstruct(ep)}) {
+ iter = &std::get<parser::Block>(bc->t);
+ } else {
+ break;
}
- break;
}
return *iter;
}
+bool IsStrictlyStructuredBlock(const parser::Block &block) {
+ if (block.size() == 1) {
+ return GetFortranBlockConstruct(block.front()) != nullptr;
+ } else {
+ return false;
+ }
+}
+
} // namespace Fortran::semantics::omp
``````````
</details>
https://github.com/llvm/llvm-project/pull/158111
More information about the flang-commits
mailing list