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 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
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
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/>. */
26 #include "coretypes.h"
29 #include "gimple.h" /* For create_tmp_var_raw. */
30 #include "langhooks.h"
33 /* Complete a #pragma omp master construct. STMT is the structured-block
34 that follows the pragma. LOC is the l*/
37 c_finish_omp_master (location_t loc, tree stmt)
39 tree t = add_stmt (build1 (OMP_MASTER, void_type_node, stmt));
40 SET_EXPR_LOCATION (t, loc);
44 /* Complete a #pragma omp critical construct. STMT is the structured-block
45 that follows the pragma, NAME is the identifier in the pragma, or null
46 if it was omitted. LOC is the location of the #pragma. */
49 c_finish_omp_critical (location_t loc, tree body, tree name)
51 tree stmt = make_node (OMP_CRITICAL);
52 TREE_TYPE (stmt) = void_type_node;
53 OMP_CRITICAL_BODY (stmt) = body;
54 OMP_CRITICAL_NAME (stmt) = name;
55 SET_EXPR_LOCATION (stmt, loc);
56 return add_stmt (stmt);
59 /* Complete a #pragma omp ordered construct. STMT is the structured-block
60 that follows the pragma. LOC is the location of the #pragma. */
63 c_finish_omp_ordered (location_t loc, tree stmt)
65 tree t = build1 (OMP_ORDERED, void_type_node, stmt);
66 SET_EXPR_LOCATION (t, loc);
71 /* Complete a #pragma omp barrier construct. LOC is the location of
75 c_finish_omp_barrier (location_t loc)
79 x = built_in_decls[BUILT_IN_GOMP_BARRIER];
80 x = build_call_expr_loc (loc, x, 0);
85 /* Complete a #pragma omp taskwait construct. LOC is the location of the
89 c_finish_omp_taskwait (location_t loc)
93 x = built_in_decls[BUILT_IN_GOMP_TASKWAIT];
94 x = build_call_expr_loc (loc, x, 0);
99 /* Complete a #pragma omp atomic construct. The expression to be
100 implemented atomically is LHS code= RHS. LOC is the location of
101 the atomic statement. The value returned is either error_mark_node
102 (if the construct was erroneous) or an OMP_ATOMIC node which should
103 be added to the current statement tree with add_stmt.*/
106 c_finish_omp_atomic (location_t loc, enum tree_code code, tree lhs, tree rhs)
110 if (lhs == error_mark_node || rhs == error_mark_node)
111 return error_mark_node;
113 /* ??? According to one reading of the OpenMP spec, complex type are
114 supported, but there are no atomic stores for any architecture.
115 But at least icc 9.0 doesn't support complex types here either.
116 And lets not even talk about vector types... */
117 type = TREE_TYPE (lhs);
118 if (!INTEGRAL_TYPE_P (type)
119 && !POINTER_TYPE_P (type)
120 && !SCALAR_FLOAT_TYPE_P (type))
122 error_at (loc, "invalid expression type for %<#pragma omp atomic%>");
123 return error_mark_node;
126 /* ??? Validate that rhs does not overlap lhs. */
128 /* Take and save the address of the lhs. From then on we'll reference it
130 addr = build_unary_op (loc, ADDR_EXPR, lhs, 0);
131 if (addr == error_mark_node)
132 return error_mark_node;
133 addr = save_expr (addr);
134 if (TREE_CODE (addr) != SAVE_EXPR
135 && (TREE_CODE (addr) != ADDR_EXPR
136 || TREE_CODE (TREE_OPERAND (addr, 0)) != VAR_DECL))
138 /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize
139 it even after unsharing function body. */
140 tree var = create_tmp_var_raw (TREE_TYPE (addr), NULL);
141 DECL_CONTEXT (var) = current_function_decl;
142 addr = build4 (TARGET_EXPR, TREE_TYPE (addr), var, addr, NULL, NULL);
144 lhs = build_indirect_ref (loc, addr, RO_NULL);
146 /* There are lots of warnings, errors, and conversions that need to happen
147 in the course of interpreting a statement. Use the normal mechanisms
148 to do this, and then take it apart again. */
149 x = build_modify_expr (input_location, lhs, NULL_TREE, code,
150 input_location, rhs, NULL_TREE);
151 if (x == error_mark_node)
152 return error_mark_node;
153 gcc_assert (TREE_CODE (x) == MODIFY_EXPR);
154 rhs = TREE_OPERAND (x, 1);
156 /* Punt the actual generation of atomic operations to common code. */
157 x = build2 (OMP_ATOMIC, void_type_node, addr, rhs);
158 SET_EXPR_LOCATION (x, loc);
163 /* Complete a #pragma omp flush construct. We don't do anything with
164 the variable list that the syntax allows. LOC is the location of
168 c_finish_omp_flush (location_t loc)
172 x = built_in_decls[BUILT_IN_SYNC_SYNCHRONIZE];
173 x = build_call_expr_loc (loc, x, 0);
178 /* Check and canonicalize #pragma omp for increment expression.
179 Helper function for c_finish_omp_for. */
182 check_omp_for_incr_expr (location_t loc, tree exp, tree decl)
186 if (!INTEGRAL_TYPE_P (TREE_TYPE (exp))
187 || TYPE_PRECISION (TREE_TYPE (exp)) < TYPE_PRECISION (TREE_TYPE (decl)))
188 return error_mark_node;
191 return build_int_cst (TREE_TYPE (exp), 0);
193 switch (TREE_CODE (exp))
196 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
197 if (t != error_mark_node)
198 return fold_convert_loc (loc, TREE_TYPE (exp), t);
201 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
202 if (t != error_mark_node)
203 return fold_build2_loc (loc, MINUS_EXPR,
204 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
207 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 0), decl);
208 if (t != error_mark_node)
209 return fold_build2_loc (loc, PLUS_EXPR,
210 TREE_TYPE (exp), t, TREE_OPERAND (exp, 1));
211 t = check_omp_for_incr_expr (loc, TREE_OPERAND (exp, 1), decl);
212 if (t != error_mark_node)
213 return fold_build2_loc (loc, PLUS_EXPR,
214 TREE_TYPE (exp), TREE_OPERAND (exp, 0), t);
218 /* cp_build_modify_expr forces preevaluation of the RHS to make
219 sure that it is evaluated before the lvalue-rvalue conversion
220 is applied to the LHS. Reconstruct the original expression. */
221 tree op0 = TREE_OPERAND (exp, 0);
222 if (TREE_CODE (op0) == TARGET_EXPR
223 && !VOID_TYPE_P (TREE_TYPE (op0)))
225 tree op1 = TREE_OPERAND (exp, 1);
226 tree temp = TARGET_EXPR_SLOT (op0);
227 if (TREE_CODE_CLASS (TREE_CODE (op1)) == tcc_binary
228 && TREE_OPERAND (op1, 1) == temp)
230 op1 = copy_node (op1);
231 TREE_OPERAND (op1, 1) = TARGET_EXPR_INITIAL (op0);
232 return check_omp_for_incr_expr (loc, op1, decl);
241 return error_mark_node;
244 /* Validate and emit code for the OpenMP directive #pragma omp for.
245 DECLV is a vector of iteration variables, for each collapsed loop.
246 INITV, CONDV and INCRV are vectors containing initialization
247 expressions, controlling predicates and increment expressions.
248 BODY is the body of the loop and PRE_BODY statements that go before
252 c_finish_omp_for (location_t locus, tree declv, tree initv, tree condv,
253 tree incrv, tree body, tree pre_body)
259 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (initv));
260 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (condv));
261 gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv));
262 for (i = 0; i < TREE_VEC_LENGTH (declv); i++)
264 tree decl = TREE_VEC_ELT (declv, i);
265 tree init = TREE_VEC_ELT (initv, i);
266 tree cond = TREE_VEC_ELT (condv, i);
267 tree incr = TREE_VEC_ELT (incrv, i);
270 if (EXPR_HAS_LOCATION (init))
271 elocus = EXPR_LOCATION (init);
273 /* Validate the iteration variable. */
274 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl))
275 && TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE)
277 error_at (elocus, "invalid type for iteration variable %qE", decl);
281 /* In the case of "for (int i = 0...)", init will be a decl. It should
282 have a DECL_INITIAL that we can turn into an assignment. */
285 elocus = DECL_SOURCE_LOCATION (decl);
287 init = DECL_INITIAL (decl);
290 error_at (elocus, "%qE is not initialized", decl);
291 init = integer_zero_node;
295 init = build_modify_expr (elocus, decl, NULL_TREE, NOP_EXPR,
296 /* FIXME diagnostics: This should
297 be the location of the INIT. */
302 gcc_assert (TREE_CODE (init) == MODIFY_EXPR);
303 gcc_assert (TREE_OPERAND (init, 0) == decl);
305 if (cond == NULL_TREE)
307 error_at (elocus, "missing controlling predicate");
312 bool cond_ok = false;
314 if (EXPR_HAS_LOCATION (cond))
315 elocus = EXPR_LOCATION (cond);
317 if (TREE_CODE (cond) == LT_EXPR
318 || TREE_CODE (cond) == LE_EXPR
319 || TREE_CODE (cond) == GT_EXPR
320 || TREE_CODE (cond) == GE_EXPR
321 || TREE_CODE (cond) == NE_EXPR
322 || TREE_CODE (cond) == EQ_EXPR)
324 tree op0 = TREE_OPERAND (cond, 0);
325 tree op1 = TREE_OPERAND (cond, 1);
327 /* 2.5.1. The comparison in the condition is computed in
328 the type of DECL, otherwise the behavior is undefined.
334 according to ISO will be evaluated as:
339 if (TREE_CODE (op0) == NOP_EXPR
340 && decl == TREE_OPERAND (op0, 0))
342 TREE_OPERAND (cond, 0) = TREE_OPERAND (op0, 0);
343 TREE_OPERAND (cond, 1)
344 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
345 TREE_OPERAND (cond, 1));
347 else if (TREE_CODE (op1) == NOP_EXPR
348 && decl == TREE_OPERAND (op1, 0))
350 TREE_OPERAND (cond, 1) = TREE_OPERAND (op1, 0);
351 TREE_OPERAND (cond, 0)
352 = fold_build1_loc (elocus, NOP_EXPR, TREE_TYPE (decl),
353 TREE_OPERAND (cond, 0));
356 if (decl == TREE_OPERAND (cond, 0))
358 else if (decl == TREE_OPERAND (cond, 1))
361 swap_tree_comparison (TREE_CODE (cond)));
362 TREE_OPERAND (cond, 1) = TREE_OPERAND (cond, 0);
363 TREE_OPERAND (cond, 0) = decl;
367 if (TREE_CODE (cond) == NE_EXPR
368 || TREE_CODE (cond) == EQ_EXPR)
370 if (!INTEGRAL_TYPE_P (TREE_TYPE (decl)))
372 else if (operand_equal_p (TREE_OPERAND (cond, 1),
373 TYPE_MIN_VALUE (TREE_TYPE (decl)),
375 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
376 ? GT_EXPR : LE_EXPR);
377 else if (operand_equal_p (TREE_OPERAND (cond, 1),
378 TYPE_MAX_VALUE (TREE_TYPE (decl)),
380 TREE_SET_CODE (cond, TREE_CODE (cond) == NE_EXPR
381 ? LT_EXPR : GE_EXPR);
389 error_at (elocus, "invalid controlling predicate");
394 if (incr == NULL_TREE)
396 error_at (elocus, "missing increment expression");
401 bool incr_ok = false;
403 if (EXPR_HAS_LOCATION (incr))
404 elocus = EXPR_LOCATION (incr);
406 /* Check all the valid increment expressions: v++, v--, ++v, --v,
407 v = v + incr, v = incr + v and v = v - incr. */
408 switch (TREE_CODE (incr))
410 case POSTINCREMENT_EXPR:
411 case PREINCREMENT_EXPR:
412 case POSTDECREMENT_EXPR:
413 case PREDECREMENT_EXPR:
414 if (TREE_OPERAND (incr, 0) != decl)
418 if (POINTER_TYPE_P (TREE_TYPE (decl))
419 && TREE_OPERAND (incr, 1))
421 tree t = fold_convert_loc (elocus,
422 sizetype, TREE_OPERAND (incr, 1));
424 if (TREE_CODE (incr) == POSTDECREMENT_EXPR
425 || TREE_CODE (incr) == PREDECREMENT_EXPR)
426 t = fold_build1_loc (elocus, NEGATE_EXPR, sizetype, t);
427 t = fold_build_pointer_plus (decl, t);
428 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
433 if (TREE_OPERAND (incr, 0) != decl)
435 if (TREE_OPERAND (incr, 1) == decl)
437 if (TREE_CODE (TREE_OPERAND (incr, 1)) == PLUS_EXPR
438 && (TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl
439 || TREE_OPERAND (TREE_OPERAND (incr, 1), 1) == decl))
441 else if ((TREE_CODE (TREE_OPERAND (incr, 1)) == MINUS_EXPR
442 || (TREE_CODE (TREE_OPERAND (incr, 1))
443 == POINTER_PLUS_EXPR))
444 && TREE_OPERAND (TREE_OPERAND (incr, 1), 0) == decl)
448 tree t = check_omp_for_incr_expr (elocus,
449 TREE_OPERAND (incr, 1),
451 if (t != error_mark_node)
454 t = build2 (PLUS_EXPR, TREE_TYPE (decl), decl, t);
455 incr = build2 (MODIFY_EXPR, void_type_node, decl, t);
465 error_at (elocus, "invalid increment expression");
470 TREE_VEC_ELT (initv, i) = init;
471 TREE_VEC_ELT (incrv, i) = incr;
478 tree t = make_node (OMP_FOR);
480 TREE_TYPE (t) = void_type_node;
481 OMP_FOR_INIT (t) = initv;
482 OMP_FOR_COND (t) = condv;
483 OMP_FOR_INCR (t) = incrv;
484 OMP_FOR_BODY (t) = body;
485 OMP_FOR_PRE_BODY (t) = pre_body;
487 SET_EXPR_LOCATION (t, locus);
493 /* Divide CLAUSES into two lists: those that apply to a parallel
494 construct, and those that apply to a work-sharing construct. Place
495 the results in *PAR_CLAUSES and *WS_CLAUSES respectively. In
496 addition, add a nowait clause to the work-sharing list. LOC is the
497 location of the OMP_PARALLEL*. */
500 c_split_parallel_clauses (location_t loc, tree clauses,
501 tree *par_clauses, tree *ws_clauses)
506 *ws_clauses = build_omp_clause (loc, OMP_CLAUSE_NOWAIT);
508 for (; clauses ; clauses = next)
510 next = OMP_CLAUSE_CHAIN (clauses);
512 switch (OMP_CLAUSE_CODE (clauses))
514 case OMP_CLAUSE_PRIVATE:
515 case OMP_CLAUSE_SHARED:
516 case OMP_CLAUSE_FIRSTPRIVATE:
517 case OMP_CLAUSE_LASTPRIVATE:
518 case OMP_CLAUSE_REDUCTION:
519 case OMP_CLAUSE_COPYIN:
521 case OMP_CLAUSE_NUM_THREADS:
522 case OMP_CLAUSE_DEFAULT:
523 OMP_CLAUSE_CHAIN (clauses) = *par_clauses;
524 *par_clauses = clauses;
527 case OMP_CLAUSE_SCHEDULE:
528 case OMP_CLAUSE_ORDERED:
529 case OMP_CLAUSE_COLLAPSE:
530 OMP_CLAUSE_CHAIN (clauses) = *ws_clauses;
531 *ws_clauses = clauses;
540 /* True if OpenMP sharing attribute of DECL is predetermined. */
542 enum omp_clause_default_kind
543 c_omp_predetermined_sharing (tree decl)
545 /* Variables with const-qualified type having no mutable member
546 are predetermined shared. */
547 if (TREE_READONLY (decl))
548 return OMP_CLAUSE_DEFAULT_SHARED;
550 return OMP_CLAUSE_DEFAULT_UNSPECIFIED;