]> gcc.gnu.org Git - gcc.git/blame - gcc/c-omp.c
Remove trailing white spaces.
[gcc.git] / gcc / c-omp.c
CommitLineData
b8698a0f 1/* This file contains routines to construct GNU OpenMP constructs,
953ff289
DN
2 called from parsing in the C and C++ front ends.
3
ea1199ee 4 Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
953ff289
DN
5 Contributed by Richard Henderson <rth@redhat.com>,
6 Diego Novillo <dnovillo@redhat.com>.
7
8This file is part of GCC.
9
10GCC is free software; you can redistribute it and/or modify it under
11the terms of the GNU General Public License as published by the Free
9dcd6f09 12Software Foundation; either version 3, or (at your option) any later
953ff289
DN
13version.
14
15GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16WARRANTY; without even the implied warranty of MERCHANTABILITY or
17FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18for more details.
19
20You should have received a copy of the GNU General Public License
9dcd6f09
NC
21along with GCC; see the file COPYING3. If not see
22<http://www.gnu.org/licenses/>. */
953ff289
DN
23
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"
726a989a 32#include "gimple.h"
953ff289
DN
33#include "bitmap.h"
34#include "langhooks.h"
35
36
37/* Complete a #pragma omp master construct. STMT is the structured-block
c2255bc4 38 that follows the pragma. LOC is the l*/
953ff289
DN
39
40tree
c2255bc4 41c_finish_omp_master (location_t loc, tree stmt)
953ff289 42{
c2255bc4
AH
43 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
44 SET_EXPR_LOCATION (t, loc);
45 return t;
953ff289
DN
46}
47
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
c2255bc4 50 if it was omitted. LOC is the location of the #pragma. */
953ff289
DN
51
52tree
c2255bc4 53c_finish_omp_critical (location_t loc, tree body, tree name)
953ff289
DN
54{
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;
c2255bc4 59 SET_EXPR_LOCATION (stmt, loc);
953ff289
DN
60 return add_stmt (stmt);
61}
62
63/* Complete a #pragma omp ordered construct. STMT is the structured-block
c2255bc4 64 that follows the pragma. LOC is the location of the #pragma. */
953ff289
DN
65
66tree
c2255bc4 67c_finish_omp_ordered (location_t loc, tree stmt)
953ff289 68{
c2255bc4
AH
69 tree t = build1 (OMP_ORDERED, void_type_node, stmt);
70 SET_EXPR_LOCATION (t, loc);
71 return add_stmt (t);
953ff289
DN
72}
73
74
c2255bc4
AH
75/* Complete a #pragma omp barrier construct. LOC is the location of
76 the #pragma. */
953ff289
DN
77
78void
c2255bc4 79c_finish_omp_barrier (location_t loc)
953ff289
DN
80{
81 tree x;
82
83 x = built_in_decls[BUILT_IN_GOMP_BARRIER];
db3927fb 84 x = build_call_expr_loc (loc, x, 0);
953ff289
DN
85 add_stmt (x);
86}
87
88
c2255bc4
AH
89/* Complete a #pragma omp taskwait construct. LOC is the location of the
90 pragma. */
a68ab351
JJ
91
92void
c2255bc4 93c_finish_omp_taskwait (location_t loc)
a68ab351
JJ
94{
95 tree x;
96
97 x = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
db3927fb 98 x = build_call_expr_loc (loc, x, 0);
a68ab351
JJ
99 add_stmt (x);
100}
101
102
c2255bc4
AH
103/* Complete a #pragma omp atomic construct. The expression to be
104 implemented atomically is LHS code= RHS. LOC is the location of
105 the atomic statement. The value returned is either error_mark_node
106 (if the construct was erroneous) or an OMP_ATOMIC node which should
107 be added to the current statement tree with add_stmt.*/
953ff289 108
fe89d797 109tree
c2255bc4 110c_finish_omp_atomic (location_t loc, enum tree_code code, tree lhs, tree rhs)
953ff289
DN
111{
112 tree x, type, addr;
113
114 if (lhs == error_mark_node || rhs == error_mark_node)
fe89d797 115 return error_mark_node;
953ff289
DN
116
117 /* ??? According to one reading of the OpenMP spec, complex type are
118 supported, but there are no atomic stores for any architecture.
119 But at least icc 9.0 doesn't support complex types here either.
120 And lets not even talk about vector types... */
121 type = TREE_TYPE (lhs);
122 if (!INTEGRAL_TYPE_P (type)
123 && !POINTER_TYPE_P (type)
124 && !SCALAR_FLOAT_TYPE_P (type))
125 {
c2255bc4 126 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
fe89d797 127 return error_mark_node;
953ff289
DN
128 }
129
130 /* ??? Validate that rhs does not overlap lhs. */
131
132 /* Take and save the address of the lhs. From then on we'll reference it
133 via indirection. */
c2255bc4 134 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
953ff289 135 if (addr == error_mark_node)
fe89d797 136 return error_mark_node;
953ff289 137 addr = save_expr (addr);
66bb4f32
JJ
138 if (TREE_CODE (addr) != SAVE_EXPR
139 && (TREE_CODE (addr) != ADDR_EXPR
140 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
141 {
142 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
143 it even after unsharing function body. */
144 tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
a406865a 145 DECL_CONTEXT (var) = current_function_decl;
66bb4f32
JJ
146 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
147 }
c2255bc4 148 lhs = build_indirect_ref (loc, addr, NULL);
953ff289
DN
149
150 /* There are lots of warnings, errors, and conversions that need to happen
151 in the course of interpreting a statement. Use the normal mechanisms
152 to do this, and then take it apart again. */
c2255bc4
AH
153 x = build_modify_expr (input_location, lhs, NULL_TREE, code,
154 input_location, rhs, NULL_TREE);
953ff289 155 if (x == error_mark_node)
fe89d797 156 return error_mark_node;
b8698a0f 157 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
953ff289
DN
158 rhs = TREE_OPERAND (x, 1);
159
160 /* Punt the actual generation of atomic operations to common code. */
c2255bc4
AH
161 x = build2 (OMP_ATOMIC, void_type_node, addr, rhs);
162 SET_EXPR_LOCATION (x, loc);
163 return x;
953ff289
DN
164}
165
166
c2255bc4
AH
167/* Complete a #pragma omp flush construct. We don't do anything with
168 the variable list that the syntax allows. LOC is the location of
169 the #pragma. */
953ff289
DN
170
171void
c2255bc4 172c_finish_omp_flush (location_t loc)
953ff289
DN
173{
174 tree x;
175
176 x = built_in_decls[BUILT_IN_SYNCHRONIZE];
db3927fb 177 x = build_call_expr_loc (loc, x, 0);
953ff289
DN
178 add_stmt (x);
179}
180
181
182/* Check and canonicalize #pragma omp for increment expression.
183 Helper function for c_finish_omp_for. */
184
185static tree
db3927fb 186check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
953ff289
DN
187{
188 tree t;
189
190 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
191 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
192 return error_mark_node;
193
194 if (exp == decl)
195 return build_int_cst (TREE_TYPE (exp), 0);
196
197 switch (TREE_CODE (exp))
198 {
1043771b 199 CASE_CONVERT:
db3927fb 200 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
953ff289 201 if (t != error_mark_node)
db3927fb 202 return fold_convert_loc (loc, TREE_TYPE (exp), t);
953ff289
DN
203 break;
204 case MINUS_EXPR:
db3927fb 205 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
953ff289 206 if (t != error_mark_node)
db3927fb
AH
207 return fold_build2_loc (loc, MINUS_EXPR,
208 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
953ff289
DN
209 break;
210 case PLUS_EXPR:
db3927fb 211 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
953ff289 212 if (t != error_mark_node)
db3927fb
AH
213 return fold_build2_loc (loc, PLUS_EXPR,
214 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
215 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
953ff289 216 if (t != error_mark_node)
db3927fb
AH
217 return fold_build2_loc (loc, PLUS_EXPR,
218 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
953ff289
DN
219 break;
220 default:
221 break;
222 }
223
224 return error_mark_node;
225}
226
227/* Validate and emit code for the OpenMP directive #pragma omp for.
a68ab351
JJ
228 DECLV is a vector of iteration variables, for each collapsed loop.
229 INITV, CONDV and INCRV are vectors containing initialization
230 expressions, controlling predicates and increment expressions.
231 BODY is the body of the loop and PRE_BODY statements that go before
232 the loop. */
953ff289
DN
233
234tree
a68ab351
JJ
235c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
236 tree incrv, tree body, tree pre_body)
953ff289 237{
a68ab351 238 location_t elocus;
953ff289 239 bool fail = false;
a68ab351 240 int i;
953ff289 241
a68ab351
JJ
242 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
243 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
244 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
245 for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
953ff289 246 {
a68ab351
JJ
247 tree decl = TREE_VEC_ELT (declv, i);
248 tree init = TREE_VEC_ELT (initv, i);
249 tree cond = TREE_VEC_ELT (condv, i);
250 tree incr = TREE_VEC_ELT (incrv, i);
251
252 elocus = locus;
253 if (EXPR_HAS_LOCATION (init))
254 elocus = EXPR_LOCATION (init);
255
256 /* Validate the iteration variable. */
257 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
258 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
259 {
c9f9eb5d 260 error_at (elocus, "invalid type for iteration variable %qE", decl);
a68ab351
JJ
261 fail = true;
262 }
953ff289 263
a68ab351
JJ
264 /* In the case of "for (int i = 0...)", init will be a decl. It should
265 have a DECL_INITIAL that we can turn into an assignment. */
266 if (init == decl)
267 {
268 elocus = DECL_SOURCE_LOCATION (decl);
269
270 init = DECL_INITIAL (decl);
271 if (init == NULL)
272 {
c9f9eb5d 273 error_at (elocus, "%qE is not initialized", decl);
a68ab351
JJ
274 init = integer_zero_node;
275 fail = true;
276 }
953ff289 277
b8698a0f 278 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
c2255bc4
AH
279 /* FIXME diagnostics: This should
280 be the location of the INIT. */
281 elocus,
282 init,
32e8bb8e 283 NULL_TREE);
a68ab351
JJ
284 }
285 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
286 gcc_assert (TREE_OPERAND (init, 0) == decl);
287
288 if (cond == NULL_TREE)
953ff289 289 {
c9f9eb5d 290 error_at (elocus, "missing controlling predicate");
953ff289
DN
291 fail = true;
292 }
a68ab351
JJ
293 else
294 {
295 bool cond_ok = false;
953ff289 296
a68ab351
JJ
297 if (EXPR_HAS_LOCATION (cond))
298 elocus = EXPR_LOCATION (cond);
953ff289 299
a68ab351
JJ
300 if (TREE_CODE (cond) == LT_EXPR
301 || TREE_CODE (cond) == LE_EXPR
302 || TREE_CODE (cond) == GT_EXPR
ea1199ee
JJ
303 || TREE_CODE (cond) == GE_EXPR
304 || TREE_CODE (cond) == NE_EXPR)
a68ab351
JJ
305 {
306 tree op0 = TREE_OPERAND (cond, 0);
307 tree op1 = TREE_OPERAND (cond, 1);
953ff289 308
a68ab351
JJ
309 /* 2.5.1. The comparison in the condition is computed in
310 the type of DECL, otherwise the behavior is undefined.
953ff289 311
a68ab351
JJ
312 For example:
313 long n; int i;
314 i < n;
953ff289 315
a68ab351
JJ
316 according to ISO will be evaluated as:
317 (long)i < n;
953ff289 318
a68ab351
JJ
319 We want to force:
320 i < (int)n; */
321 if (TREE_CODE (op0) == NOP_EXPR
322 && decl == TREE_OPERAND (op0, 0))
323 {
324 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
325 TREE_OPERAND (cond, 1)
db3927fb 326 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
a68ab351
JJ
327 TREE_OPERAND (cond, 1));
328 }
329 else if (TREE_CODE (op1) == NOP_EXPR
330 && decl == TREE_OPERAND (op1, 0))
331 {
332 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
333 TREE_OPERAND (cond, 0)
db3927fb 334 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
a68ab351
JJ
335 TREE_OPERAND (cond, 0));
336 }
953ff289 337
a68ab351
JJ
338 if (decl == TREE_OPERAND (cond, 0))
339 cond_ok = true;
340 else if (decl == TREE_OPERAND (cond, 1))
341 {
342 TREE_SET_CODE (cond,
343 swap_tree_comparison (TREE_CODE (cond)));
344 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
345 TREE_OPERAND (cond, 0) = decl;
346 cond_ok = true;
347 }
ea1199ee
JJ
348
349 if (TREE_CODE (cond) == NE_EXPR)
350 {
351 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
352 cond_ok = false;
353 else if (operand_equal_p (TREE_OPERAND (cond, 1),
354 TYPE_MIN_VALUE (TREE_TYPE (decl)),
355 0))
356 TREE_SET_CODE (cond, GT_EXPR);
357 else if (operand_equal_p (TREE_OPERAND (cond, 1),
358 TYPE_MAX_VALUE (TREE_TYPE (decl)),
359 0))
360 TREE_SET_CODE (cond, LT_EXPR);
361 else
362 cond_ok = false;
363 }
953ff289
DN
364 }
365
a68ab351 366 if (!cond_ok)
953ff289 367 {
c9f9eb5d 368 error_at (elocus, "invalid controlling predicate");
a68ab351 369 fail = true;
953ff289
DN
370 }
371 }
372
a68ab351 373 if (incr == NULL_TREE)
953ff289 374 {
c9f9eb5d 375 error_at (elocus, "missing increment expression");
953ff289
DN
376 fail = true;
377 }
a68ab351 378 else
953ff289 379 {
a68ab351 380 bool incr_ok = false;
953ff289 381
a68ab351
JJ
382 if (EXPR_HAS_LOCATION (incr))
383 elocus = EXPR_LOCATION (incr);
384
385 /* Check all the valid increment expressions: v++, v--, ++v, --v,
386 v = v + incr, v = incr + v and v = v - incr. */
387 switch (TREE_CODE (incr))
953ff289 388 {
a68ab351
JJ
389 case POSTINCREMENT_EXPR:
390 case PREINCREMENT_EXPR:
391 case POSTDECREMENT_EXPR:
392 case PREDECREMENT_EXPR:
393 if (TREE_OPERAND (incr, 0) != decl)
394 break;
395
396 incr_ok = true;
956adfaf
JJ
397 if (POINTER_TYPE_P (TREE_TYPE (decl))
398 && TREE_OPERAND (incr, 1))
953ff289 399 {
db3927fb
AH
400 tree t = fold_convert_loc (elocus,
401 sizetype, TREE_OPERAND (incr, 1));
a68ab351
JJ
402
403 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
404 || TREE_CODE (incr) == PREDECREMENT_EXPR)
db3927fb 405 t = fold_build1_loc (elocus, NEGATE_EXPR, sizetype, t);
a68ab351 406 t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (decl), decl, t);
953ff289
DN
407 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
408 }
a68ab351
JJ
409 break;
410
411 case MODIFY_EXPR:
412 if (TREE_OPERAND (incr, 0) != decl)
413 break;
414 if (TREE_OPERAND (incr, 1) == decl)
415 break;
416 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
417 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
418 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
419 incr_ok = true;
420 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
421 || (TREE_CODE (TREE_OPERAND (incr, 1))
422 == POINTER_PLUS_EXPR))
423 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
424 incr_ok = true;
425 else
426 {
db3927fb
AH
427 tree t = check_omp_for_incr_expr (elocus,
428 TREE_OPERAND (incr, 1),
a68ab351
JJ
429 decl);
430 if (t != error_mark_node)
431 {
432 incr_ok = true;
433 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
434 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
435 }
436 }
437 break;
953ff289 438
a68ab351
JJ
439 default:
440 break;
441 }
442 if (!incr_ok)
443 {
c9f9eb5d 444 error_at (elocus, "invalid increment expression");
a68ab351
JJ
445 fail = true;
446 }
953ff289 447 }
a68ab351
JJ
448
449 TREE_VEC_ELT (initv, i) = init;
450 TREE_VEC_ELT (incrv, i) = incr;
953ff289
DN
451 }
452
453 if (fail)
454 return NULL;
455 else
456 {
457 tree t = make_node (OMP_FOR);
458
459 TREE_TYPE (t) = void_type_node;
a68ab351
JJ
460 OMP_FOR_INIT (t) = initv;
461 OMP_FOR_COND (t) = condv;
462 OMP_FOR_INCR (t) = incrv;
953ff289
DN
463 OMP_FOR_BODY (t) = body;
464 OMP_FOR_PRE_BODY (t) = pre_body;
465
466 SET_EXPR_LOCATION (t, locus);
467 return add_stmt (t);
468 }
469}
470
471
c2255bc4
AH
472/* Divide CLAUSES into two lists: those that apply to a parallel
473 construct, and those that apply to a work-sharing construct. Place
474 the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In
475 addition, add a nowait clause to the work-sharing list. LOC is the
476 location of the OMP_PARALLEL*. */
953ff289
DN
477
478void
c2255bc4
AH
479c_split_parallel_clauses (location_t loc, tree clauses,
480 tree *par_clauses, tree *ws_clauses)
953ff289
DN
481{
482 tree next;
483
484 *par_clauses = NULL;
c2255bc4 485 *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
953ff289
DN
486
487 for (; clauses ; clauses = next)
488 {
489 next = OMP_CLAUSE_CHAIN (clauses);
490
aaf46ef9 491 switch (OMP_CLAUSE_CODE (clauses))
953ff289
DN
492 {
493 case OMP_CLAUSE_PRIVATE:
494 case OMP_CLAUSE_SHARED:
495 case OMP_CLAUSE_FIRSTPRIVATE:
496 case OMP_CLAUSE_LASTPRIVATE:
497 case OMP_CLAUSE_REDUCTION:
498 case OMP_CLAUSE_COPYIN:
499 case OMP_CLAUSE_IF:
500 case OMP_CLAUSE_NUM_THREADS:
501 case OMP_CLAUSE_DEFAULT:
502 OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
503 *par_clauses = clauses;
504 break;
505
506 case OMP_CLAUSE_SCHEDULE:
507 case OMP_CLAUSE_ORDERED:
a68ab351 508 case OMP_CLAUSE_COLLAPSE:
953ff289
DN
509 OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
510 *ws_clauses = clauses;
511 break;
512
513 default:
514 gcc_unreachable ();
515 }
516 }
517}
518
519/* True if OpenMP sharing attribute of DECL is predetermined. */
520
521enum omp_clause_default_kind
522c_omp_predetermined_sharing (tree decl)
523{
524 /* Variables with const-qualified type having no mutable member
525 are predetermined shared. */
526 if (TREE_READONLY (decl))
527 return OMP_CLAUSE_DEFAULT_SHARED;
528
529 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
530}
This page took 0.771018 seconds and 5 git commands to generate.