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