File: | build/gcc/omp-general.cc |
Warning: | line 716, column 6 Value stored to 'n2last' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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-2023 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 | /* Find an OMP clause of type KIND within CLAUSES. */ |
23 | |
24 | #include "config.h" |
25 | #include "system.h" |
26 | #include "coretypes.h" |
27 | #include "backend.h" |
28 | #include "target.h" |
29 | #include "tree.h" |
30 | #include "gimple.h" |
31 | #include "ssa.h" |
32 | #include "diagnostic-core.h" |
33 | #include "fold-const.h" |
34 | #include "langhooks.h" |
35 | #include "omp-general.h" |
36 | #include "stringpool.h" |
37 | #include "attribs.h" |
38 | #include "gimplify.h" |
39 | #include "cgraph.h" |
40 | #include "alloc-pool.h" |
41 | #include "symbol-summary.h" |
42 | #include "tree-pass.h" |
43 | #include "omp-device-properties.h" |
44 | #include "tree-iterator.h" |
45 | #include "data-streamer.h" |
46 | #include "streamer-hooks.h" |
47 | #include "opts.h" |
48 | |
49 | enum omp_requires omp_requires_mask; |
50 | |
51 | tree |
52 | omp_find_clause (tree clauses, enum omp_clause_code kind) |
53 | { |
54 | for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses)((contains_struct_check (((tree_check ((clauses), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 54, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 54, __FUNCTION__))->common.chain)) |
55 | if (OMP_CLAUSE_CODE (clauses)((tree_check ((clauses), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 55, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code == kind) |
56 | return clauses; |
57 | |
58 | return NULL_TREE(tree) nullptr; |
59 | } |
60 | |
61 | /* True if OpenMP should regard this DECL as being a scalar which has Fortran's |
62 | allocatable or pointer attribute. */ |
63 | bool |
64 | omp_is_allocatable_or_ptr (tree decl) |
65 | { |
66 | return lang_hooks.decls.omp_is_allocatable_or_ptr (decl); |
67 | } |
68 | |
69 | /* Check whether this DECL belongs to a Fortran optional argument. |
70 | With 'for_present_check' set to false, decls which are optional parameters |
71 | themselve are returned as tree - or a NULL_TREE otherwise. Those decls are |
72 | always pointers. With 'for_present_check' set to true, the decl for checking |
73 | whether an argument is present is returned; for arguments with value |
74 | attribute this is the hidden argument and of BOOLEAN_TYPE. If the decl is |
75 | unrelated to optional arguments, NULL_TREE is returned. */ |
76 | |
77 | tree |
78 | omp_check_optional_argument (tree decl, bool for_present_check) |
79 | { |
80 | return lang_hooks.decls.omp_check_optional_argument (decl, for_present_check); |
81 | } |
82 | |
83 | /* Return true if TYPE is an OpenMP mappable type. */ |
84 | |
85 | bool |
86 | omp_mappable_type (tree type) |
87 | { |
88 | /* Mappable type has to be complete. */ |
89 | if (type == error_mark_nodeglobal_trees[TI_ERROR_MARK] || !COMPLETE_TYPE_P (type)(((tree_class_check ((type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 89, __FUNCTION__))->type_common.size) != (tree) nullptr)) |
90 | return false; |
91 | return true; |
92 | } |
93 | |
94 | /* True if OpenMP should privatize what this DECL points to rather |
95 | than the DECL itself. */ |
96 | |
97 | bool |
98 | omp_privatize_by_reference (tree decl) |
99 | { |
100 | return lang_hooks.decls.omp_privatize_by_reference (decl); |
101 | } |
102 | |
103 | /* Adjust *COND_CODE and *N2 so that the former is either LT_EXPR or GT_EXPR, |
104 | given that V is the loop index variable and STEP is loop step. */ |
105 | |
106 | void |
107 | omp_adjust_for_condition (location_t loc, enum tree_code *cond_code, tree *n2, |
108 | tree v, tree step) |
109 | { |
110 | switch (*cond_code) |
111 | { |
112 | case LT_EXPR: |
113 | case GT_EXPR: |
114 | break; |
115 | |
116 | case NE_EXPR: |
117 | gcc_assert (TREE_CODE (step) == INTEGER_CST)((void)(!(((enum tree_code) (step)->base.code) == INTEGER_CST ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 117, __FUNCTION__), 0 : 0)); |
118 | if (TREE_CODE (TREE_TYPE (v))((enum tree_code) (((contains_struct_check ((v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 118, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE) |
119 | { |
120 | if (integer_onep (step)) |
121 | *cond_code = LT_EXPR; |
122 | else |
123 | { |
124 | gcc_assert (integer_minus_onep (step))((void)(!(integer_minus_onep (step)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 124, __FUNCTION__), 0 : 0)); |
125 | *cond_code = GT_EXPR; |
126 | } |
127 | } |
128 | else |
129 | { |
130 | tree unit = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (v)))((tree_class_check ((((contains_struct_check ((((contains_struct_check ((v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 130, __FUNCTION__))->typed.type)), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 130, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 130, __FUNCTION__))->type_common.size_unit); |
131 | gcc_assert (TREE_CODE (unit) == INTEGER_CST)((void)(!(((enum tree_code) (unit)->base.code) == INTEGER_CST ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 131, __FUNCTION__), 0 : 0)); |
132 | if (tree_int_cst_equal (unit, step)) |
133 | *cond_code = LT_EXPR; |
134 | else |
135 | { |
136 | gcc_assert (wi::neg (wi::to_widest (unit))((void)(!(wi::neg (wi::to_widest (unit)) == wi::to_widest (step )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 137, __FUNCTION__), 0 : 0)) |
137 | == wi::to_widest (step))((void)(!(wi::neg (wi::to_widest (unit)) == wi::to_widest (step )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 137, __FUNCTION__), 0 : 0)); |
138 | *cond_code = GT_EXPR; |
139 | } |
140 | } |
141 | |
142 | break; |
143 | |
144 | case LE_EXPR: |
145 | if (POINTER_TYPE_P (TREE_TYPE (*n2))(((enum tree_code) (((contains_struct_check ((*n2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 145, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((*n2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 145, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
146 | *n2 = fold_build_pointer_plus_hwi_loc (loc, *n2, 1); |
147 | else |
148 | *n2 = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (*n2)((contains_struct_check ((*n2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 148, __FUNCTION__))->typed.type), *n2, |
149 | build_int_cst (TREE_TYPE (*n2)((contains_struct_check ((*n2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 149, __FUNCTION__))->typed.type), 1)); |
150 | *cond_code = LT_EXPR; |
151 | break; |
152 | case GE_EXPR: |
153 | if (POINTER_TYPE_P (TREE_TYPE (*n2))(((enum tree_code) (((contains_struct_check ((*n2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 153, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((*n2), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 153, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
154 | *n2 = fold_build_pointer_plus_hwi_loc (loc, *n2, -1); |
155 | else |
156 | *n2 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (*n2)((contains_struct_check ((*n2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 156, __FUNCTION__))->typed.type), *n2, |
157 | build_int_cst (TREE_TYPE (*n2)((contains_struct_check ((*n2), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 157, __FUNCTION__))->typed.type), 1)); |
158 | *cond_code = GT_EXPR; |
159 | break; |
160 | default: |
161 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 161, __FUNCTION__)); |
162 | } |
163 | } |
164 | |
165 | /* Return the looping step from INCR, extracted from the step of a gimple omp |
166 | for statement. */ |
167 | |
168 | tree |
169 | omp_get_for_step_from_incr (location_t loc, tree incr) |
170 | { |
171 | tree step; |
172 | switch (TREE_CODE (incr)((enum tree_code) (incr)->base.code)) |
173 | { |
174 | case PLUS_EXPR: |
175 | step = TREE_OPERAND (incr, 1)(*((const_cast<tree*> (tree_operand_check ((incr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 175, __FUNCTION__))))); |
176 | break; |
177 | case POINTER_PLUS_EXPR: |
178 | step = fold_convert (ssizetype, TREE_OPERAND (incr, 1))fold_convert_loc (((location_t) 0), sizetype_tab[(int) stk_ssizetype ], (*((const_cast<tree*> (tree_operand_check ((incr), ( 1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 178, __FUNCTION__)))))); |
179 | break; |
180 | case MINUS_EXPR: |
181 | step = TREE_OPERAND (incr, 1)(*((const_cast<tree*> (tree_operand_check ((incr), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 181, __FUNCTION__))))); |
182 | step = fold_build1_loc (loc, NEGATE_EXPR, TREE_TYPE (step)((contains_struct_check ((step), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 182, __FUNCTION__))->typed.type), step); |
183 | break; |
184 | default: |
185 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 185, __FUNCTION__)); |
186 | } |
187 | return step; |
188 | } |
189 | |
190 | /* Extract the header elements of parallel loop FOR_STMT and store |
191 | them into *FD. */ |
192 | |
193 | void |
194 | omp_extract_for_data (gomp_for *for_stmt, struct omp_for_data *fd, |
195 | struct omp_for_data_loop *loops) |
196 | { |
197 | tree t, var, *collapse_iter, *collapse_count; |
198 | tree count = NULL_TREE(tree) nullptr, iter_type = long_integer_type_nodeinteger_types[itk_long]; |
199 | struct omp_for_data_loop *loop; |
200 | int i; |
201 | struct omp_for_data_loop dummy_loop; |
202 | location_t loc = gimple_location (for_stmt); |
203 | bool simd = gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_SIMD; |
204 | bool distribute = gimple_omp_for_kind (for_stmt) |
205 | == GF_OMP_FOR_KIND_DISTRIBUTE; |
206 | bool taskloop = gimple_omp_for_kind (for_stmt) |
207 | == GF_OMP_FOR_KIND_TASKLOOP; |
208 | bool order_reproducible = false; |
209 | tree iterv, countv; |
210 | |
211 | fd->for_stmt = for_stmt; |
212 | fd->pre = NULLnullptr; |
213 | fd->have_nowait = distribute || simd; |
214 | fd->have_ordered = false; |
215 | fd->have_reductemp = false; |
216 | fd->have_pointer_condtemp = false; |
217 | fd->have_scantemp = false; |
218 | fd->have_nonctrl_scantemp = false; |
219 | fd->non_rect = false; |
220 | fd->lastprivate_conditional = 0; |
221 | fd->tiling = NULL_TREE(tree) nullptr; |
222 | fd->collapse = 1; |
223 | fd->ordered = 0; |
224 | fd->first_nonrect = -1; |
225 | fd->last_nonrect = -1; |
226 | fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC; |
227 | fd->sched_modifiers = 0; |
228 | fd->chunk_size = NULL_TREE(tree) nullptr; |
229 | fd->simd_schedule = false; |
230 | fd->first_inner_iterations = NULL_TREE(tree) nullptr; |
231 | fd->factor = NULL_TREE(tree) nullptr; |
232 | fd->adjn1 = NULL_TREE(tree) nullptr; |
233 | collapse_iter = NULLnullptr; |
234 | collapse_count = NULLnullptr; |
235 | |
236 | for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t)((contains_struct_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 236, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 236, __FUNCTION__))->common.chain)) |
237 | switch (OMP_CLAUSE_CODE (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 237, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code) |
238 | { |
239 | case OMP_CLAUSE_NOWAIT: |
240 | fd->have_nowait = true; |
241 | break; |
242 | case OMP_CLAUSE_ORDERED: |
243 | fd->have_ordered = true; |
244 | if (OMP_CLAUSE_ORDERED_DOACROSS (t)((omp_clause_subcode_check ((t), (OMP_CLAUSE_ORDERED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 244, __FUNCTION__))->base.public_flag)) |
245 | { |
246 | if (OMP_CLAUSE_ORDERED_EXPR (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_ORDERED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 246, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 246, __FUNCTION__)))) |
247 | fd->ordered = tree_to_shwi (OMP_CLAUSE_ORDERED_EXPR (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_ORDERED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 247, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 247, __FUNCTION__)))); |
248 | else |
249 | fd->ordered = -1; |
250 | } |
251 | break; |
252 | case OMP_CLAUSE_SCHEDULE: |
253 | gcc_assert (!distribute && !taskloop)((void)(!(!distribute && !taskloop) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 253, __FUNCTION__), 0 : 0)); |
254 | fd->sched_kind |
255 | = (enum omp_clause_schedule_kind) |
256 | (OMP_CLAUSE_SCHEDULE_KIND (t)((omp_clause_subcode_check ((t), (OMP_CLAUSE_SCHEDULE), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 256, __FUNCTION__))->omp_clause.subcode.schedule_kind) & OMP_CLAUSE_SCHEDULE_MASK); |
257 | fd->sched_modifiers = (OMP_CLAUSE_SCHEDULE_KIND (t)((omp_clause_subcode_check ((t), (OMP_CLAUSE_SCHEDULE), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 257, __FUNCTION__))->omp_clause.subcode.schedule_kind) |
258 | & ~OMP_CLAUSE_SCHEDULE_MASK); |
259 | fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_SCHEDULE ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 259, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 259, __FUNCTION__))); |
260 | fd->simd_schedule = OMP_CLAUSE_SCHEDULE_SIMD (t)((omp_clause_subcode_check ((t), (OMP_CLAUSE_SCHEDULE), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 260, __FUNCTION__))->base.public_flag); |
261 | break; |
262 | case OMP_CLAUSE_DIST_SCHEDULE: |
263 | gcc_assert (distribute)((void)(!(distribute) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 263, __FUNCTION__), 0 : 0)); |
264 | fd->chunk_size = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_DIST_SCHEDULE ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 264, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 264, __FUNCTION__))); |
265 | break; |
266 | case OMP_CLAUSE_COLLAPSE: |
267 | fd->collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_COLLAPSE ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 267, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 267, __FUNCTION__)))); |
268 | if (fd->collapse > 1) |
269 | { |
270 | collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_COLLAPSE ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 270, __FUNCTION__))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 270, __FUNCTION__))); |
271 | collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_COLLAPSE ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 271, __FUNCTION__))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 271, __FUNCTION__))); |
272 | } |
273 | break; |
274 | case OMP_CLAUSE_TILE: |
275 | fd->tiling = OMP_CLAUSE_TILE_LIST (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_TILE ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 275, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 275, __FUNCTION__))); |
276 | fd->collapse = list_length (fd->tiling); |
277 | gcc_assert (fd->collapse)((void)(!(fd->collapse) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 277, __FUNCTION__), 0 : 0)); |
278 | collapse_iter = &OMP_CLAUSE_TILE_ITERVAR (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_TILE ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 278, __FUNCTION__))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 278, __FUNCTION__))); |
279 | collapse_count = &OMP_CLAUSE_TILE_COUNT (t)(*(omp_clause_elt_check (((omp_clause_subcode_check ((t), (OMP_CLAUSE_TILE ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 279, __FUNCTION__))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 279, __FUNCTION__))); |
280 | break; |
281 | case OMP_CLAUSE__REDUCTEMP_: |
282 | fd->have_reductemp = true; |
283 | break; |
284 | case OMP_CLAUSE_LASTPRIVATE: |
285 | if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (t)(((omp_clause_subcode_check ((t), (OMP_CLAUSE_LASTPRIVATE), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 285, __FUNCTION__)))->base.private_flag)) |
286 | fd->lastprivate_conditional++; |
287 | break; |
288 | case OMP_CLAUSE__CONDTEMP_: |
289 | if (POINTER_TYPE_P (TREE_TYPE (OMP_CLAUSE_DECL (t)))(((enum tree_code) (((contains_struct_check (((*(omp_clause_elt_check (((omp_clause_range_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 289, __FUNCTION__, (OMP_CLAUSE)))), (OMP_CLAUSE_PRIVATE), ( OMP_CLAUSE__SCANTEMP_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 289, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 289, __FUNCTION__)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 289, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check (((*(omp_clause_elt_check (((omp_clause_range_check (((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 289, __FUNCTION__, (OMP_CLAUSE)))), (OMP_CLAUSE_PRIVATE), ( OMP_CLAUSE__SCANTEMP_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 289, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 289, __FUNCTION__)))), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 289, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
290 | fd->have_pointer_condtemp = true; |
291 | break; |
292 | case OMP_CLAUSE__SCANTEMP_: |
293 | fd->have_scantemp = true; |
294 | if (!OMP_CLAUSE__SCANTEMP__ALLOC (t)((omp_clause_subcode_check ((t), (OMP_CLAUSE__SCANTEMP_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 294, __FUNCTION__))->base.public_flag) |
295 | && !OMP_CLAUSE__SCANTEMP__CONTROL (t)(((omp_clause_subcode_check ((t), (OMP_CLAUSE__SCANTEMP_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 295, __FUNCTION__)))->base.private_flag)) |
296 | fd->have_nonctrl_scantemp = true; |
297 | break; |
298 | case OMP_CLAUSE_ORDER: |
299 | /* FIXME: For OpenMP 5.2 this should change to |
300 | if (OMP_CLAUSE_ORDER_REPRODUCIBLE (t)) |
301 | (with the exception of loop construct but that lowers to |
302 | no schedule/dist_schedule clauses currently). */ |
303 | if (!OMP_CLAUSE_ORDER_UNCONSTRAINED (t)((omp_clause_subcode_check ((t), (OMP_CLAUSE_ORDER), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 303, __FUNCTION__))->base.public_flag)) |
304 | order_reproducible = true; |
305 | default: |
306 | break; |
307 | } |
308 | |
309 | if (fd->ordered == -1) |
310 | fd->ordered = fd->collapse; |
311 | |
312 | /* For order(reproducible:concurrent) schedule ({dynamic,guided,runtime}) |
313 | we have either the option to expensively remember at runtime how we've |
314 | distributed work from first loop and reuse that in following loops with |
315 | the same number of iterations and schedule, or just force static schedule. |
316 | OpenMP API calls etc. aren't allowed in order(concurrent) bodies so |
317 | users can't observe it easily anyway. */ |
318 | if (order_reproducible) |
319 | fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC; |
320 | if (fd->collapse > 1 || fd->tiling) |
321 | fd->loops = loops; |
322 | else |
323 | fd->loops = &fd->loop; |
324 | |
325 | if (fd->ordered && fd->collapse == 1 && loops != NULLnullptr) |
326 | { |
327 | fd->loops = loops; |
328 | iterv = NULL_TREE(tree) nullptr; |
329 | countv = NULL_TREE(tree) nullptr; |
330 | collapse_iter = &iterv; |
331 | collapse_count = &countv; |
332 | } |
333 | |
334 | /* FIXME: for now map schedule(auto) to schedule(static). |
335 | There should be analysis to determine whether all iterations |
336 | are approximately the same amount of work (then schedule(static) |
337 | is best) or if it varies (then schedule(dynamic,N) is better). */ |
338 | if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO) |
339 | { |
340 | fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC; |
341 | gcc_assert (fd->chunk_size == NULL)((void)(!(fd->chunk_size == nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 341, __FUNCTION__), 0 : 0)); |
342 | } |
343 | gcc_assert ((fd->collapse == 1 && !fd->tiling) || collapse_iter != NULL)((void)(!((fd->collapse == 1 && !fd->tiling) || collapse_iter != nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 343, __FUNCTION__), 0 : 0)); |
344 | if (taskloop) |
345 | fd->sched_kind = OMP_CLAUSE_SCHEDULE_RUNTIME; |
346 | if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME) |
347 | gcc_assert (fd->chunk_size == NULL)((void)(!(fd->chunk_size == nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 347, __FUNCTION__), 0 : 0)); |
348 | else if (fd->chunk_size == NULLnullptr) |
349 | { |
350 | /* We only need to compute a default chunk size for ordered |
351 | static loops and dynamic loops. */ |
352 | if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC |
353 | || fd->have_ordered) |
354 | fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC) |
355 | ? integer_zero_nodeglobal_trees[TI_INTEGER_ZERO] : integer_one_nodeglobal_trees[TI_INTEGER_ONE]; |
356 | } |
357 | |
358 | int cnt = fd->ordered ? fd->ordered : fd->collapse; |
359 | int single_nonrect = -1; |
360 | tree single_nonrect_count = NULL_TREE(tree) nullptr; |
361 | enum tree_code single_nonrect_cond_code = ERROR_MARK; |
362 | for (i = 1; i < cnt; i++) |
363 | { |
364 | tree n1 = gimple_omp_for_initial (for_stmt, i); |
365 | tree n2 = gimple_omp_for_final (for_stmt, i); |
366 | if (TREE_CODE (n1)((enum tree_code) (n1)->base.code) == TREE_VEC) |
367 | { |
368 | if (fd->non_rect) |
369 | { |
370 | single_nonrect = -1; |
371 | break; |
372 | } |
373 | for (int j = i - 1; j >= 0; j--) |
374 | if (TREE_VEC_ELT (n1, 0)(*((const_cast<tree *> (tree_vec_elt_check ((n1), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 374, __FUNCTION__))))) == gimple_omp_for_index (for_stmt, j)) |
375 | { |
376 | single_nonrect = j; |
377 | break; |
378 | } |
379 | fd->non_rect = true; |
380 | } |
381 | else if (TREE_CODE (n2)((enum tree_code) (n2)->base.code) == TREE_VEC) |
382 | { |
383 | if (fd->non_rect) |
384 | { |
385 | single_nonrect = -1; |
386 | break; |
387 | } |
388 | for (int j = i - 1; j >= 0; j--) |
389 | if (TREE_VEC_ELT (n2, 0)(*((const_cast<tree *> (tree_vec_elt_check ((n2), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 389, __FUNCTION__))))) == gimple_omp_for_index (for_stmt, j)) |
390 | { |
391 | single_nonrect = j; |
392 | break; |
393 | } |
394 | fd->non_rect = true; |
395 | } |
396 | } |
397 | for (i = 0; i < cnt; i++) |
398 | { |
399 | if (i == 0 |
400 | && fd->collapse == 1 |
401 | && !fd->tiling |
402 | && (fd->ordered == 0 || loops == NULLnullptr)) |
403 | loop = &fd->loop; |
404 | else if (loops != NULLnullptr) |
405 | loop = loops + i; |
406 | else |
407 | loop = &dummy_loop; |
408 | |
409 | loop->v = gimple_omp_for_index (for_stmt, i); |
410 | gcc_assert (SSA_VAR_P (loop->v))((void)(!((((enum tree_code) (loop->v)->base.code) == VAR_DECL || ((enum tree_code) (loop->v)->base.code) == PARM_DECL || ((enum tree_code) (loop->v)->base.code) == RESULT_DECL || ((enum tree_code) (loop->v)->base.code) == SSA_NAME )) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 410, __FUNCTION__), 0 : 0)); |
411 | gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE((void)(!(((enum tree_code) (((contains_struct_check ((loop-> v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 411, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE || ((enum tree_code) (((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 412, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 412, __FUNCTION__), 0 : 0)) |
412 | || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE)((void)(!(((enum tree_code) (((contains_struct_check ((loop-> v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 411, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE || ((enum tree_code) (((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 412, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE ) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 412, __FUNCTION__), 0 : 0)); |
413 | var = TREE_CODE (loop->v)((enum tree_code) (loop->v)->base.code) == SSA_NAME ? SSA_NAME_VAR (loop->v)((tree_check ((loop->v), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 413, __FUNCTION__, (SSA_NAME)))->ssa_name.var == (tree) nullptr || ((enum tree_code) ((loop->v)->ssa_name.var)->base .code) == IDENTIFIER_NODE ? (tree) nullptr : (loop->v)-> ssa_name.var) : loop->v; |
414 | loop->n1 = gimple_omp_for_initial (for_stmt, i); |
415 | loop->m1 = NULL_TREE(tree) nullptr; |
416 | loop->m2 = NULL_TREE(tree) nullptr; |
417 | loop->outer = 0; |
418 | loop->non_rect_referenced = false; |
419 | if (TREE_CODE (loop->n1)((enum tree_code) (loop->n1)->base.code) == TREE_VEC) |
420 | { |
421 | for (int j = i - 1; j >= 0; j--) |
422 | if (TREE_VEC_ELT (loop->n1, 0)(*((const_cast<tree *> (tree_vec_elt_check ((loop->n1 ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 422, __FUNCTION__))))) == gimple_omp_for_index (for_stmt, j)) |
423 | { |
424 | loop->outer = i - j; |
425 | if (loops != NULLnullptr) |
426 | loops[j].non_rect_referenced = true; |
427 | if (fd->first_nonrect == -1 || fd->first_nonrect > j) |
428 | fd->first_nonrect = j; |
429 | break; |
430 | } |
431 | gcc_assert (loop->outer)((void)(!(loop->outer) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 431, __FUNCTION__), 0 : 0)); |
432 | loop->m1 = TREE_VEC_ELT (loop->n1, 1)(*((const_cast<tree *> (tree_vec_elt_check ((loop->n1 ), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 432, __FUNCTION__))))); |
433 | loop->n1 = TREE_VEC_ELT (loop->n1, 2)(*((const_cast<tree *> (tree_vec_elt_check ((loop->n1 ), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 433, __FUNCTION__))))); |
434 | fd->non_rect = true; |
435 | fd->last_nonrect = i; |
436 | } |
437 | |
438 | loop->cond_code = gimple_omp_for_cond (for_stmt, i); |
439 | loop->n2 = gimple_omp_for_final (for_stmt, i); |
440 | gcc_assert (loop->cond_code != NE_EXPR((void)(!(loop->cond_code != NE_EXPR || (gimple_omp_for_kind (for_stmt) != GF_OMP_FOR_KIND_OACC_LOOP)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 442, __FUNCTION__), 0 : 0)) |
441 | || (gimple_omp_for_kind (for_stmt)((void)(!(loop->cond_code != NE_EXPR || (gimple_omp_for_kind (for_stmt) != GF_OMP_FOR_KIND_OACC_LOOP)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 442, __FUNCTION__), 0 : 0)) |
442 | != GF_OMP_FOR_KIND_OACC_LOOP))((void)(!(loop->cond_code != NE_EXPR || (gimple_omp_for_kind (for_stmt) != GF_OMP_FOR_KIND_OACC_LOOP)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 442, __FUNCTION__), 0 : 0)); |
443 | if (TREE_CODE (loop->n2)((enum tree_code) (loop->n2)->base.code) == TREE_VEC) |
444 | { |
445 | if (loop->outer) |
446 | gcc_assert (TREE_VEC_ELT (loop->n2, 0)((void)(!((*((const_cast<tree *> (tree_vec_elt_check (( loop->n2), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 446, __FUNCTION__))))) == gimple_omp_for_index (for_stmt, i - loop->outer)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 447, __FUNCTION__), 0 : 0)) |
447 | == gimple_omp_for_index (for_stmt, i - loop->outer))((void)(!((*((const_cast<tree *> (tree_vec_elt_check (( loop->n2), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 446, __FUNCTION__))))) == gimple_omp_for_index (for_stmt, i - loop->outer)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 447, __FUNCTION__), 0 : 0)); |
448 | else |
449 | for (int j = i - 1; j >= 0; j--) |
450 | if (TREE_VEC_ELT (loop->n2, 0)(*((const_cast<tree *> (tree_vec_elt_check ((loop->n2 ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 450, __FUNCTION__))))) == gimple_omp_for_index (for_stmt, j)) |
451 | { |
452 | loop->outer = i - j; |
453 | if (loops != NULLnullptr) |
454 | loops[j].non_rect_referenced = true; |
455 | if (fd->first_nonrect == -1 || fd->first_nonrect > j) |
456 | fd->first_nonrect = j; |
457 | break; |
458 | } |
459 | gcc_assert (loop->outer)((void)(!(loop->outer) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 459, __FUNCTION__), 0 : 0)); |
460 | loop->m2 = TREE_VEC_ELT (loop->n2, 1)(*((const_cast<tree *> (tree_vec_elt_check ((loop->n2 ), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 460, __FUNCTION__))))); |
461 | loop->n2 = TREE_VEC_ELT (loop->n2, 2)(*((const_cast<tree *> (tree_vec_elt_check ((loop->n2 ), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 461, __FUNCTION__))))); |
462 | fd->non_rect = true; |
463 | fd->last_nonrect = i; |
464 | } |
465 | |
466 | t = gimple_omp_for_incr (for_stmt, i); |
467 | gcc_assert (TREE_OPERAND (t, 0) == var)((void)(!((*((const_cast<tree*> (tree_operand_check ((t ), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 467, __FUNCTION__))))) == var) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 467, __FUNCTION__), 0 : 0)); |
468 | loop->step = omp_get_for_step_from_incr (loc, t); |
469 | |
470 | omp_adjust_for_condition (loc, &loop->cond_code, &loop->n2, loop->v, |
471 | loop->step); |
472 | |
473 | if (simd |
474 | || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC |
475 | && !fd->have_ordered)) |
476 | { |
477 | if (fd->collapse == 1 && !fd->tiling) |
478 | iter_type = TREE_TYPE (loop->v)((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 478, __FUNCTION__))->typed.type); |
479 | else if (i == 0 |
480 | || TYPE_PRECISION (iter_type)((tree_class_check ((iter_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 480, __FUNCTION__))->type_common.precision) |
481 | < TYPE_PRECISION (TREE_TYPE (loop->v))((tree_class_check ((((contains_struct_check ((loop->v), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 481, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 481, __FUNCTION__))->type_common.precision)) |
482 | iter_type |
483 | = build_nonstandard_integer_type |
484 | (TYPE_PRECISION (TREE_TYPE (loop->v))((tree_class_check ((((contains_struct_check ((loop->v), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 484, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 484, __FUNCTION__))->type_common.precision), 1); |
485 | } |
486 | else if (iter_type != long_long_unsigned_type_nodeinteger_types[itk_unsigned_long_long]) |
487 | { |
488 | if (POINTER_TYPE_P (TREE_TYPE (loop->v))(((enum tree_code) (((contains_struct_check ((loop->v), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 488, __FUNCTION__))->typed.type))->base.code) == POINTER_TYPE || ((enum tree_code) (((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 488, __FUNCTION__))->typed.type))->base.code) == REFERENCE_TYPE )) |
489 | iter_type = long_long_unsigned_type_nodeinteger_types[itk_unsigned_long_long]; |
490 | else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))((tree_class_check ((((contains_struct_check ((loop->v), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 490, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 490, __FUNCTION__))->base.u.bits.unsigned_flag) |
491 | && TYPE_PRECISION (TREE_TYPE (loop->v))((tree_class_check ((((contains_struct_check ((loop->v), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 491, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 491, __FUNCTION__))->type_common.precision) |
492 | >= TYPE_PRECISION (iter_type)((tree_class_check ((iter_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 492, __FUNCTION__))->type_common.precision)) |
493 | { |
494 | tree n; |
495 | |
496 | if (loop->cond_code == LT_EXPR) |
497 | n = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (loop->v)((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 497, __FUNCTION__))->typed.type), |
498 | loop->n2, loop->step); |
499 | else |
500 | n = loop->n1; |
501 | if (loop->m1 |
502 | || loop->m2 |
503 | || TREE_CODE (n)((enum tree_code) (n)->base.code) != INTEGER_CST |
504 | || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type)((tree_check5 ((iter_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 504, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ), n)) |
505 | iter_type = long_long_unsigned_type_nodeinteger_types[itk_unsigned_long_long]; |
506 | } |
507 | else if (TYPE_PRECISION (TREE_TYPE (loop->v))((tree_class_check ((((contains_struct_check ((loop->v), ( TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 507, __FUNCTION__))->typed.type)), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 507, __FUNCTION__))->type_common.precision) |
508 | > TYPE_PRECISION (iter_type)((tree_class_check ((iter_type), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 508, __FUNCTION__))->type_common.precision)) |
509 | { |
510 | tree n1, n2; |
511 | |
512 | if (loop->cond_code == LT_EXPR) |
513 | { |
514 | n1 = loop->n1; |
515 | n2 = fold_build2_loc (loc, PLUS_EXPR, TREE_TYPE (loop->v)((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 515, __FUNCTION__))->typed.type), |
516 | loop->n2, loop->step); |
517 | } |
518 | else |
519 | { |
520 | n1 = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (loop->v)((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 520, __FUNCTION__))->typed.type), |
521 | loop->n2, loop->step); |
522 | n2 = loop->n1; |
523 | } |
524 | if (loop->m1 |
525 | || loop->m2 |
526 | || TREE_CODE (n1)((enum tree_code) (n1)->base.code) != INTEGER_CST |
527 | || TREE_CODE (n2)((enum tree_code) (n2)->base.code) != INTEGER_CST |
528 | || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type)((tree_check5 ((iter_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 528, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.minval ), n1) |
529 | || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)((tree_check5 ((iter_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 529, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ))) |
530 | iter_type = long_long_unsigned_type_nodeinteger_types[itk_unsigned_long_long]; |
531 | } |
532 | } |
533 | |
534 | if (i >= fd->collapse) |
535 | continue; |
536 | |
537 | if (collapse_count && *collapse_count == NULLnullptr) |
538 | { |
539 | if (count && integer_zerop (count)) |
540 | continue; |
541 | tree n1first = NULL_TREE(tree) nullptr, n2first = NULL_TREE(tree) nullptr; |
542 | tree n1last = NULL_TREE(tree) nullptr, n2last = NULL_TREE(tree) nullptr; |
543 | tree ostep = NULL_TREE(tree) nullptr; |
544 | if (loop->m1 || loop->m2) |
545 | { |
546 | if (count == NULL_TREE(tree) nullptr) |
547 | continue; |
548 | if (single_nonrect == -1 |
549 | || (loop->m1 && TREE_CODE (loop->m1)((enum tree_code) (loop->m1)->base.code) != INTEGER_CST) |
550 | || (loop->m2 && TREE_CODE (loop->m2)((enum tree_code) (loop->m2)->base.code) != INTEGER_CST) |
551 | || TREE_CODE (loop->n1)((enum tree_code) (loop->n1)->base.code) != INTEGER_CST |
552 | || TREE_CODE (loop->n2)((enum tree_code) (loop->n2)->base.code) != INTEGER_CST |
553 | || TREE_CODE (loop->step)((enum tree_code) (loop->step)->base.code) != INTEGER_CST) |
554 | { |
555 | count = NULL_TREE(tree) nullptr; |
556 | continue; |
557 | } |
558 | tree var = gimple_omp_for_initial (for_stmt, single_nonrect); |
559 | tree itype = TREE_TYPE (var)((contains_struct_check ((var), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 559, __FUNCTION__))->typed.type); |
560 | tree first = gimple_omp_for_initial (for_stmt, single_nonrect); |
561 | t = gimple_omp_for_incr (for_stmt, single_nonrect); |
562 | ostep = omp_get_for_step_from_incr (loc, t); |
563 | t = fold_binary (MINUS_EXPR, long_long_unsigned_type_node,fold_binary_loc (((location_t) 0), MINUS_EXPR, integer_types[ itk_unsigned_long_long], single_nonrect_count, build_one_cst ( integer_types[itk_unsigned_long_long])) |
564 | single_nonrect_count,fold_binary_loc (((location_t) 0), MINUS_EXPR, integer_types[ itk_unsigned_long_long], single_nonrect_count, build_one_cst ( integer_types[itk_unsigned_long_long])) |
565 | build_one_cst (long_long_unsigned_type_node))fold_binary_loc (((location_t) 0), MINUS_EXPR, integer_types[ itk_unsigned_long_long], single_nonrect_count, build_one_cst ( integer_types[itk_unsigned_long_long])); |
566 | t = fold_convert (itype, t)fold_convert_loc (((location_t) 0), itype, t); |
567 | first = fold_convert (itype, first)fold_convert_loc (((location_t) 0), itype, first); |
568 | ostep = fold_convert (itype, ostep)fold_convert_loc (((location_t) 0), itype, ostep); |
569 | tree last = fold_binary (PLUS_EXPR, itype, first,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, first, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, t, ostep)) |
570 | fold_binary (MULT_EXPR, itype, t,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, first, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, t, ostep)) |
571 | ostep))fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, first, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, t, ostep)); |
572 | if (TREE_CODE (first)((enum tree_code) (first)->base.code) != INTEGER_CST |
573 | || TREE_CODE (last)((enum tree_code) (last)->base.code) != INTEGER_CST) |
574 | { |
575 | count = NULL_TREE(tree) nullptr; |
576 | continue; |
577 | } |
578 | if (loop->m1) |
579 | { |
580 | tree m1 = fold_convert (itype, loop->m1)fold_convert_loc (((location_t) 0), itype, loop->m1); |
581 | tree n1 = fold_convert (itype, loop->n1)fold_convert_loc (((location_t) 0), itype, loop->n1); |
582 | n1first = fold_binary (PLUS_EXPR, itype,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, first, m1), n1) |
583 | fold_binary (MULT_EXPR, itype,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, first, m1), n1) |
584 | first, m1), n1)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, first, m1), n1); |
585 | n1last = fold_binary (PLUS_EXPR, itype,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, last, m1), n1) |
586 | fold_binary (MULT_EXPR, itype,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, last, m1), n1) |
587 | last, m1), n1)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, last, m1), n1); |
588 | } |
589 | else |
590 | n1first = n1last = loop->n1; |
591 | if (loop->m2) |
592 | { |
593 | tree n2 = fold_convert (itype, loop->n2)fold_convert_loc (((location_t) 0), itype, loop->n2); |
594 | tree m2 = fold_convert (itype, loop->m2)fold_convert_loc (((location_t) 0), itype, loop->m2); |
595 | n2first = fold_binary (PLUS_EXPR, itype,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, first, m2), n2) |
596 | fold_binary (MULT_EXPR, itype,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, first, m2), n2) |
597 | first, m2), n2)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, first, m2), n2); |
598 | n2last = fold_binary (PLUS_EXPR, itype,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, last, m2), n2) |
599 | fold_binary (MULT_EXPR, itype,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, last, m2), n2) |
600 | last, m2), n2)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, last, m2), n2); |
601 | } |
602 | else |
603 | n2first = n2last = loop->n2; |
604 | n1first = fold_convert (TREE_TYPE (loop->v), n1first)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 604, __FUNCTION__))->typed.type), n1first); |
605 | n2first = fold_convert (TREE_TYPE (loop->v), n2first)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 605, __FUNCTION__))->typed.type), n2first); |
606 | n1last = fold_convert (TREE_TYPE (loop->v), n1last)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 606, __FUNCTION__))->typed.type), n1last); |
607 | n2last = fold_convert (TREE_TYPE (loop->v), n2last)fold_convert_loc (((location_t) 0), ((contains_struct_check ( (loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 607, __FUNCTION__))->typed.type), n2last); |
608 | t = fold_binary (loop->cond_code, boolean_type_node,fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], n1first, n2first) |
609 | n1first, n2first)fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], n1first, n2first); |
610 | tree t2 = fold_binary (loop->cond_code, boolean_type_node,fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], n1last, n2last) |
611 | n1last, n2last)fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], n1last, n2last); |
612 | if (t && t2 && integer_nonzerop (t) && integer_nonzerop (t2)) |
613 | /* All outer loop iterators have at least one inner loop |
614 | iteration. Try to compute the count at compile time. */ |
615 | t = NULL_TREE(tree) nullptr; |
616 | else if (t && t2 && integer_zerop (t) && integer_zerop (t2)) |
617 | /* No iterations of the inner loop. count will be set to |
618 | zero cst below. */; |
619 | else if (TYPE_UNSIGNED (itype)((tree_class_check ((itype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 619, __FUNCTION__))->base.u.bits.unsigned_flag) |
620 | || t == NULL_TREE(tree) nullptr |
621 | || t2 == NULL_TREE(tree) nullptr |
622 | || TREE_CODE (t)((enum tree_code) (t)->base.code) != INTEGER_CST |
623 | || TREE_CODE (t2)((enum tree_code) (t2)->base.code) != INTEGER_CST) |
624 | { |
625 | /* Punt (for now). */ |
626 | count = NULL_TREE(tree) nullptr; |
627 | continue; |
628 | } |
629 | else |
630 | { |
631 | /* Some iterations of the outer loop have zero iterations |
632 | of the inner loop, while others have at least one. |
633 | In this case, we need to adjust one of those outer |
634 | loop bounds. If ADJ_FIRST, we need to adjust outer n1 |
635 | (first), otherwise outer n2 (last). */ |
636 | bool adj_first = integer_zerop (t); |
637 | tree n1 = fold_convert (itype, loop->n1)fold_convert_loc (((location_t) 0), itype, loop->n1); |
638 | tree n2 = fold_convert (itype, loop->n2)fold_convert_loc (((location_t) 0), itype, loop->n2); |
639 | tree m1 = loop->m1 ? fold_convert (itype, loop->m1)fold_convert_loc (((location_t) 0), itype, loop->m1) |
640 | : build_zero_cst (itype); |
641 | tree m2 = loop->m2 ? fold_convert (itype, loop->m2)fold_convert_loc (((location_t) 0), itype, loop->m2) |
642 | : build_zero_cst (itype); |
643 | t = fold_binary (MINUS_EXPR, itype, n1, n2)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, n1, n2); |
644 | t2 = fold_binary (MINUS_EXPR, itype, m2, m1)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, m2, m1); |
645 | t = fold_binary (TRUNC_DIV_EXPR, itype, t, t2)fold_binary_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, t, t2 ); |
646 | t2 = fold_binary (MINUS_EXPR, itype, t, first)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, t, first ); |
647 | t2 = fold_binary (TRUNC_MOD_EXPR, itype, t2, ostep)fold_binary_loc (((location_t) 0), TRUNC_MOD_EXPR, itype, t2, ostep); |
648 | t = fold_binary (MINUS_EXPR, itype, t, t2)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, t, t2); |
649 | tree n1cur |
650 | = fold_binary (PLUS_EXPR, itype, n1,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, n1, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, m1, t)) |
651 | fold_binary (MULT_EXPR, itype, m1, t))fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, n1, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, m1, t)); |
652 | tree n2cur |
653 | = fold_binary (PLUS_EXPR, itype, n2,fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, n2, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, m2, t)) |
654 | fold_binary (MULT_EXPR, itype, m2, t))fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, n2, fold_binary_loc (((location_t) 0), MULT_EXPR, itype, m2, t)); |
655 | t2 = fold_binary (loop->cond_code, boolean_type_node,fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], n1cur, n2cur) |
656 | n1cur, n2cur)fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], n1cur, n2cur); |
657 | tree t3 = fold_binary (MULT_EXPR, itype, m1, ostep)fold_binary_loc (((location_t) 0), MULT_EXPR, itype, m1, ostep ); |
658 | tree t4 = fold_binary (MULT_EXPR, itype, m2, ostep)fold_binary_loc (((location_t) 0), MULT_EXPR, itype, m2, ostep ); |
659 | tree diff; |
660 | if (adj_first) |
661 | { |
662 | tree new_first; |
663 | if (integer_nonzerop (t2)) |
664 | { |
665 | new_first = t; |
666 | n1first = n1cur; |
667 | n2first = n2cur; |
668 | if (flag_checkingglobal_options.x_flag_checking) |
669 | { |
670 | t3 = fold_binary (MINUS_EXPR, itype, n1cur, t3)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, n1cur, t3 ); |
671 | t4 = fold_binary (MINUS_EXPR, itype, n2cur, t4)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, n2cur, t4 ); |
672 | t3 = fold_binary (loop->cond_code,fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], t3, t4) |
673 | boolean_type_node, t3, t4)fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], t3, t4); |
674 | gcc_assert (integer_zerop (t3))((void)(!(integer_zerop (t3)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 674, __FUNCTION__), 0 : 0)); |
675 | } |
676 | } |
677 | else |
678 | { |
679 | t3 = fold_binary (PLUS_EXPR, itype, n1cur, t3)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, n1cur, t3 ); |
680 | t4 = fold_binary (PLUS_EXPR, itype, n2cur, t4)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, n2cur, t4 ); |
681 | new_first = fold_binary (PLUS_EXPR, itype, t, ostep)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, t, ostep ); |
682 | n1first = t3; |
683 | n2first = t4; |
684 | if (flag_checkingglobal_options.x_flag_checking) |
685 | { |
686 | t3 = fold_binary (loop->cond_code,fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], t3, t4) |
687 | boolean_type_node, t3, t4)fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], t3, t4); |
688 | gcc_assert (integer_nonzerop (t3))((void)(!(integer_nonzerop (t3)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 688, __FUNCTION__), 0 : 0)); |
689 | } |
690 | } |
691 | diff = fold_binary (MINUS_EXPR, itype, new_first, first)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, new_first , first); |
692 | first = new_first; |
693 | fd->adjn1 = first; |
694 | } |
695 | else |
696 | { |
697 | tree new_last; |
698 | if (integer_zerop (t2)) |
699 | { |
700 | t3 = fold_binary (MINUS_EXPR, itype, n1cur, t3)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, n1cur, t3 ); |
701 | t4 = fold_binary (MINUS_EXPR, itype, n2cur, t4)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, n2cur, t4 ); |
702 | new_last = fold_binary (MINUS_EXPR, itype, t, ostep)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, t, ostep ); |
703 | n1last = t3; |
704 | n2last = t4; |
705 | if (flag_checkingglobal_options.x_flag_checking) |
706 | { |
707 | t3 = fold_binary (loop->cond_code,fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], t3, t4) |
708 | boolean_type_node, t3, t4)fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], t3, t4); |
709 | gcc_assert (integer_nonzerop (t3))((void)(!(integer_nonzerop (t3)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 709, __FUNCTION__), 0 : 0)); |
710 | } |
711 | } |
712 | else |
713 | { |
714 | new_last = t; |
715 | n1last = n1cur; |
716 | n2last = n2cur; |
Value stored to 'n2last' is never read | |
717 | if (flag_checkingglobal_options.x_flag_checking) |
718 | { |
719 | t3 = fold_binary (PLUS_EXPR, itype, n1cur, t3)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, n1cur, t3 ); |
720 | t4 = fold_binary (PLUS_EXPR, itype, n2cur, t4)fold_binary_loc (((location_t) 0), PLUS_EXPR, itype, n2cur, t4 ); |
721 | t3 = fold_binary (loop->cond_code,fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], t3, t4) |
722 | boolean_type_node, t3, t4)fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], t3, t4); |
723 | gcc_assert (integer_zerop (t3))((void)(!(integer_zerop (t3)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 723, __FUNCTION__), 0 : 0)); |
724 | } |
725 | } |
726 | diff = fold_binary (MINUS_EXPR, itype, last, new_last)fold_binary_loc (((location_t) 0), MINUS_EXPR, itype, last, new_last ); |
727 | } |
728 | if (TYPE_UNSIGNED (itype)((tree_class_check ((itype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 728, __FUNCTION__))->base.u.bits.unsigned_flag) |
729 | && single_nonrect_cond_code == GT_EXPR) |
730 | diff = fold_binary (TRUNC_DIV_EXPR, itype,fold_binary_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_unary_loc (((location_t) 0), NEGATE_EXPR, itype, diff), fold_unary_loc (((location_t) 0), NEGATE_EXPR, itype, ostep)) |
731 | fold_unary (NEGATE_EXPR, itype, diff),fold_binary_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_unary_loc (((location_t) 0), NEGATE_EXPR, itype, diff), fold_unary_loc (((location_t) 0), NEGATE_EXPR, itype, ostep)) |
732 | fold_unary (NEGATE_EXPR, itype,fold_binary_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_unary_loc (((location_t) 0), NEGATE_EXPR, itype, diff), fold_unary_loc (((location_t) 0), NEGATE_EXPR, itype, ostep)) |
733 | ostep))fold_binary_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_unary_loc (((location_t) 0), NEGATE_EXPR, itype, diff), fold_unary_loc (((location_t) 0), NEGATE_EXPR, itype, ostep)); |
734 | else |
735 | diff = fold_binary (TRUNC_DIV_EXPR, itype, diff, ostep)fold_binary_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, diff , ostep); |
736 | diff = fold_convert (long_long_unsigned_type_node, diff)fold_convert_loc (((location_t) 0), integer_types[itk_unsigned_long_long ], diff); |
737 | single_nonrect_count |
738 | = fold_binary (MINUS_EXPR, long_long_unsigned_type_node,fold_binary_loc (((location_t) 0), MINUS_EXPR, integer_types[ itk_unsigned_long_long], single_nonrect_count, diff) |
739 | single_nonrect_count, diff)fold_binary_loc (((location_t) 0), MINUS_EXPR, integer_types[ itk_unsigned_long_long], single_nonrect_count, diff); |
740 | t = NULL_TREE(tree) nullptr; |
741 | } |
742 | } |
743 | else |
744 | t = fold_binary (loop->cond_code, boolean_type_node,fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], fold_convert_loc (((location_t) 0), ((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 745, __FUNCTION__))->typed.type), loop->n1), fold_convert_loc (((location_t) 0), ((contains_struct_check ((loop->v), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 746, __FUNCTION__))->typed.type), loop->n2)) |
745 | fold_convert (TREE_TYPE (loop->v), loop->n1),fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], fold_convert_loc (((location_t) 0), ((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 745, __FUNCTION__))->typed.type), loop->n1), fold_convert_loc (((location_t) 0), ((contains_struct_check ((loop->v), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 746, __FUNCTION__))->typed.type), loop->n2)) |
746 | fold_convert (TREE_TYPE (loop->v), loop->n2))fold_binary_loc (((location_t) 0), loop->cond_code, global_trees [TI_BOOLEAN_TYPE], fold_convert_loc (((location_t) 0), ((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 745, __FUNCTION__))->typed.type), loop->n1), fold_convert_loc (((location_t) 0), ((contains_struct_check ((loop->v), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 746, __FUNCTION__))->typed.type), loop->n2)); |
747 | if (t && integer_zerop (t)) |
748 | count = build_zero_cst (long_long_unsigned_type_nodeinteger_types[itk_unsigned_long_long]); |
749 | else if ((i == 0 || count != NULL_TREE(tree) nullptr) |
750 | && TREE_CODE (TREE_TYPE (loop->v))((enum tree_code) (((contains_struct_check ((loop->v), (TS_TYPED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 750, __FUNCTION__))->typed.type))->base.code) == INTEGER_TYPE |
751 | && TREE_CONSTANT (loop->n1)((non_type_check ((loop->n1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 751, __FUNCTION__))->base.constant_flag) |
752 | && TREE_CONSTANT (loop->n2)((non_type_check ((loop->n2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 752, __FUNCTION__))->base.constant_flag) |
753 | && TREE_CODE (loop->step)((enum tree_code) (loop->step)->base.code) == INTEGER_CST) |
754 | { |
755 | tree itype = TREE_TYPE (loop->v)((contains_struct_check ((loop->v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 755, __FUNCTION__))->typed.type); |
756 | |
757 | if (POINTER_TYPE_P (itype)(((enum tree_code) (itype)->base.code) == POINTER_TYPE || ( (enum tree_code) (itype)->base.code) == REFERENCE_TYPE)) |
758 | itype = signed_type_for (itype); |
759 | t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1)); |
760 | t = fold_build2 (PLUS_EXPR, itype,fold_build2_loc (((location_t) 0), PLUS_EXPR, itype, fold_convert_loc (((location_t) 0), itype, loop->step), t ) |
761 | fold_convert (itype, loop->step), t)fold_build2_loc (((location_t) 0), PLUS_EXPR, itype, fold_convert_loc (((location_t) 0), itype, loop->step), t ); |
762 | tree n1 = loop->n1; |
763 | tree n2 = loop->n2; |
764 | if (loop->m1 || loop->m2) |
765 | { |
766 | gcc_assert (single_nonrect != -1)((void)(!(single_nonrect != -1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 766, __FUNCTION__), 0 : 0)); |
767 | n1 = n1first; |
768 | n2 = n2first; |
769 | } |
770 | t = fold_build2 (PLUS_EXPR, itype, t, fold_convert (itype, n2))fold_build2_loc (((location_t) 0), PLUS_EXPR, itype, t, fold_convert_loc (((location_t) 0), itype, n2) ); |
771 | t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, n1))fold_build2_loc (((location_t) 0), MINUS_EXPR, itype, t, fold_convert_loc (((location_t) 0), itype, n1) ); |
772 | tree step = fold_convert_loc (loc, itype, loop->step); |
773 | if (TYPE_UNSIGNED (itype)((tree_class_check ((itype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 773, __FUNCTION__))->base.u.bits.unsigned_flag) && loop->cond_code == GT_EXPR) |
774 | t = fold_build2 (TRUNC_DIV_EXPR, itype,fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, t ), fold_build1_loc ( ((location_t) 0), NEGATE_EXPR, itype, step ) ) |
775 | fold_build1 (NEGATE_EXPR, itype, t),fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, t ), fold_build1_loc ( ((location_t) 0), NEGATE_EXPR, itype, step ) ) |
776 | fold_build1 (NEGATE_EXPR, itype, step))fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, t ), fold_build1_loc ( ((location_t) 0), NEGATE_EXPR, itype, step ) ); |
777 | else |
778 | t = fold_build2 (TRUNC_DIV_EXPR, itype, t, step)fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, t, step ); |
779 | tree llutype = long_long_unsigned_type_nodeinteger_types[itk_unsigned_long_long]; |
780 | t = fold_convert (llutype, t)fold_convert_loc (((location_t) 0), llutype, t); |
781 | if (loop->m1 || loop->m2) |
782 | { |
783 | /* t is number of iterations of inner loop at either first |
784 | or last value of the outer iterator (the one with fewer |
785 | iterations). |
786 | Compute t2 = ((m2 - m1) * ostep) / step |
787 | and niters = outer_count * t |
788 | + t2 * ((outer_count - 1) * outer_count / 2) |
789 | */ |
790 | tree m1 = loop->m1 ? loop->m1 : integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
791 | tree m2 = loop->m2 ? loop->m2 : integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
792 | m1 = fold_convert (itype, m1)fold_convert_loc (((location_t) 0), itype, m1); |
793 | m2 = fold_convert (itype, m2)fold_convert_loc (((location_t) 0), itype, m2); |
794 | tree t2 = fold_build2 (MINUS_EXPR, itype, m2, m1)fold_build2_loc (((location_t) 0), MINUS_EXPR, itype, m2, m1 ); |
795 | t2 = fold_build2 (MULT_EXPR, itype, t2, ostep)fold_build2_loc (((location_t) 0), MULT_EXPR, itype, t2, ostep ); |
796 | if (TYPE_UNSIGNED (itype)((tree_class_check ((itype), (tcc_type), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 796, __FUNCTION__))->base.u.bits.unsigned_flag) && loop->cond_code == GT_EXPR) |
797 | t2 = fold_build2 (TRUNC_DIV_EXPR, itype,fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, t2 ), fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, step ) ) |
798 | fold_build1 (NEGATE_EXPR, itype, t2),fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, t2 ), fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, step ) ) |
799 | fold_build1 (NEGATE_EXPR, itype, step))fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, t2 ), fold_build1_loc (((location_t) 0), NEGATE_EXPR, itype, step ) ); |
800 | else |
801 | t2 = fold_build2 (TRUNC_DIV_EXPR, itype, t2, step)fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, itype, t2, step ); |
802 | t2 = fold_convert (llutype, t2)fold_convert_loc (((location_t) 0), llutype, t2); |
803 | fd->first_inner_iterations = t; |
804 | fd->factor = t2; |
805 | t = fold_build2 (MULT_EXPR, llutype, t,fold_build2_loc (((location_t) 0), MULT_EXPR, llutype, t, single_nonrect_count ) |
806 | single_nonrect_count)fold_build2_loc (((location_t) 0), MULT_EXPR, llutype, t, single_nonrect_count ); |
807 | tree t3 = fold_build2 (MINUS_EXPR, llutype,fold_build2_loc (((location_t) 0), MINUS_EXPR, llutype, single_nonrect_count , build_one_cst (llutype) ) |
808 | single_nonrect_count,fold_build2_loc (((location_t) 0), MINUS_EXPR, llutype, single_nonrect_count , build_one_cst (llutype) ) |
809 | build_one_cst (llutype))fold_build2_loc (((location_t) 0), MINUS_EXPR, llutype, single_nonrect_count , build_one_cst (llutype) ); |
810 | t3 = fold_build2 (MULT_EXPR, llutype, t3,fold_build2_loc (((location_t) 0), MULT_EXPR, llutype, t3, single_nonrect_count ) |
811 | single_nonrect_count)fold_build2_loc (((location_t) 0), MULT_EXPR, llutype, t3, single_nonrect_count ); |
812 | t3 = fold_build2 (TRUNC_DIV_EXPR, llutype, t3,fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, llutype, t3 , build_int_cst (llutype, 2) ) |
813 | build_int_cst (llutype, 2))fold_build2_loc (((location_t) 0), TRUNC_DIV_EXPR, llutype, t3 , build_int_cst (llutype, 2) ); |
814 | t2 = fold_build2 (MULT_EXPR, llutype, t2, t3)fold_build2_loc (((location_t) 0), MULT_EXPR, llutype, t2, t3 ); |
815 | t = fold_build2 (PLUS_EXPR, llutype, t, t2)fold_build2_loc (((location_t) 0), PLUS_EXPR, llutype, t, t2 ); |
816 | } |
817 | if (i == single_nonrect) |
818 | { |
819 | if (integer_zerop (t) || TREE_CODE (t)((enum tree_code) (t)->base.code) != INTEGER_CST) |
820 | count = t; |
821 | else |
822 | { |
823 | single_nonrect_count = t; |
824 | single_nonrect_cond_code = loop->cond_code; |
825 | if (count == NULL_TREE(tree) nullptr) |
826 | count = build_one_cst (llutype); |
827 | } |
828 | } |
829 | else if (count != NULL_TREE(tree) nullptr) |
830 | count = fold_build2 (MULT_EXPR, llutype, count, t)fold_build2_loc (((location_t) 0), MULT_EXPR, llutype, count, t ); |
831 | else |
832 | count = t; |
833 | if (TREE_CODE (count)((enum tree_code) (count)->base.code) != INTEGER_CST) |
834 | count = NULL_TREE(tree) nullptr; |
835 | } |
836 | else if (count && !integer_zerop (count)) |
837 | count = NULL_TREE(tree) nullptr; |
838 | } |
839 | } |
840 | |
841 | if (count |
842 | && !simd |
843 | && (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC |
844 | || fd->have_ordered)) |
845 | { |
846 | if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)((tree_check5 ((integer_types[itk_long]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 846, __FUNCTION__, (INTEGER_TYPE), (ENUMERAL_TYPE), (BOOLEAN_TYPE ), (REAL_TYPE), (FIXED_POINT_TYPE)))->type_non_common.maxval ))) |
847 | iter_type = long_long_unsigned_type_nodeinteger_types[itk_unsigned_long_long]; |
848 | else |
849 | iter_type = long_integer_type_nodeinteger_types[itk_long]; |
850 | } |
851 | else if (collapse_iter && *collapse_iter != NULLnullptr) |
852 | iter_type = TREE_TYPE (*collapse_iter)((contains_struct_check ((*collapse_iter), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 852, __FUNCTION__))->typed.type); |
853 | fd->iter_type = iter_type; |
854 | if (collapse_iter && *collapse_iter == NULLnullptr) |
855 | *collapse_iter = create_tmp_var (iter_type, ".iter"); |
856 | if (collapse_count && *collapse_count == NULLnullptr) |
857 | { |
858 | if (count) |
859 | { |
860 | *collapse_count = fold_convert_loc (loc, iter_type, count); |
861 | if (fd->first_inner_iterations && fd->factor) |
862 | { |
863 | t = make_tree_vec (4); |
864 | TREE_VEC_ELT (t, 0)(*((const_cast<tree *> (tree_vec_elt_check ((t), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 864, __FUNCTION__))))) = *collapse_count; |
865 | TREE_VEC_ELT (t, 1)(*((const_cast<tree *> (tree_vec_elt_check ((t), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 865, __FUNCTION__))))) = fd->first_inner_iterations; |
866 | TREE_VEC_ELT (t, 2)(*((const_cast<tree *> (tree_vec_elt_check ((t), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 866, __FUNCTION__))))) = fd->factor; |
867 | TREE_VEC_ELT (t, 3)(*((const_cast<tree *> (tree_vec_elt_check ((t), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 867, __FUNCTION__))))) = fd->adjn1; |
868 | *collapse_count = t; |
869 | } |
870 | } |
871 | else |
872 | *collapse_count = create_tmp_var (iter_type, ".count"); |
873 | } |
874 | |
875 | if (fd->collapse > 1 || fd->tiling || (fd->ordered && loops)) |
876 | { |
877 | fd->loop.v = *collapse_iter; |
878 | fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v)((contains_struct_check ((fd->loop.v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 878, __FUNCTION__))->typed.type), 0); |
879 | fd->loop.n2 = *collapse_count; |
880 | if (TREE_CODE (fd->loop.n2)((enum tree_code) (fd->loop.n2)->base.code) == TREE_VEC) |
881 | { |
882 | gcc_assert (fd->non_rect)((void)(!(fd->non_rect) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 882, __FUNCTION__), 0 : 0)); |
883 | fd->first_inner_iterations = TREE_VEC_ELT (fd->loop.n2, 1)(*((const_cast<tree *> (tree_vec_elt_check ((fd->loop .n2), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 883, __FUNCTION__))))); |
884 | fd->factor = TREE_VEC_ELT (fd->loop.n2, 2)(*((const_cast<tree *> (tree_vec_elt_check ((fd->loop .n2), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 884, __FUNCTION__))))); |
885 | fd->adjn1 = TREE_VEC_ELT (fd->loop.n2, 3)(*((const_cast<tree *> (tree_vec_elt_check ((fd->loop .n2), (3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 885, __FUNCTION__))))); |
886 | fd->loop.n2 = TREE_VEC_ELT (fd->loop.n2, 0)(*((const_cast<tree *> (tree_vec_elt_check ((fd->loop .n2), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 886, __FUNCTION__))))); |
887 | } |
888 | fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v)((contains_struct_check ((fd->loop.v), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 888, __FUNCTION__))->typed.type), 1); |
889 | fd->loop.m1 = NULL_TREE(tree) nullptr; |
890 | fd->loop.m2 = NULL_TREE(tree) nullptr; |
891 | fd->loop.outer = 0; |
892 | fd->loop.cond_code = LT_EXPR; |
893 | } |
894 | else if (loops) |
895 | loops[0] = fd->loop; |
896 | } |
897 | |
898 | /* Build a call to GOMP_barrier. */ |
899 | |
900 | gimple * |
901 | omp_build_barrier (tree lhs) |
902 | { |
903 | tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL |
904 | : BUILT_IN_GOMP_BARRIER); |
905 | gcall *g = gimple_build_call (fndecl, 0); |
906 | if (lhs) |
907 | gimple_call_set_lhs (g, lhs); |
908 | return g; |
909 | } |
910 | |
911 | /* Find OMP_FOR resp. OMP_SIMD with non-NULL OMP_FOR_INIT. Also, fill in pdata |
912 | array, pdata[0] non-NULL if there is anything non-trivial in between, |
913 | pdata[1] is address of OMP_PARALLEL in between if any, pdata[2] is address |
914 | of OMP_FOR in between if any and pdata[3] is address of the inner |
915 | OMP_FOR/OMP_SIMD. */ |
916 | |
917 | tree |
918 | find_combined_omp_for (tree *tp, int *walk_subtrees, void *data) |
919 | { |
920 | tree **pdata = (tree **) data; |
921 | *walk_subtrees = 0; |
922 | switch (TREE_CODE (*tp)((enum tree_code) (*tp)->base.code)) |
923 | { |
924 | case OMP_FOR: |
925 | if (OMP_FOR_INIT (*tp)(*((const_cast<tree*> (tree_operand_check (((tree_range_check ((*tp), (OMP_FOR), (OACC_LOOP), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 925, __FUNCTION__))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 925, __FUNCTION__))))) != NULL_TREE(tree) nullptr) |
926 | { |
927 | pdata[3] = tp; |
928 | return *tp; |
929 | } |
930 | pdata[2] = tp; |
931 | *walk_subtrees = 1; |
932 | break; |
933 | case OMP_SIMD: |
934 | if (OMP_FOR_INIT (*tp)(*((const_cast<tree*> (tree_operand_check (((tree_range_check ((*tp), (OMP_FOR), (OACC_LOOP), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 934, __FUNCTION__))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 934, __FUNCTION__))))) != NULL_TREE(tree) nullptr) |
935 | { |
936 | pdata[3] = tp; |
937 | return *tp; |
938 | } |
939 | break; |
940 | case BIND_EXPR: |
941 | if (BIND_EXPR_VARS (*tp)((*((const_cast<tree*> (tree_operand_check (((tree_check ((*tp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 941, __FUNCTION__, (BIND_EXPR)))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 941, __FUNCTION__)))))) |
942 | || (BIND_EXPR_BLOCK (*tp)((*((const_cast<tree*> (tree_operand_check (((tree_check ((*tp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 942, __FUNCTION__, (BIND_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 942, __FUNCTION__)))))) |
943 | && BLOCK_VARS (BIND_EXPR_BLOCK (*tp))((tree_check ((((*((const_cast<tree*> (tree_operand_check (((tree_check ((*tp), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 943, __FUNCTION__, (BIND_EXPR)))), (2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 943, __FUNCTION__))))))), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 943, __FUNCTION__, (BLOCK)))->block.vars))) |
944 | pdata[0] = tp; |
945 | *walk_subtrees = 1; |
946 | break; |
947 | case STATEMENT_LIST: |
948 | if (!tsi_one_before_end_p (tsi_start (*tp))) |
949 | pdata[0] = tp; |
950 | *walk_subtrees = 1; |
951 | break; |
952 | case TRY_FINALLY_EXPR: |
953 | pdata[0] = tp; |
954 | *walk_subtrees = 1; |
955 | break; |
956 | case OMP_PARALLEL: |
957 | pdata[1] = tp; |
958 | *walk_subtrees = 1; |
959 | break; |
960 | default: |
961 | break; |
962 | } |
963 | return NULL_TREE(tree) nullptr; |
964 | } |
965 | |
966 | /* Return maximum possible vectorization factor for the target. */ |
967 | |
968 | poly_uint64 |
969 | omp_max_vf (void) |
970 | { |
971 | if (!optimizeglobal_options.x_optimize |
972 | || optimize_debugglobal_options.x_optimize_debug |
973 | || !flag_tree_loop_optimizeglobal_options.x_flag_tree_loop_optimize |
974 | || (!flag_tree_loop_vectorizeglobal_options.x_flag_tree_loop_vectorize |
975 | && OPTION_SET_P (flag_tree_loop_vectorize)global_options_set.x_flag_tree_loop_vectorize)) |
976 | return 1; |
977 | |
978 | auto_vector_modes modes; |
979 | targetm.vectorize.autovectorize_vector_modes (&modes, true); |
980 | if (!modes.is_empty ()) |
981 | { |
982 | poly_uint64 vf = 0; |
983 | for (unsigned int i = 0; i < modes.length (); ++i) |
984 | /* The returned modes use the smallest element size (and thus |
985 | the largest nunits) for the vectorization approach that they |
986 | represent. */ |
987 | vf = ordered_max (vf, GET_MODE_NUNITS (modes[i])); |
988 | return vf; |
989 | } |
990 | |
991 | machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode(scalar_int_mode ((scalar_int_mode::from_int) E_QImode))); |
992 | if (GET_MODE_CLASS (vqimode)((enum mode_class) mode_class[vqimode]) == MODE_VECTOR_INT) |
993 | return GET_MODE_NUNITS (vqimode); |
994 | |
995 | return 1; |
996 | } |
997 | |
998 | /* Return maximum SIMT width if offloading may target SIMT hardware. */ |
999 | |
1000 | int |
1001 | omp_max_simt_vf (void) |
1002 | { |
1003 | if (!optimizeglobal_options.x_optimize) |
1004 | return 0; |
1005 | if (ENABLE_OFFLOADING0) |
1006 | for (const char *c = getenv ("OFFLOAD_TARGET_NAMES"); c;) |
1007 | { |
1008 | if (startswith (c, "nvptx")) |
1009 | return 32; |
1010 | else if ((c = strchr (c, ':'))) |
1011 | c++; |
1012 | } |
1013 | return 0; |
1014 | } |
1015 | |
1016 | /* Store the construct selectors as tree codes from last to first, |
1017 | return their number. */ |
1018 | |
1019 | int |
1020 | omp_constructor_traits_to_codes (tree ctx, enum tree_code *constructs) |
1021 | { |
1022 | int nconstructs = list_length (ctx); |
1023 | int i = nconstructs - 1; |
1024 | for (tree t2 = ctx; t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1024, __FUNCTION__))->common.chain), i--) |
1025 | { |
1026 | const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t2))((const char *) (tree_check ((((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1026, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1026, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
1027 | if (!strcmp (sel, "target")) |
1028 | constructs[i] = OMP_TARGET; |
1029 | else if (!strcmp (sel, "teams")) |
1030 | constructs[i] = OMP_TEAMS; |
1031 | else if (!strcmp (sel, "parallel")) |
1032 | constructs[i] = OMP_PARALLEL; |
1033 | else if (!strcmp (sel, "for") || !strcmp (sel, "do")) |
1034 | constructs[i] = OMP_FOR; |
1035 | else if (!strcmp (sel, "simd")) |
1036 | constructs[i] = OMP_SIMD; |
1037 | else |
1038 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1038, __FUNCTION__)); |
1039 | } |
1040 | gcc_assert (i == -1)((void)(!(i == -1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1040, __FUNCTION__), 0 : 0)); |
1041 | return nconstructs; |
1042 | } |
1043 | |
1044 | /* Return true if PROP is possibly present in one of the offloading target's |
1045 | OpenMP contexts. The format of PROPS string is always offloading target's |
1046 | name terminated by '\0', followed by properties for that offloading |
1047 | target separated by '\0' and terminated by another '\0'. The strings |
1048 | are created from omp-device-properties installed files of all configured |
1049 | offloading targets. */ |
1050 | |
1051 | static bool |
1052 | omp_offload_device_kind_arch_isa (const char *props, const char *prop) |
1053 | { |
1054 | const char *names = getenv ("OFFLOAD_TARGET_NAMES"); |
1055 | if (names == NULLnullptr || *names == '\0') |
1056 | return false; |
1057 | while (*props != '\0') |
1058 | { |
1059 | size_t name_len = strlen (props); |
1060 | bool matches = false; |
1061 | for (const char *c = names; c; ) |
1062 | { |
1063 | if (strncmp (props, c, name_len) == 0 |
1064 | && (c[name_len] == '\0' |
1065 | || c[name_len] == ':' |
1066 | || c[name_len] == '=')) |
1067 | { |
1068 | matches = true; |
1069 | break; |
1070 | } |
1071 | else if ((c = strchr (c, ':'))) |
1072 | c++; |
1073 | } |
1074 | props = props + name_len + 1; |
1075 | while (*props != '\0') |
1076 | { |
1077 | if (matches && strcmp (props, prop) == 0) |
1078 | return true; |
1079 | props = strchr (props, '\0') + 1; |
1080 | } |
1081 | props++; |
1082 | } |
1083 | return false; |
1084 | } |
1085 | |
1086 | /* Return true if the current code location is or might be offloaded. |
1087 | Return true in declare target functions, or when nested in a target |
1088 | region or when unsure, return false otherwise. */ |
1089 | |
1090 | static bool |
1091 | omp_maybe_offloaded (void) |
1092 | { |
1093 | if (!ENABLE_OFFLOADING0) |
1094 | return false; |
1095 | const char *names = getenv ("OFFLOAD_TARGET_NAMES"); |
1096 | if (names == NULLnullptr || *names == '\0') |
1097 | return false; |
1098 | |
1099 | if (symtab->state == PARSING) |
1100 | /* Maybe. */ |
1101 | return true; |
1102 | if (cfun(cfun + 0) && cfun(cfun + 0)->after_inlining) |
1103 | return false; |
1104 | if (current_function_decl |
1105 | && lookup_attribute ("omp declare target", |
1106 | DECL_ATTRIBUTES (current_function_decl)((contains_struct_check ((current_function_decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1106, __FUNCTION__))->decl_common.attributes))) |
1107 | return true; |
1108 | if (cfun(cfun + 0) && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) == 0) |
1109 | { |
1110 | enum tree_code construct = OMP_TARGET; |
1111 | if (omp_construct_selector_matches (&construct, 1, NULLnullptr)) |
1112 | return true; |
1113 | } |
1114 | return false; |
1115 | } |
1116 | |
1117 | |
1118 | /* Diagnose errors in an OpenMP context selector, return CTX if |
1119 | it is correct or error_mark_node otherwise. */ |
1120 | |
1121 | tree |
1122 | omp_check_context_selector (location_t loc, tree ctx) |
1123 | { |
1124 | /* Each trait-set-selector-name can only be specified once. |
1125 | There are just 4 set names. */ |
1126 | for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1126, __FUNCTION__))->common.chain)) |
1127 | for (tree t2 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1127, __FUNCTION__))->common.chain); t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1127, __FUNCTION__))->common.chain)) |
1128 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1128, __FUNCTION__, (TREE_LIST)))->list.purpose) == TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1128, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1129 | { |
1130 | error_at (loc, "selector set %qs specified more than once", |
1131 | IDENTIFIER_POINTER (TREE_PURPOSE (t1))((const char *) (tree_check ((((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1131, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1131, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); |
1132 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
1133 | } |
1134 | for (tree t = ctx; t; t = TREE_CHAIN (t)((contains_struct_check ((t), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1134, __FUNCTION__))->common.chain)) |
1135 | { |
1136 | /* Each trait-selector-name can only be specified once. */ |
1137 | if (list_length (TREE_VALUE (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1137, __FUNCTION__, (TREE_LIST)))->list.value)) < 5) |
1138 | { |
1139 | for (tree t1 = TREE_VALUE (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1139, __FUNCTION__, (TREE_LIST)))->list.value); t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1139, __FUNCTION__))->common.chain)) |
1140 | for (tree t2 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1140, __FUNCTION__))->common.chain); t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1140, __FUNCTION__))->common.chain)) |
1141 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1141, __FUNCTION__, (TREE_LIST)))->list.purpose) == TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1141, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1142 | { |
1143 | error_at (loc, |
1144 | "selector %qs specified more than once in set %qs", |
1145 | IDENTIFIER_POINTER (TREE_PURPOSE (t1))((const char *) (tree_check ((((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1145, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1145, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1146 | IDENTIFIER_POINTER (TREE_PURPOSE (t))((const char *) (tree_check ((((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1146, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1146, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); |
1147 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
1148 | } |
1149 | } |
1150 | else |
1151 | { |
1152 | hash_set<tree> pset; |
1153 | for (tree t1 = TREE_VALUE (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1153, __FUNCTION__, (TREE_LIST)))->list.value); t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1153, __FUNCTION__))->common.chain)) |
1154 | if (pset.add (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1154, __FUNCTION__, (TREE_LIST)))->list.purpose))) |
1155 | { |
1156 | error_at (loc, |
1157 | "selector %qs specified more than once in set %qs", |
1158 | IDENTIFIER_POINTER (TREE_PURPOSE (t1))((const char *) (tree_check ((((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1158, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1158, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1159 | IDENTIFIER_POINTER (TREE_PURPOSE (t))((const char *) (tree_check ((((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1159, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1159, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )); |
1160 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
1161 | } |
1162 | } |
1163 | |
1164 | static const char *const kind[] = { |
1165 | "host", "nohost", "cpu", "gpu", "fpga", "any", NULLnullptr }; |
1166 | static const char *const vendor[] = { |
1167 | "amd", "arm", "bsc", "cray", "fujitsu", "gnu", "ibm", "intel", |
1168 | "llvm", "nvidia", "pgi", "ti", "unknown", NULLnullptr }; |
1169 | static const char *const extension[] = { NULLnullptr }; |
1170 | static const char *const atomic_default_mem_order[] = { |
1171 | "seq_cst", "relaxed", "acq_rel", NULLnullptr }; |
1172 | struct known_properties { const char *set; const char *selector; |
1173 | const char *const *props; }; |
1174 | known_properties props[] = { |
1175 | { "device", "kind", kind }, |
1176 | { "implementation", "vendor", vendor }, |
1177 | { "implementation", "extension", extension }, |
1178 | { "implementation", "atomic_default_mem_order", |
1179 | atomic_default_mem_order } }; |
1180 | for (tree t1 = TREE_VALUE (t)((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1180, __FUNCTION__, (TREE_LIST)))->list.value); t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1180, __FUNCTION__))->common.chain)) |
1181 | for (unsigned i = 0; i < ARRAY_SIZE (props)(sizeof (props) / sizeof ((props)[0])); i++) |
1182 | if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1))((const char *) (tree_check ((((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1182, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1182, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1183 | props[i].selector) |
1184 | && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t))((const char *) (tree_check ((((tree_check ((t), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1184, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1184, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1185 | props[i].set)) |
1186 | for (tree t2 = TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1186, __FUNCTION__, (TREE_LIST)))->list.value); t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1186, __FUNCTION__))->common.chain)) |
1187 | for (unsigned j = 0; ; j++) |
1188 | { |
1189 | if (props[i].props[j] == NULLnullptr) |
1190 | { |
1191 | if (TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1191, __FUNCTION__, (TREE_LIST)))->list.purpose) |
1192 | && !strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2))((const char *) (tree_check ((((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1192, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1192, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1193 | " score")) |
1194 | break; |
1195 | if (props[i].props == atomic_default_mem_order) |
1196 | { |
1197 | error_at (loc, |
1198 | "incorrect property %qs of %qs selector", |
1199 | IDENTIFIER_POINTER (TREE_PURPOSE (t2))((const char *) (tree_check ((((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1199, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1199, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1200 | "atomic_default_mem_order"); |
1201 | return error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
1202 | } |
1203 | else if (TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1203, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1204 | warning_at (loc, 0, |
1205 | "unknown property %qs of %qs selector", |
1206 | IDENTIFIER_POINTER (TREE_PURPOSE (t2))((const char *) (tree_check ((((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1206, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1206, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1207 | props[i].selector); |
1208 | else |
1209 | warning_at (loc, 0, |
1210 | "unknown property %qE of %qs selector", |
1211 | TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1211, __FUNCTION__, (TREE_LIST)))->list.value), props[i].selector); |
1212 | break; |
1213 | } |
1214 | else if (TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1214, __FUNCTION__, (TREE_LIST)))->list.purpose) == NULL_TREE(tree) nullptr) |
1215 | { |
1216 | const char *str = TREE_STRING_POINTER (TREE_VALUE (t2))((const char *)((tree_check ((((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1216, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1216, __FUNCTION__, (STRING_CST)))->string.str)); |
1217 | if (!strcmp (str, props[i].props[j]) |
1218 | && ((size_t) TREE_STRING_LENGTH (TREE_VALUE (t2))((tree_check ((((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1218, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1218, __FUNCTION__, (STRING_CST)))->string.length) |
1219 | == strlen (str) + (lang_GNU_Fortran () ? 0 : 1))) |
1220 | break; |
1221 | } |
1222 | else if (!strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t2))((const char *) (tree_check ((((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1222, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1222, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1223 | props[i].props[j])) |
1224 | break; |
1225 | } |
1226 | } |
1227 | return ctx; |
1228 | } |
1229 | |
1230 | |
1231 | /* Register VARIANT as variant of some base function marked with |
1232 | #pragma omp declare variant. CONSTRUCT is corresponding construct |
1233 | selector set. */ |
1234 | |
1235 | void |
1236 | omp_mark_declare_variant (location_t loc, tree variant, tree construct) |
1237 | { |
1238 | tree attr = lookup_attribute ("omp declare variant variant", |
1239 | DECL_ATTRIBUTES (variant)((contains_struct_check ((variant), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1239, __FUNCTION__))->decl_common.attributes)); |
1240 | if (attr == NULL_TREE(tree) nullptr) |
1241 | { |
1242 | attr = tree_cons (get_identifier ("omp declare variant variant")(__builtin_constant_p ("omp declare variant variant") ? get_identifier_with_length (("omp declare variant variant"), strlen ("omp declare variant variant" )) : get_identifier ("omp declare variant variant")), |
1243 | unshare_expr (construct), |
1244 | DECL_ATTRIBUTES (variant)((contains_struct_check ((variant), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1244, __FUNCTION__))->decl_common.attributes)); |
1245 | DECL_ATTRIBUTES (variant)((contains_struct_check ((variant), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1245, __FUNCTION__))->decl_common.attributes) = attr; |
1246 | return; |
1247 | } |
1248 | if ((TREE_VALUE (attr)((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1248, __FUNCTION__, (TREE_LIST)))->list.value) != NULL_TREE(tree) nullptr) != (construct != NULL_TREE(tree) nullptr) |
1249 | || (construct != NULL_TREE(tree) nullptr |
1250 | && omp_context_selector_set_compare ("construct", TREE_VALUE (attr)((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1250, __FUNCTION__, (TREE_LIST)))->list.value), |
1251 | construct))) |
1252 | error_at (loc, "%qD used as a variant with incompatible %<construct%> " |
1253 | "selector sets", variant); |
1254 | } |
1255 | |
1256 | |
1257 | /* Return a name from PROP, a property in selectors accepting |
1258 | name lists. */ |
1259 | |
1260 | static const char * |
1261 | omp_context_name_list_prop (tree prop) |
1262 | { |
1263 | if (TREE_PURPOSE (prop)((tree_check ((prop), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1263, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1264 | return IDENTIFIER_POINTER (TREE_PURPOSE (prop))((const char *) (tree_check ((((tree_check ((prop), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1264, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1264, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
1265 | else |
1266 | { |
1267 | const char *ret = TREE_STRING_POINTER (TREE_VALUE (prop))((const char *)((tree_check ((((tree_check ((prop), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1267, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1267, __FUNCTION__, (STRING_CST)))->string.str)); |
1268 | if ((size_t) TREE_STRING_LENGTH (TREE_VALUE (prop))((tree_check ((((tree_check ((prop), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1268, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1268, __FUNCTION__, (STRING_CST)))->string.length) |
1269 | == strlen (ret) + (lang_GNU_Fortran () ? 0 : 1)) |
1270 | return ret; |
1271 | return NULLnullptr; |
1272 | } |
1273 | } |
1274 | |
1275 | /* Return 1 if context selector matches the current OpenMP context, 0 |
1276 | if it does not and -1 if it is unknown and need to be determined later. |
1277 | Some properties can be checked right away during parsing (this routine), |
1278 | others need to wait until the whole TU is parsed, others need to wait until |
1279 | IPA, others until vectorization. */ |
1280 | |
1281 | int |
1282 | omp_context_selector_matches (tree ctx) |
1283 | { |
1284 | int ret = 1; |
1285 | for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1285, __FUNCTION__))->common.chain)) |
1286 | { |
1287 | char set = IDENTIFIER_POINTER (TREE_PURPOSE (t1))((const char *) (tree_check ((((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1287, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1287, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str )[0]; |
1288 | if (set == 'c') |
1289 | { |
1290 | /* For now, ignore the construct set. While something can be |
1291 | determined already during parsing, we don't know until end of TU |
1292 | whether additional constructs aren't added through declare variant |
1293 | unless "omp declare variant variant" attribute exists already |
1294 | (so in most of the cases), and we'd need to maintain set of |
1295 | surrounding OpenMP constructs, which is better handled during |
1296 | gimplification. */ |
1297 | if (symtab->state == PARSING) |
1298 | { |
1299 | ret = -1; |
1300 | continue; |
1301 | } |
1302 | |
1303 | enum tree_code constructs[5]; |
1304 | int nconstructs |
1305 | = omp_constructor_traits_to_codes (TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1305, __FUNCTION__, (TREE_LIST)))->list.value), constructs); |
1306 | |
1307 | if (cfun(cfun + 0) && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) != 0) |
1308 | { |
1309 | if (!cfun(cfun + 0)->after_inlining) |
1310 | { |
1311 | ret = -1; |
1312 | continue; |
1313 | } |
1314 | int i; |
1315 | for (i = 0; i < nconstructs; ++i) |
1316 | if (constructs[i] == OMP_SIMD) |
1317 | break; |
1318 | if (i < nconstructs) |
1319 | { |
1320 | ret = -1; |
1321 | continue; |
1322 | } |
1323 | /* If there is no simd, assume it is ok after IPA, |
1324 | constructs should have been checked before. */ |
1325 | continue; |
1326 | } |
1327 | |
1328 | int r = omp_construct_selector_matches (constructs, nconstructs, |
1329 | NULLnullptr); |
1330 | if (r == 0) |
1331 | return 0; |
1332 | if (r == -1) |
1333 | ret = -1; |
1334 | continue; |
1335 | } |
1336 | for (tree t2 = TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1336, __FUNCTION__, (TREE_LIST)))->list.value); t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1336, __FUNCTION__))->common.chain)) |
1337 | { |
1338 | const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t2))((const char *) (tree_check ((((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1338, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1338, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
1339 | switch (*sel) |
1340 | { |
1341 | case 'v': |
1342 | if (set == 'i' && !strcmp (sel, "vendor")) |
1343 | for (tree t3 = TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1343, __FUNCTION__, (TREE_LIST)))->list.value); t3; t3 = TREE_CHAIN (t3)((contains_struct_check ((t3), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1343, __FUNCTION__))->common.chain)) |
1344 | { |
1345 | const char *prop = omp_context_name_list_prop (t3); |
1346 | if (prop == NULLnullptr) |
1347 | return 0; |
1348 | if ((!strcmp (prop, " score") && TREE_PURPOSE (t3)((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1348, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1349 | || !strcmp (prop, "gnu")) |
1350 | continue; |
1351 | return 0; |
1352 | } |
1353 | break; |
1354 | case 'e': |
1355 | if (set == 'i' && !strcmp (sel, "extension")) |
1356 | /* We don't support any extensions right now. */ |
1357 | return 0; |
1358 | break; |
1359 | case 'a': |
1360 | if (set == 'i' && !strcmp (sel, "atomic_default_mem_order")) |
1361 | { |
1362 | if (cfun(cfun + 0) && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) != 0) |
1363 | break; |
1364 | |
1365 | enum omp_memory_order omo |
1366 | = ((enum omp_memory_order) |
1367 | (omp_requires_mask |
1368 | & OMP_REQUIRES_ATOMIC_DEFAULT_MEM_ORDER)); |
1369 | if (omo == OMP_MEMORY_ORDER_UNSPECIFIED) |
1370 | { |
1371 | /* We don't know yet, until end of TU. */ |
1372 | if (symtab->state == PARSING) |
1373 | { |
1374 | ret = -1; |
1375 | break; |
1376 | } |
1377 | else |
1378 | omo = OMP_MEMORY_ORDER_RELAXED; |
1379 | } |
1380 | tree t3 = TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1380, __FUNCTION__, (TREE_LIST)))->list.value); |
1381 | const char *prop = IDENTIFIER_POINTER (TREE_PURPOSE (t3))((const char *) (tree_check ((((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1381, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1381, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
1382 | if (!strcmp (prop, " score")) |
1383 | { |
1384 | t3 = TREE_CHAIN (t3)((contains_struct_check ((t3), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1384, __FUNCTION__))->common.chain); |
1385 | prop = IDENTIFIER_POINTER (TREE_PURPOSE (t3))((const char *) (tree_check ((((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1385, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1385, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
1386 | } |
1387 | if (!strcmp (prop, "relaxed") |
1388 | && omo != OMP_MEMORY_ORDER_RELAXED) |
1389 | return 0; |
1390 | else if (!strcmp (prop, "seq_cst") |
1391 | && omo != OMP_MEMORY_ORDER_SEQ_CST) |
1392 | return 0; |
1393 | else if (!strcmp (prop, "acq_rel") |
1394 | && omo != OMP_MEMORY_ORDER_ACQ_REL) |
1395 | return 0; |
1396 | } |
1397 | if (set == 'd' && !strcmp (sel, "arch")) |
1398 | for (tree t3 = TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1398, __FUNCTION__, (TREE_LIST)))->list.value); t3; t3 = TREE_CHAIN (t3)((contains_struct_check ((t3), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1398, __FUNCTION__))->common.chain)) |
1399 | { |
1400 | const char *arch = omp_context_name_list_prop (t3); |
1401 | if (arch == NULLnullptr) |
1402 | return 0; |
1403 | int r = 0; |
1404 | if (targetm.omp.device_kind_arch_isa != NULLnullptr) |
1405 | r = targetm.omp.device_kind_arch_isa (omp_device_arch, |
1406 | arch); |
1407 | if (r == 0 || (r == -1 && symtab->state != PARSING)) |
1408 | { |
1409 | /* If we are or might be in a target region or |
1410 | declare target function, need to take into account |
1411 | also offloading values. */ |
1412 | if (!omp_maybe_offloaded ()) |
1413 | return 0; |
1414 | if (ENABLE_OFFLOADING0) |
1415 | { |
1416 | const char *arches = omp_offload_device_arch; |
1417 | if (omp_offload_device_kind_arch_isa (arches, |
1418 | arch)) |
1419 | { |
1420 | ret = -1; |
1421 | continue; |
1422 | } |
1423 | } |
1424 | return 0; |
1425 | } |
1426 | else if (r == -1) |
1427 | ret = -1; |
1428 | /* If arch matches on the host, it still might not match |
1429 | in the offloading region. */ |
1430 | else if (omp_maybe_offloaded ()) |
1431 | ret = -1; |
1432 | } |
1433 | break; |
1434 | case 'u': |
1435 | if (set == 'i' && !strcmp (sel, "unified_address")) |
1436 | { |
1437 | if (cfun(cfun + 0) && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) != 0) |
1438 | break; |
1439 | |
1440 | if ((omp_requires_mask & OMP_REQUIRES_UNIFIED_ADDRESS) == 0) |
1441 | { |
1442 | if (symtab->state == PARSING) |
1443 | ret = -1; |
1444 | else |
1445 | return 0; |
1446 | } |
1447 | break; |
1448 | } |
1449 | if (set == 'i' && !strcmp (sel, "unified_shared_memory")) |
1450 | { |
1451 | if (cfun(cfun + 0) && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) != 0) |
1452 | break; |
1453 | |
1454 | if ((omp_requires_mask |
1455 | & OMP_REQUIRES_UNIFIED_SHARED_MEMORY) == 0) |
1456 | { |
1457 | if (symtab->state == PARSING) |
1458 | ret = -1; |
1459 | else |
1460 | return 0; |
1461 | } |
1462 | break; |
1463 | } |
1464 | break; |
1465 | case 'd': |
1466 | if (set == 'i' && !strcmp (sel, "dynamic_allocators")) |
1467 | { |
1468 | if (cfun(cfun + 0) && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) != 0) |
1469 | break; |
1470 | |
1471 | if ((omp_requires_mask |
1472 | & OMP_REQUIRES_DYNAMIC_ALLOCATORS) == 0) |
1473 | { |
1474 | if (symtab->state == PARSING) |
1475 | ret = -1; |
1476 | else |
1477 | return 0; |
1478 | } |
1479 | break; |
1480 | } |
1481 | break; |
1482 | case 'r': |
1483 | if (set == 'i' && !strcmp (sel, "reverse_offload")) |
1484 | { |
1485 | if (cfun(cfun + 0) && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) != 0) |
1486 | break; |
1487 | |
1488 | if ((omp_requires_mask & OMP_REQUIRES_REVERSE_OFFLOAD) == 0) |
1489 | { |
1490 | if (symtab->state == PARSING) |
1491 | ret = -1; |
1492 | else |
1493 | return 0; |
1494 | } |
1495 | break; |
1496 | } |
1497 | break; |
1498 | case 'k': |
1499 | if (set == 'd' && !strcmp (sel, "kind")) |
1500 | for (tree t3 = TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1500, __FUNCTION__, (TREE_LIST)))->list.value); t3; t3 = TREE_CHAIN (t3)((contains_struct_check ((t3), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1500, __FUNCTION__))->common.chain)) |
1501 | { |
1502 | const char *prop = omp_context_name_list_prop (t3); |
1503 | if (prop == NULLnullptr) |
1504 | return 0; |
1505 | if (!strcmp (prop, "any")) |
1506 | continue; |
1507 | if (!strcmp (prop, "host")) |
1508 | { |
1509 | #ifdef ACCEL_COMPILER |
1510 | return 0; |
1511 | #else |
1512 | if (omp_maybe_offloaded ()) |
1513 | ret = -1; |
1514 | continue; |
1515 | #endif |
1516 | } |
1517 | if (!strcmp (prop, "nohost")) |
1518 | { |
1519 | #ifndef ACCEL_COMPILER |
1520 | if (omp_maybe_offloaded ()) |
1521 | ret = -1; |
1522 | else |
1523 | return 0; |
1524 | #endif |
1525 | continue; |
1526 | } |
1527 | int r = 0; |
1528 | if (targetm.omp.device_kind_arch_isa != NULLnullptr) |
1529 | r = targetm.omp.device_kind_arch_isa (omp_device_kind, |
1530 | prop); |
1531 | else |
1532 | r = strcmp (prop, "cpu") == 0; |
1533 | if (r == 0 || (r == -1 && symtab->state != PARSING)) |
1534 | { |
1535 | /* If we are or might be in a target region or |
1536 | declare target function, need to take into account |
1537 | also offloading values. */ |
1538 | if (!omp_maybe_offloaded ()) |
1539 | return 0; |
1540 | if (ENABLE_OFFLOADING0) |
1541 | { |
1542 | const char *kinds = omp_offload_device_kind; |
1543 | if (omp_offload_device_kind_arch_isa (kinds, prop)) |
1544 | { |
1545 | ret = -1; |
1546 | continue; |
1547 | } |
1548 | } |
1549 | return 0; |
1550 | } |
1551 | else if (r == -1) |
1552 | ret = -1; |
1553 | /* If kind matches on the host, it still might not match |
1554 | in the offloading region. */ |
1555 | else if (omp_maybe_offloaded ()) |
1556 | ret = -1; |
1557 | } |
1558 | break; |
1559 | case 'i': |
1560 | if (set == 'd' && !strcmp (sel, "isa")) |
1561 | for (tree t3 = TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1561, __FUNCTION__, (TREE_LIST)))->list.value); t3; t3 = TREE_CHAIN (t3)((contains_struct_check ((t3), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1561, __FUNCTION__))->common.chain)) |
1562 | { |
1563 | const char *isa = omp_context_name_list_prop (t3); |
1564 | if (isa == NULLnullptr) |
1565 | return 0; |
1566 | int r = 0; |
1567 | if (targetm.omp.device_kind_arch_isa != NULLnullptr) |
1568 | r = targetm.omp.device_kind_arch_isa (omp_device_isa, |
1569 | isa); |
1570 | if (r == 0 || (r == -1 && symtab->state != PARSING)) |
1571 | { |
1572 | /* If isa is valid on the target, but not in the |
1573 | current function and current function has |
1574 | #pragma omp declare simd on it, some simd clones |
1575 | might have the isa added later on. */ |
1576 | if (r == -1 |
1577 | && targetm.simd_clone.compute_vecsize_and_simdlen |
1578 | && (cfun(cfun + 0) == NULLnullptr || !cfun(cfun + 0)->after_inlining)) |
1579 | { |
1580 | tree attrs |
1581 | = DECL_ATTRIBUTES (current_function_decl)((contains_struct_check ((current_function_decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1581, __FUNCTION__))->decl_common.attributes); |
1582 | if (lookup_attribute ("omp declare simd", attrs)) |
1583 | { |
1584 | ret = -1; |
1585 | continue; |
1586 | } |
1587 | } |
1588 | /* If we are or might be in a target region or |
1589 | declare target function, need to take into account |
1590 | also offloading values. */ |
1591 | if (!omp_maybe_offloaded ()) |
1592 | return 0; |
1593 | if (ENABLE_OFFLOADING0) |
1594 | { |
1595 | const char *isas = omp_offload_device_isa; |
1596 | if (omp_offload_device_kind_arch_isa (isas, isa)) |
1597 | { |
1598 | ret = -1; |
1599 | continue; |
1600 | } |
1601 | } |
1602 | return 0; |
1603 | } |
1604 | else if (r == -1) |
1605 | ret = -1; |
1606 | /* If isa matches on the host, it still might not match |
1607 | in the offloading region. */ |
1608 | else if (omp_maybe_offloaded ()) |
1609 | ret = -1; |
1610 | } |
1611 | break; |
1612 | case 'c': |
1613 | if (set == 'u' && !strcmp (sel, "condition")) |
1614 | for (tree t3 = TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1614, __FUNCTION__, (TREE_LIST)))->list.value); t3; t3 = TREE_CHAIN (t3)((contains_struct_check ((t3), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1614, __FUNCTION__))->common.chain)) |
1615 | if (TREE_PURPOSE (t3)((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1615, __FUNCTION__, (TREE_LIST)))->list.purpose) == NULL_TREE(tree) nullptr) |
1616 | { |
1617 | if (integer_zerop (TREE_VALUE (t3)((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1617, __FUNCTION__, (TREE_LIST)))->list.value))) |
1618 | return 0; |
1619 | if (integer_nonzerop (TREE_VALUE (t3)((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1619, __FUNCTION__, (TREE_LIST)))->list.value))) |
1620 | break; |
1621 | ret = -1; |
1622 | } |
1623 | break; |
1624 | default: |
1625 | break; |
1626 | } |
1627 | } |
1628 | } |
1629 | return ret; |
1630 | } |
1631 | |
1632 | /* Compare construct={simd} CLAUSES1 with CLAUSES2, return 0/-1/1/2 as |
1633 | in omp_context_selector_set_compare. */ |
1634 | |
1635 | static int |
1636 | omp_construct_simd_compare (tree clauses1, tree clauses2) |
1637 | { |
1638 | if (clauses1 == NULL_TREE(tree) nullptr) |
1639 | return clauses2 == NULL_TREE(tree) nullptr ? 0 : -1; |
1640 | if (clauses2 == NULL_TREE(tree) nullptr) |
1641 | return 1; |
1642 | |
1643 | int r = 0; |
1644 | struct declare_variant_simd_data { |
1645 | bool inbranch, notinbranch; |
1646 | tree simdlen; |
1647 | auto_vec<tree,16> data_sharing; |
1648 | auto_vec<tree,16> aligned; |
1649 | declare_variant_simd_data () |
1650 | : inbranch(false), notinbranch(false), simdlen(NULL_TREE(tree) nullptr) {} |
1651 | } data[2]; |
1652 | unsigned int i; |
1653 | for (i = 0; i < 2; i++) |
1654 | for (tree c = i ? clauses2 : clauses1; c; c = OMP_CLAUSE_CHAIN (c)((contains_struct_check (((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1654, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1654, __FUNCTION__))->common.chain)) |
1655 | { |
1656 | vec<tree> *v; |
1657 | switch (OMP_CLAUSE_CODE (c)((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1657, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code) |
1658 | { |
1659 | case OMP_CLAUSE_INBRANCH: |
1660 | data[i].inbranch = true; |
1661 | continue; |
1662 | case OMP_CLAUSE_NOTINBRANCH: |
1663 | data[i].notinbranch = true; |
1664 | continue; |
1665 | case OMP_CLAUSE_SIMDLEN: |
1666 | data[i].simdlen = OMP_CLAUSE_SIMDLEN_EXPR (c)(*(omp_clause_elt_check (((omp_clause_subcode_check ((c), (OMP_CLAUSE_SIMDLEN ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1666, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1666, __FUNCTION__))); |
1667 | continue; |
1668 | case OMP_CLAUSE_UNIFORM: |
1669 | case OMP_CLAUSE_LINEAR: |
1670 | v = &data[i].data_sharing; |
1671 | break; |
1672 | case OMP_CLAUSE_ALIGNED: |
1673 | v = &data[i].aligned; |
1674 | break; |
1675 | default: |
1676 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1676, __FUNCTION__)); |
1677 | } |
1678 | unsigned HOST_WIDE_INTlong argno = tree_to_uhwi (OMP_CLAUSE_DECL (c)(*(omp_clause_elt_check (((omp_clause_range_check (((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1678, __FUNCTION__, (OMP_CLAUSE)))), (OMP_CLAUSE_PRIVATE), ( OMP_CLAUSE__SCANTEMP_), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1678, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1678, __FUNCTION__)))); |
1679 | if (argno >= v->length ()) |
1680 | v->safe_grow_cleared (argno + 1, true); |
1681 | (*v)[argno] = c; |
1682 | } |
1683 | /* Here, r is used as a bitmask, 2 is set if CLAUSES1 has something |
1684 | CLAUSES2 doesn't, 1 is set if CLAUSES2 has something CLAUSES1 |
1685 | doesn't. Thus, r == 3 implies return value 2, r == 1 implies |
1686 | -1, r == 2 implies 1 and r == 0 implies 0. */ |
1687 | if (data[0].inbranch != data[1].inbranch) |
1688 | r |= data[0].inbranch ? 2 : 1; |
1689 | if (data[0].notinbranch != data[1].notinbranch) |
1690 | r |= data[0].notinbranch ? 2 : 1; |
1691 | if (!simple_cst_equal (data[0].simdlen, data[1].simdlen)) |
1692 | { |
1693 | if (data[0].simdlen && data[1].simdlen) |
1694 | return 2; |
1695 | r |= data[0].simdlen ? 2 : 1; |
1696 | } |
1697 | if (data[0].data_sharing.length () < data[1].data_sharing.length () |
1698 | || data[0].aligned.length () < data[1].aligned.length ()) |
1699 | r |= 1; |
1700 | tree c1, c2; |
1701 | FOR_EACH_VEC_ELT (data[0].data_sharing, i, c1)for (i = 0; (data[0].data_sharing).iterate ((i), &(c1)); ++ (i)) |
1702 | { |
1703 | c2 = (i < data[1].data_sharing.length () |
1704 | ? data[1].data_sharing[i] : NULL_TREE(tree) nullptr); |
1705 | if ((c1 == NULL_TREE(tree) nullptr) != (c2 == NULL_TREE(tree) nullptr)) |
1706 | { |
1707 | r |= c1 != NULL_TREE(tree) nullptr ? 2 : 1; |
1708 | continue; |
1709 | } |
1710 | if (c1 == NULL_TREE(tree) nullptr) |
1711 | continue; |
1712 | if (OMP_CLAUSE_CODE (c1)((tree_check ((c1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1712, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code != OMP_CLAUSE_CODE (c2)((tree_check ((c2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1712, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code) |
1713 | return 2; |
1714 | if (OMP_CLAUSE_CODE (c1)((tree_check ((c1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1714, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code != OMP_CLAUSE_LINEAR) |
1715 | continue; |
1716 | if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c1)(((omp_clause_subcode_check ((c1), (OMP_CLAUSE_LINEAR), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1716, __FUNCTION__)))->base.protected_flag) |
1717 | != OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c2)(((omp_clause_subcode_check ((c2), (OMP_CLAUSE_LINEAR), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1717, __FUNCTION__)))->base.protected_flag)) |
1718 | return 2; |
1719 | if (OMP_CLAUSE_LINEAR_KIND (c1)((omp_clause_subcode_check ((c1), (OMP_CLAUSE_LINEAR), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1719, __FUNCTION__))->omp_clause.subcode.linear_kind) != OMP_CLAUSE_LINEAR_KIND (c2)((omp_clause_subcode_check ((c2), (OMP_CLAUSE_LINEAR), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1719, __FUNCTION__))->omp_clause.subcode.linear_kind)) |
1720 | return 2; |
1721 | if (!simple_cst_equal (OMP_CLAUSE_LINEAR_STEP (c1)(*(omp_clause_elt_check (((omp_clause_subcode_check ((c1), (OMP_CLAUSE_LINEAR ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1721, __FUNCTION__))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1721, __FUNCTION__))), |
1722 | OMP_CLAUSE_LINEAR_STEP (c2)(*(omp_clause_elt_check (((omp_clause_subcode_check ((c2), (OMP_CLAUSE_LINEAR ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1722, __FUNCTION__))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1722, __FUNCTION__))))) |
1723 | return 2; |
1724 | } |
1725 | FOR_EACH_VEC_ELT (data[0].aligned, i, c1)for (i = 0; (data[0].aligned).iterate ((i), &(c1)); ++(i) ) |
1726 | { |
1727 | c2 = i < data[1].aligned.length () ? data[1].aligned[i] : NULL_TREE(tree) nullptr; |
1728 | if ((c1 == NULL_TREE(tree) nullptr) != (c2 == NULL_TREE(tree) nullptr)) |
1729 | { |
1730 | r |= c1 != NULL_TREE(tree) nullptr ? 2 : 1; |
1731 | continue; |
1732 | } |
1733 | if (c1 == NULL_TREE(tree) nullptr) |
1734 | continue; |
1735 | if (!simple_cst_equal (OMP_CLAUSE_ALIGNED_ALIGNMENT (c1)(*(omp_clause_elt_check (((omp_clause_subcode_check ((c1), (OMP_CLAUSE_ALIGNED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1735, __FUNCTION__))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1735, __FUNCTION__))), |
1736 | OMP_CLAUSE_ALIGNED_ALIGNMENT (c2)(*(omp_clause_elt_check (((omp_clause_subcode_check ((c2), (OMP_CLAUSE_ALIGNED ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1736, __FUNCTION__))), (1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1736, __FUNCTION__))))) |
1737 | return 2; |
1738 | } |
1739 | switch (r) |
1740 | { |
1741 | case 0: return 0; |
1742 | case 1: return -1; |
1743 | case 2: return 1; |
1744 | case 3: return 2; |
1745 | default: gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1745, __FUNCTION__)); |
1746 | } |
1747 | } |
1748 | |
1749 | /* Compare properties of selectors SEL from SET other than construct. |
1750 | Return 0/-1/1/2 as in omp_context_selector_set_compare. |
1751 | Unlike set names or selector names, properties can have duplicates. */ |
1752 | |
1753 | static int |
1754 | omp_context_selector_props_compare (const char *set, const char *sel, |
1755 | tree ctx1, tree ctx2) |
1756 | { |
1757 | int ret = 0; |
1758 | for (int pass = 0; pass < 2; pass++) |
1759 | for (tree t1 = pass ? ctx2 : ctx1; t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1759, __FUNCTION__))->common.chain)) |
1760 | { |
1761 | tree t2; |
1762 | for (t2 = pass ? ctx1 : ctx2; t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1762, __FUNCTION__))->common.chain)) |
1763 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1763, __FUNCTION__, (TREE_LIST)))->list.purpose) == TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1763, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1764 | { |
1765 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1765, __FUNCTION__, (TREE_LIST)))->list.purpose) == NULL_TREE(tree) nullptr) |
1766 | { |
1767 | if (set[0] == 'u' && strcmp (sel, "condition") == 0) |
1768 | { |
1769 | if (integer_zerop (TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1769, __FUNCTION__, (TREE_LIST)))->list.value)) |
1770 | != integer_zerop (TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1770, __FUNCTION__, (TREE_LIST)))->list.value))) |
1771 | return 2; |
1772 | break; |
1773 | } |
1774 | if (simple_cst_equal (TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1774, __FUNCTION__, (TREE_LIST)))->list.value), TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1774, __FUNCTION__, (TREE_LIST)))->list.value))) |
1775 | break; |
1776 | } |
1777 | else if (strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t1))((const char *) (tree_check ((((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1777, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1777, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), |
1778 | " score") == 0) |
1779 | { |
1780 | if (!simple_cst_equal (TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1780, __FUNCTION__, (TREE_LIST)))->list.value), TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1780, __FUNCTION__, (TREE_LIST)))->list.value))) |
1781 | return 2; |
1782 | break; |
1783 | } |
1784 | else |
1785 | break; |
1786 | } |
1787 | else if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1787, __FUNCTION__, (TREE_LIST)))->list.purpose) |
1788 | && TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1788, __FUNCTION__, (TREE_LIST)))->list.purpose) == NULL_TREE(tree) nullptr |
1789 | && TREE_CODE (TREE_VALUE (t2))((enum tree_code) (((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1789, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == STRING_CST) |
1790 | { |
1791 | const char *p1 = omp_context_name_list_prop (t1); |
1792 | const char *p2 = omp_context_name_list_prop (t2); |
1793 | if (p2 |
1794 | && strcmp (p1, p2) == 0 |
1795 | && strcmp (p1, " score")) |
1796 | break; |
1797 | } |
1798 | else if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1798, __FUNCTION__, (TREE_LIST)))->list.purpose) == NULL_TREE(tree) nullptr |
1799 | && TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1799, __FUNCTION__, (TREE_LIST)))->list.purpose) |
1800 | && TREE_CODE (TREE_VALUE (t1))((enum tree_code) (((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1800, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == STRING_CST) |
1801 | { |
1802 | const char *p1 = omp_context_name_list_prop (t1); |
1803 | const char *p2 = omp_context_name_list_prop (t2); |
1804 | if (p1 |
1805 | && strcmp (p1, p2) == 0 |
1806 | && strcmp (p1, " score")) |
1807 | break; |
1808 | } |
1809 | if (t2 == NULL_TREE(tree) nullptr) |
1810 | { |
1811 | int r = pass ? -1 : 1; |
1812 | if (ret && ret != r) |
1813 | return 2; |
1814 | else if (pass) |
1815 | return r; |
1816 | else |
1817 | { |
1818 | ret = r; |
1819 | break; |
1820 | } |
1821 | } |
1822 | } |
1823 | return ret; |
1824 | } |
1825 | |
1826 | /* Compare single context selector sets CTX1 and CTX2 with SET name. |
1827 | Return 0 if CTX1 is equal to CTX2, |
1828 | -1 if CTX1 is a strict subset of CTX2, |
1829 | 1 if CTX2 is a strict subset of CTX1, or |
1830 | 2 if neither context is a subset of another one. */ |
1831 | |
1832 | int |
1833 | omp_context_selector_set_compare (const char *set, tree ctx1, tree ctx2) |
1834 | { |
1835 | bool swapped = false; |
1836 | int ret = 0; |
1837 | int len1 = list_length (ctx1); |
1838 | int len2 = list_length (ctx2); |
1839 | int cnt = 0; |
1840 | if (len1 < len2) |
1841 | { |
1842 | swapped = true; |
1843 | std::swap (ctx1, ctx2); |
1844 | std::swap (len1, len2); |
1845 | } |
1846 | if (set[0] == 'c') |
1847 | { |
1848 | tree t1; |
1849 | tree t2 = ctx2; |
1850 | tree simd = get_identifier ("simd")(__builtin_constant_p ("simd") ? get_identifier_with_length ( ("simd"), strlen ("simd")) : get_identifier ("simd")); |
1851 | /* Handle construct set specially. In this case the order |
1852 | of the selector matters too. */ |
1853 | for (t1 = ctx1; t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1853, __FUNCTION__))->common.chain)) |
1854 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1854, __FUNCTION__, (TREE_LIST)))->list.purpose) == TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1854, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1855 | { |
1856 | int r = 0; |
1857 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1857, __FUNCTION__, (TREE_LIST)))->list.purpose) == simd) |
1858 | r = omp_construct_simd_compare (TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1858, __FUNCTION__, (TREE_LIST)))->list.value), |
1859 | TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1859, __FUNCTION__, (TREE_LIST)))->list.value)); |
1860 | if (r == 2 || (ret && r && (ret < 0) != (r < 0))) |
1861 | return 2; |
1862 | if (ret == 0) |
1863 | ret = r; |
1864 | t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1864, __FUNCTION__))->common.chain); |
1865 | if (t2 == NULL_TREE(tree) nullptr) |
1866 | { |
1867 | t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1867, __FUNCTION__))->common.chain); |
1868 | break; |
1869 | } |
1870 | } |
1871 | else if (ret < 0) |
1872 | return 2; |
1873 | else |
1874 | ret = 1; |
1875 | if (t2 != NULL_TREE(tree) nullptr) |
1876 | return 2; |
1877 | if (t1 != NULL_TREE(tree) nullptr) |
1878 | { |
1879 | if (ret < 0) |
1880 | return 2; |
1881 | ret = 1; |
1882 | } |
1883 | if (ret == 0) |
1884 | return 0; |
1885 | return swapped ? -ret : ret; |
1886 | } |
1887 | for (tree t1 = ctx1; t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1887, __FUNCTION__))->common.chain)) |
1888 | { |
1889 | tree t2; |
1890 | for (t2 = ctx2; t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1890, __FUNCTION__))->common.chain)) |
1891 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1891, __FUNCTION__, (TREE_LIST)))->list.purpose) == TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1891, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1892 | { |
1893 | const char *sel = IDENTIFIER_POINTER (TREE_PURPOSE (t1))((const char *) (tree_check ((((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1893, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1893, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
1894 | int r = omp_context_selector_props_compare (set, sel, |
1895 | TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1895, __FUNCTION__, (TREE_LIST)))->list.value), |
1896 | TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1896, __FUNCTION__, (TREE_LIST)))->list.value)); |
1897 | if (r == 2 || (ret && r && (ret < 0) != (r < 0))) |
1898 | return 2; |
1899 | if (ret == 0) |
1900 | ret = r; |
1901 | cnt++; |
1902 | break; |
1903 | } |
1904 | if (t2 == NULL_TREE(tree) nullptr) |
1905 | { |
1906 | if (ret == -1) |
1907 | return 2; |
1908 | ret = 1; |
1909 | } |
1910 | } |
1911 | if (cnt < len2) |
1912 | return 2; |
1913 | if (ret == 0) |
1914 | return 0; |
1915 | return swapped ? -ret : ret; |
1916 | } |
1917 | |
1918 | /* Compare whole context selector specification CTX1 and CTX2. |
1919 | Return 0 if CTX1 is equal to CTX2, |
1920 | -1 if CTX1 is a strict subset of CTX2, |
1921 | 1 if CTX2 is a strict subset of CTX1, or |
1922 | 2 if neither context is a subset of another one. */ |
1923 | |
1924 | static int |
1925 | omp_context_selector_compare (tree ctx1, tree ctx2) |
1926 | { |
1927 | bool swapped = false; |
1928 | int ret = 0; |
1929 | int len1 = list_length (ctx1); |
1930 | int len2 = list_length (ctx2); |
1931 | int cnt = 0; |
1932 | if (len1 < len2) |
1933 | { |
1934 | swapped = true; |
1935 | std::swap (ctx1, ctx2); |
1936 | std::swap (len1, len2); |
1937 | } |
1938 | for (tree t1 = ctx1; t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1938, __FUNCTION__))->common.chain)) |
1939 | { |
1940 | tree t2; |
1941 | for (t2 = ctx2; t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1941, __FUNCTION__))->common.chain)) |
1942 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1942, __FUNCTION__, (TREE_LIST)))->list.purpose) == TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1942, __FUNCTION__, (TREE_LIST)))->list.purpose)) |
1943 | { |
1944 | const char *set = IDENTIFIER_POINTER (TREE_PURPOSE (t1))((const char *) (tree_check ((((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1944, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1944, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ); |
1945 | int r = omp_context_selector_set_compare (set, TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1945, __FUNCTION__, (TREE_LIST)))->list.value), |
1946 | TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1946, __FUNCTION__, (TREE_LIST)))->list.value)); |
1947 | if (r == 2 || (ret && r && (ret < 0) != (r < 0))) |
1948 | return 2; |
1949 | if (ret == 0) |
1950 | ret = r; |
1951 | cnt++; |
1952 | break; |
1953 | } |
1954 | if (t2 == NULL_TREE(tree) nullptr) |
1955 | { |
1956 | if (ret == -1) |
1957 | return 2; |
1958 | ret = 1; |
1959 | } |
1960 | } |
1961 | if (cnt < len2) |
1962 | return 2; |
1963 | if (ret == 0) |
1964 | return 0; |
1965 | return swapped ? -ret : ret; |
1966 | } |
1967 | |
1968 | /* From context selector CTX, return trait-selector with name SEL in |
1969 | trait-selector-set with name SET if any, or NULL_TREE if not found. |
1970 | If SEL is NULL, return the list of trait-selectors in SET. */ |
1971 | |
1972 | tree |
1973 | omp_get_context_selector (tree ctx, const char *set, const char *sel) |
1974 | { |
1975 | tree setid = get_identifier (set)(__builtin_constant_p (set) ? get_identifier_with_length ((set ), strlen (set)) : get_identifier (set)); |
1976 | tree selid = sel ? get_identifier (sel)(__builtin_constant_p (sel) ? get_identifier_with_length ((sel ), strlen (sel)) : get_identifier (sel)) : NULL_TREE(tree) nullptr; |
1977 | for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1977, __FUNCTION__))->common.chain)) |
1978 | if (TREE_PURPOSE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1978, __FUNCTION__, (TREE_LIST)))->list.purpose) == setid) |
1979 | { |
1980 | if (sel == NULLnullptr) |
1981 | return TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1981, __FUNCTION__, (TREE_LIST)))->list.value); |
1982 | for (tree t2 = TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1982, __FUNCTION__, (TREE_LIST)))->list.value); t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1982, __FUNCTION__))->common.chain)) |
1983 | if (TREE_PURPOSE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 1983, __FUNCTION__, (TREE_LIST)))->list.purpose) == selid) |
1984 | return t2; |
1985 | } |
1986 | return NULL_TREE(tree) nullptr; |
1987 | } |
1988 | |
1989 | /* Compute *SCORE for context selector CTX. Return true if the score |
1990 | would be different depending on whether it is a declare simd clone or |
1991 | not. DECLARE_SIMD should be true for the case when it would be |
1992 | a declare simd clone. */ |
1993 | |
1994 | static bool |
1995 | omp_context_compute_score (tree ctx, widest_int *score, bool declare_simd) |
1996 | { |
1997 | tree construct = omp_get_context_selector (ctx, "construct", NULLnullptr); |
1998 | bool has_kind = omp_get_context_selector (ctx, "device", "kind"); |
1999 | bool has_arch = omp_get_context_selector (ctx, "device", "arch"); |
2000 | bool has_isa = omp_get_context_selector (ctx, "device", "isa"); |
2001 | bool ret = false; |
2002 | *score = 1; |
2003 | for (tree t1 = ctx; t1; t1 = TREE_CHAIN (t1)((contains_struct_check ((t1), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2003, __FUNCTION__))->common.chain)) |
2004 | if (TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2004, __FUNCTION__, (TREE_LIST)))->list.value) != construct) |
2005 | for (tree t2 = TREE_VALUE (t1)((tree_check ((t1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2005, __FUNCTION__, (TREE_LIST)))->list.value); t2; t2 = TREE_CHAIN (t2)((contains_struct_check ((t2), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2005, __FUNCTION__))->common.chain)) |
2006 | if (tree t3 = TREE_VALUE (t2)((tree_check ((t2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2006, __FUNCTION__, (TREE_LIST)))->list.value)) |
2007 | if (TREE_PURPOSE (t3)((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2007, __FUNCTION__, (TREE_LIST)))->list.purpose) |
2008 | && strcmp (IDENTIFIER_POINTER (TREE_PURPOSE (t3))((const char *) (tree_check ((((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2008, __FUNCTION__, (TREE_LIST)))->list.purpose)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2008, __FUNCTION__, (IDENTIFIER_NODE)))->identifier.id.str ), " score") == 0 |
2009 | && TREE_CODE (TREE_VALUE (t3))((enum tree_code) (((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2009, __FUNCTION__, (TREE_LIST)))->list.value))->base .code) == INTEGER_CST) |
2010 | *score += wi::to_widest (TREE_VALUE (t3)((tree_check ((t3), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2010, __FUNCTION__, (TREE_LIST)))->list.value)); |
2011 | if (construct || has_kind || has_arch || has_isa) |
2012 | { |
2013 | int scores[12]; |
2014 | enum tree_code constructs[5]; |
2015 | int nconstructs = 0; |
2016 | if (construct) |
2017 | nconstructs = omp_constructor_traits_to_codes (construct, constructs); |
2018 | if (omp_construct_selector_matches (constructs, nconstructs, scores) |
2019 | == 2) |
2020 | ret = true; |
2021 | int b = declare_simd ? nconstructs + 1 : 0; |
2022 | if (scores[b + nconstructs] + 4U < score->get_precision ()) |
2023 | { |
2024 | for (int n = 0; n < nconstructs; ++n) |
2025 | { |
2026 | if (scores[b + n] < 0) |
2027 | { |
2028 | *score = -1; |
2029 | return ret; |
2030 | } |
2031 | *score += wi::shifted_mask <widest_int> (scores[b + n], 1, false); |
2032 | } |
2033 | if (has_kind) |
2034 | *score += wi::shifted_mask <widest_int> (scores[b + nconstructs], |
2035 | 1, false); |
2036 | if (has_arch) |
2037 | *score += wi::shifted_mask <widest_int> (scores[b + nconstructs] + 1, |
2038 | 1, false); |
2039 | if (has_isa) |
2040 | *score += wi::shifted_mask <widest_int> (scores[b + nconstructs] + 2, |
2041 | 1, false); |
2042 | } |
2043 | else /* FIXME: Implement this. */ |
2044 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2044, __FUNCTION__)); |
2045 | } |
2046 | return ret; |
2047 | } |
2048 | |
2049 | /* Class describing a single variant. */ |
2050 | struct GTY(()) omp_declare_variant_entry { |
2051 | /* NODE of the variant. */ |
2052 | cgraph_node *variant; |
2053 | /* Score if not in declare simd clone. */ |
2054 | widest_int score; |
2055 | /* Score if in declare simd clone. */ |
2056 | widest_int score_in_declare_simd_clone; |
2057 | /* Context selector for the variant. */ |
2058 | tree ctx; |
2059 | /* True if the context selector is known to match already. */ |
2060 | bool matches; |
2061 | }; |
2062 | |
2063 | /* Class describing a function with variants. */ |
2064 | struct GTY((for_user)) omp_declare_variant_base_entry { |
2065 | /* NODE of the base function. */ |
2066 | cgraph_node *base; |
2067 | /* NODE of the artificial function created for the deferred variant |
2068 | resolution. */ |
2069 | cgraph_node *node; |
2070 | /* Vector of the variants. */ |
2071 | vec<omp_declare_variant_entry, va_gc> *variants; |
2072 | }; |
2073 | |
2074 | struct omp_declare_variant_hasher |
2075 | : ggc_ptr_hash<omp_declare_variant_base_entry> { |
2076 | static hashval_t hash (omp_declare_variant_base_entry *); |
2077 | static bool equal (omp_declare_variant_base_entry *, |
2078 | omp_declare_variant_base_entry *); |
2079 | }; |
2080 | |
2081 | hashval_t |
2082 | omp_declare_variant_hasher::hash (omp_declare_variant_base_entry *x) |
2083 | { |
2084 | inchash::hash hstate; |
2085 | hstate.add_int (DECL_UID (x->base->decl)((contains_struct_check ((x->base->decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2085, __FUNCTION__))->decl_minimal.uid)); |
2086 | hstate.add_int (x->variants->length ()); |
2087 | omp_declare_variant_entry *variant; |
2088 | unsigned int i; |
2089 | FOR_EACH_VEC_SAFE_ELT (x->variants, i, variant)for (i = 0; vec_safe_iterate ((x->variants), (i), &(variant )); ++(i)) |
2090 | { |
2091 | hstate.add_int (DECL_UID (variant->variant->decl)((contains_struct_check ((variant->variant->decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2091, __FUNCTION__))->decl_minimal.uid)); |
2092 | hstate.add_wide_int (variant->score); |
2093 | hstate.add_wide_int (variant->score_in_declare_simd_clone); |
2094 | hstate.add_ptr (variant->ctx); |
2095 | hstate.add_int (variant->matches); |
2096 | } |
2097 | return hstate.end (); |
2098 | } |
2099 | |
2100 | bool |
2101 | omp_declare_variant_hasher::equal (omp_declare_variant_base_entry *x, |
2102 | omp_declare_variant_base_entry *y) |
2103 | { |
2104 | if (x->base != y->base |
2105 | || x->variants->length () != y->variants->length ()) |
2106 | return false; |
2107 | omp_declare_variant_entry *variant; |
2108 | unsigned int i; |
2109 | FOR_EACH_VEC_SAFE_ELT (x->variants, i, variant)for (i = 0; vec_safe_iterate ((x->variants), (i), &(variant )); ++(i)) |
2110 | if (variant->variant != (*y->variants)[i].variant |
2111 | || variant->score != (*y->variants)[i].score |
2112 | || (variant->score_in_declare_simd_clone |
2113 | != (*y->variants)[i].score_in_declare_simd_clone) |
2114 | || variant->ctx != (*y->variants)[i].ctx |
2115 | || variant->matches != (*y->variants)[i].matches) |
2116 | return false; |
2117 | return true; |
2118 | } |
2119 | |
2120 | static GTY(()) hash_table<omp_declare_variant_hasher> *omp_declare_variants; |
2121 | |
2122 | struct omp_declare_variant_alt_hasher |
2123 | : ggc_ptr_hash<omp_declare_variant_base_entry> { |
2124 | static hashval_t hash (omp_declare_variant_base_entry *); |
2125 | static bool equal (omp_declare_variant_base_entry *, |
2126 | omp_declare_variant_base_entry *); |
2127 | }; |
2128 | |
2129 | hashval_t |
2130 | omp_declare_variant_alt_hasher::hash (omp_declare_variant_base_entry *x) |
2131 | { |
2132 | return DECL_UID (x->node->decl)((contains_struct_check ((x->node->decl), (TS_DECL_MINIMAL ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2132, __FUNCTION__))->decl_minimal.uid); |
2133 | } |
2134 | |
2135 | bool |
2136 | omp_declare_variant_alt_hasher::equal (omp_declare_variant_base_entry *x, |
2137 | omp_declare_variant_base_entry *y) |
2138 | { |
2139 | return x->node == y->node; |
2140 | } |
2141 | |
2142 | static GTY(()) hash_table<omp_declare_variant_alt_hasher> |
2143 | *omp_declare_variant_alt; |
2144 | |
2145 | /* Try to resolve declare variant after gimplification. */ |
2146 | |
2147 | static tree |
2148 | omp_resolve_late_declare_variant (tree alt) |
2149 | { |
2150 | cgraph_node *node = cgraph_node::get (alt); |
2151 | cgraph_node *cur_node = cgraph_node::get (cfun(cfun + 0)->decl); |
2152 | if (node == NULLnullptr |
2153 | || !node->declare_variant_alt |
2154 | || !cfun(cfun + 0)->after_inlining) |
2155 | return alt; |
2156 | |
2157 | omp_declare_variant_base_entry entry; |
2158 | entry.base = NULLnullptr; |
2159 | entry.node = node; |
2160 | entry.variants = NULLnullptr; |
2161 | omp_declare_variant_base_entry *entryp |
2162 | = omp_declare_variant_alt->find_with_hash (&entry, DECL_UID (alt)((contains_struct_check ((alt), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2162, __FUNCTION__))->decl_minimal.uid)); |
2163 | |
2164 | unsigned int i, j; |
2165 | omp_declare_variant_entry *varentry1, *varentry2; |
2166 | auto_vec <bool, 16> matches; |
2167 | unsigned int nmatches = 0; |
2168 | FOR_EACH_VEC_SAFE_ELT (entryp->variants, i, varentry1)for (i = 0; vec_safe_iterate ((entryp->variants), (i), & (varentry1)); ++(i)) |
2169 | { |
2170 | if (varentry1->matches) |
2171 | { |
2172 | /* This has been checked to be ok already. */ |
2173 | matches.safe_push (true); |
2174 | nmatches++; |
2175 | continue; |
2176 | } |
2177 | switch (omp_context_selector_matches (varentry1->ctx)) |
2178 | { |
2179 | case 0: |
2180 | matches.safe_push (false); |
2181 | break; |
2182 | case -1: |
2183 | return alt; |
2184 | default: |
2185 | matches.safe_push (true); |
2186 | nmatches++; |
2187 | break; |
2188 | } |
2189 | } |
2190 | |
2191 | if (nmatches == 0) |
2192 | return entryp->base->decl; |
2193 | |
2194 | /* A context selector that is a strict subset of another context selector |
2195 | has a score of zero. */ |
2196 | FOR_EACH_VEC_SAFE_ELT (entryp->variants, i, varentry1)for (i = 0; vec_safe_iterate ((entryp->variants), (i), & (varentry1)); ++(i)) |
2197 | if (matches[i]) |
2198 | { |
2199 | for (j = i + 1; |
2200 | vec_safe_iterate (entryp->variants, j, &varentry2); ++j) |
2201 | if (matches[j]) |
2202 | { |
2203 | int r = omp_context_selector_compare (varentry1->ctx, |
2204 | varentry2->ctx); |
2205 | if (r == -1) |
2206 | { |
2207 | /* ctx1 is a strict subset of ctx2, ignore ctx1. */ |
2208 | matches[i] = false; |
2209 | break; |
2210 | } |
2211 | else if (r == 1) |
2212 | /* ctx2 is a strict subset of ctx1, remove ctx2. */ |
2213 | matches[j] = false; |
2214 | } |
2215 | } |
2216 | |
2217 | widest_int max_score = -1; |
2218 | varentry2 = NULLnullptr; |
2219 | FOR_EACH_VEC_SAFE_ELT (entryp->variants, i, varentry1)for (i = 0; vec_safe_iterate ((entryp->variants), (i), & (varentry1)); ++(i)) |
2220 | if (matches[i]) |
2221 | { |
2222 | widest_int score |
2223 | = (cur_node->simdclone ? varentry1->score_in_declare_simd_clone |
2224 | : varentry1->score); |
2225 | if (score > max_score) |
2226 | { |
2227 | max_score = score; |
2228 | varentry2 = varentry1; |
2229 | } |
2230 | } |
2231 | return varentry2->variant->decl; |
2232 | } |
2233 | |
2234 | /* Hook to adjust hash tables on cgraph_node removal. */ |
2235 | |
2236 | static void |
2237 | omp_declare_variant_remove_hook (struct cgraph_node *node, void *) |
2238 | { |
2239 | if (!node->declare_variant_alt) |
2240 | return; |
2241 | |
2242 | /* Drop this hash table completely. */ |
2243 | omp_declare_variants = NULLnullptr; |
2244 | /* And remove node from the other hash table. */ |
2245 | if (omp_declare_variant_alt) |
2246 | { |
2247 | omp_declare_variant_base_entry entry; |
2248 | entry.base = NULLnullptr; |
2249 | entry.node = node; |
2250 | entry.variants = NULLnullptr; |
2251 | omp_declare_variant_alt->remove_elt_with_hash (&entry, |
2252 | DECL_UID (node->decl)((contains_struct_check ((node->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2252, __FUNCTION__))->decl_minimal.uid)); |
2253 | } |
2254 | } |
2255 | |
2256 | /* Try to resolve declare variant, return the variant decl if it should |
2257 | be used instead of base, or base otherwise. */ |
2258 | |
2259 | tree |
2260 | omp_resolve_declare_variant (tree base) |
2261 | { |
2262 | tree variant1 = NULL_TREE(tree) nullptr, variant2 = NULL_TREE(tree) nullptr; |
2263 | if (cfun(cfun + 0) && (cfun(cfun + 0)->curr_properties & PROP_gimple_any(1 << 0)) != 0) |
2264 | return omp_resolve_late_declare_variant (base); |
2265 | |
2266 | auto_vec <tree, 16> variants; |
2267 | auto_vec <bool, 16> defer; |
2268 | bool any_deferred = false; |
2269 | for (tree attr = DECL_ATTRIBUTES (base)((contains_struct_check ((base), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2269, __FUNCTION__))->decl_common.attributes); attr; attr = TREE_CHAIN (attr)((contains_struct_check ((attr), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2269, __FUNCTION__))->common.chain)) |
2270 | { |
2271 | attr = lookup_attribute ("omp declare variant base", attr); |
2272 | if (attr == NULL_TREE(tree) nullptr) |
2273 | break; |
2274 | if (TREE_CODE (TREE_PURPOSE (TREE_VALUE (attr)))((enum tree_code) (((tree_check ((((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2274, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2274, __FUNCTION__, (TREE_LIST)))->list.purpose))->base .code) != FUNCTION_DECL) |
2275 | continue; |
2276 | cgraph_node *node = cgraph_node::get (base); |
2277 | /* If this is already a magic decl created by this function, |
2278 | don't process it again. */ |
2279 | if (node && node->declare_variant_alt) |
2280 | return base; |
2281 | switch (omp_context_selector_matches (TREE_VALUE (TREE_VALUE (attr))((tree_check ((((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2281, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2281, __FUNCTION__, (TREE_LIST)))->list.value))) |
2282 | { |
2283 | case 0: |
2284 | /* No match, ignore. */ |
2285 | break; |
2286 | case -1: |
2287 | /* Needs to be deferred. */ |
2288 | any_deferred = true; |
2289 | variants.safe_push (attr); |
2290 | defer.safe_push (true); |
2291 | break; |
2292 | default: |
2293 | variants.safe_push (attr); |
2294 | defer.safe_push (false); |
2295 | break; |
2296 | } |
2297 | } |
2298 | if (variants.length () == 0) |
2299 | return base; |
2300 | |
2301 | if (any_deferred) |
2302 | { |
2303 | widest_int max_score1 = 0; |
2304 | widest_int max_score2 = 0; |
2305 | bool first = true; |
2306 | unsigned int i; |
2307 | tree attr1, attr2; |
2308 | omp_declare_variant_base_entry entry; |
2309 | entry.base = cgraph_node::get_create (base); |
2310 | entry.node = NULLnullptr; |
2311 | vec_alloc (entry.variants, variants.length ()); |
2312 | FOR_EACH_VEC_ELT (variants, i, attr1)for (i = 0; (variants).iterate ((i), &(attr1)); ++(i)) |
2313 | { |
2314 | widest_int score1; |
2315 | widest_int score2; |
2316 | bool need_two; |
2317 | tree ctx = TREE_VALUE (TREE_VALUE (attr1))((tree_check ((((tree_check ((attr1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2317, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2317, __FUNCTION__, (TREE_LIST)))->list.value); |
2318 | need_two = omp_context_compute_score (ctx, &score1, false); |
2319 | if (need_two) |
2320 | omp_context_compute_score (ctx, &score2, true); |
2321 | else |
2322 | score2 = score1; |
2323 | if (first) |
2324 | { |
2325 | first = false; |
2326 | max_score1 = score1; |
2327 | max_score2 = score2; |
2328 | if (!defer[i]) |
2329 | { |
2330 | variant1 = attr1; |
2331 | variant2 = attr1; |
2332 | } |
2333 | } |
2334 | else |
2335 | { |
2336 | if (max_score1 == score1) |
2337 | variant1 = NULL_TREE(tree) nullptr; |
2338 | else if (score1 > max_score1) |
2339 | { |
2340 | max_score1 = score1; |
2341 | variant1 = defer[i] ? NULL_TREE(tree) nullptr : attr1; |
2342 | } |
2343 | if (max_score2 == score2) |
2344 | variant2 = NULL_TREE(tree) nullptr; |
2345 | else if (score2 > max_score2) |
2346 | { |
2347 | max_score2 = score2; |
2348 | variant2 = defer[i] ? NULL_TREE(tree) nullptr : attr1; |
2349 | } |
2350 | } |
2351 | omp_declare_variant_entry varentry; |
2352 | varentry.variant |
2353 | = cgraph_node::get_create (TREE_PURPOSE (TREE_VALUE (attr1))((tree_check ((((tree_check ((attr1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2353, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2353, __FUNCTION__, (TREE_LIST)))->list.purpose)); |
2354 | varentry.score = score1; |
2355 | varentry.score_in_declare_simd_clone = score2; |
2356 | varentry.ctx = ctx; |
2357 | varentry.matches = !defer[i]; |
2358 | entry.variants->quick_push (varentry); |
2359 | } |
2360 | |
2361 | /* If there is a clear winner variant with the score which is not |
2362 | deferred, verify it is not a strict subset of any other context |
2363 | selector and if it is not, it is the best alternative no matter |
2364 | whether the others do or don't match. */ |
2365 | if (variant1 && variant1 == variant2) |
2366 | { |
2367 | tree ctx1 = TREE_VALUE (TREE_VALUE (variant1))((tree_check ((((tree_check ((variant1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2367, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2367, __FUNCTION__, (TREE_LIST)))->list.value); |
2368 | FOR_EACH_VEC_ELT (variants, i, attr2)for (i = 0; (variants).iterate ((i), &(attr2)); ++(i)) |
2369 | { |
2370 | if (attr2 == variant1) |
2371 | continue; |
2372 | tree ctx2 = TREE_VALUE (TREE_VALUE (attr2))((tree_check ((((tree_check ((attr2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2372, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2372, __FUNCTION__, (TREE_LIST)))->list.value); |
2373 | int r = omp_context_selector_compare (ctx1, ctx2); |
2374 | if (r == -1) |
2375 | { |
2376 | /* The winner is a strict subset of ctx2, can't |
2377 | decide now. */ |
2378 | variant1 = NULL_TREE(tree) nullptr; |
2379 | break; |
2380 | } |
2381 | } |
2382 | if (variant1) |
2383 | { |
2384 | vec_free (entry.variants); |
2385 | return TREE_PURPOSE (TREE_VALUE (variant1))((tree_check ((((tree_check ((variant1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2385, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2385, __FUNCTION__, (TREE_LIST)))->list.purpose); |
2386 | } |
2387 | } |
2388 | |
2389 | static struct cgraph_node_hook_list *node_removal_hook_holder; |
2390 | if (!node_removal_hook_holder) |
2391 | node_removal_hook_holder |
2392 | = symtab->add_cgraph_removal_hook (omp_declare_variant_remove_hook, |
2393 | NULLnullptr); |
2394 | |
2395 | if (omp_declare_variants == NULLnullptr) |
2396 | omp_declare_variants |
2397 | = hash_table<omp_declare_variant_hasher>::create_ggc (64); |
2398 | omp_declare_variant_base_entry **slot |
2399 | = omp_declare_variants->find_slot (&entry, INSERT); |
2400 | if (*slot != NULLnullptr) |
2401 | { |
2402 | vec_free (entry.variants); |
2403 | return (*slot)->node->decl; |
2404 | } |
2405 | |
2406 | *slot = ggc_cleared_alloc<omp_declare_variant_base_entry> (); |
2407 | (*slot)->base = entry.base; |
2408 | (*slot)->node = entry.base; |
2409 | (*slot)->variants = entry.variants; |
2410 | tree alt = build_decl (DECL_SOURCE_LOCATION (base)((contains_struct_check ((base), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2410, __FUNCTION__))->decl_minimal.locus), FUNCTION_DECL, |
2411 | DECL_NAME (base)((contains_struct_check ((base), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2411, __FUNCTION__))->decl_minimal.name), TREE_TYPE (base)((contains_struct_check ((base), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2411, __FUNCTION__))->typed.type)); |
2412 | DECL_ARTIFICIAL (alt)((contains_struct_check ((alt), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2412, __FUNCTION__))->decl_common.artificial_flag) = 1; |
2413 | DECL_IGNORED_P (alt)((contains_struct_check ((alt), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2413, __FUNCTION__))->decl_common.ignored_flag) = 1; |
2414 | TREE_STATIC (alt)((alt)->base.static_flag) = 1; |
2415 | tree attributes = DECL_ATTRIBUTES (base)((contains_struct_check ((base), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2415, __FUNCTION__))->decl_common.attributes); |
2416 | if (lookup_attribute ("noipa", attributes) == NULLnullptr) |
2417 | { |
2418 | attributes = tree_cons (get_identifier ("noipa")(__builtin_constant_p ("noipa") ? get_identifier_with_length ( ("noipa"), strlen ("noipa")) : get_identifier ("noipa")), NULLnullptr, attributes); |
2419 | if (lookup_attribute ("noinline", attributes) == NULLnullptr) |
2420 | attributes = tree_cons (get_identifier ("noinline")(__builtin_constant_p ("noinline") ? get_identifier_with_length (("noinline"), strlen ("noinline")) : get_identifier ("noinline" )), NULLnullptr, |
2421 | attributes); |
2422 | if (lookup_attribute ("noclone", attributes) == NULLnullptr) |
2423 | attributes = tree_cons (get_identifier ("noclone")(__builtin_constant_p ("noclone") ? get_identifier_with_length (("noclone"), strlen ("noclone")) : get_identifier ("noclone" )), NULLnullptr, |
2424 | attributes); |
2425 | if (lookup_attribute ("no_icf", attributes) == NULLnullptr) |
2426 | attributes = tree_cons (get_identifier ("no_icf")(__builtin_constant_p ("no_icf") ? get_identifier_with_length (("no_icf"), strlen ("no_icf")) : get_identifier ("no_icf")), NULLnullptr, |
2427 | attributes); |
2428 | } |
2429 | DECL_ATTRIBUTES (alt)((contains_struct_check ((alt), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2429, __FUNCTION__))->decl_common.attributes) = attributes; |
2430 | DECL_INITIAL (alt)((contains_struct_check ((alt), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2430, __FUNCTION__))->decl_common.initial) = error_mark_nodeglobal_trees[TI_ERROR_MARK]; |
2431 | (*slot)->node = cgraph_node::create (alt); |
2432 | (*slot)->node->declare_variant_alt = 1; |
2433 | (*slot)->node->create_reference (entry.base, IPA_REF_ADDR); |
2434 | omp_declare_variant_entry *varentry; |
2435 | FOR_EACH_VEC_SAFE_ELT (entry.variants, i, varentry)for (i = 0; vec_safe_iterate ((entry.variants), (i), &(varentry )); ++(i)) |
2436 | (*slot)->node->create_reference (varentry->variant, IPA_REF_ADDR); |
2437 | if (omp_declare_variant_alt == NULLnullptr) |
2438 | omp_declare_variant_alt |
2439 | = hash_table<omp_declare_variant_alt_hasher>::create_ggc (64); |
2440 | *omp_declare_variant_alt->find_slot_with_hash (*slot, DECL_UID (alt)((contains_struct_check ((alt), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2440, __FUNCTION__))->decl_minimal.uid), |
2441 | INSERT) = *slot; |
2442 | return alt; |
2443 | } |
2444 | |
2445 | if (variants.length () == 1) |
2446 | return TREE_PURPOSE (TREE_VALUE (variants[0]))((tree_check ((((tree_check ((variants[0]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2446, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2446, __FUNCTION__, (TREE_LIST)))->list.purpose); |
2447 | |
2448 | /* A context selector that is a strict subset of another context selector |
2449 | has a score of zero. */ |
2450 | tree attr1, attr2; |
2451 | unsigned int i, j; |
2452 | FOR_EACH_VEC_ELT (variants, i, attr1)for (i = 0; (variants).iterate ((i), &(attr1)); ++(i)) |
2453 | if (attr1) |
2454 | { |
2455 | tree ctx1 = TREE_VALUE (TREE_VALUE (attr1))((tree_check ((((tree_check ((attr1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2455, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2455, __FUNCTION__, (TREE_LIST)))->list.value); |
2456 | FOR_EACH_VEC_ELT_FROM (variants, j, attr2, i + 1)for (j = (i + 1); (variants).iterate ((j), &(attr2)); ++( j)) |
2457 | if (attr2) |
2458 | { |
2459 | tree ctx2 = TREE_VALUE (TREE_VALUE (attr2))((tree_check ((((tree_check ((attr2), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2459, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2459, __FUNCTION__, (TREE_LIST)))->list.value); |
2460 | int r = omp_context_selector_compare (ctx1, ctx2); |
2461 | if (r == -1) |
2462 | { |
2463 | /* ctx1 is a strict subset of ctx2, remove |
2464 | attr1 from the vector. */ |
2465 | variants[i] = NULL_TREE(tree) nullptr; |
2466 | break; |
2467 | } |
2468 | else if (r == 1) |
2469 | /* ctx2 is a strict subset of ctx1, remove attr2 |
2470 | from the vector. */ |
2471 | variants[j] = NULL_TREE(tree) nullptr; |
2472 | } |
2473 | } |
2474 | widest_int max_score1 = 0; |
2475 | widest_int max_score2 = 0; |
2476 | bool first = true; |
2477 | FOR_EACH_VEC_ELT (variants, i, attr1)for (i = 0; (variants).iterate ((i), &(attr1)); ++(i)) |
2478 | if (attr1) |
2479 | { |
2480 | if (variant1) |
2481 | { |
2482 | widest_int score1; |
2483 | widest_int score2; |
2484 | bool need_two; |
2485 | tree ctx; |
2486 | if (first) |
2487 | { |
2488 | first = false; |
2489 | ctx = TREE_VALUE (TREE_VALUE (variant1))((tree_check ((((tree_check ((variant1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2489, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2489, __FUNCTION__, (TREE_LIST)))->list.value); |
2490 | need_two = omp_context_compute_score (ctx, &max_score1, false); |
2491 | if (need_two) |
2492 | omp_context_compute_score (ctx, &max_score2, true); |
2493 | else |
2494 | max_score2 = max_score1; |
2495 | } |
2496 | ctx = TREE_VALUE (TREE_VALUE (attr1))((tree_check ((((tree_check ((attr1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2496, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2496, __FUNCTION__, (TREE_LIST)))->list.value); |
2497 | need_two = omp_context_compute_score (ctx, &score1, false); |
2498 | if (need_two) |
2499 | omp_context_compute_score (ctx, &score2, true); |
2500 | else |
2501 | score2 = score1; |
2502 | if (score1 > max_score1) |
2503 | { |
2504 | max_score1 = score1; |
2505 | variant1 = attr1; |
2506 | } |
2507 | if (score2 > max_score2) |
2508 | { |
2509 | max_score2 = score2; |
2510 | variant2 = attr1; |
2511 | } |
2512 | } |
2513 | else |
2514 | { |
2515 | variant1 = attr1; |
2516 | variant2 = attr1; |
2517 | } |
2518 | } |
2519 | /* If there is a disagreement on which variant has the highest score |
2520 | depending on whether it will be in a declare simd clone or not, |
2521 | punt for now and defer until after IPA where we will know that. */ |
2522 | return ((variant1 && variant1 == variant2) |
2523 | ? TREE_PURPOSE (TREE_VALUE (variant1))((tree_check ((((tree_check ((variant1), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2523, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2523, __FUNCTION__, (TREE_LIST)))->list.purpose) : base); |
2524 | } |
2525 | |
2526 | void |
2527 | omp_lto_output_declare_variant_alt (lto_simple_output_block *ob, |
2528 | cgraph_node *node, |
2529 | lto_symtab_encoder_t encoder) |
2530 | { |
2531 | gcc_assert (node->declare_variant_alt)((void)(!(node->declare_variant_alt) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2531, __FUNCTION__), 0 : 0)); |
2532 | |
2533 | omp_declare_variant_base_entry entry; |
2534 | entry.base = NULLnullptr; |
2535 | entry.node = node; |
2536 | entry.variants = NULLnullptr; |
2537 | omp_declare_variant_base_entry *entryp |
2538 | = omp_declare_variant_alt->find_with_hash (&entry, DECL_UID (node->decl)((contains_struct_check ((node->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2538, __FUNCTION__))->decl_minimal.uid)); |
2539 | gcc_assert (entryp)((void)(!(entryp) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2539, __FUNCTION__), 0 : 0)); |
2540 | |
2541 | int nbase = lto_symtab_encoder_lookup (encoder, entryp->base); |
2542 | gcc_assert (nbase != LCC_NOT_FOUND)((void)(!(nbase != (-1)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2542, __FUNCTION__), 0 : 0)); |
2543 | streamer_write_hwi_stream (ob->main_stream, nbase); |
2544 | |
2545 | streamer_write_hwi_stream (ob->main_stream, entryp->variants->length ()); |
2546 | |
2547 | unsigned int i; |
2548 | omp_declare_variant_entry *varentry; |
2549 | FOR_EACH_VEC_SAFE_ELT (entryp->variants, i, varentry)for (i = 0; vec_safe_iterate ((entryp->variants), (i), & (varentry)); ++(i)) |
2550 | { |
2551 | int nvar = lto_symtab_encoder_lookup (encoder, varentry->variant); |
2552 | gcc_assert (nvar != LCC_NOT_FOUND)((void)(!(nvar != (-1)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2552, __FUNCTION__), 0 : 0)); |
2553 | streamer_write_hwi_stream (ob->main_stream, nvar); |
2554 | |
2555 | for (widest_int *w = &varentry->score; ; |
2556 | w = &varentry->score_in_declare_simd_clone) |
2557 | { |
2558 | unsigned len = w->get_len (); |
2559 | streamer_write_hwi_stream (ob->main_stream, len); |
2560 | const HOST_WIDE_INTlong *val = w->get_val (); |
2561 | for (unsigned j = 0; j < len; j++) |
2562 | streamer_write_hwi_stream (ob->main_stream, val[j]); |
2563 | if (w == &varentry->score_in_declare_simd_clone) |
2564 | break; |
2565 | } |
2566 | |
2567 | HOST_WIDE_INTlong cnt = -1; |
2568 | HOST_WIDE_INTlong i = varentry->matches ? 1 : 0; |
2569 | for (tree attr = DECL_ATTRIBUTES (entryp->base->decl)((contains_struct_check ((entryp->base->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2569, __FUNCTION__))->decl_common.attributes); |
2570 | attr; attr = TREE_CHAIN (attr)((contains_struct_check ((attr), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2570, __FUNCTION__))->common.chain), i += 2) |
2571 | { |
2572 | attr = lookup_attribute ("omp declare variant base", attr); |
2573 | if (attr == NULL_TREE(tree) nullptr) |
2574 | break; |
2575 | |
2576 | if (varentry->ctx == TREE_VALUE (TREE_VALUE (attr))((tree_check ((((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2576, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2576, __FUNCTION__, (TREE_LIST)))->list.value)) |
2577 | { |
2578 | cnt = i; |
2579 | break; |
2580 | } |
2581 | } |
2582 | |
2583 | gcc_assert (cnt != -1)((void)(!(cnt != -1) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2583, __FUNCTION__), 0 : 0)); |
2584 | streamer_write_hwi_stream (ob->main_stream, cnt); |
2585 | } |
2586 | } |
2587 | |
2588 | void |
2589 | omp_lto_input_declare_variant_alt (lto_input_block *ib, cgraph_node *node, |
2590 | vec<symtab_node *> nodes) |
2591 | { |
2592 | gcc_assert (node->declare_variant_alt)((void)(!(node->declare_variant_alt) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2592, __FUNCTION__), 0 : 0)); |
2593 | omp_declare_variant_base_entry *entryp |
2594 | = ggc_cleared_alloc<omp_declare_variant_base_entry> (); |
2595 | entryp->base = dyn_cast<cgraph_node *> (nodes[streamer_read_hwi (ib)]); |
2596 | entryp->node = node; |
2597 | unsigned int len = streamer_read_hwi (ib); |
2598 | vec_alloc (entryp->variants, len); |
2599 | |
2600 | for (unsigned int i = 0; i < len; i++) |
2601 | { |
2602 | omp_declare_variant_entry varentry; |
2603 | varentry.variant |
2604 | = dyn_cast<cgraph_node *> (nodes[streamer_read_hwi (ib)]); |
2605 | for (widest_int *w = &varentry.score; ; |
2606 | w = &varentry.score_in_declare_simd_clone) |
2607 | { |
2608 | unsigned len2 = streamer_read_hwi (ib); |
2609 | HOST_WIDE_INTlong arr[WIDE_INT_MAX_ELTS(((64*(8)) + 64) / 64)]; |
2610 | gcc_assert (len2 <= WIDE_INT_MAX_ELTS)((void)(!(len2 <= (((64*(8)) + 64) / 64)) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2610, __FUNCTION__), 0 : 0)); |
2611 | for (unsigned int j = 0; j < len2; j++) |
2612 | arr[j] = streamer_read_hwi (ib); |
2613 | *w = widest_int::from_array (arr, len2, true); |
2614 | if (w == &varentry.score_in_declare_simd_clone) |
2615 | break; |
2616 | } |
2617 | |
2618 | HOST_WIDE_INTlong cnt = streamer_read_hwi (ib); |
2619 | HOST_WIDE_INTlong j = 0; |
2620 | varentry.ctx = NULL_TREE(tree) nullptr; |
2621 | varentry.matches = (cnt & 1) ? true : false; |
2622 | cnt &= ~HOST_WIDE_INT_11L; |
2623 | for (tree attr = DECL_ATTRIBUTES (entryp->base->decl)((contains_struct_check ((entryp->base->decl), (TS_DECL_COMMON ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2623, __FUNCTION__))->decl_common.attributes); |
2624 | attr; attr = TREE_CHAIN (attr)((contains_struct_check ((attr), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2624, __FUNCTION__))->common.chain), j += 2) |
2625 | { |
2626 | attr = lookup_attribute ("omp declare variant base", attr); |
2627 | if (attr == NULL_TREE(tree) nullptr) |
2628 | break; |
2629 | |
2630 | if (cnt == j) |
2631 | { |
2632 | varentry.ctx = TREE_VALUE (TREE_VALUE (attr))((tree_check ((((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2632, __FUNCTION__, (TREE_LIST)))->list.value)), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2632, __FUNCTION__, (TREE_LIST)))->list.value); |
2633 | break; |
2634 | } |
2635 | } |
2636 | gcc_assert (varentry.ctx != NULL_TREE)((void)(!(varentry.ctx != (tree) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2636, __FUNCTION__), 0 : 0)); |
2637 | entryp->variants->quick_push (varentry); |
2638 | } |
2639 | if (omp_declare_variant_alt == NULLnullptr) |
2640 | omp_declare_variant_alt |
2641 | = hash_table<omp_declare_variant_alt_hasher>::create_ggc (64); |
2642 | *omp_declare_variant_alt->find_slot_with_hash (entryp, DECL_UID (node->decl)((contains_struct_check ((node->decl), (TS_DECL_MINIMAL), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2642, __FUNCTION__))->decl_minimal.uid), |
2643 | INSERT) = entryp; |
2644 | } |
2645 | |
2646 | /* Encode an oacc launch argument. This matches the GOMP_LAUNCH_PACK |
2647 | macro on gomp-constants.h. We do not check for overflow. */ |
2648 | |
2649 | tree |
2650 | oacc_launch_pack (unsigned code, tree device, unsigned op) |
2651 | { |
2652 | tree res; |
2653 | |
2654 | res = build_int_cst (unsigned_type_nodeinteger_types[itk_unsigned_int], GOMP_LAUNCH_PACK (code, 0, op)(((code) << 28) | ((0) << 16) | ((op) << 0) )); |
2655 | if (device) |
2656 | { |
2657 | device = fold_build2 (LSHIFT_EXPR, unsigned_type_node,fold_build2_loc (((location_t) 0), LSHIFT_EXPR, integer_types [itk_unsigned_int], device, build_int_cst (integer_types[itk_unsigned_int ], 16) ) |
2658 | device, build_int_cst (unsigned_type_node,fold_build2_loc (((location_t) 0), LSHIFT_EXPR, integer_types [itk_unsigned_int], device, build_int_cst (integer_types[itk_unsigned_int ], 16) ) |
2659 | GOMP_LAUNCH_DEVICE_SHIFT))fold_build2_loc (((location_t) 0), LSHIFT_EXPR, integer_types [itk_unsigned_int], device, build_int_cst (integer_types[itk_unsigned_int ], 16) ); |
2660 | res = fold_build2 (BIT_IOR_EXPR, unsigned_type_node, res, device)fold_build2_loc (((location_t) 0), BIT_IOR_EXPR, integer_types [itk_unsigned_int], res, device ); |
2661 | } |
2662 | return res; |
2663 | } |
2664 | |
2665 | /* FIXME: What is the following comment for? */ |
2666 | /* Look for compute grid dimension clauses and convert to an attribute |
2667 | attached to FN. This permits the target-side code to (a) massage |
2668 | the dimensions, (b) emit that data and (c) optimize. Non-constant |
2669 | dimensions are pushed onto ARGS. |
2670 | |
2671 | The attribute value is a TREE_LIST. A set of dimensions is |
2672 | represented as a list of INTEGER_CST. Those that are runtime |
2673 | exprs are represented as an INTEGER_CST of zero. |
2674 | |
2675 | TODO: Normally the attribute will just contain a single such list. If |
2676 | however it contains a list of lists, this will represent the use of |
2677 | device_type. Each member of the outer list is an assoc list of |
2678 | dimensions, keyed by the device type. The first entry will be the |
2679 | default. Well, that's the plan. */ |
2680 | |
2681 | /* Replace any existing oacc fn attribute with updated dimensions. */ |
2682 | |
2683 | /* Variant working on a list of attributes. */ |
2684 | |
2685 | tree |
2686 | oacc_replace_fn_attrib_attr (tree attribs, tree dims) |
2687 | { |
2688 | tree ident = get_identifier (OACC_FN_ATTRIB)(__builtin_constant_p ("oacc function") ? get_identifier_with_length (("oacc function"), strlen ("oacc function")) : get_identifier ("oacc function")); |
2689 | |
2690 | /* If we happen to be present as the first attrib, drop it. */ |
2691 | if (attribs && TREE_PURPOSE (attribs)((tree_check ((attribs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2691, __FUNCTION__, (TREE_LIST)))->list.purpose) == ident) |
2692 | attribs = TREE_CHAIN (attribs)((contains_struct_check ((attribs), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2692, __FUNCTION__))->common.chain); |
2693 | return tree_cons (ident, dims, attribs); |
2694 | } |
2695 | |
2696 | /* Variant working on a function decl. */ |
2697 | |
2698 | void |
2699 | oacc_replace_fn_attrib (tree fn, tree dims) |
2700 | { |
2701 | DECL_ATTRIBUTES (fn)((contains_struct_check ((fn), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2701, __FUNCTION__))->decl_common.attributes) |
2702 | = oacc_replace_fn_attrib_attr (DECL_ATTRIBUTES (fn)((contains_struct_check ((fn), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2702, __FUNCTION__))->decl_common.attributes), dims); |
2703 | } |
2704 | |
2705 | /* Scan CLAUSES for launch dimensions and attach them to the oacc |
2706 | function attribute. Push any that are non-constant onto the ARGS |
2707 | list, along with an appropriate GOMP_LAUNCH_DIM tag. */ |
2708 | |
2709 | void |
2710 | oacc_set_fn_attrib (tree fn, tree clauses, vec<tree> *args) |
2711 | { |
2712 | /* Must match GOMP_DIM ordering. */ |
2713 | static const omp_clause_code ids[] |
2714 | = { OMP_CLAUSE_NUM_GANGS, OMP_CLAUSE_NUM_WORKERS, |
2715 | OMP_CLAUSE_VECTOR_LENGTH }; |
2716 | unsigned ix; |
2717 | tree dims[GOMP_DIM_MAX3]; |
2718 | |
2719 | tree attr = NULL_TREE(tree) nullptr; |
2720 | unsigned non_const = 0; |
2721 | |
2722 | for (ix = GOMP_DIM_MAX3; ix--;) |
2723 | { |
2724 | tree clause = omp_find_clause (clauses, ids[ix]); |
2725 | tree dim = NULL_TREE(tree) nullptr; |
2726 | |
2727 | if (clause) |
2728 | dim = OMP_CLAUSE_EXPR (clause, ids[ix])(*(omp_clause_elt_check (((omp_clause_subcode_check ((clause) , (ids[ix]), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2728, __FUNCTION__))), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2728, __FUNCTION__))); |
2729 | dims[ix] = dim; |
2730 | if (dim && TREE_CODE (dim)((enum tree_code) (dim)->base.code) != INTEGER_CST) |
2731 | { |
2732 | dim = integer_zero_nodeglobal_trees[TI_INTEGER_ZERO]; |
2733 | non_const |= GOMP_DIM_MASK (ix)(1u << (ix)); |
2734 | } |
2735 | attr = tree_cons (NULL_TREE(tree) nullptr, dim, attr); |
2736 | } |
2737 | |
2738 | oacc_replace_fn_attrib (fn, attr); |
2739 | |
2740 | if (non_const) |
2741 | { |
2742 | /* Push a dynamic argument set. */ |
2743 | args->safe_push (oacc_launch_pack (GOMP_LAUNCH_DIM1, |
2744 | NULL_TREE(tree) nullptr, non_const)); |
2745 | for (unsigned ix = 0; ix != GOMP_DIM_MAX3; ix++) |
2746 | if (non_const & GOMP_DIM_MASK (ix)(1u << (ix))) |
2747 | args->safe_push (dims[ix]); |
2748 | } |
2749 | } |
2750 | |
2751 | /* Verify OpenACC routine clauses. |
2752 | |
2753 | Returns 0 if FNDECL should be marked with an OpenACC 'routine' directive, 1 |
2754 | if it has already been marked in compatible way, and -1 if incompatible. |
2755 | Upon returning, the chain of clauses will contain exactly one clause |
2756 | specifying the level of parallelism. */ |
2757 | |
2758 | int |
2759 | oacc_verify_routine_clauses (tree fndecl, tree *clauses, location_t loc, |
2760 | const char *routine_str) |
2761 | { |
2762 | tree c_level = NULL_TREE(tree) nullptr; |
2763 | tree c_nohost = NULL_TREE(tree) nullptr; |
2764 | tree c_p = NULL_TREE(tree) nullptr; |
2765 | for (tree c = *clauses; c; c_p = c, c = OMP_CLAUSE_CHAIN (c)((contains_struct_check (((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2765, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2765, __FUNCTION__))->common.chain)) |
2766 | switch (OMP_CLAUSE_CODE (c)((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2766, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code) |
2767 | { |
2768 | case OMP_CLAUSE_GANG: |
2769 | case OMP_CLAUSE_WORKER: |
2770 | case OMP_CLAUSE_VECTOR: |
2771 | case OMP_CLAUSE_SEQ: |
2772 | if (c_level == NULL_TREE(tree) nullptr) |
2773 | c_level = c; |
2774 | else if (OMP_CLAUSE_CODE (c)((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2774, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code == OMP_CLAUSE_CODE (c_level)((tree_check ((c_level), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2774, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code) |
2775 | { |
2776 | /* This has already been diagnosed in the front ends. */ |
2777 | /* Drop the duplicate clause. */ |
2778 | gcc_checking_assert (c_p != NULL_TREE)((void)(!(c_p != (tree) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2778, __FUNCTION__), 0 : 0)); |
2779 | OMP_CLAUSE_CHAIN (c_p)((contains_struct_check (((tree_check ((c_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2779, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2779, __FUNCTION__))->common.chain) = OMP_CLAUSE_CHAIN (c)((contains_struct_check (((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2779, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2779, __FUNCTION__))->common.chain); |
2780 | c = c_p; |
2781 | } |
2782 | else |
2783 | { |
2784 | error_at (OMP_CLAUSE_LOCATION (c)((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2784, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.locus, |
2785 | "%qs specifies a conflicting level of parallelism", |
2786 | omp_clause_code_name[OMP_CLAUSE_CODE (c)((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2786, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code]); |
2787 | inform (OMP_CLAUSE_LOCATION (c_level)((tree_check ((c_level), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2787, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.locus, |
2788 | "... to the previous %qs clause here", |
2789 | omp_clause_code_name[OMP_CLAUSE_CODE (c_level)((tree_check ((c_level), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2789, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code]); |
2790 | /* Drop the conflicting clause. */ |
2791 | gcc_checking_assert (c_p != NULL_TREE)((void)(!(c_p != (tree) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2791, __FUNCTION__), 0 : 0)); |
2792 | OMP_CLAUSE_CHAIN (c_p)((contains_struct_check (((tree_check ((c_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2792, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2792, __FUNCTION__))->common.chain) = OMP_CLAUSE_CHAIN (c)((contains_struct_check (((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2792, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2792, __FUNCTION__))->common.chain); |
2793 | c = c_p; |
2794 | } |
2795 | break; |
2796 | case OMP_CLAUSE_NOHOST: |
2797 | /* Don't worry about duplicate clauses here. */ |
2798 | c_nohost = c; |
2799 | break; |
2800 | default: |
2801 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2801, __FUNCTION__)); |
2802 | } |
2803 | if (c_level == NULL_TREE(tree) nullptr) |
2804 | { |
2805 | /* Default to an implicit 'seq' clause. */ |
2806 | c_level = build_omp_clause (loc, OMP_CLAUSE_SEQ); |
2807 | OMP_CLAUSE_CHAIN (c_level)((contains_struct_check (((tree_check ((c_level), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2807, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2807, __FUNCTION__))->common.chain) = *clauses; |
2808 | *clauses = c_level; |
2809 | } |
2810 | /* In *clauses, we now have exactly one clause specifying the level of |
2811 | parallelism. */ |
2812 | |
2813 | tree attr |
2814 | = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (fndecl)((contains_struct_check ((fndecl), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2814, __FUNCTION__))->decl_common.attributes)); |
2815 | if (attr != NULL_TREE(tree) nullptr) |
2816 | { |
2817 | /* Diagnose if "#pragma omp declare target" has also been applied. */ |
2818 | if (TREE_VALUE (attr)((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2818, __FUNCTION__, (TREE_LIST)))->list.value) == NULL_TREE(tree) nullptr) |
2819 | { |
2820 | /* See <https://gcc.gnu.org/PR93465>; the semantics of combining |
2821 | OpenACC and OpenMP 'target' are not clear. */ |
2822 | error_at (loc, |
2823 | "cannot apply %<%s%> to %qD, which has also been" |
2824 | " marked with an OpenMP 'declare target' directive", |
2825 | routine_str, fndecl); |
2826 | /* Incompatible. */ |
2827 | return -1; |
2828 | } |
2829 | |
2830 | /* If a "#pragma acc routine" has already been applied, just verify |
2831 | this one for compatibility. */ |
2832 | /* Collect previous directive's clauses. */ |
2833 | tree c_level_p = NULL_TREE(tree) nullptr; |
2834 | tree c_nohost_p = NULL_TREE(tree) nullptr; |
2835 | for (tree c = TREE_VALUE (attr)((tree_check ((attr), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2835, __FUNCTION__, (TREE_LIST)))->list.value); c; c = OMP_CLAUSE_CHAIN (c)((contains_struct_check (((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2835, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2835, __FUNCTION__))->common.chain)) |
2836 | switch (OMP_CLAUSE_CODE (c)((tree_check ((c), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2836, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code) |
2837 | { |
2838 | case OMP_CLAUSE_GANG: |
2839 | case OMP_CLAUSE_WORKER: |
2840 | case OMP_CLAUSE_VECTOR: |
2841 | case OMP_CLAUSE_SEQ: |
2842 | gcc_checking_assert (c_level_p == NULL_TREE)((void)(!(c_level_p == (tree) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2842, __FUNCTION__), 0 : 0)); |
2843 | c_level_p = c; |
2844 | break; |
2845 | case OMP_CLAUSE_NOHOST: |
2846 | gcc_checking_assert (c_nohost_p == NULL_TREE)((void)(!(c_nohost_p == (tree) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2846, __FUNCTION__), 0 : 0)); |
2847 | c_nohost_p = c; |
2848 | break; |
2849 | default: |
2850 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2850, __FUNCTION__)); |
2851 | } |
2852 | gcc_checking_assert (c_level_p != NULL_TREE)((void)(!(c_level_p != (tree) nullptr) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2852, __FUNCTION__), 0 : 0)); |
2853 | /* ..., and compare to current directive's, which we've already collected |
2854 | above. */ |
2855 | tree c_diag; |
2856 | tree c_diag_p; |
2857 | /* Matching level of parallelism? */ |
2858 | if (OMP_CLAUSE_CODE (c_level)((tree_check ((c_level), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2858, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code != OMP_CLAUSE_CODE (c_level_p)((tree_check ((c_level_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2858, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code) |
2859 | { |
2860 | c_diag = c_level; |
2861 | c_diag_p = c_level_p; |
2862 | goto incompatible; |
2863 | } |
2864 | /* Matching 'nohost' clauses? */ |
2865 | if ((c_nohost == NULL_TREE(tree) nullptr) != (c_nohost_p == NULL_TREE(tree) nullptr)) |
2866 | { |
2867 | c_diag = c_nohost; |
2868 | c_diag_p = c_nohost_p; |
2869 | goto incompatible; |
2870 | } |
2871 | /* Compatible. */ |
2872 | return 1; |
2873 | |
2874 | incompatible: |
2875 | if (c_diag != NULL_TREE(tree) nullptr) |
2876 | error_at (OMP_CLAUSE_LOCATION (c_diag)((tree_check ((c_diag), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2876, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.locus, |
2877 | "incompatible %qs clause when applying" |
2878 | " %<%s%> to %qD, which has already been" |
2879 | " marked with an OpenACC 'routine' directive", |
2880 | omp_clause_code_name[OMP_CLAUSE_CODE (c_diag)((tree_check ((c_diag), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2880, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code], |
2881 | routine_str, fndecl); |
2882 | else if (c_diag_p != NULL_TREE(tree) nullptr) |
2883 | error_at (loc, |
2884 | "missing %qs clause when applying" |
2885 | " %<%s%> to %qD, which has already been" |
2886 | " marked with an OpenACC 'routine' directive", |
2887 | omp_clause_code_name[OMP_CLAUSE_CODE (c_diag_p)((tree_check ((c_diag_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2887, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code], |
2888 | routine_str, fndecl); |
2889 | else |
2890 | gcc_unreachable ()(fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2890, __FUNCTION__)); |
2891 | if (c_diag_p != NULL_TREE(tree) nullptr) |
2892 | inform (OMP_CLAUSE_LOCATION (c_diag_p)((tree_check ((c_diag_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2892, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.locus, |
2893 | "... with %qs clause here", |
2894 | omp_clause_code_name[OMP_CLAUSE_CODE (c_diag_p)((tree_check ((c_diag_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2894, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code]); |
2895 | else |
2896 | { |
2897 | /* In the front ends, we don't preserve location information for the |
2898 | OpenACC routine directive itself. However, that of c_level_p |
2899 | should be close. */ |
2900 | location_t loc_routine = OMP_CLAUSE_LOCATION (c_level_p)((tree_check ((c_level_p), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2900, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.locus; |
2901 | inform (loc_routine, "... without %qs clause near to here", |
2902 | omp_clause_code_name[OMP_CLAUSE_CODE (c_diag)((tree_check ((c_diag), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2902, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code]); |
2903 | } |
2904 | /* Incompatible. */ |
2905 | return -1; |
2906 | } |
2907 | |
2908 | return 0; |
2909 | } |
2910 | |
2911 | /* Process the OpenACC 'routine' directive clauses to generate an attribute |
2912 | for the level of parallelism. All dimensions have a size of zero |
2913 | (dynamic). TREE_PURPOSE is set to indicate whether that dimension |
2914 | can have a loop partitioned on it. non-zero indicates |
2915 | yes, zero indicates no. By construction once a non-zero has been |
2916 | reached, further inner dimensions must also be non-zero. We set |
2917 | TREE_VALUE to zero for the dimensions that may be partitioned and |
2918 | 1 for the other ones -- if a loop is (erroneously) spawned at |
2919 | an outer level, we don't want to try and partition it. */ |
2920 | |
2921 | tree |
2922 | oacc_build_routine_dims (tree clauses) |
2923 | { |
2924 | /* Must match GOMP_DIM ordering. */ |
2925 | static const omp_clause_code ids[] |
2926 | = {OMP_CLAUSE_GANG, OMP_CLAUSE_WORKER, OMP_CLAUSE_VECTOR, OMP_CLAUSE_SEQ}; |
2927 | int ix; |
2928 | int level = -1; |
2929 | |
2930 | for (; clauses; clauses = OMP_CLAUSE_CHAIN (clauses)((contains_struct_check (((tree_check ((clauses), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2930, __FUNCTION__, (OMP_CLAUSE)))), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2930, __FUNCTION__))->common.chain)) |
2931 | for (ix = GOMP_DIM_MAX3 + 1; ix--;) |
2932 | if (OMP_CLAUSE_CODE (clauses)((tree_check ((clauses), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2932, __FUNCTION__, (OMP_CLAUSE))))->omp_clause.code == ids[ix]) |
2933 | { |
2934 | level = ix; |
2935 | break; |
2936 | } |
2937 | gcc_checking_assert (level >= 0)((void)(!(level >= 0) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2937, __FUNCTION__), 0 : 0)); |
2938 | |
2939 | tree dims = NULL_TREE(tree) nullptr; |
2940 | |
2941 | for (ix = GOMP_DIM_MAX3; ix--;) |
2942 | dims = tree_cons (build_int_cst (boolean_type_nodeglobal_trees[TI_BOOLEAN_TYPE], ix >= level), |
2943 | build_int_cst (integer_type_nodeinteger_types[itk_int], ix < level), dims); |
2944 | |
2945 | return dims; |
2946 | } |
2947 | |
2948 | /* Retrieve the oacc function attrib and return it. Non-oacc |
2949 | functions will return NULL. */ |
2950 | |
2951 | tree |
2952 | oacc_get_fn_attrib (tree fn) |
2953 | { |
2954 | return lookup_attribute (OACC_FN_ATTRIB"oacc function", DECL_ATTRIBUTES (fn)((contains_struct_check ((fn), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2954, __FUNCTION__))->decl_common.attributes)); |
2955 | } |
2956 | |
2957 | /* Return true if FN is an OpenMP or OpenACC offloading function. */ |
2958 | |
2959 | bool |
2960 | offloading_function_p (tree fn) |
2961 | { |
2962 | tree attrs = DECL_ATTRIBUTES (fn)((contains_struct_check ((fn), (TS_DECL_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2962, __FUNCTION__))->decl_common.attributes); |
2963 | return (lookup_attribute ("omp declare target", attrs) |
2964 | || lookup_attribute ("omp target entrypoint", attrs)); |
2965 | } |
2966 | |
2967 | /* Extract an oacc execution dimension from FN. FN must be an |
2968 | offloaded function or routine that has already had its execution |
2969 | dimensions lowered to the target-specific values. */ |
2970 | |
2971 | int |
2972 | oacc_get_fn_dim_size (tree fn, int axis) |
2973 | { |
2974 | tree attrs = oacc_get_fn_attrib (fn); |
2975 | |
2976 | gcc_assert (axis < GOMP_DIM_MAX)((void)(!(axis < 3) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2976, __FUNCTION__), 0 : 0)); |
2977 | |
2978 | tree dims = TREE_VALUE (attrs)((tree_check ((attrs), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2978, __FUNCTION__, (TREE_LIST)))->list.value); |
2979 | while (axis--) |
2980 | dims = TREE_CHAIN (dims)((contains_struct_check ((dims), (TS_COMMON), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2980, __FUNCTION__))->common.chain); |
2981 | |
2982 | int size = TREE_INT_CST_LOW (TREE_VALUE (dims))((unsigned long) (*tree_int_cst_elt_check ((((tree_check ((dims ), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2982, __FUNCTION__, (TREE_LIST)))->list.value)), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2982, __FUNCTION__))); |
2983 | |
2984 | return size; |
2985 | } |
2986 | |
2987 | /* Extract the dimension axis from an IFN_GOACC_DIM_POS or |
2988 | IFN_GOACC_DIM_SIZE call. */ |
2989 | |
2990 | int |
2991 | oacc_get_ifn_dim_arg (const gimple *stmt) |
2992 | { |
2993 | gcc_checking_assert (gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_SIZE((void)(!(gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_SIZE || gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_POS) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2994, __FUNCTION__), 0 : 0)) |
2994 | || gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_POS)((void)(!(gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_SIZE || gimple_call_internal_fn (stmt) == IFN_GOACC_DIM_POS) ? fancy_abort ("/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2994, __FUNCTION__), 0 : 0)); |
2995 | tree arg = gimple_call_arg (stmt, 0); |
2996 | HOST_WIDE_INTlong axis = TREE_INT_CST_LOW (arg)((unsigned long) (*tree_int_cst_elt_check ((arg), (0), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2996, __FUNCTION__))); |
2997 | |
2998 | gcc_checking_assert (axis >= 0 && axis < GOMP_DIM_MAX)((void)(!(axis >= 0 && axis < 3) ? fancy_abort ( "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 2998, __FUNCTION__), 0 : 0)); |
2999 | return (int) axis; |
3000 | } |
3001 | |
3002 | /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it |
3003 | as appropriate. */ |
3004 | |
3005 | tree |
3006 | omp_build_component_ref (tree obj, tree field) |
3007 | { |
3008 | tree ret = build3 (COMPONENT_REF, TREE_TYPE (field)((contains_struct_check ((field), (TS_TYPED), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 3008, __FUNCTION__))->typed.type), obj, field, NULLnullptr); |
3009 | if (TREE_THIS_VOLATILE (field)((field)->base.volatile_flag)) |
3010 | TREE_THIS_VOLATILE (ret)((ret)->base.volatile_flag) |= 1; |
3011 | if (TREE_READONLY (field)((non_type_check ((field), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 3011, __FUNCTION__))->base.readonly_flag)) |
3012 | TREE_READONLY (ret)((non_type_check ((ret), "/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/omp-general.cc" , 3012, __FUNCTION__))->base.readonly_flag) |= 1; |
3013 | return ret; |
3014 | } |
3015 | |
3016 | #include "gt-omp-general.h" |