re PR c++/26559 (ICE with __builtin_constant_p in template argument)
[gcc.git] / gcc / c-omp.c
1 /* This file contains routines to construct GNU OpenMP constructs,
2 called from parsing in the C and C++ front ends.
3
4 Copyright (C) 2005 Free Software Foundation, Inc.
5 Contributed by Richard Henderson <rth@redhat.com>,
6 Diego Novillo <dnovillo@redhat.com>.
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 2, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING. If not, write to the Free
22 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 02110-1301, USA. */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "tree.h"
30 #include "function.h"
31 #include "c-common.h"
32 #include "toplev.h"
33 #include "tree-gimple.h"
34 #include "bitmap.h"
35 #include "langhooks.h"
36
37
38 /* Complete a #pragma omp master construct. STMT is the structured-block
39 that follows the pragma. */
40
41 tree
42 c_finish_omp_master (tree stmt)
43 {
44 return add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
45 }
46
47 /* Complete a #pragma omp critical construct. STMT is the structured-block
48 that follows the pragma, NAME is the identifier in the pragma, or null
49 if it was omitted. */
50
51 tree
52 c_finish_omp_critical (tree body, tree name)
53 {
54 tree stmt = make_node (OMP_CRITICAL);
55 TREE_TYPE (stmt) = void_type_node;
56 OMP_CRITICAL_BODY (stmt) = body;
57 OMP_CRITICAL_NAME (stmt) = name;
58 return add_stmt (stmt);
59 }
60
61 /* Complete a #pragma omp ordered construct. STMT is the structured-block
62 that follows the pragma. */
63
64 tree
65 c_finish_omp_ordered (tree stmt)
66 {
67 return add_stmt (build1 (OMP_ORDERED, void_type_node, stmt));
68 }
69
70
71 /* Complete a #pragma omp barrier construct. */
72
73 void
74 c_finish_omp_barrier (void)
75 {
76 tree x;
77
78 x = built_in_decls[BUILT_IN_GOMP_BARRIER];
79 x = build_function_call_expr (x, NULL);
80 add_stmt (x);
81 }
82
83
84 /* Complete a #pragma omp atomic construct. The expression to be
85 implemented atomically is LHS code= RHS. The value returned is
86 either error_mark_node (if the construct was erroneous) or an
87 OMP_ATOMIC node which should be added to the current statement tree
88 with add_stmt. */
89
90 tree
91 c_finish_omp_atomic (enum tree_code code, tree lhs, tree rhs)
92 {
93 tree x, type, addr;
94
95 if (lhs == error_mark_node || rhs == error_mark_node)
96 return error_mark_node;
97
98 /* ??? According to one reading of the OpenMP spec, complex type are
99 supported, but there are no atomic stores for any architecture.
100 But at least icc 9.0 doesn't support complex types here either.
101 And lets not even talk about vector types... */
102 type = TREE_TYPE (lhs);
103 if (!INTEGRAL_TYPE_P (type)
104 && !POINTER_TYPE_P (type)
105 && !SCALAR_FLOAT_TYPE_P (type))
106 {
107 error ("invalid expression type for %<#pragma omp atomic%>");
108 return error_mark_node;
109 }
110
111 /* ??? Validate that rhs does not overlap lhs. */
112
113 /* Take and save the address of the lhs. From then on we'll reference it
114 via indirection. */
115 addr = build_unary_op (ADDR_EXPR, lhs, 0);
116 if (addr == error_mark_node)
117 return error_mark_node;
118 addr = save_expr (addr);
119 lhs = build_indirect_ref (addr, NULL);
120
121 /* There are lots of warnings, errors, and conversions that need to happen
122 in the course of interpreting a statement. Use the normal mechanisms
123 to do this, and then take it apart again. */
124 x = build_modify_expr (lhs, code, rhs);
125 if (x == error_mark_node)
126 return error_mark_node;
127 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
128 rhs = TREE_OPERAND (x, 1);
129
130 /* Punt the actual generation of atomic operations to common code. */
131 return build2 (OMP_ATOMIC, void_type_node, addr, rhs);
132 }
133
134
135 /* Complete a #pragma omp flush construct. We don't do anything with the
136 variable list that the syntax allows. */
137
138 void
139 c_finish_omp_flush (void)
140 {
141 tree x;
142
143 x = built_in_decls[BUILT_IN_SYNCHRONIZE];
144 x = build_function_call_expr (x, NULL);
145 add_stmt (x);
146 }
147
148
149 /* Check and canonicalize #pragma omp for increment expression.
150 Helper function for c_finish_omp_for. */
151
152 static tree
153 check_omp_for_incr_expr (tree exp, tree decl)
154 {
155 tree t;
156
157 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
158 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
159 return error_mark_node;
160
161 if (exp == decl)
162 return build_int_cst (TREE_TYPE (exp), 0);
163
164 switch (TREE_CODE (exp))
165 {
166 case NOP_EXPR:
167 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
168 if (t != error_mark_node)
169 return fold_convert (TREE_TYPE (exp), t);
170 break;
171 case MINUS_EXPR:
172 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
173 if (t != error_mark_node)
174 return fold_build2 (MINUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
175 break;
176 case PLUS_EXPR:
177 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
178 if (t != error_mark_node)
179 return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
180 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 1), decl);
181 if (t != error_mark_node)
182 return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
183 break;
184 default:
185 break;
186 }
187
188 return error_mark_node;
189 }
190
191 /* Validate and emit code for the OpenMP directive #pragma omp for.
192 INIT, COND, INCR, BODY and PRE_BODY are the five basic elements
193 of the loop (initialization expression, controlling predicate, increment
194 expression, body of the loop and statements to go before the loop).
195 DECL is the iteration variable. */
196
197 tree
198 c_finish_omp_for (location_t locus, tree decl, tree init, tree cond,
199 tree incr, tree body, tree pre_body)
200 {
201 location_t elocus = locus;
202 bool fail = false;
203
204 if (EXPR_HAS_LOCATION (init))
205 elocus = EXPR_LOCATION (init);
206
207 /* Validate the iteration variable. */
208 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
209 {
210 error ("%Hinvalid type for iteration variable %qE", &elocus, decl);
211 fail = true;
212 }
213 if (TYPE_UNSIGNED (TREE_TYPE (decl)))
214 warning (0, "%Hiteration variable %qE is unsigned", &elocus, decl);
215
216 /* In the case of "for (int i = 0...)", init will be a decl. It should
217 have a DECL_INITIAL that we can turn into an assignment. */
218 if (init == decl)
219 {
220 elocus = DECL_SOURCE_LOCATION (decl);
221
222 init = DECL_INITIAL (decl);
223 if (init == NULL)
224 {
225 error ("%H%qE is not initialized", &elocus, decl);
226 init = integer_zero_node;
227 fail = true;
228 }
229
230 init = build_modify_expr (decl, NOP_EXPR, init);
231 SET_EXPR_LOCATION (init, elocus);
232 }
233 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
234 gcc_assert (TREE_OPERAND (init, 0) == decl);
235
236 if (cond == NULL_TREE)
237 {
238 error ("%Hmissing controlling predicate", &elocus);
239 fail = true;
240 }
241 else
242 {
243 bool cond_ok = false;
244
245 if (EXPR_HAS_LOCATION (cond))
246 elocus = EXPR_LOCATION (cond);
247
248 if (TREE_CODE (cond) == LT_EXPR
249 || TREE_CODE (cond) == LE_EXPR
250 || TREE_CODE (cond) == GT_EXPR
251 || TREE_CODE (cond) == GE_EXPR)
252 {
253 tree op0 = TREE_OPERAND (cond, 0);
254 tree op1 = TREE_OPERAND (cond, 1);
255
256 /* 2.5.1. The comparison in the condition is computed in the type
257 of DECL, otherwise the behavior is undefined.
258
259 For example:
260 long n; int i;
261 i < n;
262
263 according to ISO will be evaluated as:
264 (long)i < n;
265
266 We want to force:
267 i < (int)n; */
268 if (TREE_CODE (op0) == NOP_EXPR
269 && decl == TREE_OPERAND (op0, 0))
270 {
271 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
272 TREE_OPERAND (cond, 1) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
273 TREE_OPERAND (cond, 1));
274 }
275 else if (TREE_CODE (op1) == NOP_EXPR
276 && decl == TREE_OPERAND (op1, 0))
277 {
278 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
279 TREE_OPERAND (cond, 0) = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
280 TREE_OPERAND (cond, 0));
281 }
282
283 if (decl == TREE_OPERAND (cond, 0))
284 cond_ok = true;
285 else if (decl == TREE_OPERAND (cond, 1))
286 {
287 TREE_SET_CODE (cond, swap_tree_comparison (TREE_CODE (cond)));
288 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
289 TREE_OPERAND (cond, 0) = decl;
290 cond_ok = true;
291 }
292 }
293
294 if (!cond_ok)
295 {
296 error ("%Hinvalid controlling predicate", &elocus);
297 fail = true;
298 }
299 }
300
301 if (incr == NULL_TREE)
302 {
303 error ("%Hmissing increment expression", &elocus);
304 fail = true;
305 }
306 else
307 {
308 bool incr_ok = false;
309
310 if (EXPR_HAS_LOCATION (incr))
311 elocus = EXPR_LOCATION (incr);
312
313 /* Check all the valid increment expressions: v++, v--, ++v, --v,
314 v = v + incr, v = incr + v and v = v - incr. */
315 switch (TREE_CODE (incr))
316 {
317 case POSTINCREMENT_EXPR:
318 case PREINCREMENT_EXPR:
319 case POSTDECREMENT_EXPR:
320 case PREDECREMENT_EXPR:
321 incr_ok = (TREE_OPERAND (incr, 0) == decl);
322 break;
323
324 case MODIFY_EXPR:
325 if (TREE_OPERAND (incr, 0) != decl)
326 break;
327 if (TREE_OPERAND (incr, 1) == decl)
328 break;
329 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
330 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
331 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
332 incr_ok = true;
333 else if (TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
334 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
335 incr_ok = true;
336 else
337 {
338 tree t = check_omp_for_incr_expr (TREE_OPERAND (incr, 1), decl);
339 if (t != error_mark_node)
340 {
341 incr_ok = true;
342 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
343 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
344 }
345 }
346 break;
347
348 default:
349 break;
350 }
351 if (!incr_ok)
352 {
353 error ("%Hinvalid increment expression", &elocus);
354 fail = true;
355 }
356 }
357
358 if (fail)
359 return NULL;
360 else
361 {
362 tree t = make_node (OMP_FOR);
363
364 TREE_TYPE (t) = void_type_node;
365 OMP_FOR_INIT (t) = init;
366 OMP_FOR_COND (t) = cond;
367 OMP_FOR_INCR (t) = incr;
368 OMP_FOR_BODY (t) = body;
369 OMP_FOR_PRE_BODY (t) = pre_body;
370
371 SET_EXPR_LOCATION (t, locus);
372 return add_stmt (t);
373 }
374 }
375
376
377 /* Divide CLAUSES into two lists: those that apply to a parallel construct,
378 and those that apply to a work-sharing construct. Place the results in
379 *PAR_CLAUSES and *WS_CLAUSES respectively. In addition, add a nowait
380 clause to the work-sharing list. */
381
382 void
383 c_split_parallel_clauses (tree clauses, tree *par_clauses, tree *ws_clauses)
384 {
385 tree next;
386
387 *par_clauses = NULL;
388 *ws_clauses = build_omp_clause (OMP_CLAUSE_NOWAIT);
389
390 for (; clauses ; clauses = next)
391 {
392 next = OMP_CLAUSE_CHAIN (clauses);
393
394 switch (OMP_CLAUSE_CODE (clauses))
395 {
396 case OMP_CLAUSE_PRIVATE:
397 case OMP_CLAUSE_SHARED:
398 case OMP_CLAUSE_FIRSTPRIVATE:
399 case OMP_CLAUSE_LASTPRIVATE:
400 case OMP_CLAUSE_REDUCTION:
401 case OMP_CLAUSE_COPYIN:
402 case OMP_CLAUSE_IF:
403 case OMP_CLAUSE_NUM_THREADS:
404 case OMP_CLAUSE_DEFAULT:
405 OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
406 *par_clauses = clauses;
407 break;
408
409 case OMP_CLAUSE_SCHEDULE:
410 case OMP_CLAUSE_ORDERED:
411 OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
412 *ws_clauses = clauses;
413 break;
414
415 default:
416 gcc_unreachable ();
417 }
418 }
419 }
420
421 /* True if OpenMP sharing attribute of DECL is predetermined. */
422
423 enum omp_clause_default_kind
424 c_omp_predetermined_sharing (tree decl)
425 {
426 /* Variables with const-qualified type having no mutable member
427 are predetermined shared. */
428 if (TREE_READONLY (decl))
429 return OMP_CLAUSE_DEFAULT_SHARED;
430
431 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
432 }