PR c++/40619
[official-gcc/constexpr.git] / gcc / c-omp.c
blob5ec9f94ff6818a51c64dfb2ebfa4b199ecdc9142
1 /* This file contains routines to construct GNU OpenMP constructs,
2 called from parsing in the C and C++ front ends.
4 Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
5 Contributed by Richard Henderson <rth@redhat.com>,
6 Diego Novillo <dnovillo@redhat.com>.
8 This file is part of GCC.
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 3, or (at your option) any later
13 version.
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.
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "tree.h"
29 #include "function.h"
30 #include "c-common.h"
31 #include "toplev.h"
32 #include "gimple.h"
33 #include "bitmap.h"
34 #include "langhooks.h"
37 /* Complete a #pragma omp master construct. STMT is the structured-block
38 that follows the pragma. LOC is the l*/
40 tree
41 c_finish_omp_master (location_t loc, tree stmt)
43 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
44 SET_EXPR_LOCATION (t, loc);
45 return t;
48 /* Complete a #pragma omp critical construct. STMT is the structured-block
49 that follows the pragma, NAME is the identifier in the pragma, or null
50 if it was omitted. LOC is the location of the #pragma. */
52 tree
53 c_finish_omp_critical (location_t loc, tree body, tree name)
55 tree stmt = make_node (OMP_CRITICAL);
56 TREE_TYPE (stmt) = void_type_node;
57 OMP_CRITICAL_BODY (stmt) = body;
58 OMP_CRITICAL_NAME (stmt) = name;
59 SET_EXPR_LOCATION (stmt, loc);
60 return add_stmt (stmt);
63 /* Complete a #pragma omp ordered construct. STMT is the structured-block
64 that follows the pragma. LOC is the location of the #pragma. */
66 tree
67 c_finish_omp_ordered (location_t loc, tree stmt)
69 tree t = build1 (OMP_ORDERED, void_type_node, stmt);
70 SET_EXPR_LOCATION (t, loc);
71 return add_stmt (t);
75 /* Complete a #pragma omp barrier construct. LOC is the location of
76 the #pragma. */
78 void
79 c_finish_omp_barrier (location_t loc)
81 tree x;
83 x = built_in_decls[BUILT_IN_GOMP_BARRIER];
84 x = build_call_expr (x, 0);
85 SET_EXPR_LOCATION (x, loc);
86 add_stmt (x);
90 /* Complete a #pragma omp taskwait construct. LOC is the location of the
91 pragma. */
93 void
94 c_finish_omp_taskwait (location_t loc)
96 tree x;
98 x = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
99 x = build_call_expr (x, 0);
100 SET_EXPR_LOCATION (x, loc);
101 add_stmt (x);
105 /* Complete a #pragma omp atomic construct. The expression to be
106 implemented atomically is LHS code= RHS. LOC is the location of
107 the atomic statement. The value returned is either error_mark_node
108 (if the construct was erroneous) or an OMP_ATOMIC node which should
109 be added to the current statement tree with add_stmt.*/
111 tree
112 c_finish_omp_atomic (location_t loc, enum tree_code code, tree lhs, tree rhs)
114 tree x, type, addr;
116 if (lhs == error_mark_node || rhs == error_mark_node)
117 return error_mark_node;
119 /* ??? According to one reading of the OpenMP spec, complex type are
120 supported, but there are no atomic stores for any architecture.
121 But at least icc 9.0 doesn't support complex types here either.
122 And lets not even talk about vector types... */
123 type = TREE_TYPE (lhs);
124 if (!INTEGRAL_TYPE_P (type)
125 && !POINTER_TYPE_P (type)
126 && !SCALAR_FLOAT_TYPE_P (type))
128 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
129 return error_mark_node;
132 /* ??? Validate that rhs does not overlap lhs. */
134 /* Take and save the address of the lhs. From then on we'll reference it
135 via indirection. */
136 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
137 if (addr == error_mark_node)
138 return error_mark_node;
139 addr = save_expr (addr);
140 if (TREE_CODE (addr) != SAVE_EXPR
141 && (TREE_CODE (addr) != ADDR_EXPR
142 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
144 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
145 it even after unsharing function body. */
146 tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
147 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
149 lhs = build_indirect_ref (loc, addr, NULL);
151 /* There are lots of warnings, errors, and conversions that need to happen
152 in the course of interpreting a statement. Use the normal mechanisms
153 to do this, and then take it apart again. */
154 x = build_modify_expr (input_location, lhs, NULL_TREE, code,
155 input_location, rhs, NULL_TREE);
156 if (x == error_mark_node)
157 return error_mark_node;
158 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
159 rhs = TREE_OPERAND (x, 1);
161 /* Punt the actual generation of atomic operations to common code. */
162 x = build2 (OMP_ATOMIC, void_type_node, addr, rhs);
163 SET_EXPR_LOCATION (x, loc);
164 return x;
168 /* Complete a #pragma omp flush construct. We don't do anything with
169 the variable list that the syntax allows. LOC is the location of
170 the #pragma. */
172 void
173 c_finish_omp_flush (location_t loc)
175 tree x;
177 x = built_in_decls[BUILT_IN_SYNCHRONIZE];
178 x = build_call_expr (x, 0);
179 SET_EXPR_LOCATION (x, loc);
180 add_stmt (x);
184 /* Check and canonicalize #pragma omp for increment expression.
185 Helper function for c_finish_omp_for. */
187 static tree
188 check_omp_for_incr_expr (tree exp, tree decl)
190 tree t;
192 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
193 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
194 return error_mark_node;
196 if (exp == decl)
197 return build_int_cst (TREE_TYPE (exp), 0);
199 switch (TREE_CODE (exp))
201 CASE_CONVERT:
202 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
203 if (t != error_mark_node)
204 return fold_convert (TREE_TYPE (exp), t);
205 break;
206 case MINUS_EXPR:
207 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
208 if (t != error_mark_node)
209 return fold_build2 (MINUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
210 break;
211 case PLUS_EXPR:
212 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 0), decl);
213 if (t != error_mark_node)
214 return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
215 t = check_omp_for_incr_expr (TREE_OPERAND (exp, 1), decl);
216 if (t != error_mark_node)
217 return fold_build2 (PLUS_EXPR, TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
218 break;
219 default:
220 break;
223 return error_mark_node;
226 /* Validate and emit code for the OpenMP directive #pragma omp for.
227 DECLV is a vector of iteration variables, for each collapsed loop.
228 INITV, CONDV and INCRV are vectors containing initialization
229 expressions, controlling predicates and increment expressions.
230 BODY is the body of the loop and PRE_BODY statements that go before
231 the loop. */
233 tree
234 c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
235 tree incrv, tree body, tree pre_body)
237 location_t elocus;
238 bool fail = false;
239 int i;
241 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
242 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
243 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
244 for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
246 tree decl = TREE_VEC_ELT (declv, i);
247 tree init = TREE_VEC_ELT (initv, i);
248 tree cond = TREE_VEC_ELT (condv, i);
249 tree incr = TREE_VEC_ELT (incrv, i);
251 elocus = locus;
252 if (EXPR_HAS_LOCATION (init))
253 elocus = EXPR_LOCATION (init);
255 /* Validate the iteration variable. */
256 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
257 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
259 error_at (elocus, "invalid type for iteration variable %qE", decl);
260 fail = true;
263 /* In the case of "for (int i = 0...)", init will be a decl. It should
264 have a DECL_INITIAL that we can turn into an assignment. */
265 if (init == decl)
267 elocus = DECL_SOURCE_LOCATION (decl);
269 init = DECL_INITIAL (decl);
270 if (init == NULL)
272 error_at (elocus, "%qE is not initialized", decl);
273 init = integer_zero_node;
274 fail = true;
277 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
278 /* FIXME diagnostics: This should
279 be the location of the INIT. */
280 elocus,
281 init,
282 NULL_TREE);
284 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
285 gcc_assert (TREE_OPERAND (init, 0) == decl);
287 if (cond == NULL_TREE)
289 error_at (elocus, "missing controlling predicate");
290 fail = true;
292 else
294 bool cond_ok = false;
296 if (EXPR_HAS_LOCATION (cond))
297 elocus = EXPR_LOCATION (cond);
299 if (TREE_CODE (cond) == LT_EXPR
300 || TREE_CODE (cond) == LE_EXPR
301 || TREE_CODE (cond) == GT_EXPR
302 || TREE_CODE (cond) == GE_EXPR
303 || TREE_CODE (cond) == NE_EXPR)
305 tree op0 = TREE_OPERAND (cond, 0);
306 tree op1 = TREE_OPERAND (cond, 1);
308 /* 2.5.1. The comparison in the condition is computed in
309 the type of DECL, otherwise the behavior is undefined.
311 For example:
312 long n; int i;
313 i < n;
315 according to ISO will be evaluated as:
316 (long)i < n;
318 We want to force:
319 i < (int)n; */
320 if (TREE_CODE (op0) == NOP_EXPR
321 && decl == TREE_OPERAND (op0, 0))
323 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
324 TREE_OPERAND (cond, 1)
325 = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
326 TREE_OPERAND (cond, 1));
328 else if (TREE_CODE (op1) == NOP_EXPR
329 && decl == TREE_OPERAND (op1, 0))
331 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
332 TREE_OPERAND (cond, 0)
333 = fold_build1 (NOP_EXPR, TREE_TYPE (decl),
334 TREE_OPERAND (cond, 0));
337 if (decl == TREE_OPERAND (cond, 0))
338 cond_ok = true;
339 else if (decl == TREE_OPERAND (cond, 1))
341 TREE_SET_CODE (cond,
342 swap_tree_comparison (TREE_CODE (cond)));
343 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
344 TREE_OPERAND (cond, 0) = decl;
345 cond_ok = true;
348 if (TREE_CODE (cond) == NE_EXPR)
350 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
351 cond_ok = false;
352 else if (operand_equal_p (TREE_OPERAND (cond, 1),
353 TYPE_MIN_VALUE (TREE_TYPE (decl)),
355 TREE_SET_CODE (cond, GT_EXPR);
356 else if (operand_equal_p (TREE_OPERAND (cond, 1),
357 TYPE_MAX_VALUE (TREE_TYPE (decl)),
359 TREE_SET_CODE (cond, LT_EXPR);
360 else
361 cond_ok = false;
365 if (!cond_ok)
367 error_at (elocus, "invalid controlling predicate");
368 fail = true;
372 if (incr == NULL_TREE)
374 error_at (elocus, "missing increment expression");
375 fail = true;
377 else
379 bool incr_ok = false;
381 if (EXPR_HAS_LOCATION (incr))
382 elocus = EXPR_LOCATION (incr);
384 /* Check all the valid increment expressions: v++, v--, ++v, --v,
385 v = v + incr, v = incr + v and v = v - incr. */
386 switch (TREE_CODE (incr))
388 case POSTINCREMENT_EXPR:
389 case PREINCREMENT_EXPR:
390 case POSTDECREMENT_EXPR:
391 case PREDECREMENT_EXPR:
392 if (TREE_OPERAND (incr, 0) != decl)
393 break;
395 incr_ok = true;
396 if (POINTER_TYPE_P (TREE_TYPE (decl))
397 && TREE_OPERAND (incr, 1))
399 tree t = fold_convert (sizetype, TREE_OPERAND (incr, 1));
401 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
402 || TREE_CODE (incr) == PREDECREMENT_EXPR)
403 t = fold_build1 (NEGATE_EXPR, sizetype, t);
404 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (decl), decl, t);
405 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
407 break;
409 case MODIFY_EXPR:
410 if (TREE_OPERAND (incr, 0) != decl)
411 break;
412 if (TREE_OPERAND (incr, 1) == decl)
413 break;
414 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
415 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
416 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
417 incr_ok = true;
418 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
419 || (TREE_CODE (TREE_OPERAND (incr, 1))
420 == POINTER_PLUS_EXPR))
421 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
422 incr_ok = true;
423 else
425 tree t = check_omp_for_incr_expr (TREE_OPERAND (incr, 1),
426 decl);
427 if (t != error_mark_node)
429 incr_ok = true;
430 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
431 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
434 break;
436 default:
437 break;
439 if (!incr_ok)
441 error_at (elocus, "invalid increment expression");
442 fail = true;
446 TREE_VEC_ELT (initv, i) = init;
447 TREE_VEC_ELT (incrv, i) = incr;
450 if (fail)
451 return NULL;
452 else
454 tree t = make_node (OMP_FOR);
456 TREE_TYPE (t) = void_type_node;
457 OMP_FOR_INIT (t) = initv;
458 OMP_FOR_COND (t) = condv;
459 OMP_FOR_INCR (t) = incrv;
460 OMP_FOR_BODY (t) = body;
461 OMP_FOR_PRE_BODY (t) = pre_body;
463 SET_EXPR_LOCATION (t, locus);
464 return add_stmt (t);
469 /* Divide CLAUSES into two lists: those that apply to a parallel
470 construct, and those that apply to a work-sharing construct. Place
471 the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In
472 addition, add a nowait clause to the work-sharing list. LOC is the
473 location of the OMP_PARALLEL*. */
475 void
476 c_split_parallel_clauses (location_t loc, tree clauses,
477 tree *par_clauses, tree *ws_clauses)
479 tree next;
481 *par_clauses = NULL;
482 *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
484 for (; clauses ; clauses = next)
486 next = OMP_CLAUSE_CHAIN (clauses);
488 switch (OMP_CLAUSE_CODE (clauses))
490 case OMP_CLAUSE_PRIVATE:
491 case OMP_CLAUSE_SHARED:
492 case OMP_CLAUSE_FIRSTPRIVATE:
493 case OMP_CLAUSE_LASTPRIVATE:
494 case OMP_CLAUSE_REDUCTION:
495 case OMP_CLAUSE_COPYIN:
496 case OMP_CLAUSE_IF:
497 case OMP_CLAUSE_NUM_THREADS:
498 case OMP_CLAUSE_DEFAULT:
499 OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
500 *par_clauses = clauses;
501 break;
503 case OMP_CLAUSE_SCHEDULE:
504 case OMP_CLAUSE_ORDERED:
505 case OMP_CLAUSE_COLLAPSE:
506 OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
507 *ws_clauses = clauses;
508 break;
510 default:
511 gcc_unreachable ();
516 /* True if OpenMP sharing attribute of DECL is predetermined. */
518 enum omp_clause_default_kind
519 c_omp_predetermined_sharing (tree decl)
521 /* Variables with const-qualified type having no mutable member
522 are predetermined shared. */
523 if (TREE_READONLY (decl))
524 return OMP_CLAUSE_DEFAULT_SHARED;
526 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;