x86: Add a test for PR rtl-optimization/111673
[official-gcc.git] / gcc / omp-general.h
blob4e143ed586b77cb945fbb70896470712110415e7
1 /* General types and functions that are uselful for processing of OpenMP,
2 OpenACC and similar directivers at various stages of compilation.
4 Copyright (C) 2005-2025 Free Software Foundation, Inc.
6 This file is part of GCC.
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.
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.
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/>. */
22 #ifndef GCC_OMP_GENERAL_H
23 #define GCC_OMP_GENERAL_H
25 #include "gomp-constants.h"
26 #include "omp-api.h"
27 #include "omp-selectors.h"
29 /* Flags for an OpenACC loop. */
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. */
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),
45 OLF_MAX = OLF_DIM_BASE + GOMP_DIM_MAX
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. */
57 struct omp_for_data_loop
59 tree v, n1, n2, step, m1, m2;
60 enum tree_code cond_code;
61 int outer;
62 bool non_rect_referenced;
65 /* A structure describing the main elements of a parallel loop. */
67 struct omp_for_data
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;
94 /* Needs to be a GC-friendly widest_int variant, but precision is
95 desirable to be the same on all targets. */
96 typedef generic_wide_int <fixed_wide_int_storage <1024> > score_wide_int;
98 /* A structure describing a variant alternative in a metadirective or
99 variant function, used for matching and scoring during resolution. */
100 struct GTY(()) omp_variant
102 /* Context selector. This is NULL_TREE for the default. */
103 tree selector;
104 /* For early resolution of "metadirective", contains the nested directive.
105 For early resolution of "declare variant", contains the function decl
106 for this alternative. For late resolution of both, contains the label
107 that is the branch target for this alternative. */
108 tree alternative;
109 /* Common body, used for metadirective, null otherwise. */
110 tree body;
111 /* The score, or the best guess if scorable is false. */
112 score_wide_int score;
113 /* True if the selector is dynamic. Filled in during resolution. */
114 bool dynamic_selector;
115 /* Whether the selector is known to definitely match. */
116 bool matchable;
117 /* Whether the score for the selector is definitely known. */
118 bool scorable;
121 #define OACC_FN_ATTRIB "oacc function"
123 /* Accessors for OMP context selectors, used by variant directives.
124 These are represented internally by a multilevel TREE_LIST structure, but
125 these accessors should be used to avoid confusion. The grammar is:
127 context-set-selector-specification:
128 trait-set-selector [, trait-set-selector [, ...]]
129 trait-set-selector:
130 trait-set-selector-name = { trait-selector [, trait-selector [, ... ]] }
131 trait-selector:
132 trait-selector-name [ ( [trait-score: ]
133 trait-property [, trait-property [, ...]] ) ]
135 trait-properties can variously be identifiers, strings, clauses, or
136 expressions.
138 All the lists are chained via TREE_CHAIN. If a score is present, it is
139 internally tacked on to the properties with a TREE_PURPOSE of
140 OMP_TS_SCORE_NODE. */
142 #define OMP_TS_SCORE_NODE integer_minus_one_node
143 #define OMP_TP_NAMELIST_NODE integer_one_node
145 #define OMP_TSS_ID(NODE) \
146 TREE_PURPOSE (NODE)
147 #define OMP_TSS_TRAIT_SELECTORS(NODE) \
148 TREE_VALUE (NODE)
149 #define OMP_TS_ID(NODE) \
150 TREE_PURPOSE (NODE)
151 #define OMP_TS_SCORE(NODE) \
152 ((TREE_VALUE (NODE) \
153 && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST \
154 && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \
155 ? TREE_VALUE (TREE_VALUE (NODE)) : NULL_TREE)
156 #define OMP_TS_PROPERTIES(NODE) \
157 ((TREE_VALUE (NODE) \
158 && TREE_CODE (TREE_VALUE (NODE)) == TREE_LIST \
159 && TREE_PURPOSE (TREE_VALUE (NODE)) == OMP_TS_SCORE_NODE) \
160 ? TREE_CHAIN (TREE_VALUE (NODE)) : TREE_VALUE (NODE))
161 #define OMP_TP_NAME(NODE) \
162 TREE_PURPOSE (NODE)
163 #define OMP_TP_VALUE(NODE) \
164 TREE_VALUE (NODE)
166 #define OMP_TSS_CODE(t) \
167 ((enum omp_tss_code) TREE_INT_CST_LOW (OMP_TSS_ID (t)))
168 #define OMP_TSS_NAME(t) \
169 (omp_tss_map[OMP_TSS_CODE (t)])
171 #define OMP_TS_CODE(t) \
172 ((enum omp_ts_code) TREE_INT_CST_LOW (OMP_TS_ID (t)))
173 #define OMP_TS_NAME(t) \
174 (omp_ts_map[OMP_TS_CODE (t)].name)
176 extern tree make_trait_set_selector (enum omp_tss_code, tree, tree);
177 extern tree make_trait_selector (enum omp_ts_code, tree, tree, tree);
178 extern tree make_trait_property (tree, tree, tree);
180 extern tree make_omp_metadirective_variant (tree, tree, tree);
182 extern tree omp_find_clause (tree clauses, enum omp_clause_code kind);
183 extern bool omp_is_allocatable_or_ptr (tree decl);
184 extern tree omp_check_optional_argument (tree decl, bool for_present_check);
185 extern bool omp_mappable_type (tree type);
186 extern bool omp_privatize_by_reference (tree decl);
187 extern void omp_adjust_for_condition (location_t loc, enum tree_code *cond_code,
188 tree *n2, tree v, tree step);
189 extern tree omp_get_for_step_from_incr (location_t loc, tree incr);
190 extern void omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
191 struct omp_for_data_loop *loops);
192 extern gimple *omp_build_barrier (tree lhs);
193 extern tree find_combined_omp_for (tree *, int *, void *);
194 extern poly_uint64 omp_max_vf (bool);
195 extern int omp_max_simt_vf (void);
196 extern const char *omp_context_name_list_prop (tree);
197 extern tree omp_check_context_selector (location_t loc, tree ctx,
198 bool metadirective_p);
199 extern void omp_mark_declare_variant (location_t loc, tree variant,
200 tree construct);
201 extern int omp_context_selector_matches (tree, tree, bool);
202 extern tree resolve_omp_target_device_matches (tree node);
203 extern tree omp_get_context_selector (tree, enum omp_tss_code,
204 enum omp_ts_code);
205 extern tree omp_get_context_selector_list (tree, enum omp_tss_code);
206 extern vec<struct omp_variant> omp_declare_variant_candidates (tree, tree);
207 extern vec<struct omp_variant> omp_metadirective_candidates (tree, tree);
208 extern vec<struct omp_variant>
209 omp_get_dynamic_candidates (vec<struct omp_variant>&, tree);
210 extern vec<struct omp_variant> omp_early_resolve_metadirective (tree);
211 extern vec<struct omp_variant> omp_resolve_variant_construct (tree, tree);
212 extern tree omp_dynamic_cond (tree, tree);
213 extern tree oacc_launch_pack (unsigned code, tree device, unsigned op);
214 extern tree oacc_replace_fn_attrib_attr (tree attribs, tree dims);
215 extern void oacc_replace_fn_attrib (tree fn, tree dims);
216 extern void oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args);
217 extern int oacc_verify_routine_clauses (tree, tree *, location_t,
218 const char *);
219 extern tree oacc_build_routine_dims (tree clauses);
220 extern tree oacc_get_fn_attrib (tree fn);
221 extern bool offloading_function_p (tree fn);
222 extern int oacc_get_fn_dim_size (tree fn, int axis);
223 extern int oacc_get_ifn_dim_arg (const gimple *stmt);
225 enum omp_requires {
226 OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER = 0xf,
227 OMP_REQUIRES_UNIFIED_ADDRESS = GOMP_REQUIRES_UNIFIED_ADDRESS,
228 OMP_REQUIRES_UNIFIED_SHARED_MEMORY = GOMP_REQUIRES_UNIFIED_SHARED_MEMORY,
229 OMP_REQUIRES_DYNAMIC_ALLOCATORS = 0x40,
230 OMP_REQUIRES_REVERSE_OFFLOAD = GOMP_REQUIRES_REVERSE_OFFLOAD,
231 OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER_USED = 0x100,
232 OMP_REQUIRES_TARGET_USED = GOMP_REQUIRES_TARGET_USED,
233 OMP_REQUIRES_SELF_MAPS = GOMP_REQUIRES_SELF_MAPS
236 extern GTY(()) enum omp_requires omp_requires_mask;
238 inline dump_flags_t
239 get_openacc_privatization_dump_flags ()
241 dump_flags_t l_dump_flags = MSG_NOTE;
243 /* For '--param=openacc-privatization=quiet', diagnostics only go to dump
244 files. */
245 if (param_openacc_privatization == OPENACC_PRIVATIZATION_QUIET)
246 l_dump_flags |= MSG_PRIORITY_INTERNALS;
248 return l_dump_flags;
251 extern tree omp_build_component_ref (tree obj, tree field);
253 namespace omp_addr_tokenizer {
255 /* These are the ways of accessing a variable that have special-case handling
256 in the middle end (gimplify, omp-lower, etc.). */
258 /* These are the kinds of access that an ACCESS_METHOD token can represent. */
260 enum access_method_kinds
262 ACCESS_DIRECT,
263 ACCESS_REF,
264 ACCESS_POINTER,
265 ACCESS_REF_TO_POINTER,
266 ACCESS_POINTER_OFFSET,
267 ACCESS_REF_TO_POINTER_OFFSET,
268 ACCESS_INDEXED_ARRAY,
269 ACCESS_INDEXED_REF_TO_ARRAY
272 /* These are the kinds that a STRUCTURE_BASE or ARRAY_BASE (except
273 BASE_COMPONENT_EXPR) can represent. */
275 enum structure_base_kinds
277 BASE_DECL,
278 BASE_COMPONENT_EXPR,
279 BASE_ARBITRARY_EXPR
282 /* The coarse type for an address token. These can have subtypes for
283 ARRAY_BASE or STRUCTURE_BASE (structure_base_kinds) or ACCESS_METHOD
284 (access_method_kinds). */
286 enum token_type
288 ARRAY_BASE,
289 STRUCTURE_BASE,
290 COMPONENT_SELECTOR,
291 ACCESS_METHOD
294 /* The struct that forms a single token of an address expression as parsed by
295 omp_parse_expr. These are typically held in a vec after parsing. */
297 struct omp_addr_token
299 enum token_type type;
300 tree expr;
302 union
304 access_method_kinds access_kind;
305 structure_base_kinds structure_base_kind;
306 } u;
308 omp_addr_token (token_type, tree);
309 omp_addr_token (access_method_kinds, tree);
310 omp_addr_token (token_type, structure_base_kinds, tree);
313 extern bool omp_access_chain_p (vec<omp_addr_token *> &, unsigned);
314 extern tree omp_accessed_addr (vec<omp_addr_token *> &, unsigned, tree);
318 typedef omp_addr_tokenizer::omp_addr_token omp_addr_token;
320 extern bool omp_parse_expr (vec<omp_addr_token *> &, tree);
322 extern tree omp_loop_number_of_iterations (tree, int, tree * = NULL);
323 extern void omp_maybe_apply_loop_xforms (tree *, tree);
325 #endif /* GCC_OMP_GENERAL_H */