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, 2010, 2011
5 Free Software Foundation, Inc.
6 Contributed by Richard Henderson <rth@redhat.com>,
7 Diego Novillo <dnovillo@redhat.com>.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
27 #include "coretypes.h"
30 #include "gimple.h" /* For create_tmp_var_raw. */
31 #include "langhooks.h"
34 /* Complete a #pragma omp master construct. STMT is the structured-block
35 that follows the pragma. LOC is the l*/
38 c_finish_omp_master (location_t loc, tree stmt)
40 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
41 SET_EXPR_LOCATION (t, loc);
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. */
50 c_finish_omp_critical (location_t loc, tree body, tree name)
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);
60 /* Complete a #pragma omp ordered construct. STMT is the structured-block
61 that follows the pragma. LOC is the location of the #pragma. */
64 c_finish_omp_ordered (location_t loc, tree stmt)
66 tree t = build1 (OMP_ORDERED, void_type_node, stmt);
67 SET_EXPR_LOCATION (t, loc);
72 /* Complete a #pragma omp barrier construct. LOC is the location of
76 c_finish_omp_barrier (location_t loc)
80 x = built_in_decls[BUILT_IN_GOMP_BARRIER];
81 x = build_call_expr_loc (loc, x, 0);
86 /* Complete a #pragma omp taskwait construct. LOC is the location of the
90 c_finish_omp_taskwait (location_t loc)
94 x = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
95 x = build_call_expr_loc (loc, x, 0);
100 /* Complete a #pragma omp taskyield construct. LOC is the location of the
104 c_finish_omp_taskyield (location_t loc)
108 x = built_in_decls[BUILT_IN_GOMP_TASKYIELD];
109 x = build_call_expr_loc (loc, x, 0);
114 /* Complete a #pragma omp atomic construct. For CODE OMP_ATOMIC
115 the expression to be implemented atomically is LHS opcode= RHS.
116 For OMP_ATOMIC_READ V = LHS, for OMP_ATOMIC_CAPTURE_{NEW,OLD} LHS
117 opcode= RHS with the new or old content of LHS returned.
118 LOC is the location of the atomic statement. The value returned
119 is either error_mark_node (if the construct was erroneous) or an
120 OMP_ATOMIC* node which should be added to the current statement
121 tree with add_stmt. */
124 c_finish_omp_atomic (location_t loc, enum tree_code code,
125 enum tree_code opcode, tree lhs, tree rhs,
126 tree v, tree lhs1, tree rhs1)
130 if (lhs == error_mark_node || rhs == error_mark_node
131 || v == error_mark_node || lhs1 == error_mark_node
132 || rhs1 == error_mark_node)
133 return error_mark_node;
135 /* ??? According to one reading of the OpenMP spec, complex type are
136 supported, but there are no atomic stores for any architecture.
137 But at least icc 9.0 doesn't support complex types here either.
138 And lets not even talk about vector types... */
139 type = TREE_TYPE (lhs);
140 if (!INTEGRAL_TYPE_P (type)
141 && !POINTER_TYPE_P (type)
142 && !SCALAR_FLOAT_TYPE_P (type))
144 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
145 return error_mark_node;
148 /* ??? Validate that rhs does not overlap lhs. */
150 /* Take and save the address of the lhs. From then on we'll reference it
152 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
153 if (addr == error_mark_node)
154 return error_mark_node;
155 addr = save_expr (addr);
156 if (TREE_CODE (addr) != SAVE_EXPR
157 && (TREE_CODE (addr) != ADDR_EXPR
158 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
160 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
161 it even after unsharing function body. */
162 tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
163 DECL_CONTEXT (var) = current_function_decl;
164 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
166 lhs = build_indirect_ref (loc, addr, RO_NULL);
168 if (code == OMP_ATOMIC_READ)
170 x = build1 (OMP_ATOMIC_READ, type, addr);
171 SET_EXPR_LOCATION (x, loc);
172 return build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
177 /* There are lots of warnings, errors, and conversions that need to happen
178 in the course of interpreting a statement. Use the normal mechanisms
179 to do this, and then take it apart again. */
180 x = build_modify_expr (input_location, lhs, NULL_TREE, opcode,
181 input_location, rhs, NULL_TREE);
182 if (x == error_mark_node)
183 return error_mark_node;
184 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
185 rhs = TREE_OPERAND (x, 1);
187 /* Punt the actual generation of atomic operations to common code. */
188 if (code == OMP_ATOMIC)
189 type = void_type_node;
190 x = build2 (code, type, addr, rhs);
191 SET_EXPR_LOCATION (x, loc);
193 /* Generally it is hard to prove lhs1 and lhs are the same memory
194 location, just diagnose different variables. */
196 && TREE_CODE (rhs1) == VAR_DECL
197 && TREE_CODE (lhs) == VAR_DECL
200 if (code == OMP_ATOMIC)
201 error_at (loc, "%<#pragma omp atomic update%> uses two different variables for memory");
203 error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
204 return error_mark_node;
207 if (code != OMP_ATOMIC)
209 /* Generally it is hard to prove lhs1 and lhs are the same memory
210 location, just diagnose different variables. */
211 if (lhs1 && TREE_CODE (lhs1) == VAR_DECL && TREE_CODE (lhs) == VAR_DECL)
215 error_at (loc, "%<#pragma omp atomic capture%> uses two different variables for memory");
216 return error_mark_node;
219 x = build_modify_expr (loc, v, NULL_TREE, NOP_EXPR,
221 if (rhs1 && rhs1 != lhs)
223 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
224 if (rhs1addr == error_mark_node)
225 return error_mark_node;
226 x = omit_one_operand_loc (loc, type, x, rhs1addr);
228 if (lhs1 && lhs1 != lhs)
230 tree lhs1addr = build_unary_op (loc, ADDR_EXPR, lhs1, 0);
231 if (lhs1addr == error_mark_node)
232 return error_mark_node;
233 if (code == OMP_ATOMIC_CAPTURE_OLD)
234 x = omit_one_operand_loc (loc, type, x, lhs1addr);
238 x = omit_two_operands_loc (loc, type, x, x, lhs1addr);
242 else if (rhs1 && rhs1 != lhs)
244 tree rhs1addr = build_unary_op (loc, ADDR_EXPR, rhs1, 0);
245 if (rhs1addr == error_mark_node)
246 return error_mark_node;
247 x = omit_one_operand_loc (loc, type, x, rhs1addr);
254 /* Complete a #pragma omp flush construct. We don't do anything with
255 the variable list that the syntax allows. LOC is the location of
259 c_finish_omp_flush (location_t loc)
263 x = built_in_decls[BUILT_IN_SYNC_SYNCHRONIZE];
264 x = build_call_expr_loc (loc, x, 0);
269 /* Check and canonicalize #pragma omp for increment expression.
270 Helper function for c_finish_omp_for. */
273 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
277 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
278 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
279 return error_mark_node;
282 return build_int_cst (TREE_TYPE (exp), 0);
284 switch (TREE_CODE (exp))
287 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
288 if (t != error_mark_node)
289 return fold_convert_loc (loc, TREE_TYPE (exp), t);
292 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
293 if (t != error_mark_node)
294 return fold_build2_loc (loc, MINUS_EXPR,
295 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
298 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
299 if (t != error_mark_node)
300 return fold_build2_loc (loc, PLUS_EXPR,
301 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
302 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
303 if (t != error_mark_node)
304 return fold_build2_loc (loc, PLUS_EXPR,
305 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
309 /* cp_build_modify_expr forces preevaluation of the RHS to make
310 sure that it is evaluated before the lvalue-rvalue conversion
311 is applied to the LHS. Reconstruct the original expression. */
312 tree op0 = TREE_OPERAND (exp, 0);
313 if (TREE_CODE (op0) == TARGET_EXPR
314 && !VOID_TYPE_P (TREE_TYPE (op0)))
316 tree op1 = TREE_OPERAND (exp, 1);
317 tree temp = TARGET_EXPR_SLOT (op0);
318 if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary
319 && TREE_OPERAND (op1, 1) == temp)
321 op1 = copy_node (op1);
322 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
323 return check_omp_for_incr_expr (loc, op1, decl);
332 return error_mark_node;
335 /* Validate and emit code for the OpenMP directive #pragma omp for.
336 DECLV is a vector of iteration variables, for each collapsed loop.
337 INITV, CONDV and INCRV are vectors containing initialization
338 expressions, controlling predicates and increment expressions.
339 BODY is the body of the loop and PRE_BODY statements that go before
343 c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
344 tree incrv, tree body, tree pre_body)
350 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
351 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
352 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
353 for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
355 tree decl = TREE_VEC_ELT (declv, i);
356 tree init = TREE_VEC_ELT (initv, i);
357 tree cond = TREE_VEC_ELT (condv, i);
358 tree incr = TREE_VEC_ELT (incrv, i);
361 if (EXPR_HAS_LOCATION (init))
362 elocus = EXPR_LOCATION (init);
364 /* Validate the iteration variable. */
365 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
366 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
368 error_at (elocus, "invalid type for iteration variable %qE", decl);
372 /* In the case of "for (int i = 0...)", init will be a decl. It should
373 have a DECL_INITIAL that we can turn into an assignment. */
376 elocus = DECL_SOURCE_LOCATION (decl);
378 init = DECL_INITIAL (decl);
381 error_at (elocus, "%qE is not initialized", decl);
382 init = integer_zero_node;
386 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
387 /* FIXME diagnostics: This should
388 be the location of the INIT. */
393 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
394 gcc_assert (TREE_OPERAND (init, 0) == decl);
396 if (cond == NULL_TREE)
398 error_at (elocus, "missing controlling predicate");
403 bool cond_ok = false;
405 if (EXPR_HAS_LOCATION (cond))
406 elocus = EXPR_LOCATION (cond);
408 if (TREE_CODE (cond) == LT_EXPR
409 || TREE_CODE (cond) == LE_EXPR
410 || TREE_CODE (cond) == GT_EXPR
411 || TREE_CODE (cond) == GE_EXPR
412 || TREE_CODE (cond) == NE_EXPR
413 || TREE_CODE (cond) == EQ_EXPR)
415 tree op0 = TREE_OPERAND (cond, 0);
416 tree op1 = TREE_OPERAND (cond, 1);
418 /* 2.5.1. The comparison in the condition is computed in
419 the type of DECL, otherwise the behavior is undefined.
425 according to ISO will be evaluated as:
430 if (TREE_CODE (op0) == NOP_EXPR
431 && decl == TREE_OPERAND (op0, 0))
433 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
434 TREE_OPERAND (cond, 1)
435 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
436 TREE_OPERAND (cond, 1));
438 else if (TREE_CODE (op1) == NOP_EXPR
439 && decl == TREE_OPERAND (op1, 0))
441 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
442 TREE_OPERAND (cond, 0)
443 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
444 TREE_OPERAND (cond, 0));
447 if (decl == TREE_OPERAND (cond, 0))
449 else if (decl == TREE_OPERAND (cond, 1))
452 swap_tree_comparison (TREE_CODE (cond)));
453 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
454 TREE_OPERAND (cond, 0) = decl;
458 if (TREE_CODE (cond) == NE_EXPR
459 || TREE_CODE (cond) == EQ_EXPR)
461 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
463 else if (operand_equal_p (TREE_OPERAND (cond, 1),
464 TYPE_MIN_VALUE (TREE_TYPE (decl)),
466 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
467 ? GT_EXPR : LE_EXPR);
468 else if (operand_equal_p (TREE_OPERAND (cond, 1),
469 TYPE_MAX_VALUE (TREE_TYPE (decl)),
471 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
472 ? LT_EXPR : GE_EXPR);
480 error_at (elocus, "invalid controlling predicate");
485 if (incr == NULL_TREE)
487 error_at (elocus, "missing increment expression");
492 bool incr_ok = false;
494 if (EXPR_HAS_LOCATION (incr))
495 elocus = EXPR_LOCATION (incr);
497 /* Check all the valid increment expressions: v++, v--, ++v, --v,
498 v = v + incr, v = incr + v and v = v - incr. */
499 switch (TREE_CODE (incr))
501 case POSTINCREMENT_EXPR:
502 case PREINCREMENT_EXPR:
503 case POSTDECREMENT_EXPR:
504 case PREDECREMENT_EXPR:
505 if (TREE_OPERAND (incr, 0) != decl)
509 if (POINTER_TYPE_P (TREE_TYPE (decl))
510 && TREE_OPERAND (incr, 1))
512 tree t = fold_convert_loc (elocus,
513 sizetype, TREE_OPERAND (incr, 1));
515 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
516 || TREE_CODE (incr) == PREDECREMENT_EXPR)
517 t = fold_build1_loc (elocus, NEGATE_EXPR, sizetype, t);
518 t = fold_build_pointer_plus (decl, t);
519 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
524 if (TREE_OPERAND (incr, 0) != decl)
526 if (TREE_OPERAND (incr, 1) == decl)
528 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
529 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
530 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
532 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
533 || (TREE_CODE (TREE_OPERAND (incr, 1))
534 == POINTER_PLUS_EXPR))
535 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
539 tree t = check_omp_for_incr_expr (elocus,
540 TREE_OPERAND (incr, 1),
542 if (t != error_mark_node)
545 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
546 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
556 error_at (elocus, "invalid increment expression");
561 TREE_VEC_ELT (initv, i) = init;
562 TREE_VEC_ELT (incrv, i) = incr;
569 tree t = make_node (OMP_FOR);
571 TREE_TYPE (t) = void_type_node;
572 OMP_FOR_INIT (t) = initv;
573 OMP_FOR_COND (t) = condv;
574 OMP_FOR_INCR (t) = incrv;
575 OMP_FOR_BODY (t) = body;
576 OMP_FOR_PRE_BODY (t) = pre_body;
578 SET_EXPR_LOCATION (t, locus);
584 /* Divide CLAUSES into two lists: those that apply to a parallel
585 construct, and those that apply to a work-sharing construct. Place
586 the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In
587 addition, add a nowait clause to the work-sharing list. LOC is the
588 location of the OMP_PARALLEL*. */
591 c_split_parallel_clauses (location_t loc, tree clauses,
592 tree *par_clauses, tree *ws_clauses)
597 *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
599 for (; clauses ; clauses = next)
601 next = OMP_CLAUSE_CHAIN (clauses);
603 switch (OMP_CLAUSE_CODE (clauses))
605 case OMP_CLAUSE_PRIVATE:
606 case OMP_CLAUSE_SHARED:
607 case OMP_CLAUSE_FIRSTPRIVATE:
608 case OMP_CLAUSE_LASTPRIVATE:
609 case OMP_CLAUSE_REDUCTION:
610 case OMP_CLAUSE_COPYIN:
612 case OMP_CLAUSE_NUM_THREADS:
613 case OMP_CLAUSE_DEFAULT:
614 OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
615 *par_clauses = clauses;
618 case OMP_CLAUSE_SCHEDULE:
619 case OMP_CLAUSE_ORDERED:
620 case OMP_CLAUSE_COLLAPSE:
621 OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
622 *ws_clauses = clauses;
631 /* True if OpenMP sharing attribute of DECL is predetermined. */
633 enum omp_clause_default_kind
634 c_omp_predetermined_sharing (tree decl)
636 /* Variables with const-qualified type having no mutable member
637 are predetermined shared. */
638 if (TREE_READONLY (decl))
639 return OMP_CLAUSE_DEFAULT_SHARED;
641 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;