1 | /* General types and functions that are uselful for processing of OpenMP, |
2 | OpenACC and similar directivers at various stages of compilation. |
3 | |
4 | Copyright (C) 2005-2024 Free Software Foundation, Inc. |
5 | |
6 | This file is part of GCC. |
7 | |
8 | GCC is free software; you can redistribute it and/or modify it under |
9 | the terms of the GNU General Public License as published by the Free |
10 | Software Foundation; either version 3, or (at your option) any later |
11 | version. |
12 | |
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
16 | for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ |
21 | |
22 | #ifndef GCC_OMP_GENERAL_H |
23 | #define GCC_OMP_GENERAL_H |
24 | |
25 | #include "gomp-constants.h" |
26 | #include "omp-api.h" |
27 | #include "omp-selectors.h" |
28 | |
29 | /* Flags for an OpenACC loop. */ |
30 | |
31 | enum oacc_loop_flags { |
32 | OLF_SEQ = 1u << 0, /* Explicitly sequential */ |
33 | OLF_AUTO = 1u << 1, /* Compiler chooses axes. */ |
34 | OLF_INDEPENDENT = 1u << 2, /* Iterations are known independent. */ |
35 | OLF_GANG_STATIC = 1u << 3, /* Gang partitioning is static (has op). */ |
36 | OLF_TILE = 1u << 4, /* Tiled loop. */ |
37 | OLF_REDUCTION = 1u << 5, /* Reduction loop. */ |
38 | |
39 | /* Explicitly specified loop axes. */ |
40 | OLF_DIM_BASE = 6, |
41 | OLF_DIM_GANG = 1u << (OLF_DIM_BASE + GOMP_DIM_GANG), |
42 | OLF_DIM_WORKER = 1u << (OLF_DIM_BASE + GOMP_DIM_WORKER), |
43 | OLF_DIM_VECTOR = 1u << (OLF_DIM_BASE + GOMP_DIM_VECTOR), |
44 | |
45 | OLF_MAX = OLF_DIM_BASE + GOMP_DIM_MAX |
46 | }; |
47 | |
48 | /* A structure holding the elements of: |
49 | for (V = N1; V cond N2; V += STEP) [...] |
50 | or for non-rectangular loops: |
51 | for (V = M1 * W + N1; V cond M2 * W + N2; V += STEP; |
52 | where W is V of the OUTER-th loop (e.g. for OUTER 1 it is the |
53 | the index of the immediately surrounding loop). |
54 | NON_RECT_REFERENCED is true for loops referenced by loops |
55 | with non-NULL M1 or M2. */ |
56 | |
57 | struct omp_for_data_loop |
58 | { |
59 | tree v, n1, n2, step, m1, m2; |
60 | enum tree_code cond_code; |
61 | int outer; |
62 | bool non_rect_referenced; |
63 | }; |
64 | |
65 | /* A structure describing the main elements of a parallel loop. */ |
66 | |
67 | struct omp_for_data |
68 | { |
69 | struct omp_for_data_loop loop; |
70 | tree chunk_size; |
71 | gomp_for *for_stmt; |
72 | tree pre, iter_type; |
73 | tree tiling; /* Tiling values (if non null). */ |
74 | int collapse; /* Collapsed loops, 1 for a non-collapsed loop. */ |
75 | int ordered; |
76 | int first_nonrect, last_nonrect; |
77 | bool have_nowait, have_ordered, simd_schedule, have_reductemp; |
78 | bool have_pointer_condtemp, have_scantemp, have_nonctrl_scantemp; |
79 | bool non_rect; |
80 | int lastprivate_conditional; |
81 | unsigned char sched_modifiers; |
82 | enum omp_clause_schedule_kind sched_kind; |
83 | struct omp_for_data_loop *loops; |
84 | /* The following are relevant only for non-rectangular loops |
85 | where only a single loop depends on an outer loop iterator. */ |
86 | tree first_inner_iterations; /* Number of iterations of the inner |
87 | loop with the first outer iterator |
88 | (or adjn1, if that is non-NULL). */ |
89 | tree factor; /* (m2 - m1) * outer_step / inner_step. */ |
90 | /* Adjusted n1 of the outer loop in such loop nests (if needed). */ |
91 | tree adjn1; |
92 | }; |
93 | |
94 | #define OACC_FN_ATTRIB "oacc function" |
95 | |
96 | /* Accessors for OMP context selectors, used by variant directives. |
97 | These are represented internally by a multilevel TREE_LIST structure, but |
98 | these accessors should be used to avoid confusion. The grammar is: |
99 | |
100 | context-set-selector-specification: |
101 | trait-set-selector [, trait-set-selector [, ...]] |
102 | trait-set-selector: |
103 | trait-set-selector-name = { trait-selector [, trait-selector [, ... ]] } |
104 | trait-selector: |
105 | trait-selector-name [ ( [trait-score: ] |
106 | trait-property [, trait-property [, ...]] ) ] |
107 | |
108 | trait-properties can variously be identifiers, strings, clauses, or |
109 | expressions. |
110 | |
111 | All the lists are chained via TREE_CHAIN. If a score is present, it is |
112 | internally tacked on to the properties with a TREE_PURPOSE of |
113 | OMP_TS_SCORE_NODE. */ |
114 | |
115 | #define OMP_TS_SCORE_NODE integer_minus_one_node |
116 | #define OMP_TP_NAMELIST_NODE integer_one_node |
117 | |
118 | #define OMP_TSS_ID(NODE) \ |
119 | TREE_PURPOSE (NODE) |
120 | #define OMP_TSS_TRAIT_SELECTORS(NODE) \ |
121 | TREE_VALUE (NODE) |
122 | #define OMP_TS_ID(NODE) \ |
123 | TREE_PURPOSE (NODE) |
124 | #define OMP_TS_SCORE(NODE) \ |
125 | ((TREE_VALUE (NODE) \ |
126 | && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST \ |
127 | && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \ |
128 | ? TREE_VALUE (TREE_VALUE (NODE)) : NULL_TREE) |
129 | #define OMP_TS_PROPERTIES(NODE) \ |
130 | ((TREE_VALUE (NODE) \ |
131 | && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST \ |
132 | && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \ |
133 | ? TREE_CHAIN (TREE_VALUE (NODE)) : TREE_VALUE (NODE)) |
134 | #define OMP_TP_NAME(NODE) \ |
135 | TREE_PURPOSE (NODE) |
136 | #define OMP_TP_VALUE(NODE) \ |
137 | TREE_VALUE (NODE) |
138 | |
139 | #define OMP_TSS_CODE(t) \ |
140 | ((enum omp_tss_code) TREE_INT_CST_LOW (OMP_TSS_ID (t))) |
141 | #define OMP_TSS_NAME(t) \ |
142 | (omp_tss_map[OMP_TSS_CODE (t)]) |
143 | |
144 | #define OMP_TS_CODE(t) \ |
145 | ((enum omp_ts_code) TREE_INT_CST_LOW (OMP_TS_ID (t))) |
146 | #define OMP_TS_NAME(t) \ |
147 | (omp_ts_map[OMP_TS_CODE (t)].name) |
148 | |
149 | extern tree make_trait_set_selector (enum omp_tss_code, tree, tree); |
150 | extern tree make_trait_selector (enum omp_ts_code, tree, tree, tree); |
151 | extern tree make_trait_property (tree, tree, tree); |
152 | |
153 | extern tree omp_find_clause (tree clauses, enum omp_clause_code kind); |
154 | extern bool omp_is_allocatable_or_ptr (tree decl); |
155 | extern tree omp_check_optional_argument (tree decl, bool for_present_check); |
156 | extern bool omp_mappable_type (tree type); |
157 | extern bool omp_privatize_by_reference (tree decl); |
158 | extern void omp_adjust_for_condition (location_t loc, enum tree_code *cond_code, |
159 | tree *n2, tree v, tree step); |
160 | extern tree omp_get_for_step_from_incr (location_t loc, tree incr); |
161 | extern void (gomp_for *for_stmt, struct omp_for_data *fd, |
162 | struct omp_for_data_loop *loops); |
163 | extern gimple *omp_build_barrier (tree lhs); |
164 | extern tree find_combined_omp_for (tree *, int *, void *); |
165 | extern poly_uint64 omp_max_vf (void); |
166 | extern int omp_max_simt_vf (void); |
167 | extern const char *omp_context_name_list_prop (tree); |
168 | extern void omp_construct_traits_to_codes (tree, int, enum tree_code *); |
169 | extern tree omp_check_context_selector (location_t loc, tree ctx); |
170 | extern void omp_mark_declare_variant (location_t loc, tree variant, |
171 | tree construct); |
172 | extern int omp_context_selector_matches (tree); |
173 | extern int omp_context_selector_set_compare (enum omp_tss_code, tree, tree); |
174 | extern tree omp_get_context_selector (tree, enum omp_tss_code, |
175 | enum omp_ts_code); |
176 | extern tree omp_get_context_selector_list (tree, enum omp_tss_code); |
177 | extern tree omp_resolve_declare_variant (tree); |
178 | extern tree oacc_launch_pack (unsigned code, tree device, unsigned op); |
179 | extern tree oacc_replace_fn_attrib_attr (tree attribs, tree dims); |
180 | extern void oacc_replace_fn_attrib (tree fn, tree dims); |
181 | extern void oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args); |
182 | extern int oacc_verify_routine_clauses (tree, tree *, location_t, |
183 | const char *); |
184 | extern tree oacc_build_routine_dims (tree clauses); |
185 | extern tree oacc_get_fn_attrib (tree fn); |
186 | extern bool offloading_function_p (tree fn); |
187 | extern int oacc_get_fn_dim_size (tree fn, int axis); |
188 | extern int oacc_get_ifn_dim_arg (const gimple *stmt); |
189 | |
190 | enum omp_requires { |
191 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER = 0xf, |
192 | OMP_REQUIRES_UNIFIED_ADDRESS = GOMP_REQUIRES_UNIFIED_ADDRESS, |
193 | OMP_REQUIRES_UNIFIED_SHARED_MEMORY = GOMP_REQUIRES_UNIFIED_SHARED_MEMORY, |
194 | OMP_REQUIRES_DYNAMIC_ALLOCATORS = 0x40, |
195 | OMP_REQUIRES_REVERSE_OFFLOAD = GOMP_REQUIRES_REVERSE_OFFLOAD, |
196 | OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED = 0x100, |
197 | OMP_REQUIRES_TARGET_USED = GOMP_REQUIRES_TARGET_USED, |
198 | }; |
199 | |
200 | extern GTY(()) enum omp_requires omp_requires_mask; |
201 | |
202 | inline dump_flags_t |
203 | get_openacc_privatization_dump_flags () |
204 | { |
205 | dump_flags_t l_dump_flags = MSG_NOTE; |
206 | |
207 | /* For '--param=openacc-privatization=quiet', diagnostics only go to dump |
208 | files. */ |
209 | if (param_openacc_privatization == OPENACC_PRIVATIZATION_QUIET) |
210 | l_dump_flags |= MSG_PRIORITY_INTERNALS; |
211 | |
212 | return l_dump_flags; |
213 | } |
214 | |
215 | extern tree omp_build_component_ref (tree obj, tree field); |
216 | |
217 | namespace omp_addr_tokenizer { |
218 | |
219 | /* These are the ways of accessing a variable that have special-case handling |
220 | in the middle end (gimplify, omp-lower, etc.). */ |
221 | |
222 | /* These are the kinds of access that an ACCESS_METHOD token can represent. */ |
223 | |
224 | enum access_method_kinds |
225 | { |
226 | ACCESS_DIRECT, |
227 | ACCESS_REF, |
228 | ACCESS_POINTER, |
229 | ACCESS_REF_TO_POINTER, |
230 | ACCESS_POINTER_OFFSET, |
231 | ACCESS_REF_TO_POINTER_OFFSET, |
232 | ACCESS_INDEXED_ARRAY, |
233 | ACCESS_INDEXED_REF_TO_ARRAY |
234 | }; |
235 | |
236 | /* These are the kinds that a STRUCTURE_BASE or ARRAY_BASE (except |
237 | BASE_COMPONENT_EXPR) can represent. */ |
238 | |
239 | enum structure_base_kinds |
240 | { |
241 | BASE_DECL, |
242 | BASE_COMPONENT_EXPR, |
243 | BASE_ARBITRARY_EXPR |
244 | }; |
245 | |
246 | /* The coarse type for an address token. These can have subtypes for |
247 | ARRAY_BASE or STRUCTURE_BASE (structure_base_kinds) or ACCESS_METHOD |
248 | (access_method_kinds). */ |
249 | |
250 | enum token_type |
251 | { |
252 | ARRAY_BASE, |
253 | STRUCTURE_BASE, |
254 | COMPONENT_SELECTOR, |
255 | ACCESS_METHOD |
256 | }; |
257 | |
258 | /* The struct that forms a single token of an address expression as parsed by |
259 | omp_parse_expr. These are typically held in a vec after parsing. */ |
260 | |
261 | struct omp_addr_token |
262 | { |
263 | enum token_type type; |
264 | tree expr; |
265 | |
266 | union |
267 | { |
268 | access_method_kinds access_kind; |
269 | structure_base_kinds structure_base_kind; |
270 | } u; |
271 | |
272 | omp_addr_token (token_type, tree); |
273 | omp_addr_token (access_method_kinds, tree); |
274 | omp_addr_token (token_type, structure_base_kinds, tree); |
275 | }; |
276 | |
277 | extern bool omp_access_chain_p (vec<omp_addr_token *> &, unsigned); |
278 | extern tree omp_accessed_addr (vec<omp_addr_token *> &, unsigned, tree); |
279 | |
280 | } |
281 | |
282 | typedef omp_addr_tokenizer::omp_addr_token omp_addr_token; |
283 | |
284 | extern bool omp_parse_expr (vec<omp_addr_token *> &, tree); |
285 | |
286 | #endif /* GCC_OMP_GENERAL_H */ |
287 | |