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);
89const Symbol *GetObjectSymbol(
91const Symbol *GetArgumentSymbol(
94bool IsCommonBlock(
const Symbol &sym);
95bool IsExtendedListItem(
const Symbol &sym);
96bool IsVariableListItem(
const Symbol &sym);
97bool IsTypeParamInquiry(
const Symbol &sym);
98bool IsStructureComponent(
const Symbol &sym);
99bool IsPrivatizable(
const Symbol &sym);
100bool IsVarOrFunctionRef(
const MaybeExpr &expr);
106bool IsMapEnteringType(parser::OmpMapType::Value type);
107bool IsMapExitingType(parser::OmpMapType::Value type);
109MaybeExpr GetEvaluateExpr(
const parser::Expr &parserExpr);
110template <
typename T> MaybeExpr GetEvaluateExpr(
const T &inp) {
111 return GetEvaluateExpr(parser::UnwrapRef<parser::Expr>(inp));
114std::optional<evaluate::DynamicType> GetDynamicType(
117std::optional<bool> GetLogicalValue(
const SomeExpr &expr);
118std::optional<int64_t> GetIntValueFromExpr(
122std::optional<int64_t> GetIntValueFromExpr(
124 if (
auto *parserExpr{parser::Unwrap<parser::Expr>(wrappedExpr)}) {
125 return GetIntValueFromExpr(*parserExpr, semaCtx);
130std::optional<bool> IsContiguous(
131 SemanticsContext &semaCtx,
const parser::OmpObject &
object);
133std::vector<SomeExpr> GetTopLevelDesignators(
const SomeExpr &expr);
134const SomeExpr *HasStorageOverlap(
135 const SomeExpr &base, llvm::ArrayRef<SomeExpr> exprs);
137bool IsAssignment(
const parser::ActionStmt *x);
138bool IsPointerAssignment(
const evaluate::Assignment &x);
140MaybeExpr MakeEvaluateExpr(
const parser::OmpStylizedInstance &inp);
142bool IsLoopTransforming(llvm::omp::Directive dir);
143bool HasDataEnvironment(llvm::omp::Directive dir);
145bool IsFullUnroll(
const parser::OmpDirectiveSpecification &spec);
147inline bool IsDoConcurrentLegal(
unsigned version) {
150 return version >= 60;
154 LoopControl(LoopControl &&x) =
default;
155 LoopControl(
const LoopControl &x) =
default;
156 LoopControl(
const parser::LoopControl::Bounds &x);
171 Reason(Reason &&) =
default;
172 Reason(
const Reason &);
173 Reason &operator=(Reason &&) =
default;
174 Reason &operator=(
const Reason &);
178 template <
typename... Ts> Reason &Say(Ts &&...args) {
179 msgs.Say(std::forward<Ts>(args)...);
183 Reason &Append(
const Reason &other) {
187 operator bool()
const {
return !msgs.empty(); }
190 void CopyFrom(
const Reason &other);
195template <
typename T>
struct WithReason {
196 std::optional<T> value;
199 WithReason() =
default;
200 WithReason(std::optional<T> v,
const Reason &r =
Reason())
201 : value(v), reason(r) {}
202 operator bool()
const {
return value.has_value(); }
217std::pair<WithReason<int64_t>,
bool> GetAffectedNestDepthWithReason(
222std::pair<WithReason<int64_t>,
bool> GetGeneratedNestDepthWithReason(
239std::optional<int64_t> GetMinimumSequenceCount(
240 std::optional<int64_t> first, std::optional<int64_t> count);
241std::optional<int64_t> GetMinimumSequenceCount(
242 std::optional<std::pair<int64_t, int64_t>> range);
249std::optional<std::vector<const parser::DoConstruct *>> CollectAffectedDoLoops(
257 template <
typename R,
typename = std::enable_if_t<is_range_v<R>>>
258 LoopSequence(
const R &range,
unsigned version,
bool allowAllLoops =
false,
260 : version_(version), allowAllLoops_(allowAllLoops), semaCtx_(semaCtx) {
261 entry_ = std::make_unique<Construct>(range,
nullptr);
262 createChildrenFromRange(entry_->location);
275 bool isNest()
const {
return length_.value == 1; }
278 const Depth &depth()
const {
return depth_; }
279 const std::vector<LoopSequence> &children()
const {
return children_; }
280 const parser::ExecutionPartConstruct *owner()
const {
return entry_->owner; }
282 WithReason<bool> isWellFormedSequence()
const;
283 WithReason<bool> isWellFormedNest()
const;
289 std::vector<LoopControl> getLoopControls()
const;
292 WithReason<bool> isRectangular(
293 const std::vector<const LoopSequence *> &outer)
const;
296 using Construct = ExecutionPartIterator::Construct;
298 LoopSequence(std::unique_ptr<Construct> entry,
unsigned version,
299 bool allowAllLoops, SemanticsContext *semaCtx =
nullptr);
301 template <
typename R,
typename = std::enable_if_t<is_range_v<R>>>
302 void createChildrenFromRange(
const R &range) {
303 createChildrenFromRange(range.begin(), range.end());
306 std::unique_ptr<Construct> createConstructEntry(
307 const parser::ExecutionPartConstruct &code);
309 void createChildrenFromRange(
310 ExecutionPartIterator::IteratorType begin,
311 ExecutionPartIterator::IteratorType end);
316 WithReason<int64_t> calculateLength()
const;
317 WithReason<int64_t> getNestedLength()
const;
318 Depth calculateDepths()
const;
319 Depth getNestedDepths()
const;
320 WithReason<int64_t> calculateHeight()
const;
325 const parser::ExecutionPartConstruct *invalidIC_{
nullptr};
329 const parser::ExecutionPartConstruct *opaqueIC_{
nullptr};
335 WithReason<int64_t> length_;
344 WithReason<int64_t> height_;
349 std::unique_ptr<Construct> entry_;
350 std::vector<LoopSequence> children_;
351 SemanticsContext *semaCtx_{
nullptr};
Definition char-block.h:28
Definition semantics.h:68
Definition parse-tree.h:2241
Definition parse-tree.h:2328
Definition parse-tree.h:556
Definition parse-tree.h:1698
Definition parse-tree.h:589
Definition parse-tree.h:5091
Definition parse-tree.h:3568
Definition parse-tree.h:5464
Definition parse-tree.h:3699
Definition openmp-utils.h:266
const LoopSequence * getNestedDoConcurrent() const
Definition openmp-utils.cpp:1429
A representation of a "because" message.
Definition openmp-utils.h:169
Definition openmp-utils.h:77
Definition openmp-utils.h:195
Definition openmp-utils.h:57