[flang-commits] [flang] e70e9ec - [flang][OpenMP] Store Block in OpenMPLoopConstruct, add access functions (#168078)
via flang-commits
flang-commits at lists.llvm.org
Mon Nov 17 06:02:41 PST 2025
Author: Krzysztof Parzyszek
Date: 2025-11-17T08:02:36-06:00
New Revision: e70e9ec3b83757761ccbba217a566d77b561ec53
URL: https://github.com/llvm/llvm-project/commit/e70e9ec3b83757761ccbba217a566d77b561ec53
DIFF: https://github.com/llvm/llvm-project/commit/e70e9ec3b83757761ccbba217a566d77b561ec53.diff
LOG: [flang][OpenMP] Store Block in OpenMPLoopConstruct, add access functions (#168078)
Instead of storing a variant with specific types, store parser::Block as
the body. Add two access functions to make the traversal of the nest
simpler.
This will allow storing loop-nest sequences in the future.
Added:
Modified:
flang/include/flang/Parser/parse-tree.h
flang/lib/Lower/OpenMP/OpenMP.cpp
flang/lib/Lower/OpenMP/Utils.cpp
flang/lib/Parser/parse-tree.cpp
flang/lib/Parser/unparse.cpp
flang/lib/Semantics/canonicalize-omp.cpp
flang/lib/Semantics/check-omp-loop.cpp
flang/lib/Semantics/resolve-directives.cpp
flang/lib/Semantics/rewrite-parse-tree.cpp
flang/test/Parser/OpenMP/bind-clause.f90
flang/test/Parser/OpenMP/declare-reduction-multi.f90
flang/test/Parser/OpenMP/declare-reduction-unparse.f90
flang/test/Parser/OpenMP/do-tile-size.f90
flang/test/Parser/OpenMP/loop-transformation-construct01.f90
flang/test/Parser/OpenMP/loop-transformation-construct02.f90
flang/test/Parser/OpenMP/loop-transformation-construct03.f90
flang/test/Parser/OpenMP/transparent-clause.f90
flang/test/Parser/OpenMP/unroll-heuristic.f90
flang/test/Semantics/OpenMP/simd-only.f90
Removed:
################################################################################
diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h
index b1765f927d6c9..60d2ad0b764b9 100644
--- a/flang/include/flang/Parser/parse-tree.h
+++ b/flang/include/flang/Parser/parse-tree.h
@@ -5345,12 +5345,10 @@ struct OmpEndLoopDirective : public OmpEndDirective {
};
// OpenMP directives enclosing do loop
-using NestedConstruct =
- std::variant<DoConstruct, common::Indirection<OpenMPLoopConstruct>>;
struct OpenMPLoopConstruct {
TUPLE_CLASS_BOILERPLATE(OpenMPLoopConstruct);
OpenMPLoopConstruct(OmpBeginLoopDirective &&a)
- : t({std::move(a), std::nullopt, std::nullopt}) {}
+ : t({std::move(a), Block{}, std::nullopt}) {}
const OmpBeginLoopDirective &BeginDir() const {
return std::get<OmpBeginLoopDirective>(t);
@@ -5358,8 +5356,10 @@ struct OpenMPLoopConstruct {
const std::optional<OmpEndLoopDirective> &EndDir() const {
return std::get<std::optional<OmpEndLoopDirective>>(t);
}
- std::tuple<OmpBeginLoopDirective, std::optional<NestedConstruct>,
- std::optional<OmpEndLoopDirective>>
+ const DoConstruct *GetNestedLoop() const;
+ const OpenMPLoopConstruct *GetNestedConstruct() const;
+
+ std::tuple<OmpBeginLoopDirective, Block, std::optional<OmpEndLoopDirective>>
t;
};
diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp
index c3f670c62da06..f822fe3c8dd71 100644
--- a/flang/lib/Lower/OpenMP/OpenMP.cpp
+++ b/flang/lib/Lower/OpenMP/OpenMP.cpp
@@ -3962,27 +3962,22 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable,
mlir::Location currentLocation = converter.genLocation(beginSpec.source);
- auto &optLoopCons =
- std::get<std::optional<parser::NestedConstruct>>(loopConstruct.t);
- if (optLoopCons.has_value()) {
- if (auto *ompNestedLoopCons{
- std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
- &*optLoopCons)}) {
- llvm::omp::Directive nestedDirective =
- parser::omp::GetOmpDirectiveName(*ompNestedLoopCons).v;
- switch (nestedDirective) {
- case llvm::omp::Directive::OMPD_tile:
- // Skip OMPD_tile since the tile sizes will be retrieved when
- // generating the omp.loop_nest op.
- break;
- default: {
- unsigned version = semaCtx.langOptions().OpenMPVersion;
- TODO(currentLocation,
- "Applying a loop-associated on the loop generated by the " +
- llvm::omp::getOpenMPDirectiveName(nestedDirective, version) +
- " construct");
- }
- }
+ if (const parser::OpenMPLoopConstruct *ompNestedLoopCons =
+ loopConstruct.GetNestedConstruct()) {
+ llvm::omp::Directive nestedDirective =
+ parser::omp::GetOmpDirectiveName(*ompNestedLoopCons).v;
+ switch (nestedDirective) {
+ case llvm::omp::Directive::OMPD_tile:
+ // Skip OMPD_tile since the tile sizes will be retrieved when
+ // generating the omp.loop_nest op.
+ break;
+ default: {
+ unsigned version = semaCtx.langOptions().OpenMPVersion;
+ TODO(currentLocation,
+ "Applying a loop-associated on the loop generated by the " +
+ llvm::omp::getOpenMPDirectiveName(nestedDirective, version) +
+ " construct");
+ }
}
}
diff --git a/flang/lib/Lower/OpenMP/Utils.cpp b/flang/lib/Lower/OpenMP/Utils.cpp
index eda4d0782f486..7d7a4869ab3a6 100644
--- a/flang/lib/Lower/OpenMP/Utils.cpp
+++ b/flang/lib/Lower/OpenMP/Utils.cpp
@@ -779,17 +779,9 @@ static void processTileSizesFromOpenMPConstruct(
if (!ompCons)
return;
if (auto *ompLoop{std::get_if<parser::OpenMPLoopConstruct>(&ompCons->u)}) {
- const auto &nestedOptional =
- std::get<std::optional<parser::NestedConstruct>>(ompLoop->t);
- assert(nestedOptional.has_value() &&
- "Expected a DoConstruct or OpenMPLoopConstruct");
- const auto *innerConstruct =
- std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
- &(nestedOptional.value()));
- if (innerConstruct) {
- const auto &innerLoopDirective = innerConstruct->value();
+ if (auto *innerConstruct = ompLoop->GetNestedConstruct()) {
const parser::OmpDirectiveSpecification &innerBeginSpec =
- innerLoopDirective.BeginDir();
+ innerConstruct->BeginDir();
if (innerBeginSpec.DirId() == llvm::omp::Directive::OMPD_tile) {
// Get the size values from parse tree and convert to a vector.
for (const auto &clause : innerBeginSpec.Clauses().v) {
diff --git a/flang/lib/Parser/parse-tree.cpp b/flang/lib/Parser/parse-tree.cpp
index ad0016e1404f9..60e51895cdcea 100644
--- a/flang/lib/Parser/parse-tree.cpp
+++ b/flang/lib/Parser/parse-tree.cpp
@@ -7,8 +7,10 @@
//===----------------------------------------------------------------------===//
#include "flang/Parser/parse-tree.h"
+
#include "flang/Common/idioms.h"
#include "flang/Common/indirection.h"
+#include "flang/Parser/openmp-utils.h"
#include "flang/Parser/tools.h"
#include "flang/Parser/user-state.h"
#include "llvm/ADT/ArrayRef.h"
@@ -432,6 +434,20 @@ const OmpClauseList &OmpDirectiveSpecification::Clauses() const {
return empty;
}
+const DoConstruct *OpenMPLoopConstruct::GetNestedLoop() const {
+ if (auto &body{std::get<Block>(t)}; !body.empty()) {
+ return Unwrap<DoConstruct>(body.front());
+ }
+ return nullptr;
+}
+
+const OpenMPLoopConstruct *OpenMPLoopConstruct::GetNestedConstruct() const {
+ if (auto &body{std::get<Block>(t)}; !body.empty()) {
+ return Unwrap<OpenMPLoopConstruct>(body.front());
+ }
+ return nullptr;
+}
+
static bool InitCharBlocksFromStrings(llvm::MutableArrayRef<CharBlock> blocks,
llvm::ArrayRef<std::string> strings) {
for (auto [i, n] : llvm::enumerate(strings)) {
diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp
index e3bc3cdc42ffb..f81200d092b11 100644
--- a/flang/lib/Parser/unparse.cpp
+++ b/flang/lib/Parser/unparse.cpp
@@ -2706,12 +2706,6 @@ class UnparseVisitor {
Put("\n");
EndOpenMP();
}
- void Unparse(const OpenMPLoopConstruct &x) {
- Walk(std::get<OmpBeginLoopDirective>(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) {
Put('('), Walk(std::get<0>(x.t)), Put(","), Walk(std::get<1>(x.t));
Walk("(", std::get<std::optional<ArraySpec>>(x.t), ")"), Put(')');
diff --git a/flang/lib/Semantics/canonicalize-omp.cpp b/flang/lib/Semantics/canonicalize-omp.cpp
index a11c5250b1ab4..0cec1969e0978 100644
--- a/flang/lib/Semantics/canonicalize-omp.cpp
+++ b/flang/lib/Semantics/canonicalize-omp.cpp
@@ -143,6 +143,8 @@ class CanonicalizationOfOmp {
parser::ToUpperCaseLetters(dirName.source.ToString()));
};
+ auto &body{std::get<parser::Block>(x.t)};
+
nextIt = it;
while (++nextIt != block.end()) {
// Ignore compiler directives.
@@ -152,9 +154,7 @@ class CanonicalizationOfOmp {
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::move(*doCons);
+ body.push_back(std::move(*nextIt));
nextIt = block.erase(nextIt);
// try to match OmpEndLoopDirective
if (nextIt != block.end()) {
@@ -198,10 +198,7 @@ class CanonicalizationOfOmp {
++endIt;
}
RewriteOpenMPLoopConstruct(*ompLoopCons, block, nextIt);
- auto &ompLoop = std::get<std::optional<parser::NestedConstruct>>(x.t);
- ompLoop =
- std::optional<parser::NestedConstruct>{parser::NestedConstruct{
- common::Indirection{std::move(*ompLoopCons)}}};
+ body.push_back(std::move(*nextIt));
nextIt = block.erase(nextIt);
} else if (nestedBeginName.v == llvm::omp::Directive::OMPD_unroll &&
beginName.v == llvm::omp::Directive::OMPD_tile) {
diff --git a/flang/lib/Semantics/check-omp-loop.cpp b/flang/lib/Semantics/check-omp-loop.cpp
index aaaa2d6e78280..3d3596b500880 100644
--- a/flang/lib/Semantics/check-omp-loop.cpp
+++ b/flang/lib/Semantics/check-omp-loop.cpp
@@ -285,13 +285,9 @@ void OmpStructureChecker::Enter(const parser::OpenMPLoopConstruct &x) {
}
SetLoopInfo(x);
- auto &optLoopCons = std::get<std::optional<parser::NestedConstruct>>(x.t);
- if (optLoopCons.has_value()) {
- if (const auto &doConstruct{
- std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
- const auto &doBlock{std::get<parser::Block>(doConstruct->t)};
- CheckNoBranching(doBlock, beginName.v, beginName.source);
- }
+ if (const auto *doConstruct{x.GetNestedLoop()}) {
+ const auto &doBlock{std::get<parser::Block>(doConstruct->t)};
+ CheckNoBranching(doBlock, beginName.v, beginName.source);
}
CheckLoopItrVariableIsInt(x);
CheckAssociatedLoopConstraints(x);
@@ -314,46 +310,34 @@ const parser::Name OmpStructureChecker::GetLoopIndex(
}
void OmpStructureChecker::SetLoopInfo(const parser::OpenMPLoopConstruct &x) {
- auto &optLoopCons = std::get<std::optional<parser::NestedConstruct>>(x.t);
- if (optLoopCons.has_value()) {
- if (const auto &loopConstruct{
- std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
- const parser::DoConstruct *loop{&*loopConstruct};
- if (loop && loop->IsDoNormal()) {
- const parser::Name &itrVal{GetLoopIndex(loop)};
- SetLoopIv(itrVal.symbol);
- }
+ if (const auto *loop{x.GetNestedLoop()}) {
+ if (loop->IsDoNormal()) {
+ const parser::Name &itrVal{GetLoopIndex(loop)};
+ SetLoopIv(itrVal.symbol);
}
}
}
void OmpStructureChecker::CheckLoopItrVariableIsInt(
const parser::OpenMPLoopConstruct &x) {
- auto &optLoopCons = std::get<std::optional<parser::NestedConstruct>>(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) {
- 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{x.GetNestedLoop()}; 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;
}
}
@@ -417,29 +401,23 @@ void OmpStructureChecker::CheckDistLinear(
// Match the loop index variables with the collected symbols from linear
// clauses.
- auto &optLoopCons = std::get<std::optional<parser::NestedConstruct>>(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;
- }
- }
- // 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;
+ for (const parser::DoConstruct *loop{x.GetNestedLoop()}; 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;
}
// Show error for the remaining variables
diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp
index 7b1a3ba493f5f..68d007bc2de7e 100644
--- a/flang/lib/Semantics/resolve-directives.cpp
+++ b/flang/lib/Semantics/resolve-directives.cpp
@@ -2047,13 +2047,9 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPLoopConstruct &x) {
SetContextAssociatedLoopLevel(GetNumAffectedLoopsFromLoopConstruct(x));
if (beginName.v == llvm::omp::Directive::OMPD_do) {
- auto &optLoopCons = std::get<std::optional<parser::NestedConstruct>>(x.t);
- if (optLoopCons.has_value()) {
- if (const auto &doConstruct{
- std::get_if<parser::DoConstruct>(&*optLoopCons)}) {
- if (doConstruct->IsDoWhile()) {
- return true;
- }
+ if (const parser::DoConstruct *doConstruct{x.GetNestedLoop()}) {
+ if (doConstruct->IsDoWhile()) {
+ return true;
}
}
}
@@ -2210,18 +2206,8 @@ void OmpAttributeVisitor::CollectNumAffectedLoopsFromInnerLoopContruct(
const parser::OpenMPLoopConstruct &x,
llvm::SmallVector<std::int64_t> &levels,
llvm::SmallVector<const parser::OmpClause *> &clauses) {
-
- const auto &nestedOptional =
- std::get<std::optional<parser::NestedConstruct>>(x.t);
- assert(nestedOptional.has_value() &&
- "Expected a DoConstruct or OpenMPLoopConstruct");
- const auto *innerConstruct =
- std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
- &(nestedOptional.value()));
-
- if (innerConstruct) {
- CollectNumAffectedLoopsFromLoopConstruct(
- innerConstruct->value(), levels, clauses);
+ if (auto *innerConstruct{x.GetNestedConstruct()}) {
+ CollectNumAffectedLoopsFromLoopConstruct(*innerConstruct, levels, clauses);
}
}
@@ -2286,24 +2272,12 @@ void OmpAttributeVisitor::CheckPerfectNestAndRectangularLoop(
// Find the associated region by skipping nested loop-associated constructs
// such as loop transformations
- const parser::NestedConstruct *innermostAssocRegion{nullptr};
const parser::OpenMPLoopConstruct *innermostConstruct{&x};
- while (const auto &innerAssocStmt{
- std::get<std::optional<parser::NestedConstruct>>(
- innermostConstruct->t)}) {
- innermostAssocRegion = &(innerAssocStmt.value());
- if (const auto *innerConstruct{
- std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
- innermostAssocRegion)}) {
- innermostConstruct = &innerConstruct->value();
- } else {
- break;
- }
+ while (auto *nested{innermostConstruct->GetNestedConstruct()}) {
+ innermostConstruct = nested;
}
- if (!innermostAssocRegion)
- return;
- const auto &outer{std::get_if<parser::DoConstruct>(innermostAssocRegion)};
+ const auto *outer{innermostConstruct->GetNestedLoop()};
if (!outer)
return;
@@ -2398,61 +2372,51 @@ void OmpAttributeVisitor::PrivatizeAssociatedLoopIndexAndCheckLoopLevel(
const parser::OmpClause *clause{GetAssociatedClause()};
bool hasCollapseClause{
clause ? (clause->Id() == llvm::omp::OMPC_collapse) : false};
- const parser::OpenMPLoopConstruct *innerMostLoop = &x;
- const parser::NestedConstruct *innerMostNest = nullptr;
- while (auto &optLoopCons{
- std::get<std::optional<parser::NestedConstruct>>(innerMostLoop->t)}) {
- innerMostNest = &(optLoopCons.value());
- if (const auto *innerLoop{
- std::get_if<common::Indirection<parser::OpenMPLoopConstruct>>(
- innerMostNest)}) {
- innerMostLoop = &(innerLoop->value());
- } else
- break;
- }
- if (innerMostNest) {
- if (const auto &outer{std::get_if<parser::DoConstruct>(innerMostNest)}) {
- 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
- if (isLoopConstruct) {
- if (hasCollapseClause) {
- // hasCollapseClause implies clause != nullptr
- context_.Say(clause->source,
- "DO CONCURRENT loops cannot be used with the COLLAPSE clause."_err_en_US);
- }
- } else {
- auto &stmt =
- std::get<parser::Statement<parser::NonLabelDoStmt>>(loop->t);
- context_.Say(stmt.source,
- "DO CONCURRENT loops cannot form part of a loop nest."_err_en_US);
+ const parser::OpenMPLoopConstruct *innerMostNest = &x;
+ while (auto *nested{innerMostNest->GetNestedConstruct()}) {
+ innerMostNest = nested;
+ }
+
+ if (const auto *outer{innerMostNest->GetNestedLoop()}) {
+ 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
+ if (isLoopConstruct) {
+ if (hasCollapseClause) {
+ // hasCollapseClause implies clause != nullptr
+ context_.Say(clause->source,
+ "DO CONCURRENT loops cannot be used with the COLLAPSE clause."_err_en_US);
}
+ } else {
+ auto &stmt =
+ std::get<parser::Statement<parser::NonLabelDoStmt>>(loop->t);
+ context_.Say(stmt.source,
+ "DO CONCURRENT loops cannot form part of a loop nest."_err_en_US);
}
- // go through all the nested do-loops and resolve index variables
- const parser::Name *iv{GetLoopIndex(*loop)};
- if (iv) {
- if (auto *symbol{ResolveOmp(*iv, ivDSA, currScope())}) {
- SetSymbolDSA(*symbol, {Symbol::Flag::OmpPreDetermined, ivDSA});
- iv->symbol = symbol; // adjust the symbol within region
- AddToContextObjectWithDSA(*symbol, ivDSA);
- }
-
- const auto &block{std::get<parser::Block>(loop->t)};
- const auto it{block.begin()};
- loop = it != block.end() ? GetDoConstructIf(*it) : nullptr;
+ }
+ // go through all the nested do-loops and resolve index variables
+ const parser::Name *iv{GetLoopIndex(*loop)};
+ if (iv) {
+ if (auto *symbol{ResolveOmp(*iv, ivDSA, currScope())}) {
+ SetSymbolDSA(*symbol, {Symbol::Flag::OmpPreDetermined, ivDSA});
+ iv->symbol = symbol; // adjust the symbol within region
+ AddToContextObjectWithDSA(*symbol, ivDSA);
}
+
+ const auto &block{std::get<parser::Block>(loop->t)};
+ const auto it{block.begin()};
+ loop = it != block.end() ? GetDoConstructIf(*it) : nullptr;
}
- CheckAssocLoopLevel(level, GetAssociatedClause());
- } else {
- context_.Say(GetContext().directiveSource,
- "A DO loop must follow the %s directive"_err_en_US,
- parser::ToUpperCaseLetters(
- llvm::omp::getOpenMPDirectiveName(GetContext().directive, version)
- .str()));
}
+ CheckAssocLoopLevel(level, GetAssociatedClause());
+ } else {
+ context_.Say(GetContext().directiveSource,
+ "A DO loop must follow the %s directive"_err_en_US,
+ parser::ToUpperCaseLetters(
+ llvm::omp::getOpenMPDirectiveName(GetContext().directive, version)
+ .str()));
}
}
diff --git a/flang/lib/Semantics/rewrite-parse-tree.cpp b/flang/lib/Semantics/rewrite-parse-tree.cpp
index 5b7dab309eda7..b5a07680a3377 100644
--- a/flang/lib/Semantics/rewrite-parse-tree.cpp
+++ b/flang/lib/Semantics/rewrite-parse-tree.cpp
@@ -195,18 +195,16 @@ void RewriteMutator::OpenMPSimdOnly(
++it;
continue;
}
- auto &nest =
- std::get<std::optional<parser::NestedConstruct>>(ompLoop->t);
-
if (auto *doConstruct =
- std::get_if<parser::DoConstruct>(&nest.value())) {
+ const_cast<parser::DoConstruct *>(ompLoop->GetNestedLoop())) {
auto &loopBody = std::get<parser::Block>(doConstruct->t);
// We can only remove some constructs from a loop when it's _not_ a
// OpenMP simd loop
- OpenMPSimdOnly(loopBody, /*isNonSimdLoopBody=*/true);
- auto newDoConstruct = std::move(*doConstruct);
+ OpenMPSimdOnly(const_cast<parser::Block &>(loopBody),
+ /*isNonSimdLoopBody=*/true);
+
auto newLoop = parser::ExecutionPartConstruct{
- parser::ExecutableConstruct{std::move(newDoConstruct)}};
+ parser::ExecutableConstruct{std::move(*doConstruct)}};
it = block.erase(it);
block.insert(it, std::move(newLoop));
continue;
@@ -386,11 +384,8 @@ bool RewriteMutator::Pre(parser::OpenMPLoopConstruct &ompLoop) {
// If we're looking at a non-simd OpenMP loop, we need to explicitly
// call OpenMPSimdOnly on the nested loop block while indicating where
// the block comes from.
- auto &nest = std::get<std::optional<parser::NestedConstruct>>(ompLoop.t);
- if (!nest.has_value()) {
- return true;
- }
- if (auto *doConstruct = std::get_if<parser::DoConstruct>(&*nest)) {
+ if (auto *doConstruct =
+ const_cast<parser::DoConstruct *>(ompLoop.GetNestedLoop())) {
auto &innerBlock = std::get<parser::Block>(doConstruct->t);
OpenMPSimdOnly(innerBlock, /*isNonSimdLoopBody=*/true);
}
diff --git a/flang/test/Parser/OpenMP/bind-clause.f90 b/flang/test/Parser/OpenMP/bind-clause.f90
index a4fb3aa66c1c8..6910ffbba204f 100644
--- a/flang/test/Parser/OpenMP/bind-clause.f90
+++ b/flang/test/Parser/OpenMP/bind-clause.f90
@@ -22,5 +22,5 @@ subroutine f00
!PARSE-TREE: | | OmpDirectiveName -> llvm::omp::Directive = loop
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Bind -> OmpBindClause -> Binding = Parallel
!PARSE-TREE: | | Flags = None
-!PARSE-TREE: | DoConstruct
+!PARSE-TREE: | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
diff --git a/flang/test/Parser/OpenMP/declare-reduction-multi.f90 b/flang/test/Parser/OpenMP/declare-reduction-multi.f90
index 88566613bd412..f8104254aa6b1 100644
--- a/flang/test/Parser/OpenMP/declare-reduction-multi.f90
+++ b/flang/test/Parser/OpenMP/declare-reduction-multi.f90
@@ -198,7 +198,8 @@ program omp_examples
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'sum'
!PARSE-TREE: | | Flags = None
-!PARSE-TREE: | DoConstruct
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
do i = 1, n
sum%r = sum%r + values(i)%r
@@ -215,7 +216,8 @@ program omp_examples
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Multiply
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'prod'
!PARSE-TREE: | | Flags = None
-!PARSE-TREE: | DoConstruct
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
do i = 1, n
prod%r = prod%r * (values(i)%r+0.6)
@@ -232,7 +234,8 @@ program omp_examples
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'max'
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'big'
!PARSE-TREE: | | Flags = None
-!PARSE-TREE: | DoConstruct
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
do i = 1, n
big = mymax(values(i), big)
@@ -249,7 +252,8 @@ program omp_examples
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'min'
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'small'
!PARSE-TREE: | | Flags = None
-!PARSE-TREE: | DoConstruct
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
do i = 1, n
small%r = min(values(i)%r, small%r)
diff --git a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90 b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
index 7897eb0fb46f0..31431f5d20c45 100644
--- a/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
+++ b/flang/test/Parser/OpenMP/declare-reduction-unparse.f90
@@ -70,7 +70,8 @@ end subroutine initme
!PARSE-TREE: | | | Modifier -> OmpReductionIdentifier -> ProcedureDesignator -> Name = 'red_add'
!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'res'
!PARSE-TREE: | | Flags = None
-!PARSE-TREE: | DoConstruct
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
do i=1,n
res=res+x(i)
diff --git a/flang/test/Parser/OpenMP/do-tile-size.f90 b/flang/test/Parser/OpenMP/do-tile-size.f90
index 9ba6a3a6c2c41..b8d175c236bf9 100644
--- a/flang/test/Parser/OpenMP/do-tile-size.f90
+++ b/flang/test/Parser/OpenMP/do-tile-size.f90
@@ -21,9 +21,11 @@ subroutine openmp_do_tiles(x)
!PARSE-TREE:| | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!PARSE-TREE:| | | OmpBeginLoopDirective
-!PARSE-TREE:| | | OpenMPLoopConstruct
-!PARSE-TREE:| | | | OmpBeginLoopDirective
-!PARSE-TREE:| | | | | OmpDirectiveName -> llvm::omp::Directive = tile
-!PARSE-TREE:| | | | | OmpClauseList -> OmpClause -> Sizes -> Scalar -> Integer -> Expr = '2_4'
-!PARSE-TREE: | | | | DoConstruct
+!PARSE-TREE:| | | Block
+!PARSE-TREE:| | | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
+!PARSE-TREE:| | | | | OmpBeginLoopDirective
+!PARSE-TREE:| | | | | | OmpDirectiveName -> llvm::omp::Directive = tile
+!PARSE-TREE:| | | | | | OmpClauseList -> OmpClause -> Sizes -> Scalar -> Integer -> Expr = '2_4'
+!PARSE-TREE:| | | | | Block
+!PARSE-TREE:| | | | | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
END subroutine openmp_do_tiles
diff --git a/flang/test/Parser/OpenMP/loop-transformation-construct01.f90 b/flang/test/Parser/OpenMP/loop-transformation-construct01.f90
index 9595889b1bf98..8b314d8d823db 100644
--- a/flang/test/Parser/OpenMP/loop-transformation-construct01.f90
+++ b/flang/test/Parser/OpenMP/loop-transformation-construct01.f90
@@ -24,40 +24,42 @@ subroutine loop_transformation_construct
!CHECK-PARSE-NEXT: | | | | OmpDirectiveName -> llvm::omp::Directive = do
!CHECK-PARSE-NEXT: | | | | OmpClauseList ->
!CHECK-PARSE-NEXT: | | | | Flags = None
-!CHECK-PARSE-NEXT: | | | OpenMPLoopConstruct
-!CHECK-PARSE-NEXT: | | | | OmpBeginLoopDirective
-!CHECK-PARSE-NEXT: | | | | | OmpDirectiveName -> llvm::omp::Directive = unroll
-!CHECK-PARSE-NEXT: | | | | | OmpClauseList ->
-!CHECK-PARSE-NEXT: | | | | | Flags = None
-!CHECK-PARSE-NEXT: | | | | DoConstruct
-!CHECK-PARSE-NEXT: | | | | | NonLabelDoStmt
-!CHECK-PARSE-NEXT: | | | | | | LoopControl -> LoopBounds
-!CHECK-PARSE-NEXT: | | | | | | | Scalar -> Name = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | Scalar -> Expr = '1_4'
-!CHECK-PARSE-NEXT: | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
-!CHECK-PARSE-NEXT: | | | | | | | Scalar -> Expr = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | | Designator -> DataRef -> Name = 'i'
+!CHECK-PARSE-NEXT: | | | Block
+!CHECK-PARSE-NEXT: | | | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
+!CHECK-PARSE-NEXT: | | | | | OmpBeginLoopDirective
+!CHECK-PARSE-NEXT: | | | | | | OmpDirectiveName -> llvm::omp::Directive = unroll
+!CHECK-PARSE-NEXT: | | | | | | OmpClauseList ->
+!CHECK-PARSE-NEXT: | | | | | | Flags = None
!CHECK-PARSE-NEXT: | | | | | Block
-!CHECK-PARSE-NEXT: | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'y(int(i,kind=8))=5_4*y(int(i,kind=8))'
-!CHECK-PARSE-NEXT: | | | | | | | Variable = 'y(int(i,kind=8))'
-!CHECK-PARSE-NEXT: | | | | | | | | Designator -> DataRef -> ArrayElement
-!CHECK-PARSE-NEXT: | | | | | | | | | DataRef -> Name = 'y'
-!CHECK-PARSE-NEXT: | | | | | | | | | SectionSubscript -> Integer -> Expr = 'i'
+!CHECK-PARSE-NEXT: | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+!CHECK-PARSE-NEXT: | | | | | | | NonLabelDoStmt
+!CHECK-PARSE-NEXT: | | | | | | | | LoopControl -> LoopBounds
+!CHECK-PARSE-NEXT: | | | | | | | | | Scalar -> Name = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | Scalar -> Expr = '1_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
+!CHECK-PARSE-NEXT: | | | | | | | | | Scalar -> Expr = 'i'
!CHECK-PARSE-NEXT: | | | | | | | | | | Designator -> DataRef -> Name = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | Expr = '5_4*y(int(i,kind=8))'
-!CHECK-PARSE-NEXT: | | | | | | | | Multiply
-!CHECK-PARSE-NEXT: | | | | | | | | | Expr = 'y(int(i,kind=8))'
+!CHECK-PARSE-NEXT: | | | | | | | Block
+!CHECK-PARSE-NEXT: | | | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'y(int(i,kind=8))=5_4*y(int(i,kind=8))'
+!CHECK-PARSE-NEXT: | | | | | | | | | Variable = 'y(int(i,kind=8))'
!CHECK-PARSE-NEXT: | | | | | | | | | | Designator -> DataRef -> ArrayElement
!CHECK-PARSE-NEXT: | | | | | | | | | | | DataRef -> Name = 'y'
!CHECK-PARSE-NEXT: | | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'i'
!CHECK-PARSE-NEXT: | | | | | | | | | | | | Designator -> DataRef -> Name = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | | | Expr = '5_4'
-!CHECK-PARSE-NEXT: | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '5'
-!CHECK-PARSE-NEXT: | | | | | EndDoStmt ->
-!CHECK-PARSE-NEXT: | | | | OmpEndLoopDirective
-!CHECK-PARSE-NEXT: | | | | | OmpDirectiveName -> llvm::omp::Directive = unroll
-!CHECK-PARSE-NEXT: | | | | | OmpClauseList ->
-!CHECK-PARSE-NEXT: | | | | | Flags = None
+!CHECK-PARSE-NEXT: | | | | | | | | | Expr = '5_4*y(int(i,kind=8))'
+!CHECK-PARSE-NEXT: | | | | | | | | | | Multiply
+!CHECK-PARSE-NEXT: | | | | | | | | | | | Expr = 'y(int(i,kind=8))'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | Designator -> DataRef -> ArrayElement
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | DataRef -> Name = 'y'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | | Designator -> DataRef -> Name = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | Expr = '5_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '5'
+!CHECK-PARSE-NEXT: | | | | | | | EndDoStmt ->
+!CHECK-PARSE-NEXT: | | | | | OmpEndLoopDirective
+!CHECK-PARSE-NEXT: | | | | | | OmpDirectiveName -> llvm::omp::Directive = unroll
+!CHECK-PARSE-NEXT: | | | | | | OmpClauseList ->
+!CHECK-PARSE-NEXT: | | | | | | Flags = None
!CHECK-PARSE-NEXT: | | | OmpEndLoopDirective
!CHECK-PARSE-NEXT: | | | | OmpDirectiveName -> llvm::omp::Directive = do
!CHECK-PARSE-NEXT: | | | | OmpClauseList ->
diff --git a/flang/test/Parser/OpenMP/loop-transformation-construct02.f90 b/flang/test/Parser/OpenMP/loop-transformation-construct02.f90
index a876c77a274b5..5b5b591b35f8f 100644
--- a/flang/test/Parser/OpenMP/loop-transformation-construct02.f90
+++ b/flang/test/Parser/OpenMP/loop-transformation-construct02.f90
@@ -26,50 +26,53 @@ subroutine loop_transformation_construct
!CHECK-PARSE-NEXT: | | | | OmpDirectiveName -> llvm::omp::Directive = do
!CHECK-PARSE-NEXT: | | | | OmpClauseList ->
!CHECK-PARSE-NEXT: | | | | Flags = None
-!CHECK-PARSE-NEXT: | | | OpenMPLoopConstruct
-!CHECK-PARSE-NEXT: | | | | OmpBeginLoopDirective
-!CHECK-PARSE-NEXT: | | | | | OmpDirectiveName -> llvm::omp::Directive = unroll
-!CHECK-PARSE-NEXT: | | | | | OmpClauseList ->
-!CHECK-PARSE-NEXT: | | | | | Flags = None
-!CHECK-PARSE-NEXT: | | | | OpenMPLoopConstruct
+!CHECK-PARSE-NEXT: | | | Block
+!CHECK-PARSE-NEXT: | | | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
!CHECK-PARSE-NEXT: | | | | | OmpBeginLoopDirective
-!CHECK-PARSE-NEXT: | | | | | | OmpDirectiveName -> llvm::omp::Directive = tile
-!CHECK-PARSE-NEXT: | | | | | | OmpClauseList -> OmpClause -> Sizes -> Scalar -> Integer -> Expr = '2_4'
-!CHECK-PARSE-NEXT: | | | | | | | LiteralConstant -> IntLiteralConstant = '2'
+!CHECK-PARSE-NEXT: | | | | | | OmpDirectiveName -> llvm::omp::Directive = unroll
+!CHECK-PARSE-NEXT: | | | | | | OmpClauseList ->
!CHECK-PARSE-NEXT: | | | | | | Flags = None
-!CHECK-PARSE-NEXT: | | | | | DoConstruct
-!CHECK-PARSE-NEXT: | | | | | | NonLabelDoStmt
-!CHECK-PARSE-NEXT: | | | | | | | LoopControl -> LoopBounds
-!CHECK-PARSE-NEXT: | | | | | | | | Scalar -> Name = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | | Scalar -> Expr = '1_4'
-!CHECK-PARSE-NEXT: | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
-!CHECK-PARSE-NEXT: | | | | | | | | Scalar -> Expr = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | | | Designator -> DataRef -> Name = 'i'
-!CHECK-PARSE-NEXT: | | | | | | Block
-!CHECK-PARSE-NEXT: | | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'y(int(i,kind=8))=5_4*y(int(i,kind=8))'
-!CHECK-PARSE-NEXT: | | | | | | | | Variable = 'y(int(i,kind=8))'
-!CHECK-PARSE-NEXT: | | | | | | | | | Designator -> DataRef -> ArrayElement
-!CHECK-PARSE-NEXT: | | | | | | | | | | DataRef -> Name = 'y'
-!CHECK-PARSE-NEXT: | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | Designator -> DataRef -> Name = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | | Expr = '5_4*y(int(i,kind=8))'
-!CHECK-PARSE-NEXT: | | | | | | | | | Multiply
-!CHECK-PARSE-NEXT: | | | | | | | | | | Expr = 'y(int(i,kind=8))'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | Designator -> DataRef -> ArrayElement
-!CHECK-PARSE-NEXT: | | | | | | | | | | | | DataRef -> Name = 'y'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | | | Designator -> DataRef -> Name = 'i'
-!CHECK-PARSE-NEXT: | | | | | | | | | | Expr = '5_4'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '5'
-!CHECK-PARSE-NEXT: | | | | | | EndDoStmt ->
+!CHECK-PARSE-NEXT: | | | | | Block
+!CHECK-PARSE-NEXT: | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
+!CHECK-PARSE-NEXT: | | | | | | | OmpBeginLoopDirective
+!CHECK-PARSE-NEXT: | | | | | | | | OmpDirectiveName -> llvm::omp::Directive = tile
+!CHECK-PARSE-NEXT: | | | | | | | | OmpClauseList -> OmpClause -> Sizes -> Scalar -> Integer -> Expr = '2_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | LiteralConstant -> IntLiteralConstant = '2'
+!CHECK-PARSE-NEXT: | | | | | | | | Flags = None
+!CHECK-PARSE-NEXT: | | | | | | | Block
+!CHECK-PARSE-NEXT: | | | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+!CHECK-PARSE-NEXT: | | | | | | | | | NonLabelDoStmt
+!CHECK-PARSE-NEXT: | | | | | | | | | | LoopControl -> LoopBounds
+!CHECK-PARSE-NEXT: | | | | | | | | | | | Scalar -> Name = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | Scalar -> Expr = '1_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | Scalar -> Expr = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | Designator -> DataRef -> Name = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | Block
+!CHECK-PARSE-NEXT: | | | | | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'y(int(i,kind=8))=5_4*y(int(i,kind=8))'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | Variable = 'y(int(i,kind=8))'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | Designator -> DataRef -> ArrayElement
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | DataRef -> Name = 'y'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | | Designator -> DataRef -> Name = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | Expr = '5_4*y(int(i,kind=8))'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | Multiply
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | Expr = 'y(int(i,kind=8))'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | | Designator -> DataRef -> ArrayElement
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | | | DataRef -> Name = 'y'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | | | | Designator -> DataRef -> Name = 'i'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | Expr = '5_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '5'
+!CHECK-PARSE-NEXT: | | | | | | | | | EndDoStmt ->
+!CHECK-PARSE-NEXT: | | | | | | | OmpEndLoopDirective
+!CHECK-PARSE-NEXT: | | | | | | | | OmpDirectiveName -> llvm::omp::Directive = tile
+!CHECK-PARSE-NEXT: | | | | | | | | OmpClauseList ->
+!CHECK-PARSE-NEXT: | | | | | | | | Flags = None
!CHECK-PARSE-NEXT: | | | | | OmpEndLoopDirective
-!CHECK-PARSE-NEXT: | | | | | | OmpDirectiveName -> llvm::omp::Directive = tile
+!CHECK-PARSE-NEXT: | | | | | | OmpDirectiveName -> llvm::omp::Directive = unroll
!CHECK-PARSE-NEXT: | | | | | | OmpClauseList ->
!CHECK-PARSE-NEXT: | | | | | | Flags = None
-!CHECK-PARSE-NEXT: | | | | OmpEndLoopDirective
-!CHECK-PARSE-NEXT: | | | | | OmpDirectiveName -> llvm::omp::Directive = unroll
-!CHECK-PARSE-NEXT: | | | | | OmpClauseList ->
-!CHECK-PARSE-NEXT: | | | | | Flags = None
!CHECK-PARSE-NEXT: | | | OmpEndLoopDirective
!CHECK-PARSE-NEXT: | | | | OmpDirectiveName -> llvm::omp::Directive = do
!CHECK-PARSE-NEXT: | | | | OmpClauseList ->
diff --git a/flang/test/Parser/OpenMP/loop-transformation-construct03.f90 b/flang/test/Parser/OpenMP/loop-transformation-construct03.f90
index 8725025a51321..e431b6d535ff5 100644
--- a/flang/test/Parser/OpenMP/loop-transformation-construct03.f90
+++ b/flang/test/Parser/OpenMP/loop-transformation-construct03.f90
@@ -26,41 +26,42 @@ subroutine loop_transformation_construct7
!CHECK-PARSE-NEXT: | | | | | LiteralConstant -> IntLiteralConstant = '2'
!CHECK-PARSE-NEXT: | | | | OmpClause -> Private -> OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'b'
!CHECK-PARSE-NEXT: | | | | Flags = None
-!CHECK-PARSE-NEXT: | | | DoConstruct
-!CHECK-PARSE-NEXT: | | | | NonLabelDoStmt
-!CHECK-PARSE-NEXT: | | | | | LoopControl -> LoopBounds
-!CHECK-PARSE-NEXT: | | | | | | Scalar -> Name = 'b'
-!CHECK-PARSE-NEXT: | | | | | | Scalar -> Expr = '1_4'
-!CHECK-PARSE-NEXT: | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
-!CHECK-PARSE-NEXT: | | | | | | Scalar -> Expr = '10_4'
-!CHECK-PARSE-NEXT: | | | | | | | LiteralConstant -> IntLiteralConstant = '10'
-!CHECK-PARSE-NEXT: | | | | Block
-!CHECK-PARSE-NEXT: | | | | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
-!CHECK-PARSE-NEXT: | | | | | | NonLabelDoStmt
-!CHECK-PARSE-NEXT: | | | | | | | LoopControl -> LoopBounds
-!CHECK-PARSE-NEXT: | | | | | | | | Scalar -> Name = 'c'
-!CHECK-PARSE-NEXT: | | | | | | | | Scalar -> Expr = '1_4'
-!CHECK-PARSE-NEXT: | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
-!CHECK-PARSE-NEXT: | | | | | | | | Scalar -> Expr = '10_4'
-!CHECK-PARSE-NEXT: | | | | | | | | | LiteralConstant -> IntLiteralConstant = '10'
-!CHECK-PARSE-NEXT: | | | | | | Block
-!CHECK-PARSE-NEXT: | | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'a(int(b,kind=8),2_8)=a(int(c,kind=8),1_8)'
-!CHECK-PARSE-NEXT: | | | | | | | | Variable = 'a(int(b,kind=8),2_8)'
-!CHECK-PARSE-NEXT: | | | | | | | | | Designator -> DataRef -> ArrayElement
-!CHECK-PARSE-NEXT: | | | | | | | | | | DataRef -> Name = 'a'
-!CHECK-PARSE-NEXT: | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'b'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | Designator -> DataRef -> Name = 'b'
-!CHECK-PARSE-NEXT: | | | | | | | | | | SectionSubscript -> Integer -> Expr = '2_4'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '2'
-!CHECK-PARSE-NEXT: | | | | | | | | Expr = 'a(int(c,kind=8),1_8)'
-!CHECK-PARSE-NEXT: | | | | | | | | | Designator -> DataRef -> ArrayElement
-!CHECK-PARSE-NEXT: | | | | | | | | | | DataRef -> Name = 'a'
-!CHECK-PARSE-NEXT: | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'c'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | Designator -> DataRef -> Name = 'c'
-!CHECK-PARSE-NEXT: | | | | | | | | | | SectionSubscript -> Integer -> Expr = '1_4'
-!CHECK-PARSE-NEXT: | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
-!CHECK-PARSE-NEXT: | | | | | | EndDoStmt ->
-!CHECK-PARSE-NEXT: | | | | EndDoStmt ->
+!CHECK-PARSE-NEXT: | | | Block
+!CHECK-PARSE-NEXT: | | | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+!CHECK-PARSE-NEXT: | | | | | NonLabelDoStmt
+!CHECK-PARSE-NEXT: | | | | | | LoopControl -> LoopBounds
+!CHECK-PARSE-NEXT: | | | | | | | Scalar -> Name = 'b'
+!CHECK-PARSE-NEXT: | | | | | | | Scalar -> Expr = '1_4'
+!CHECK-PARSE-NEXT: | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
+!CHECK-PARSE-NEXT: | | | | | | | Scalar -> Expr = '10_4'
+!CHECK-PARSE-NEXT: | | | | | | | | LiteralConstant -> IntLiteralConstant = '10'
+!CHECK-PARSE-NEXT: | | | | | Block
+!CHECK-PARSE-NEXT: | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+!CHECK-PARSE-NEXT: | | | | | | | NonLabelDoStmt
+!CHECK-PARSE-NEXT: | | | | | | | | LoopControl -> LoopBounds
+!CHECK-PARSE-NEXT: | | | | | | | | | Scalar -> Name = 'c'
+!CHECK-PARSE-NEXT: | | | | | | | | | Scalar -> Expr = '1_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
+!CHECK-PARSE-NEXT: | | | | | | | | | Scalar -> Expr = '10_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '10'
+!CHECK-PARSE-NEXT: | | | | | | | Block
+!CHECK-PARSE-NEXT: | | | | | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> AssignmentStmt = 'a(int(b,kind=8),2_8)=a(int(c,kind=8),1_8)'
+!CHECK-PARSE-NEXT: | | | | | | | | | Variable = 'a(int(b,kind=8),2_8)'
+!CHECK-PARSE-NEXT: | | | | | | | | | | Designator -> DataRef -> ArrayElement
+!CHECK-PARSE-NEXT: | | | | | | | | | | | DataRef -> Name = 'a'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'b'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | Designator -> DataRef -> Name = 'b'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | SectionSubscript -> Integer -> Expr = '2_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '2'
+!CHECK-PARSE-NEXT: | | | | | | | | | Expr = 'a(int(c,kind=8),1_8)'
+!CHECK-PARSE-NEXT: | | | | | | | | | | Designator -> DataRef -> ArrayElement
+!CHECK-PARSE-NEXT: | | | | | | | | | | | DataRef -> Name = 'a'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | SectionSubscript -> Integer -> Expr = 'c'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | Designator -> DataRef -> Name = 'c'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | SectionSubscript -> Integer -> Expr = '1_4'
+!CHECK-PARSE-NEXT: | | | | | | | | | | | | LiteralConstant -> IntLiteralConstant = '1'
+!CHECK-PARSE-NEXT: | | | | | | | EndDoStmt ->
+!CHECK-PARSE-NEXT: | | | | | EndDoStmt ->
!CHECK-PARSE-NEXT: | EndSubroutineStmt ->
!CHECK-UNPARSE: SUBROUTINE loop_transformation_construct7
diff --git a/flang/test/Parser/OpenMP/transparent-clause.f90 b/flang/test/Parser/OpenMP/transparent-clause.f90
index 8f669546f2dea..3512326b321e6 100644
--- a/flang/test/Parser/OpenMP/transparent-clause.f90
+++ b/flang/test/Parser/OpenMP/transparent-clause.f90
@@ -74,4 +74,5 @@ subroutine f02
!PARSE-TREE: | | OmpClauseList -> OmpClause -> Transparent -> OmpTransparentClause -> Scalar -> Integer -> Expr = '2_4'
!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '2'
!PARSE-TREE: | | Flags = None
-!PARSE-TREE: | DoConstruct
+!PARSE-TREE: | Block
+!PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
diff --git a/flang/test/Parser/OpenMP/unroll-heuristic.f90 b/flang/test/Parser/OpenMP/unroll-heuristic.f90
index bbc2df3b57df6..c181a06b457f3 100644
--- a/flang/test/Parser/OpenMP/unroll-heuristic.f90
+++ b/flang/test/Parser/OpenMP/unroll-heuristic.f90
@@ -23,22 +23,23 @@ END subroutine openmp_parse_unroll_heuristic
!PTREE-NEXT: | | OmpDirectiveName -> llvm::omp::Directive = unroll
!PTREE-NEXT: | | OmpClauseList ->
!PTREE-NEXT: | | Flags = None
-!PTREE-NEXT: | DoConstruct
-!PTREE-NEXT: | | NonLabelDoStmt
-!PTREE-NEXT: | | | LoopControl -> LoopBounds
-!PTREE-NEXT: | | | | Scalar -> Name = 'i'
-!PTREE-NEXT: | | | | Scalar -> Expr = '1_4'
-!PTREE-NEXT: | | | | | LiteralConstant -> IntLiteralConstant = '1'
-!PTREE-NEXT: | | | | Scalar -> Expr = '100_4'
-!PTREE-NEXT: | | | | | LiteralConstant -> IntLiteralConstant = '100'
-!PTREE-NEXT: | | Block
-!PTREE-NEXT: | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> CallStmt = 'CALL func(i)'
-!PTREE-NEXT: | | | | | | Call
-!PTREE-NEXT: | | | | | ProcedureDesignator -> Name = 'func'
-!PTREE-NEXT: | | | | | ActualArgSpec
-!PTREE-NEXT: | | | | | | ActualArg -> Expr = 'i'
-!PTREE-NEXT: | | | | | | | Designator -> DataRef -> Name = 'i'
-!PTREE-NEXT: | | EndDoStmt ->
+!PTREE-NEXT: | Block
+!PTREE-NEXT: | | ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+!PTREE-NEXT: | | | NonLabelDoStmt
+!PTREE-NEXT: | | | | LoopControl -> LoopBounds
+!PTREE-NEXT: | | | | | Scalar -> Name = 'i'
+!PTREE-NEXT: | | | | | Scalar -> Expr = '1_4'
+!PTREE-NEXT: | | | | | | LiteralConstant -> IntLiteralConstant = '1'
+!PTREE-NEXT: | | | | | Scalar -> Expr = '100_4'
+!PTREE-NEXT: | | | | | | LiteralConstant -> IntLiteralConstant = '100'
+!PTREE-NEXT: | | | Block
+!PTREE-NEXT: | | | | ExecutionPartConstruct -> ExecutableConstruct -> ActionStmt -> CallStmt = 'CALL func(i)'
+!PTREE-NEXT: | | | | | | | Call
+!PTREE-NEXT: | | | | | | ProcedureDesignator -> Name = 'func'
+!PTREE-NEXT: | | | | | | ActualArgSpec
+!PTREE-NEXT: | | | | | | | ActualArg -> Expr = 'i'
+!PTREE-NEXT: | | | | | | | | Designator -> DataRef -> Name = 'i'
+!PTREE-NEXT: | | | EndDoStmt ->
!PTREE-NEXT: | OmpEndLoopDirective
!PTREE-NEXT: | | OmpDirectiveName -> llvm::omp::Directive = unroll
!PTREE-NEXT: | | OmpClauseList ->
diff --git a/flang/test/Semantics/OpenMP/simd-only.f90 b/flang/test/Semantics/OpenMP/simd-only.f90
index e137ef7d82929..4e29329e15cac 100644
--- a/flang/test/Semantics/OpenMP/simd-only.f90
+++ b/flang/test/Semantics/OpenMP/simd-only.f90
@@ -10,7 +10,7 @@ subroutine test_simd()
! CHECK: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
! CHECK: OmpDirectiveName -> llvm::omp::Directive = simd
- ! CHECK-NOT: ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+ ! CHECK: ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
!$omp simd
do i = 1, 100
end do
@@ -22,7 +22,7 @@ subroutine test_do_simd()
! CHECK: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
! CHECK: OmpDirectiveName -> llvm::omp::Directive = do simd
- ! CHECK-NOT: ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+ ! CHECK: ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
!$omp do simd
do i = 1, 100
end do
@@ -35,7 +35,7 @@ subroutine test_parallel_do_simd()
! CHECK: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
! CHECK: OmpDirectiveName -> llvm::omp::Directive = parallel do simd
- ! CHECK-NOT: ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+ ! CHECK: ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
!$omp parallel do simd
do i = 1, 100
end do
@@ -65,7 +65,7 @@ subroutine test_simd_atomic()
! CHECK: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct
! CHECK: OmpDirectiveName -> llvm::omp::Directive = simd
- ! CHECK-NOT: ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
+ ! CHECK: ExecutionPartConstruct -> ExecutableConstruct -> DoConstruct
!$omp simd
do i = 1, 100
! CHECK-NOT: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPAtomicConstruct
More information about the flang-commits
mailing list