FLANG
check-acc-structure.h
1//===-- lib/Semantics/check-acc-structure.h ---------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7// OpenACC 3.3 structure validity check list
8// 1. invalid clauses on directive
9// 2. invalid repeated clauses on directive
10// 3. invalid nesting of regions
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_
15#define FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_
16
17#include "check-directive-structure.h"
18#include "flang/Common/enum-set.h"
19#include "flang/Parser/parse-tree.h"
20#include "flang/Semantics/semantics.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/Frontend/OpenACC/ACC.h.inc"
23
24#include <cstddef>
25#include <functional>
26#include <optional>
27#include <string>
28
29using AccDirectiveSet = Fortran::common::EnumSet<llvm::acc::Directive,
30 llvm::acc::Directive_enumSize>;
31
32using AccClauseSet =
34
35#define GEN_FLANG_DIRECTIVE_CLAUSE_SETS
36#include "llvm/Frontend/OpenACC/ACC.inc"
37
38namespace Fortran::semantics {
39
40template <>
41void IterateOverMembers(
42 const AccClauseSet &set, std::function<void(llvm::acc::Clause)> func);
43
44class AccStructureChecker
45 : public DirectiveStructureChecker<llvm::acc::Directive, llvm::acc::Clause,
46 parser::AccClause, AccClauseSet> {
47public:
48 AccStructureChecker(SemanticsContext &context)
49 : DirectiveStructureChecker(context,
50#define GEN_FLANG_DIRECTIVE_CLAUSE_MAP
51#include "llvm/Frontend/OpenACC/ACC.inc"
52 ) {
53 }
54
55 // Construct and directives
56 void Enter(const parser::OpenACCBlockConstruct &);
57 void Leave(const parser::OpenACCBlockConstruct &);
58 void Enter(const parser::OpenACCCombinedConstruct &);
59 void Leave(const parser::OpenACCCombinedConstruct &);
60 void Enter(const parser::OpenACCLoopConstruct &);
61 void Leave(const parser::OpenACCLoopConstruct &);
62 void Enter(const parser::OpenACCRoutineConstruct &);
63 void Leave(const parser::OpenACCRoutineConstruct &);
64 void Enter(const parser::OpenACCStandaloneConstruct &);
65 void Leave(const parser::OpenACCStandaloneConstruct &);
68 void Enter(const parser::OpenACCWaitConstruct &);
69 void Leave(const parser::OpenACCWaitConstruct &);
70 void Enter(const parser::OpenACCAtomicConstruct &);
71 void Leave(const parser::OpenACCAtomicConstruct &);
72 void Enter(const parser::OpenACCCacheConstruct &);
73 void Leave(const parser::OpenACCCacheConstruct &);
74 void Enter(const parser::AccAtomicUpdate &);
75 void Enter(const parser::AccAtomicCapture &);
76 void Enter(const parser::AccAtomicWrite &);
77 void Enter(const parser::AccAtomicRead &);
78 void Enter(const parser::OpenACCEndConstruct &);
79
80 // Clauses
81 void Leave(const parser::AccClauseList &);
82 void Enter(const parser::AccClause &);
83
84 void Enter(const parser::Module &);
85 void Enter(const parser::SubroutineSubprogram &);
86 void Enter(const parser::FunctionSubprogram &);
87 void Enter(const parser::SeparateModuleSubprogram &);
88 void Enter(const parser::DoConstruct &);
89 void Leave(const parser::DoConstruct &);
90 void Enter(const parser::CallStmt &);
91 void Enter(const parser::FunctionReference &);
92
93#define GEN_FLANG_CLAUSE_CHECK_ENTER
94#include "llvm/Frontend/OpenACC/ACC.inc"
95
96private:
97 void CheckAtomicStmt(
98 const parser::AssignmentStmt &assign, const std::string &construct);
99 void CheckAtomicUpdateStmt(const parser::AssignmentStmt &assign,
100 const SomeExpr &updateVar, const SomeExpr *captureVar);
101 void CheckAtomicCaptureStmt(const parser::AssignmentStmt &assign,
102 const SomeExpr *updateVar, const SomeExpr &captureVar);
103 void CheckAtomicWriteStmt(const parser::AssignmentStmt &assign,
104 const SomeExpr &updateVar, const SomeExpr *captureVar);
105 void CheckAtomicUpdateVariable(
106 const parser::Variable &updateVar, const parser::Variable &captureVar);
107 void CheckAtomicCaptureVariable(
108 const parser::Variable &captureVar, const parser::Variable &updateVar);
109
110 bool CheckAllowedModifier(llvm::acc::Clause clause);
111 bool IsComputeConstruct(llvm::acc::Directive directive) const;
112 bool IsLoopConstruct(llvm::acc::Directive directive) const;
113 std::optional<llvm::acc::Directive> getParentComputeConstruct() const;
114 bool IsInsideComputeConstruct() const;
115 bool IsInsideKernelsConstruct() const;
116 void CheckNotInComputeConstruct();
117 std::optional<std::int64_t> getGangDimensionSize(
118 DirectiveContext &dirContext);
119 void CheckNotInSameOrSubLevelLoopConstruct();
120 void CheckRoutineCallInLoop(const Symbol &);
121 void CheckMultipleOccurrenceInDeclare(
122 const parser::AccObjectList &, llvm::acc::Clause);
123 void CheckMultipleOccurrenceInDeclare(
124 const parser::AccObjectListWithModifier &, llvm::acc::Clause);
125 llvm::StringRef getClauseName(llvm::acc::Clause clause) override;
126 llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override;
127
128 llvm::SmallDenseMap<Symbol *, llvm::acc::Clause> declareSymbols;
129 unsigned loopNestLevel = 0;
130};
131
132} // namespace Fortran::semantics
133
134#endif // FORTRAN_SEMANTICS_CHECK_ACC_STRUCTURE_H_
Definition enum-set.h:28
Definition semantics.h:67
Definition symbol.h:896
Definition parse-tree.h:5808
Definition parse-tree.h:5784
Definition parse-tree.h:5800
Definition parse-tree.h:5792
Definition parse-tree.h:5740
Definition parse-tree.h:5725
Definition parse-tree.h:5656
Definition parse-tree.h:2047
Definition parse-tree.h:3345
Definition parse-tree.h:2367
Definition parse-tree.h:3333
Definition parse-tree.h:3365
Definition parse-tree.h:3007
Definition parse-tree.h:5815
Definition parse-tree.h:5822
Definition parse-tree.h:5751
Definition parse-tree.h:5844
Definition parse-tree.h:5872
Definition parse-tree.h:5863
Definition parse-tree.h:5745
Definition parse-tree.h:5757
Definition parse-tree.h:3391
Definition parse-tree.h:3375
Definition parse-tree.h:1897