13#ifndef FORTRAN_SEMANTICS_OPENMP_UTILS_H
14#define FORTRAN_SEMANTICS_OPENMP_UTILS_H
16#include "flang/Common/indirection.h"
17#include "flang/Evaluate/type.h"
18#include "flang/Parser/char-block.h"
19#include "flang/Parser/message.h"
20#include "flang/Parser/openmp-utils.h"
21#include "flang/Parser/parse-tree.h"
22#include "flang/Parser/tools.h"
23#include "flang/Semantics/tools.h"
25#include "llvm/ADT/ArrayRef.h"
35namespace Fortran::semantics {
42using Fortran::parser::omp::BlockRange;
43using Fortran::parser::omp::ExecutionPartIterator;
44using Fortran::parser::omp::is_range_v;
45using Fortran::parser::omp::LoopNestIterator;
46using Fortran::parser::omp::LoopRange;
48template <
typename T,
typename U = std::remove_const_t<T>> U AsRvalue(T &t) {
52template <
typename T> T &&AsRvalue(T &&t) {
return std::move(t); }
54const Scope &GetScopingUnit(
const Scope &scope);
55const Scope &GetProgramUnit(
const Scope &scope);
57template <
typename T>
struct WithSource {
59 typename U = std::remove_reference_t<T>,
60 typename = std::enable_if_t<std::is_default_constructible_v<U>>>
61 WithSource() : value(), source() {}
62 WithSource(
const WithSource<T> &) =
default;
63 WithSource(WithSource<T> &&) =
default;
66 WithSource &operator=(
const WithSource<T> &) =
default;
67 WithSource &operator=(WithSource<T> &&) =
default;
78 using WithSource<value_type>::WithSource;
79 value_type stmt()
const {
return value; }
80 operator bool()
const {
return stmt() !=
nullptr; }
86std::string ThisVersion(
unsigned version);
87std::string TryVersion(
unsigned version);
94std::optional<parser::CharBlock> GetObjectSource(
99bool IsCommonBlock(
const Symbol &sym);
100bool IsExtendedListItem(
const Symbol &sym);
101bool IsVariableListItem(
const Symbol &sym);
102bool IsTypeParamInquiry(
const Symbol &sym);
103bool IsStructureComponent(
const Symbol &sym);
104bool IsPrivatizable(
const Symbol &sym);
105bool IsVarOrFunctionRef(
const MaybeExpr &expr);
109bool IsMapEnteringType(parser::OmpMapType::Value type);
110bool IsMapExitingType(parser::OmpMapType::Value type);
112MaybeExpr GetEvaluateExpr(
const parser::Expr &parserExpr);
113template <
typename T> MaybeExpr GetEvaluateExpr(
const T &inp) {
114 return GetEvaluateExpr(parser::UnwrapRef<parser::Expr>(inp));
117std::optional<evaluate::DynamicType> GetDynamicType(
120std::optional<bool> GetLogicalValue(
const SomeExpr &expr);
121std::optional<int64_t> GetIntValueFromExpr(
125std::optional<int64_t> GetIntValueFromExpr(
127 if (
auto *parserExpr{parser::Unwrap<parser::Expr>(wrappedExpr)}) {
128 return GetIntValueFromExpr(*parserExpr, semaCtx);
133std::optional<bool> IsContiguous(
134 SemanticsContext &semaCtx,
const parser::OmpObject &
object);
136std::vector<SomeExpr> GetTopLevelDesignators(
const SomeExpr &expr);
137const SomeExpr *HasStorageOverlap(
138 const SomeExpr &base, llvm::ArrayRef<SomeExpr> exprs);
140bool IsAssignment(
const parser::ActionStmt *x);
141bool IsPointerAssignment(
const evaluate::Assignment &x);
143MaybeExpr MakeEvaluateExpr(
const parser::OmpStylizedInstance &inp);
145bool IsLoopTransforming(llvm::omp::Directive dir);
146bool IsFullUnroll(
const parser::OmpDirectiveSpecification &spec);
148inline bool IsDoConcurrentLegal(
unsigned version) {
151 return version >= 60;
155 LoopControl(LoopControl &&x) =
default;
156 LoopControl(
const LoopControl &x) =
default;
157 LoopControl(
const parser::LoopControl::Bounds &x);
160 const Symbol *iv{
nullptr};
172 Reason(Reason &&) =
default;
173 Reason(
const Reason &);
174 Reason &operator=(Reason &&) =
default;
175 Reason &operator=(
const Reason &);
179 template <
typename... Ts> Reason &Say(Ts &&...args) {
180 msgs.Say(std::forward<Ts>(args)...);
184 Reason &Append(
const Reason &other) {
188 operator bool()
const {
return !msgs.empty(); }
191 void CopyFrom(
const Reason &other);
196template <
typename T>
struct WithReason {
197 std::optional<T> value;
200 WithReason() =
default;
201 WithReason(std::optional<T> v,
const Reason &r =
Reason())
202 : value(v), reason(r) {}
203 operator bool()
const {
return value.has_value(); }
218std::pair<WithReason<int64_t>,
bool> GetAffectedNestDepthWithReason(
223std::pair<WithReason<int64_t>,
bool> GetGeneratedNestDepthWithReason(
240std::optional<int64_t> GetMinimumSequenceCount(
241 std::optional<int64_t> first, std::optional<int64_t> count);
242std::optional<int64_t> GetMinimumSequenceCount(
243 std::optional<std::pair<int64_t, int64_t>> range);
250std::optional<std::vector<const parser::DoConstruct *>> CollectAffectedDoLoops(
258 template <
typename R,
typename = std::enable_if_t<is_range_v<R>>>
259 LoopSequence(
const R &range,
unsigned version,
bool allowAllLoops =
false,
261 : version_(version), allowAllLoops_(allowAllLoops), semaCtx_(semaCtx) {
262 entry_ = std::make_unique<Construct>(range,
nullptr);
263 createChildrenFromRange(entry_->location);
276 bool isNest()
const {
return length_.value == 1; }
279 const Depth &depth()
const {
return depth_; }
280 const std::vector<LoopSequence> &children()
const {
return children_; }
281 const parser::ExecutionPartConstruct *owner()
const {
return entry_->owner; }
283 WithReason<bool> isWellFormedSequence()
const;
284 WithReason<bool> isWellFormedNest()
const;
290 std::vector<LoopControl> getLoopControls()
const;
293 WithReason<bool> isRectangular(
294 const std::vector<const LoopSequence *> &outer)
const;
297 using Construct = ExecutionPartIterator::Construct;
299 LoopSequence(std::unique_ptr<Construct> entry,
unsigned version,
300 bool allowAllLoops, SemanticsContext *semaCtx =
nullptr);
302 template <
typename R,
typename = std::enable_if_t<is_range_v<R>>>
303 void createChildrenFromRange(
const R &range) {
304 createChildrenFromRange(range.begin(), range.end());
307 std::unique_ptr<Construct> createConstructEntry(
308 const parser::ExecutionPartConstruct &code);
310 void createChildrenFromRange(
311 ExecutionPartIterator::IteratorType begin,
312 ExecutionPartIterator::IteratorType end);
317 WithReason<int64_t> calculateLength()
const;
318 WithReason<int64_t> getNestedLength()
const;
319 Depth calculateDepths()
const;
320 Depth getNestedDepths()
const;
321 WithReason<int64_t> calculateHeight()
const;
326 const parser::ExecutionPartConstruct *invalidIC_{
nullptr};
330 const parser::ExecutionPartConstruct *opaqueIC_{
nullptr};
336 WithReason<int64_t> length_;
345 WithReason<int64_t> height_;
350 std::unique_ptr<Construct> entry_;
351 std::vector<LoopSequence> children_;
352 SemanticsContext *semaCtx_{
nullptr};
Definition char-block.h:28
Definition semantics.h:67
Definition parse-tree.h:1896
Definition parse-tree.h:2236
Definition parse-tree.h:1806
Definition parse-tree.h:1845
Definition parse-tree.h:2323
Definition parse-tree.h:554
Definition parse-tree.h:1693
Definition parse-tree.h:5048
Definition parse-tree.h:3525
Definition parse-tree.h:5424
Definition parse-tree.h:3656
Definition openmp-utils.h:267
const LoopSequence * getNestedDoConcurrent() const
Definition openmp-utils.cpp:1421
A representation of a "because" message.
Definition openmp-utils.h:170
Definition openmp-utils.h:77
Definition openmp-utils.h:196
Definition openmp-utils.h:57