Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions flang/include/flang/Parser/openmp-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ const T *GetFirstArgument(const OmpDirectiveSpecification &spec) {

const BlockConstruct *GetFortranBlockConstruct(
const ExecutionPartConstruct &epc);
const Block &GetInnermostExecPart(const Block &block);
bool IsStrictlyStructuredBlock(const Block &block);

const OmpCombinerExpression *GetCombinerExpr(
const OmpReductionSpecifier &rspec);
Expand Down
2 changes: 0 additions & 2 deletions flang/include/flang/Semantics/openmp-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ const SomeExpr *HasStorageOverlap(
const SomeExpr &base, llvm::ArrayRef<SomeExpr> exprs);
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

Expand Down
28 changes: 28 additions & 0 deletions flang/lib/Parser/openmp-utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,34 @@ const BlockConstruct *GetFortranBlockConstruct(
return nullptr;
}

/// parser::Block is a list of executable constructs, parser::BlockConstruct
/// is Fortran's BLOCK/ENDBLOCK construct.
/// Strip the outermost BlockConstructs, return the reference to the Block
/// in the executable part of the innermost of the stripped constructs.
/// Specifically, if the given `block` has a single entry (it's a list), and
/// the entry is a BlockConstruct, get the Block contained within. Repeat
/// this step as many times as possible.
const Block &GetInnermostExecPart(const Block &block) {
const Block *iter{&block};
while (iter->size() == 1) {
const ExecutionPartConstruct &ep{iter->front()};
if (auto *bc{GetFortranBlockConstruct(ep)}) {
iter = &std::get<Block>(bc->t);
} else {
break;
}
}
return *iter;
}

bool IsStrictlyStructuredBlock(const Block &block) {
if (block.size() == 1) {
return GetFortranBlockConstruct(block.front()) != nullptr;
} else {
return false;
}
}

const OmpCombinerExpression *GetCombinerExpr(
const OmpReductionSpecifier &rspec) {
return addr_if(std::get<std::optional<OmpCombinerExpression>>(rspec.t));
Expand Down
2 changes: 2 additions & 0 deletions flang/lib/Semantics/check-omp-atomic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "flang/Evaluate/rewrite.h"
#include "flang/Evaluate/tools.h"
#include "flang/Parser/char-block.h"
#include "flang/Parser/openmp-utils.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/openmp-utils.h"
#include "flang/Semantics/symbol.h"
Expand All @@ -41,6 +42,7 @@

namespace Fortran::semantics {

using namespace Fortran::parser::omp;
using namespace Fortran::semantics::omp;

namespace operation = Fortran::evaluate::operation;
Expand Down
28 changes: 0 additions & 28 deletions flang/lib/Semantics/openmp-utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,32 +496,4 @@ bool IsPointerAssignment(const evaluate::Assignment &x) {
return std::holds_alternative<evaluate::Assignment::BoundsSpec>(x.u) ||
std::holds_alternative<evaluate::Assignment::BoundsRemapping>(x.u);
}

/// parser::Block is a list of executable constructs, parser::BlockConstruct
/// is Fortran's BLOCK/ENDBLOCK construct.
/// Strip the outermost BlockConstructs, return the reference to the Block
/// in the executable part of the innermost of the stripped constructs.
/// Specifically, if the given `block` has a single entry (it's a list), and
/// the entry is a BlockConstruct, get the Block contained within. Repeat
/// this step as many times as possible.
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 *bc{GetFortranBlockConstruct(ep)}) {
iter = &std::get<parser::Block>(bc->t);
} else {
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
Loading