Fix a typo in ChangeLog
[official-gcc.git] / gcc / omp-low.c
blobbd7e7e689e5cdae35e6c5626de63d90655a49ba8
1 /* Lowering pass for OpenMP directives. Converts OpenMP directives
2 into explicit calls to the runtime library (libgomp) and data
3 marshalling to implement data sharing and copying clauses.
4 Contributed by Diego Novillo <dnovillo@redhat.com>
6 Copyright (C) 2005-2013 Free Software Foundation, Inc.
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 "rtl.h"
30 #include "gimple.h"
31 #include "tree-iterator.h"
32 #include "tree-inline.h"
33 #include "langhooks.h"
34 #include "diagnostic-core.h"
35 #include "tree-flow.h"
36 #include "flags.h"
37 #include "function.h"
38 #include "expr.h"
39 #include "tree-pass.h"
40 #include "ggc.h"
41 #include "except.h"
42 #include "splay-tree.h"
43 #include "optabs.h"
44 #include "cfgloop.h"
47 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
48 phases. The first phase scans the function looking for OMP statements
49 and then for variables that must be replaced to satisfy data sharing
50 clauses. The second phase expands code for the constructs, as well as
51 re-gimplifying things when variables have been replaced with complex
52 expressions.
54 Final code generation is done by pass_expand_omp. The flowgraph is
55 scanned for parallel regions which are then moved to a new
56 function, to be invoked by the thread library. */
58 /* Context structure. Used to store information about each parallel
59 directive in the code. */
61 typedef struct omp_context
63 /* This field must be at the beginning, as we do "inheritance": Some
64 callback functions for tree-inline.c (e.g., omp_copy_decl)
65 receive a copy_body_data pointer that is up-casted to an
66 omp_context pointer. */
67 copy_body_data cb;
69 /* The tree of contexts corresponding to the encountered constructs. */
70 struct omp_context *outer;
71 gimple stmt;
73 /* Map variables to fields in a structure that allows communication
74 between sending and receiving threads. */
75 splay_tree field_map;
76 tree record_type;
77 tree sender_decl;
78 tree receiver_decl;
80 /* These are used just by task contexts, if task firstprivate fn is
81 needed. srecord_type is used to communicate from the thread
82 that encountered the task construct to task firstprivate fn,
83 record_type is allocated by GOMP_task, initialized by task firstprivate
84 fn and passed to the task body fn. */
85 splay_tree sfield_map;
86 tree srecord_type;
88 /* A chain of variables to add to the top-level block surrounding the
89 construct. In the case of a parallel, this is in the child function. */
90 tree block_vars;
92 /* What to do with variables with implicitly determined sharing
93 attributes. */
94 enum omp_clause_default_kind default_kind;
96 /* Nesting depth of this context. Used to beautify error messages re
97 invalid gotos. The outermost ctx is depth 1, with depth 0 being
98 reserved for the main body of the function. */
99 int depth;
101 /* True if this parallel directive is nested within another. */
102 bool is_nested;
103 } omp_context;
106 struct omp_for_data_loop
108 tree v, n1, n2, step;
109 enum tree_code cond_code;
112 /* A structure describing the main elements of a parallel loop. */
114 struct omp_for_data
116 struct omp_for_data_loop loop;
117 tree chunk_size;
118 gimple for_stmt;
119 tree pre, iter_type;
120 int collapse;
121 bool have_nowait, have_ordered;
122 enum omp_clause_schedule_kind sched_kind;
123 struct omp_for_data_loop *loops;
127 static splay_tree all_contexts;
128 static int taskreg_nesting_level;
129 struct omp_region *root_omp_region;
130 static bitmap task_shared_vars;
132 static void scan_omp (gimple_seq *, omp_context *);
133 static tree scan_omp_1_op (tree *, int *, void *);
135 #define WALK_SUBSTMTS \
136 case GIMPLE_BIND: \
137 case GIMPLE_TRY: \
138 case GIMPLE_CATCH: \
139 case GIMPLE_EH_FILTER: \
140 case GIMPLE_TRANSACTION: \
141 /* The sub-statements for these should be walked. */ \
142 *handled_ops_p = false; \
143 break;
145 /* Convenience function for calling scan_omp_1_op on tree operands. */
147 static inline tree
148 scan_omp_op (tree *tp, omp_context *ctx)
150 struct walk_stmt_info wi;
152 memset (&wi, 0, sizeof (wi));
153 wi.info = ctx;
154 wi.want_locations = true;
156 return walk_tree (tp, scan_omp_1_op, &wi, NULL);
159 static void lower_omp (gimple_seq *, omp_context *);
160 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
161 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
163 /* Find an OpenMP clause of type KIND within CLAUSES. */
165 tree
166 find_omp_clause (tree clauses, enum omp_clause_code kind)
168 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
169 if (OMP_CLAUSE_CODE (clauses) == kind)
170 return clauses;
172 return NULL_TREE;
175 /* Return true if CTX is for an omp parallel. */
177 static inline bool
178 is_parallel_ctx (omp_context *ctx)
180 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
184 /* Return true if CTX is for an omp task. */
186 static inline bool
187 is_task_ctx (omp_context *ctx)
189 return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
193 /* Return true if CTX is for an omp parallel or omp task. */
195 static inline bool
196 is_taskreg_ctx (omp_context *ctx)
198 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
199 || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
203 /* Return true if REGION is a combined parallel+workshare region. */
205 static inline bool
206 is_combined_parallel (struct omp_region *region)
208 return region->is_combined_parallel;
212 /* Extract the header elements of parallel loop FOR_STMT and store
213 them into *FD. */
215 static void
216 extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
217 struct omp_for_data_loop *loops)
219 tree t, var, *collapse_iter, *collapse_count;
220 tree count = NULL_TREE, iter_type = long_integer_type_node;
221 struct omp_for_data_loop *loop;
222 int i;
223 struct omp_for_data_loop dummy_loop;
224 location_t loc = gimple_location (for_stmt);
226 fd->for_stmt = for_stmt;
227 fd->pre = NULL;
228 fd->collapse = gimple_omp_for_collapse (for_stmt);
229 if (fd->collapse > 1)
230 fd->loops = loops;
231 else
232 fd->loops = &fd->loop;
234 fd->have_nowait = fd->have_ordered = false;
235 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
236 fd->chunk_size = NULL_TREE;
237 collapse_iter = NULL;
238 collapse_count = NULL;
240 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
241 switch (OMP_CLAUSE_CODE (t))
243 case OMP_CLAUSE_NOWAIT:
244 fd->have_nowait = true;
245 break;
246 case OMP_CLAUSE_ORDERED:
247 fd->have_ordered = true;
248 break;
249 case OMP_CLAUSE_SCHEDULE:
250 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
251 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
252 break;
253 case OMP_CLAUSE_COLLAPSE:
254 if (fd->collapse > 1)
256 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
257 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
259 default:
260 break;
263 /* FIXME: for now map schedule(auto) to schedule(static).
264 There should be analysis to determine whether all iterations
265 are approximately the same amount of work (then schedule(static)
266 is best) or if it varies (then schedule(dynamic,N) is better). */
267 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
269 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
270 gcc_assert (fd->chunk_size == NULL);
272 gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
273 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
274 gcc_assert (fd->chunk_size == NULL);
275 else if (fd->chunk_size == NULL)
277 /* We only need to compute a default chunk size for ordered
278 static loops and dynamic loops. */
279 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
280 || fd->have_ordered
281 || fd->collapse > 1)
282 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
283 ? integer_zero_node : integer_one_node;
286 for (i = 0; i < fd->collapse; i++)
288 if (fd->collapse == 1)
289 loop = &fd->loop;
290 else if (loops != NULL)
291 loop = loops + i;
292 else
293 loop = &dummy_loop;
296 loop->v = gimple_omp_for_index (for_stmt, i);
297 gcc_assert (SSA_VAR_P (loop->v));
298 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
299 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
300 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
301 loop->n1 = gimple_omp_for_initial (for_stmt, i);
303 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
304 loop->n2 = gimple_omp_for_final (for_stmt, i);
305 switch (loop->cond_code)
307 case LT_EXPR:
308 case GT_EXPR:
309 break;
310 case LE_EXPR:
311 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
312 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
313 else
314 loop->n2 = fold_build2_loc (loc,
315 PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
316 build_int_cst (TREE_TYPE (loop->n2), 1));
317 loop->cond_code = LT_EXPR;
318 break;
319 case GE_EXPR:
320 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
321 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
322 else
323 loop->n2 = fold_build2_loc (loc,
324 MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
325 build_int_cst (TREE_TYPE (loop->n2), 1));
326 loop->cond_code = GT_EXPR;
327 break;
328 default:
329 gcc_unreachable ();
332 t = gimple_omp_for_incr (for_stmt, i);
333 gcc_assert (TREE_OPERAND (t, 0) == var);
334 switch (TREE_CODE (t))
336 case PLUS_EXPR:
337 loop->step = TREE_OPERAND (t, 1);
338 break;
339 case POINTER_PLUS_EXPR:
340 loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
341 break;
342 case MINUS_EXPR:
343 loop->step = TREE_OPERAND (t, 1);
344 loop->step = fold_build1_loc (loc,
345 NEGATE_EXPR, TREE_TYPE (loop->step),
346 loop->step);
347 break;
348 default:
349 gcc_unreachable ();
352 if (iter_type != long_long_unsigned_type_node)
354 if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
355 iter_type = long_long_unsigned_type_node;
356 else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
357 && TYPE_PRECISION (TREE_TYPE (loop->v))
358 >= TYPE_PRECISION (iter_type))
360 tree n;
362 if (loop->cond_code == LT_EXPR)
363 n = fold_build2_loc (loc,
364 PLUS_EXPR, TREE_TYPE (loop->v),
365 loop->n2, loop->step);
366 else
367 n = loop->n1;
368 if (TREE_CODE (n) != INTEGER_CST
369 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
370 iter_type = long_long_unsigned_type_node;
372 else if (TYPE_PRECISION (TREE_TYPE (loop->v))
373 > TYPE_PRECISION (iter_type))
375 tree n1, n2;
377 if (loop->cond_code == LT_EXPR)
379 n1 = loop->n1;
380 n2 = fold_build2_loc (loc,
381 PLUS_EXPR, TREE_TYPE (loop->v),
382 loop->n2, loop->step);
384 else
386 n1 = fold_build2_loc (loc,
387 MINUS_EXPR, TREE_TYPE (loop->v),
388 loop->n2, loop->step);
389 n2 = loop->n1;
391 if (TREE_CODE (n1) != INTEGER_CST
392 || TREE_CODE (n2) != INTEGER_CST
393 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
394 || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
395 iter_type = long_long_unsigned_type_node;
399 if (collapse_count && *collapse_count == NULL)
401 if ((i == 0 || count != NULL_TREE)
402 && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
403 && TREE_CONSTANT (loop->n1)
404 && TREE_CONSTANT (loop->n2)
405 && TREE_CODE (loop->step) == INTEGER_CST)
407 tree itype = TREE_TYPE (loop->v);
409 if (POINTER_TYPE_P (itype))
410 itype = signed_type_for (itype);
411 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
412 t = fold_build2_loc (loc,
413 PLUS_EXPR, itype,
414 fold_convert_loc (loc, itype, loop->step), t);
415 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
416 fold_convert_loc (loc, itype, loop->n2));
417 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
418 fold_convert_loc (loc, itype, loop->n1));
419 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
420 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
421 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
422 fold_build1_loc (loc, NEGATE_EXPR, itype,
423 fold_convert_loc (loc, itype,
424 loop->step)));
425 else
426 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
427 fold_convert_loc (loc, itype, loop->step));
428 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
429 if (count != NULL_TREE)
430 count = fold_build2_loc (loc,
431 MULT_EXPR, long_long_unsigned_type_node,
432 count, t);
433 else
434 count = t;
435 if (TREE_CODE (count) != INTEGER_CST)
436 count = NULL_TREE;
438 else
439 count = NULL_TREE;
443 if (count)
445 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
446 iter_type = long_long_unsigned_type_node;
447 else
448 iter_type = long_integer_type_node;
450 else if (collapse_iter && *collapse_iter != NULL)
451 iter_type = TREE_TYPE (*collapse_iter);
452 fd->iter_type = iter_type;
453 if (collapse_iter && *collapse_iter == NULL)
454 *collapse_iter = create_tmp_var (iter_type, ".iter");
455 if (collapse_count && *collapse_count == NULL)
457 if (count)
458 *collapse_count = fold_convert_loc (loc, iter_type, count);
459 else
460 *collapse_count = create_tmp_var (iter_type, ".count");
463 if (fd->collapse > 1)
465 fd->loop.v = *collapse_iter;
466 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
467 fd->loop.n2 = *collapse_count;
468 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
469 fd->loop.cond_code = LT_EXPR;
474 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
475 is the immediate dominator of PAR_ENTRY_BB, return true if there
476 are no data dependencies that would prevent expanding the parallel
477 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
479 When expanding a combined parallel+workshare region, the call to
480 the child function may need additional arguments in the case of
481 GIMPLE_OMP_FOR regions. In some cases, these arguments are
482 computed out of variables passed in from the parent to the child
483 via 'struct .omp_data_s'. For instance:
485 #pragma omp parallel for schedule (guided, i * 4)
486 for (j ...)
488 Is lowered into:
490 # BLOCK 2 (PAR_ENTRY_BB)
491 .omp_data_o.i = i;
492 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
494 # BLOCK 3 (WS_ENTRY_BB)
495 .omp_data_i = &.omp_data_o;
496 D.1667 = .omp_data_i->i;
497 D.1598 = D.1667 * 4;
498 #pragma omp for schedule (guided, D.1598)
500 When we outline the parallel region, the call to the child function
501 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
502 that value is computed *after* the call site. So, in principle we
503 cannot do the transformation.
505 To see whether the code in WS_ENTRY_BB blocks the combined
506 parallel+workshare call, we collect all the variables used in the
507 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
508 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
509 call.
511 FIXME. If we had the SSA form built at this point, we could merely
512 hoist the code in block 3 into block 2 and be done with it. But at
513 this point we don't have dataflow information and though we could
514 hack something up here, it is really not worth the aggravation. */
516 static bool
517 workshare_safe_to_combine_p (basic_block ws_entry_bb)
519 struct omp_for_data fd;
520 gimple ws_stmt = last_stmt (ws_entry_bb);
522 if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
523 return true;
525 gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
527 extract_omp_for_data (ws_stmt, &fd, NULL);
529 if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
530 return false;
531 if (fd.iter_type != long_integer_type_node)
532 return false;
534 /* FIXME. We give up too easily here. If any of these arguments
535 are not constants, they will likely involve variables that have
536 been mapped into fields of .omp_data_s for sharing with the child
537 function. With appropriate data flow, it would be possible to
538 see through this. */
539 if (!is_gimple_min_invariant (fd.loop.n1)
540 || !is_gimple_min_invariant (fd.loop.n2)
541 || !is_gimple_min_invariant (fd.loop.step)
542 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
543 return false;
545 return true;
549 /* Collect additional arguments needed to emit a combined
550 parallel+workshare call. WS_STMT is the workshare directive being
551 expanded. */
553 static vec<tree, va_gc> *
554 get_ws_args_for (gimple ws_stmt)
556 tree t;
557 location_t loc = gimple_location (ws_stmt);
558 vec<tree, va_gc> *ws_args;
560 if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
562 struct omp_for_data fd;
564 extract_omp_for_data (ws_stmt, &fd, NULL);
566 vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
568 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
569 ws_args->quick_push (t);
571 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
572 ws_args->quick_push (t);
574 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
575 ws_args->quick_push (t);
577 if (fd.chunk_size)
579 t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
580 ws_args->quick_push (t);
583 return ws_args;
585 else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
587 /* Number of sections is equal to the number of edges from the
588 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
589 the exit of the sections region. */
590 basic_block bb = single_succ (gimple_bb (ws_stmt));
591 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
592 vec_alloc (ws_args, 1);
593 ws_args->quick_push (t);
594 return ws_args;
597 gcc_unreachable ();
601 /* Discover whether REGION is a combined parallel+workshare region. */
603 static void
604 determine_parallel_type (struct omp_region *region)
606 basic_block par_entry_bb, par_exit_bb;
607 basic_block ws_entry_bb, ws_exit_bb;
609 if (region == NULL || region->inner == NULL
610 || region->exit == NULL || region->inner->exit == NULL
611 || region->inner->cont == NULL)
612 return;
614 /* We only support parallel+for and parallel+sections. */
615 if (region->type != GIMPLE_OMP_PARALLEL
616 || (region->inner->type != GIMPLE_OMP_FOR
617 && region->inner->type != GIMPLE_OMP_SECTIONS))
618 return;
620 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
621 WS_EXIT_BB -> PAR_EXIT_BB. */
622 par_entry_bb = region->entry;
623 par_exit_bb = region->exit;
624 ws_entry_bb = region->inner->entry;
625 ws_exit_bb = region->inner->exit;
627 if (single_succ (par_entry_bb) == ws_entry_bb
628 && single_succ (ws_exit_bb) == par_exit_bb
629 && workshare_safe_to_combine_p (ws_entry_bb)
630 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
631 || (last_and_only_stmt (ws_entry_bb)
632 && last_and_only_stmt (par_exit_bb))))
634 gimple ws_stmt = last_stmt (ws_entry_bb);
636 if (region->inner->type == GIMPLE_OMP_FOR)
638 /* If this is a combined parallel loop, we need to determine
639 whether or not to use the combined library calls. There
640 are two cases where we do not apply the transformation:
641 static loops and any kind of ordered loop. In the first
642 case, we already open code the loop so there is no need
643 to do anything else. In the latter case, the combined
644 parallel loop call would still need extra synchronization
645 to implement ordered semantics, so there would not be any
646 gain in using the combined call. */
647 tree clauses = gimple_omp_for_clauses (ws_stmt);
648 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
649 if (c == NULL
650 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
651 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
653 region->is_combined_parallel = false;
654 region->inner->is_combined_parallel = false;
655 return;
659 region->is_combined_parallel = true;
660 region->inner->is_combined_parallel = true;
661 region->ws_args = get_ws_args_for (ws_stmt);
666 /* Return true if EXPR is variable sized. */
668 static inline bool
669 is_variable_sized (const_tree expr)
671 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
674 /* Return true if DECL is a reference type. */
676 static inline bool
677 is_reference (tree decl)
679 return lang_hooks.decls.omp_privatize_by_reference (decl);
682 /* Lookup variables in the decl or field splay trees. The "maybe" form
683 allows for the variable form to not have been entered, otherwise we
684 assert that the variable must have been entered. */
686 static inline tree
687 lookup_decl (tree var, omp_context *ctx)
689 tree *n;
690 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
691 return *n;
694 static inline tree
695 maybe_lookup_decl (const_tree var, omp_context *ctx)
697 tree *n;
698 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
699 return n ? *n : NULL_TREE;
702 static inline tree
703 lookup_field (tree var, omp_context *ctx)
705 splay_tree_node n;
706 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
707 return (tree) n->value;
710 static inline tree
711 lookup_sfield (tree var, omp_context *ctx)
713 splay_tree_node n;
714 n = splay_tree_lookup (ctx->sfield_map
715 ? ctx->sfield_map : ctx->field_map,
716 (splay_tree_key) var);
717 return (tree) n->value;
720 static inline tree
721 maybe_lookup_field (tree var, omp_context *ctx)
723 splay_tree_node n;
724 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
725 return n ? (tree) n->value : NULL_TREE;
728 /* Return true if DECL should be copied by pointer. SHARED_CTX is
729 the parallel context if DECL is to be shared. */
731 static bool
732 use_pointer_for_field (tree decl, omp_context *shared_ctx)
734 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
735 return true;
737 /* We can only use copy-in/copy-out semantics for shared variables
738 when we know the value is not accessible from an outer scope. */
739 if (shared_ctx)
741 /* ??? Trivially accessible from anywhere. But why would we even
742 be passing an address in this case? Should we simply assert
743 this to be false, or should we have a cleanup pass that removes
744 these from the list of mappings? */
745 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
746 return true;
748 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
749 without analyzing the expression whether or not its location
750 is accessible to anyone else. In the case of nested parallel
751 regions it certainly may be. */
752 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
753 return true;
755 /* Do not use copy-in/copy-out for variables that have their
756 address taken. */
757 if (TREE_ADDRESSABLE (decl))
758 return true;
760 /* lower_send_shared_vars only uses copy-in, but not copy-out
761 for these. */
762 if (TREE_READONLY (decl)
763 || ((TREE_CODE (decl) == RESULT_DECL
764 || TREE_CODE (decl) == PARM_DECL)
765 && DECL_BY_REFERENCE (decl)))
766 return false;
768 /* Disallow copy-in/out in nested parallel if
769 decl is shared in outer parallel, otherwise
770 each thread could store the shared variable
771 in its own copy-in location, making the
772 variable no longer really shared. */
773 if (shared_ctx->is_nested)
775 omp_context *up;
777 for (up = shared_ctx->outer; up; up = up->outer)
778 if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
779 break;
781 if (up)
783 tree c;
785 for (c = gimple_omp_taskreg_clauses (up->stmt);
786 c; c = OMP_CLAUSE_CHAIN (c))
787 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
788 && OMP_CLAUSE_DECL (c) == decl)
789 break;
791 if (c)
792 goto maybe_mark_addressable_and_ret;
796 /* For tasks avoid using copy-in/out. As tasks can be
797 deferred or executed in different thread, when GOMP_task
798 returns, the task hasn't necessarily terminated. */
799 if (is_task_ctx (shared_ctx))
801 tree outer;
802 maybe_mark_addressable_and_ret:
803 outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
804 if (is_gimple_reg (outer))
806 /* Taking address of OUTER in lower_send_shared_vars
807 might need regimplification of everything that uses the
808 variable. */
809 if (!task_shared_vars)
810 task_shared_vars = BITMAP_ALLOC (NULL);
811 bitmap_set_bit (task_shared_vars, DECL_UID (outer));
812 TREE_ADDRESSABLE (outer) = 1;
814 return true;
818 return false;
821 /* Create a new VAR_DECL and copy information from VAR to it. */
823 tree
824 copy_var_decl (tree var, tree name, tree type)
826 tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
828 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
829 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
830 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
831 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
832 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
833 DECL_CONTEXT (copy) = DECL_CONTEXT (var);
834 TREE_USED (copy) = 1;
835 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
837 return copy;
840 /* Construct a new automatic decl similar to VAR. */
842 static tree
843 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
845 tree copy = copy_var_decl (var, name, type);
847 DECL_CONTEXT (copy) = current_function_decl;
848 DECL_CHAIN (copy) = ctx->block_vars;
849 ctx->block_vars = copy;
851 return copy;
854 static tree
855 omp_copy_decl_1 (tree var, omp_context *ctx)
857 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
860 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
861 as appropriate. */
862 static tree
863 omp_build_component_ref (tree obj, tree field)
865 tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
866 if (TREE_THIS_VOLATILE (field))
867 TREE_THIS_VOLATILE (ret) |= 1;
868 if (TREE_READONLY (field))
869 TREE_READONLY (ret) |= 1;
870 return ret;
873 /* Build tree nodes to access the field for VAR on the receiver side. */
875 static tree
876 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
878 tree x, field = lookup_field (var, ctx);
880 /* If the receiver record type was remapped in the child function,
881 remap the field into the new record type. */
882 x = maybe_lookup_field (field, ctx);
883 if (x != NULL)
884 field = x;
886 x = build_simple_mem_ref (ctx->receiver_decl);
887 x = omp_build_component_ref (x, field);
888 if (by_ref)
889 x = build_simple_mem_ref (x);
891 return x;
894 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
895 of a parallel, this is a component reference; for workshare constructs
896 this is some variable. */
898 static tree
899 build_outer_var_ref (tree var, omp_context *ctx)
901 tree x;
903 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
904 x = var;
905 else if (is_variable_sized (var))
907 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
908 x = build_outer_var_ref (x, ctx);
909 x = build_simple_mem_ref (x);
911 else if (is_taskreg_ctx (ctx))
913 bool by_ref = use_pointer_for_field (var, NULL);
914 x = build_receiver_ref (var, by_ref, ctx);
916 else if (ctx->outer)
917 x = lookup_decl (var, ctx->outer);
918 else if (is_reference (var))
919 /* This can happen with orphaned constructs. If var is reference, it is
920 possible it is shared and as such valid. */
921 x = var;
922 else
923 gcc_unreachable ();
925 if (is_reference (var))
926 x = build_simple_mem_ref (x);
928 return x;
931 /* Build tree nodes to access the field for VAR on the sender side. */
933 static tree
934 build_sender_ref (tree var, omp_context *ctx)
936 tree field = lookup_sfield (var, ctx);
937 return omp_build_component_ref (ctx->sender_decl, field);
940 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
942 static void
943 install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
945 tree field, type, sfield = NULL_TREE;
947 gcc_assert ((mask & 1) == 0
948 || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
949 gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
950 || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
952 type = TREE_TYPE (var);
953 if (by_ref)
954 type = build_pointer_type (type);
955 else if ((mask & 3) == 1 && is_reference (var))
956 type = TREE_TYPE (type);
958 field = build_decl (DECL_SOURCE_LOCATION (var),
959 FIELD_DECL, DECL_NAME (var), type);
961 /* Remember what variable this field was created for. This does have a
962 side effect of making dwarf2out ignore this member, so for helpful
963 debugging we clear it later in delete_omp_context. */
964 DECL_ABSTRACT_ORIGIN (field) = var;
965 if (type == TREE_TYPE (var))
967 DECL_ALIGN (field) = DECL_ALIGN (var);
968 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
969 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
971 else
972 DECL_ALIGN (field) = TYPE_ALIGN (type);
974 if ((mask & 3) == 3)
976 insert_field_into_struct (ctx->record_type, field);
977 if (ctx->srecord_type)
979 sfield = build_decl (DECL_SOURCE_LOCATION (var),
980 FIELD_DECL, DECL_NAME (var), type);
981 DECL_ABSTRACT_ORIGIN (sfield) = var;
982 DECL_ALIGN (sfield) = DECL_ALIGN (field);
983 DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
984 TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
985 insert_field_into_struct (ctx->srecord_type, sfield);
988 else
990 if (ctx->srecord_type == NULL_TREE)
992 tree t;
994 ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
995 ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
996 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
998 sfield = build_decl (DECL_SOURCE_LOCATION (var),
999 FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
1000 DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
1001 insert_field_into_struct (ctx->srecord_type, sfield);
1002 splay_tree_insert (ctx->sfield_map,
1003 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
1004 (splay_tree_value) sfield);
1007 sfield = field;
1008 insert_field_into_struct ((mask & 1) ? ctx->record_type
1009 : ctx->srecord_type, field);
1012 if (mask & 1)
1013 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
1014 (splay_tree_value) field);
1015 if ((mask & 2) && ctx->sfield_map)
1016 splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1017 (splay_tree_value) sfield);
1020 static tree
1021 install_var_local (tree var, omp_context *ctx)
1023 tree new_var = omp_copy_decl_1 (var, ctx);
1024 insert_decl_map (&ctx->cb, var, new_var);
1025 return new_var;
1028 /* Adjust the replacement for DECL in CTX for the new context. This means
1029 copying the DECL_VALUE_EXPR, and fixing up the type. */
1031 static void
1032 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1034 tree new_decl, size;
1036 new_decl = lookup_decl (decl, ctx);
1038 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1040 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1041 && DECL_HAS_VALUE_EXPR_P (decl))
1043 tree ve = DECL_VALUE_EXPR (decl);
1044 walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1045 SET_DECL_VALUE_EXPR (new_decl, ve);
1046 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1049 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1051 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1052 if (size == error_mark_node)
1053 size = TYPE_SIZE (TREE_TYPE (new_decl));
1054 DECL_SIZE (new_decl) = size;
1056 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1057 if (size == error_mark_node)
1058 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1059 DECL_SIZE_UNIT (new_decl) = size;
1063 /* The callback for remap_decl. Search all containing contexts for a
1064 mapping of the variable; this avoids having to duplicate the splay
1065 tree ahead of time. We know a mapping doesn't already exist in the
1066 given context. Create new mappings to implement default semantics. */
1068 static tree
1069 omp_copy_decl (tree var, copy_body_data *cb)
1071 omp_context *ctx = (omp_context *) cb;
1072 tree new_var;
1074 if (TREE_CODE (var) == LABEL_DECL)
1076 new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1077 DECL_CONTEXT (new_var) = current_function_decl;
1078 insert_decl_map (&ctx->cb, var, new_var);
1079 return new_var;
1082 while (!is_taskreg_ctx (ctx))
1084 ctx = ctx->outer;
1085 if (ctx == NULL)
1086 return var;
1087 new_var = maybe_lookup_decl (var, ctx);
1088 if (new_var)
1089 return new_var;
1092 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1093 return var;
1095 return error_mark_node;
1099 /* Return the parallel region associated with STMT. */
1101 /* Debugging dumps for parallel regions. */
1102 void dump_omp_region (FILE *, struct omp_region *, int);
1103 void debug_omp_region (struct omp_region *);
1104 void debug_all_omp_regions (void);
1106 /* Dump the parallel region tree rooted at REGION. */
1108 void
1109 dump_omp_region (FILE *file, struct omp_region *region, int indent)
1111 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1112 gimple_code_name[region->type]);
1114 if (region->inner)
1115 dump_omp_region (file, region->inner, indent + 4);
1117 if (region->cont)
1119 fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1120 region->cont->index);
1123 if (region->exit)
1124 fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1125 region->exit->index);
1126 else
1127 fprintf (file, "%*s[no exit marker]\n", indent, "");
1129 if (region->next)
1130 dump_omp_region (file, region->next, indent);
1133 DEBUG_FUNCTION void
1134 debug_omp_region (struct omp_region *region)
1136 dump_omp_region (stderr, region, 0);
1139 DEBUG_FUNCTION void
1140 debug_all_omp_regions (void)
1142 dump_omp_region (stderr, root_omp_region, 0);
1146 /* Create a new parallel region starting at STMT inside region PARENT. */
1148 struct omp_region *
1149 new_omp_region (basic_block bb, enum gimple_code type,
1150 struct omp_region *parent)
1152 struct omp_region *region = XCNEW (struct omp_region);
1154 region->outer = parent;
1155 region->entry = bb;
1156 region->type = type;
1158 if (parent)
1160 /* This is a nested region. Add it to the list of inner
1161 regions in PARENT. */
1162 region->next = parent->inner;
1163 parent->inner = region;
1165 else
1167 /* This is a toplevel region. Add it to the list of toplevel
1168 regions in ROOT_OMP_REGION. */
1169 region->next = root_omp_region;
1170 root_omp_region = region;
1173 return region;
1176 /* Release the memory associated with the region tree rooted at REGION. */
1178 static void
1179 free_omp_region_1 (struct omp_region *region)
1181 struct omp_region *i, *n;
1183 for (i = region->inner; i ; i = n)
1185 n = i->next;
1186 free_omp_region_1 (i);
1189 free (region);
1192 /* Release the memory for the entire omp region tree. */
1194 void
1195 free_omp_regions (void)
1197 struct omp_region *r, *n;
1198 for (r = root_omp_region; r ; r = n)
1200 n = r->next;
1201 free_omp_region_1 (r);
1203 root_omp_region = NULL;
1207 /* Create a new context, with OUTER_CTX being the surrounding context. */
1209 static omp_context *
1210 new_omp_context (gimple stmt, omp_context *outer_ctx)
1212 omp_context *ctx = XCNEW (omp_context);
1214 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1215 (splay_tree_value) ctx);
1216 ctx->stmt = stmt;
1218 if (outer_ctx)
1220 ctx->outer = outer_ctx;
1221 ctx->cb = outer_ctx->cb;
1222 ctx->cb.block = NULL;
1223 ctx->depth = outer_ctx->depth + 1;
1225 else
1227 ctx->cb.src_fn = current_function_decl;
1228 ctx->cb.dst_fn = current_function_decl;
1229 ctx->cb.src_node = cgraph_get_node (current_function_decl);
1230 gcc_checking_assert (ctx->cb.src_node);
1231 ctx->cb.dst_node = ctx->cb.src_node;
1232 ctx->cb.src_cfun = cfun;
1233 ctx->cb.copy_decl = omp_copy_decl;
1234 ctx->cb.eh_lp_nr = 0;
1235 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1236 ctx->depth = 1;
1239 ctx->cb.decl_map = pointer_map_create ();
1241 return ctx;
1244 static gimple_seq maybe_catch_exception (gimple_seq);
1246 /* Finalize task copyfn. */
1248 static void
1249 finalize_task_copyfn (gimple task_stmt)
1251 struct function *child_cfun;
1252 tree child_fn;
1253 gimple_seq seq = NULL, new_seq;
1254 gimple bind;
1256 child_fn = gimple_omp_task_copy_fn (task_stmt);
1257 if (child_fn == NULL_TREE)
1258 return;
1260 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1261 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
1263 push_cfun (child_cfun);
1264 bind = gimplify_body (child_fn, false);
1265 gimple_seq_add_stmt (&seq, bind);
1266 new_seq = maybe_catch_exception (seq);
1267 if (new_seq != seq)
1269 bind = gimple_build_bind (NULL, new_seq, NULL);
1270 seq = NULL;
1271 gimple_seq_add_stmt (&seq, bind);
1273 gimple_set_body (child_fn, seq);
1274 pop_cfun ();
1276 /* Inform the callgraph about the new function. */
1277 cgraph_add_new_function (child_fn, false);
1280 /* Destroy a omp_context data structures. Called through the splay tree
1281 value delete callback. */
1283 static void
1284 delete_omp_context (splay_tree_value value)
1286 omp_context *ctx = (omp_context *) value;
1288 pointer_map_destroy (ctx->cb.decl_map);
1290 if (ctx->field_map)
1291 splay_tree_delete (ctx->field_map);
1292 if (ctx->sfield_map)
1293 splay_tree_delete (ctx->sfield_map);
1295 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1296 it produces corrupt debug information. */
1297 if (ctx->record_type)
1299 tree t;
1300 for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
1301 DECL_ABSTRACT_ORIGIN (t) = NULL;
1303 if (ctx->srecord_type)
1305 tree t;
1306 for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
1307 DECL_ABSTRACT_ORIGIN (t) = NULL;
1310 if (is_task_ctx (ctx))
1311 finalize_task_copyfn (ctx->stmt);
1313 XDELETE (ctx);
1316 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1317 context. */
1319 static void
1320 fixup_child_record_type (omp_context *ctx)
1322 tree f, type = ctx->record_type;
1324 /* ??? It isn't sufficient to just call remap_type here, because
1325 variably_modified_type_p doesn't work the way we expect for
1326 record types. Testing each field for whether it needs remapping
1327 and creating a new record by hand works, however. */
1328 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
1329 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1330 break;
1331 if (f)
1333 tree name, new_fields = NULL;
1335 type = lang_hooks.types.make_type (RECORD_TYPE);
1336 name = DECL_NAME (TYPE_NAME (ctx->record_type));
1337 name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1338 TYPE_DECL, name, type);
1339 TYPE_NAME (type) = name;
1341 for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
1343 tree new_f = copy_node (f);
1344 DECL_CONTEXT (new_f) = type;
1345 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
1346 DECL_CHAIN (new_f) = new_fields;
1347 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1348 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1349 &ctx->cb, NULL);
1350 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1351 &ctx->cb, NULL);
1352 new_fields = new_f;
1354 /* Arrange to be able to look up the receiver field
1355 given the sender field. */
1356 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1357 (splay_tree_value) new_f);
1359 TYPE_FIELDS (type) = nreverse (new_fields);
1360 layout_type (type);
1363 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
1366 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1367 specified by CLAUSES. */
1369 static void
1370 scan_sharing_clauses (tree clauses, omp_context *ctx)
1372 tree c, decl;
1373 bool scan_array_reductions = false;
1375 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1377 bool by_ref;
1379 switch (OMP_CLAUSE_CODE (c))
1381 case OMP_CLAUSE_PRIVATE:
1382 decl = OMP_CLAUSE_DECL (c);
1383 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1384 goto do_private;
1385 else if (!is_variable_sized (decl))
1386 install_var_local (decl, ctx);
1387 break;
1389 case OMP_CLAUSE_SHARED:
1390 gcc_assert (is_taskreg_ctx (ctx));
1391 decl = OMP_CLAUSE_DECL (c);
1392 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1393 || !is_variable_sized (decl));
1394 /* Global variables don't need to be copied,
1395 the receiver side will use them directly. */
1396 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1397 break;
1398 by_ref = use_pointer_for_field (decl, ctx);
1399 if (! TREE_READONLY (decl)
1400 || TREE_ADDRESSABLE (decl)
1401 || by_ref
1402 || is_reference (decl))
1404 install_var_field (decl, by_ref, 3, ctx);
1405 install_var_local (decl, ctx);
1406 break;
1408 /* We don't need to copy const scalar vars back. */
1409 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1410 goto do_private;
1412 case OMP_CLAUSE_LASTPRIVATE:
1413 /* Let the corresponding firstprivate clause create
1414 the variable. */
1415 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1416 break;
1417 /* FALLTHRU */
1419 case OMP_CLAUSE_FIRSTPRIVATE:
1420 case OMP_CLAUSE_REDUCTION:
1421 decl = OMP_CLAUSE_DECL (c);
1422 do_private:
1423 if (is_variable_sized (decl))
1425 if (is_task_ctx (ctx))
1426 install_var_field (decl, false, 1, ctx);
1427 break;
1429 else if (is_taskreg_ctx (ctx))
1431 bool global
1432 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
1433 by_ref = use_pointer_for_field (decl, NULL);
1435 if (is_task_ctx (ctx)
1436 && (global || by_ref || is_reference (decl)))
1438 install_var_field (decl, false, 1, ctx);
1439 if (!global)
1440 install_var_field (decl, by_ref, 2, ctx);
1442 else if (!global)
1443 install_var_field (decl, by_ref, 3, ctx);
1445 install_var_local (decl, ctx);
1446 break;
1448 case OMP_CLAUSE_COPYPRIVATE:
1449 case OMP_CLAUSE_COPYIN:
1450 decl = OMP_CLAUSE_DECL (c);
1451 by_ref = use_pointer_for_field (decl, NULL);
1452 install_var_field (decl, by_ref, 3, ctx);
1453 break;
1455 case OMP_CLAUSE_DEFAULT:
1456 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1457 break;
1459 case OMP_CLAUSE_FINAL:
1460 case OMP_CLAUSE_IF:
1461 case OMP_CLAUSE_NUM_THREADS:
1462 case OMP_CLAUSE_SCHEDULE:
1463 if (ctx->outer)
1464 scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1465 break;
1467 case OMP_CLAUSE_NOWAIT:
1468 case OMP_CLAUSE_ORDERED:
1469 case OMP_CLAUSE_COLLAPSE:
1470 case OMP_CLAUSE_UNTIED:
1471 case OMP_CLAUSE_MERGEABLE:
1472 break;
1474 default:
1475 gcc_unreachable ();
1479 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1481 switch (OMP_CLAUSE_CODE (c))
1483 case OMP_CLAUSE_LASTPRIVATE:
1484 /* Let the corresponding firstprivate clause create
1485 the variable. */
1486 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1487 scan_array_reductions = true;
1488 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1489 break;
1490 /* FALLTHRU */
1492 case OMP_CLAUSE_PRIVATE:
1493 case OMP_CLAUSE_FIRSTPRIVATE:
1494 case OMP_CLAUSE_REDUCTION:
1495 decl = OMP_CLAUSE_DECL (c);
1496 if (is_variable_sized (decl))
1497 install_var_local (decl, ctx);
1498 fixup_remapped_decl (decl, ctx,
1499 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1500 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1501 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1502 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1503 scan_array_reductions = true;
1504 break;
1506 case OMP_CLAUSE_SHARED:
1507 decl = OMP_CLAUSE_DECL (c);
1508 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1509 fixup_remapped_decl (decl, ctx, false);
1510 break;
1512 case OMP_CLAUSE_COPYPRIVATE:
1513 case OMP_CLAUSE_COPYIN:
1514 case OMP_CLAUSE_DEFAULT:
1515 case OMP_CLAUSE_IF:
1516 case OMP_CLAUSE_NUM_THREADS:
1517 case OMP_CLAUSE_SCHEDULE:
1518 case OMP_CLAUSE_NOWAIT:
1519 case OMP_CLAUSE_ORDERED:
1520 case OMP_CLAUSE_COLLAPSE:
1521 case OMP_CLAUSE_UNTIED:
1522 case OMP_CLAUSE_FINAL:
1523 case OMP_CLAUSE_MERGEABLE:
1524 break;
1526 default:
1527 gcc_unreachable ();
1531 if (scan_array_reductions)
1532 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1533 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1534 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1536 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
1537 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
1539 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1540 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1541 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
1544 /* Create a new name for omp child function. Returns an identifier. */
1546 static GTY(()) unsigned int tmp_ompfn_id_num;
1548 static tree
1549 create_omp_child_function_name (bool task_copy)
1551 return (clone_function_name (current_function_decl,
1552 task_copy ? "_omp_cpyfn" : "_omp_fn"));
1555 /* Build a decl for the omp child function. It'll not contain a body
1556 yet, just the bare decl. */
1558 static void
1559 create_omp_child_function (omp_context *ctx, bool task_copy)
1561 tree decl, type, name, t;
1563 name = create_omp_child_function_name (task_copy);
1564 if (task_copy)
1565 type = build_function_type_list (void_type_node, ptr_type_node,
1566 ptr_type_node, NULL_TREE);
1567 else
1568 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1570 decl = build_decl (gimple_location (ctx->stmt),
1571 FUNCTION_DECL, name, type);
1573 if (!task_copy)
1574 ctx->cb.dst_fn = decl;
1575 else
1576 gimple_omp_task_set_copy_fn (ctx->stmt, decl);
1578 TREE_STATIC (decl) = 1;
1579 TREE_USED (decl) = 1;
1580 DECL_ARTIFICIAL (decl) = 1;
1581 DECL_NAMELESS (decl) = 1;
1582 DECL_IGNORED_P (decl) = 0;
1583 TREE_PUBLIC (decl) = 0;
1584 DECL_UNINLINABLE (decl) = 1;
1585 DECL_EXTERNAL (decl) = 0;
1586 DECL_CONTEXT (decl) = NULL_TREE;
1587 DECL_INITIAL (decl) = make_node (BLOCK);
1589 t = build_decl (DECL_SOURCE_LOCATION (decl),
1590 RESULT_DECL, NULL_TREE, void_type_node);
1591 DECL_ARTIFICIAL (t) = 1;
1592 DECL_IGNORED_P (t) = 1;
1593 DECL_CONTEXT (t) = decl;
1594 DECL_RESULT (decl) = t;
1596 t = build_decl (DECL_SOURCE_LOCATION (decl),
1597 PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1598 DECL_ARTIFICIAL (t) = 1;
1599 DECL_NAMELESS (t) = 1;
1600 DECL_ARG_TYPE (t) = ptr_type_node;
1601 DECL_CONTEXT (t) = current_function_decl;
1602 TREE_USED (t) = 1;
1603 DECL_ARGUMENTS (decl) = t;
1604 if (!task_copy)
1605 ctx->receiver_decl = t;
1606 else
1608 t = build_decl (DECL_SOURCE_LOCATION (decl),
1609 PARM_DECL, get_identifier (".omp_data_o"),
1610 ptr_type_node);
1611 DECL_ARTIFICIAL (t) = 1;
1612 DECL_NAMELESS (t) = 1;
1613 DECL_ARG_TYPE (t) = ptr_type_node;
1614 DECL_CONTEXT (t) = current_function_decl;
1615 TREE_USED (t) = 1;
1616 TREE_ADDRESSABLE (t) = 1;
1617 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
1618 DECL_ARGUMENTS (decl) = t;
1621 /* Allocate memory for the function structure. The call to
1622 allocate_struct_function clobbers CFUN, so we need to restore
1623 it afterward. */
1624 push_struct_function (decl);
1625 cfun->function_end_locus = gimple_location (ctx->stmt);
1626 pop_cfun ();
1630 /* Scan an OpenMP parallel directive. */
1632 static void
1633 scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1635 omp_context *ctx;
1636 tree name;
1637 gimple stmt = gsi_stmt (*gsi);
1639 /* Ignore parallel directives with empty bodies, unless there
1640 are copyin clauses. */
1641 if (optimize > 0
1642 && empty_body_p (gimple_omp_body (stmt))
1643 && find_omp_clause (gimple_omp_parallel_clauses (stmt),
1644 OMP_CLAUSE_COPYIN) == NULL)
1646 gsi_replace (gsi, gimple_build_nop (), false);
1647 return;
1650 ctx = new_omp_context (stmt, outer_ctx);
1651 if (taskreg_nesting_level > 1)
1652 ctx->is_nested = true;
1653 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1654 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1655 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1656 name = create_tmp_var_name (".omp_data_s");
1657 name = build_decl (gimple_location (stmt),
1658 TYPE_DECL, name, ctx->record_type);
1659 DECL_ARTIFICIAL (name) = 1;
1660 DECL_NAMELESS (name) = 1;
1661 TYPE_NAME (ctx->record_type) = name;
1662 create_omp_child_function (ctx, false);
1663 gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
1665 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
1666 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1668 if (TYPE_FIELDS (ctx->record_type) == NULL)
1669 ctx->record_type = ctx->receiver_decl = NULL;
1670 else
1672 layout_type (ctx->record_type);
1673 fixup_child_record_type (ctx);
1677 /* Scan an OpenMP task directive. */
1679 static void
1680 scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1682 omp_context *ctx;
1683 tree name, t;
1684 gimple stmt = gsi_stmt (*gsi);
1685 location_t loc = gimple_location (stmt);
1687 /* Ignore task directives with empty bodies. */
1688 if (optimize > 0
1689 && empty_body_p (gimple_omp_body (stmt)))
1691 gsi_replace (gsi, gimple_build_nop (), false);
1692 return;
1695 ctx = new_omp_context (stmt, outer_ctx);
1696 if (taskreg_nesting_level > 1)
1697 ctx->is_nested = true;
1698 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1699 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1700 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1701 name = create_tmp_var_name (".omp_data_s");
1702 name = build_decl (gimple_location (stmt),
1703 TYPE_DECL, name, ctx->record_type);
1704 DECL_ARTIFICIAL (name) = 1;
1705 DECL_NAMELESS (name) = 1;
1706 TYPE_NAME (ctx->record_type) = name;
1707 create_omp_child_function (ctx, false);
1708 gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
1710 scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
1712 if (ctx->srecord_type)
1714 name = create_tmp_var_name (".omp_data_a");
1715 name = build_decl (gimple_location (stmt),
1716 TYPE_DECL, name, ctx->srecord_type);
1717 DECL_ARTIFICIAL (name) = 1;
1718 DECL_NAMELESS (name) = 1;
1719 TYPE_NAME (ctx->srecord_type) = name;
1720 create_omp_child_function (ctx, true);
1723 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1725 if (TYPE_FIELDS (ctx->record_type) == NULL)
1727 ctx->record_type = ctx->receiver_decl = NULL;
1728 t = build_int_cst (long_integer_type_node, 0);
1729 gimple_omp_task_set_arg_size (stmt, t);
1730 t = build_int_cst (long_integer_type_node, 1);
1731 gimple_omp_task_set_arg_align (stmt, t);
1733 else
1735 tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
1736 /* Move VLA fields to the end. */
1737 p = &TYPE_FIELDS (ctx->record_type);
1738 while (*p)
1739 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
1740 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
1742 *q = *p;
1743 *p = TREE_CHAIN (*p);
1744 TREE_CHAIN (*q) = NULL_TREE;
1745 q = &TREE_CHAIN (*q);
1747 else
1748 p = &DECL_CHAIN (*p);
1749 *p = vla_fields;
1750 layout_type (ctx->record_type);
1751 fixup_child_record_type (ctx);
1752 if (ctx->srecord_type)
1753 layout_type (ctx->srecord_type);
1754 t = fold_convert_loc (loc, long_integer_type_node,
1755 TYPE_SIZE_UNIT (ctx->record_type));
1756 gimple_omp_task_set_arg_size (stmt, t);
1757 t = build_int_cst (long_integer_type_node,
1758 TYPE_ALIGN_UNIT (ctx->record_type));
1759 gimple_omp_task_set_arg_align (stmt, t);
1764 /* Scan an OpenMP loop directive. */
1766 static void
1767 scan_omp_for (gimple stmt, omp_context *outer_ctx)
1769 omp_context *ctx;
1770 size_t i;
1772 ctx = new_omp_context (stmt, outer_ctx);
1774 scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
1776 scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
1777 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
1779 scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
1780 scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
1781 scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
1782 scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
1784 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1787 /* Scan an OpenMP sections directive. */
1789 static void
1790 scan_omp_sections (gimple stmt, omp_context *outer_ctx)
1792 omp_context *ctx;
1794 ctx = new_omp_context (stmt, outer_ctx);
1795 scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
1796 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1799 /* Scan an OpenMP single directive. */
1801 static void
1802 scan_omp_single (gimple stmt, omp_context *outer_ctx)
1804 omp_context *ctx;
1805 tree name;
1807 ctx = new_omp_context (stmt, outer_ctx);
1808 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1809 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1810 name = create_tmp_var_name (".omp_copy_s");
1811 name = build_decl (gimple_location (stmt),
1812 TYPE_DECL, name, ctx->record_type);
1813 TYPE_NAME (ctx->record_type) = name;
1815 scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
1816 scan_omp (gimple_omp_body_ptr (stmt), ctx);
1818 if (TYPE_FIELDS (ctx->record_type) == NULL)
1819 ctx->record_type = NULL;
1820 else
1821 layout_type (ctx->record_type);
1825 /* Check OpenMP nesting restrictions. */
1826 static bool
1827 check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
1829 switch (gimple_code (stmt))
1831 case GIMPLE_OMP_FOR:
1832 case GIMPLE_OMP_SECTIONS:
1833 case GIMPLE_OMP_SINGLE:
1834 case GIMPLE_CALL:
1835 for (; ctx != NULL; ctx = ctx->outer)
1836 switch (gimple_code (ctx->stmt))
1838 case GIMPLE_OMP_FOR:
1839 case GIMPLE_OMP_SECTIONS:
1840 case GIMPLE_OMP_SINGLE:
1841 case GIMPLE_OMP_ORDERED:
1842 case GIMPLE_OMP_MASTER:
1843 case GIMPLE_OMP_TASK:
1844 if (is_gimple_call (stmt))
1846 error_at (gimple_location (stmt),
1847 "barrier region may not be closely nested inside "
1848 "of work-sharing, critical, ordered, master or "
1849 "explicit task region");
1850 return false;
1852 error_at (gimple_location (stmt),
1853 "work-sharing region may not be closely nested inside "
1854 "of work-sharing, critical, ordered, master or explicit "
1855 "task region");
1856 return false;
1857 case GIMPLE_OMP_PARALLEL:
1858 return true;
1859 default:
1860 break;
1862 break;
1863 case GIMPLE_OMP_MASTER:
1864 for (; ctx != NULL; ctx = ctx->outer)
1865 switch (gimple_code (ctx->stmt))
1867 case GIMPLE_OMP_FOR:
1868 case GIMPLE_OMP_SECTIONS:
1869 case GIMPLE_OMP_SINGLE:
1870 case GIMPLE_OMP_TASK:
1871 error_at (gimple_location (stmt),
1872 "master region may not be closely nested inside "
1873 "of work-sharing or explicit task region");
1874 return false;
1875 case GIMPLE_OMP_PARALLEL:
1876 return true;
1877 default:
1878 break;
1880 break;
1881 case GIMPLE_OMP_ORDERED:
1882 for (; ctx != NULL; ctx = ctx->outer)
1883 switch (gimple_code (ctx->stmt))
1885 case GIMPLE_OMP_CRITICAL:
1886 case GIMPLE_OMP_TASK:
1887 error_at (gimple_location (stmt),
1888 "ordered region may not be closely nested inside "
1889 "of critical or explicit task region");
1890 return false;
1891 case GIMPLE_OMP_FOR:
1892 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
1893 OMP_CLAUSE_ORDERED) == NULL)
1895 error_at (gimple_location (stmt),
1896 "ordered region must be closely nested inside "
1897 "a loop region with an ordered clause");
1898 return false;
1900 return true;
1901 case GIMPLE_OMP_PARALLEL:
1902 return true;
1903 default:
1904 break;
1906 break;
1907 case GIMPLE_OMP_CRITICAL:
1908 for (; ctx != NULL; ctx = ctx->outer)
1909 if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
1910 && (gimple_omp_critical_name (stmt)
1911 == gimple_omp_critical_name (ctx->stmt)))
1913 error_at (gimple_location (stmt),
1914 "critical region may not be nested inside a critical "
1915 "region with the same name");
1916 return false;
1918 break;
1919 default:
1920 break;
1922 return true;
1926 /* Helper function scan_omp.
1928 Callback for walk_tree or operators in walk_gimple_stmt used to
1929 scan for OpenMP directives in TP. */
1931 static tree
1932 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
1934 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1935 omp_context *ctx = (omp_context *) wi->info;
1936 tree t = *tp;
1938 switch (TREE_CODE (t))
1940 case VAR_DECL:
1941 case PARM_DECL:
1942 case LABEL_DECL:
1943 case RESULT_DECL:
1944 if (ctx)
1945 *tp = remap_decl (t, &ctx->cb);
1946 break;
1948 default:
1949 if (ctx && TYPE_P (t))
1950 *tp = remap_type (t, &ctx->cb);
1951 else if (!DECL_P (t))
1953 *walk_subtrees = 1;
1954 if (ctx)
1956 tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
1957 if (tem != TREE_TYPE (t))
1959 if (TREE_CODE (t) == INTEGER_CST)
1960 *tp = build_int_cst_wide (tem,
1961 TREE_INT_CST_LOW (t),
1962 TREE_INT_CST_HIGH (t));
1963 else
1964 TREE_TYPE (t) = tem;
1968 break;
1971 return NULL_TREE;
1975 /* Helper function for scan_omp.
1977 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1978 the current statement in GSI. */
1980 static tree
1981 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1982 struct walk_stmt_info *wi)
1984 gimple stmt = gsi_stmt (*gsi);
1985 omp_context *ctx = (omp_context *) wi->info;
1987 if (gimple_has_location (stmt))
1988 input_location = gimple_location (stmt);
1990 /* Check the OpenMP nesting restrictions. */
1991 if (ctx != NULL)
1993 bool remove = false;
1994 if (is_gimple_omp (stmt))
1995 remove = !check_omp_nesting_restrictions (stmt, ctx);
1996 else if (is_gimple_call (stmt))
1998 tree fndecl = gimple_call_fndecl (stmt);
1999 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
2000 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
2001 remove = !check_omp_nesting_restrictions (stmt, ctx);
2003 if (remove)
2005 stmt = gimple_build_nop ();
2006 gsi_replace (gsi, stmt, false);
2010 *handled_ops_p = true;
2012 switch (gimple_code (stmt))
2014 case GIMPLE_OMP_PARALLEL:
2015 taskreg_nesting_level++;
2016 scan_omp_parallel (gsi, ctx);
2017 taskreg_nesting_level--;
2018 break;
2020 case GIMPLE_OMP_TASK:
2021 taskreg_nesting_level++;
2022 scan_omp_task (gsi, ctx);
2023 taskreg_nesting_level--;
2024 break;
2026 case GIMPLE_OMP_FOR:
2027 scan_omp_for (stmt, ctx);
2028 break;
2030 case GIMPLE_OMP_SECTIONS:
2031 scan_omp_sections (stmt, ctx);
2032 break;
2034 case GIMPLE_OMP_SINGLE:
2035 scan_omp_single (stmt, ctx);
2036 break;
2038 case GIMPLE_OMP_SECTION:
2039 case GIMPLE_OMP_MASTER:
2040 case GIMPLE_OMP_ORDERED:
2041 case GIMPLE_OMP_CRITICAL:
2042 ctx = new_omp_context (stmt, ctx);
2043 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2044 break;
2046 case GIMPLE_BIND:
2048 tree var;
2050 *handled_ops_p = false;
2051 if (ctx)
2052 for (var = gimple_bind_vars (stmt); var ; var = DECL_CHAIN (var))
2053 insert_decl_map (&ctx->cb, var, var);
2055 break;
2056 default:
2057 *handled_ops_p = false;
2058 break;
2061 return NULL_TREE;
2065 /* Scan all the statements starting at the current statement. CTX
2066 contains context information about the OpenMP directives and
2067 clauses found during the scan. */
2069 static void
2070 scan_omp (gimple_seq *body_p, omp_context *ctx)
2072 location_t saved_location;
2073 struct walk_stmt_info wi;
2075 memset (&wi, 0, sizeof (wi));
2076 wi.info = ctx;
2077 wi.want_locations = true;
2079 saved_location = input_location;
2080 walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
2081 input_location = saved_location;
2084 /* Re-gimplification and code generation routines. */
2086 /* Build a call to GOMP_barrier. */
2088 static tree
2089 build_omp_barrier (void)
2091 return build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_BARRIER), 0);
2094 /* If a context was created for STMT when it was scanned, return it. */
2096 static omp_context *
2097 maybe_lookup_ctx (gimple stmt)
2099 splay_tree_node n;
2100 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
2101 return n ? (omp_context *) n->value : NULL;
2105 /* Find the mapping for DECL in CTX or the immediately enclosing
2106 context that has a mapping for DECL.
2108 If CTX is a nested parallel directive, we may have to use the decl
2109 mappings created in CTX's parent context. Suppose that we have the
2110 following parallel nesting (variable UIDs showed for clarity):
2112 iD.1562 = 0;
2113 #omp parallel shared(iD.1562) -> outer parallel
2114 iD.1562 = iD.1562 + 1;
2116 #omp parallel shared (iD.1562) -> inner parallel
2117 iD.1562 = iD.1562 - 1;
2119 Each parallel structure will create a distinct .omp_data_s structure
2120 for copying iD.1562 in/out of the directive:
2122 outer parallel .omp_data_s.1.i -> iD.1562
2123 inner parallel .omp_data_s.2.i -> iD.1562
2125 A shared variable mapping will produce a copy-out operation before
2126 the parallel directive and a copy-in operation after it. So, in
2127 this case we would have:
2129 iD.1562 = 0;
2130 .omp_data_o.1.i = iD.1562;
2131 #omp parallel shared(iD.1562) -> outer parallel
2132 .omp_data_i.1 = &.omp_data_o.1
2133 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2135 .omp_data_o.2.i = iD.1562; -> **
2136 #omp parallel shared(iD.1562) -> inner parallel
2137 .omp_data_i.2 = &.omp_data_o.2
2138 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2141 ** This is a problem. The symbol iD.1562 cannot be referenced
2142 inside the body of the outer parallel region. But since we are
2143 emitting this copy operation while expanding the inner parallel
2144 directive, we need to access the CTX structure of the outer
2145 parallel directive to get the correct mapping:
2147 .omp_data_o.2.i = .omp_data_i.1->i
2149 Since there may be other workshare or parallel directives enclosing
2150 the parallel directive, it may be necessary to walk up the context
2151 parent chain. This is not a problem in general because nested
2152 parallelism happens only rarely. */
2154 static tree
2155 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2157 tree t;
2158 omp_context *up;
2160 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2161 t = maybe_lookup_decl (decl, up);
2163 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
2165 return t ? t : decl;
2169 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2170 in outer contexts. */
2172 static tree
2173 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2175 tree t = NULL;
2176 omp_context *up;
2178 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2179 t = maybe_lookup_decl (decl, up);
2181 return t ? t : decl;
2185 /* Construct the initialization value for reduction CLAUSE. */
2187 tree
2188 omp_reduction_init (tree clause, tree type)
2190 location_t loc = OMP_CLAUSE_LOCATION (clause);
2191 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
2193 case PLUS_EXPR:
2194 case MINUS_EXPR:
2195 case BIT_IOR_EXPR:
2196 case BIT_XOR_EXPR:
2197 case TRUTH_OR_EXPR:
2198 case TRUTH_ORIF_EXPR:
2199 case TRUTH_XOR_EXPR:
2200 case NE_EXPR:
2201 return build_zero_cst (type);
2203 case MULT_EXPR:
2204 case TRUTH_AND_EXPR:
2205 case TRUTH_ANDIF_EXPR:
2206 case EQ_EXPR:
2207 return fold_convert_loc (loc, type, integer_one_node);
2209 case BIT_AND_EXPR:
2210 return fold_convert_loc (loc, type, integer_minus_one_node);
2212 case MAX_EXPR:
2213 if (SCALAR_FLOAT_TYPE_P (type))
2215 REAL_VALUE_TYPE max, min;
2216 if (HONOR_INFINITIES (TYPE_MODE (type)))
2218 real_inf (&max);
2219 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
2221 else
2222 real_maxval (&min, 1, TYPE_MODE (type));
2223 return build_real (type, min);
2225 else
2227 gcc_assert (INTEGRAL_TYPE_P (type));
2228 return TYPE_MIN_VALUE (type);
2231 case MIN_EXPR:
2232 if (SCALAR_FLOAT_TYPE_P (type))
2234 REAL_VALUE_TYPE max;
2235 if (HONOR_INFINITIES (TYPE_MODE (type)))
2236 real_inf (&max);
2237 else
2238 real_maxval (&max, 0, TYPE_MODE (type));
2239 return build_real (type, max);
2241 else
2243 gcc_assert (INTEGRAL_TYPE_P (type));
2244 return TYPE_MAX_VALUE (type);
2247 default:
2248 gcc_unreachable ();
2252 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2253 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2254 private variables. Initialization statements go in ILIST, while calls
2255 to destructors go in DLIST. */
2257 static void
2258 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
2259 omp_context *ctx)
2261 tree c, dtor, copyin_seq, x, ptr;
2262 bool copyin_by_ref = false;
2263 bool lastprivate_firstprivate = false;
2264 int pass;
2266 copyin_seq = NULL;
2268 /* Do all the fixed sized types in the first pass, and the variable sized
2269 types in the second pass. This makes sure that the scalar arguments to
2270 the variable sized types are processed before we use them in the
2271 variable sized operations. */
2272 for (pass = 0; pass < 2; ++pass)
2274 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2276 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
2277 tree var, new_var;
2278 bool by_ref;
2279 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2281 switch (c_kind)
2283 case OMP_CLAUSE_PRIVATE:
2284 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
2285 continue;
2286 break;
2287 case OMP_CLAUSE_SHARED:
2288 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
2290 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
2291 continue;
2293 case OMP_CLAUSE_FIRSTPRIVATE:
2294 case OMP_CLAUSE_COPYIN:
2295 case OMP_CLAUSE_REDUCTION:
2296 break;
2297 case OMP_CLAUSE_LASTPRIVATE:
2298 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2300 lastprivate_firstprivate = true;
2301 if (pass != 0)
2302 continue;
2304 break;
2305 default:
2306 continue;
2309 new_var = var = OMP_CLAUSE_DECL (c);
2310 if (c_kind != OMP_CLAUSE_COPYIN)
2311 new_var = lookup_decl (var, ctx);
2313 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
2315 if (pass != 0)
2316 continue;
2318 else if (is_variable_sized (var))
2320 /* For variable sized types, we need to allocate the
2321 actual storage here. Call alloca and store the
2322 result in the pointer decl that we created elsewhere. */
2323 if (pass == 0)
2324 continue;
2326 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
2328 gimple stmt;
2329 tree tmp, atmp;
2331 ptr = DECL_VALUE_EXPR (new_var);
2332 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
2333 ptr = TREE_OPERAND (ptr, 0);
2334 gcc_assert (DECL_P (ptr));
2335 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
2337 /* void *tmp = __builtin_alloca */
2338 atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2339 stmt = gimple_build_call (atmp, 1, x);
2340 tmp = create_tmp_var_raw (ptr_type_node, NULL);
2341 gimple_add_tmp_var (tmp);
2342 gimple_call_set_lhs (stmt, tmp);
2344 gimple_seq_add_stmt (ilist, stmt);
2346 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
2347 gimplify_assign (ptr, x, ilist);
2350 else if (is_reference (var))
2352 /* For references that are being privatized for Fortran,
2353 allocate new backing storage for the new pointer
2354 variable. This allows us to avoid changing all the
2355 code that expects a pointer to something that expects
2356 a direct variable. Note that this doesn't apply to
2357 C++, since reference types are disallowed in data
2358 sharing clauses there, except for NRV optimized
2359 return values. */
2360 if (pass == 0)
2361 continue;
2363 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
2364 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
2366 x = build_receiver_ref (var, false, ctx);
2367 x = build_fold_addr_expr_loc (clause_loc, x);
2369 else if (TREE_CONSTANT (x))
2371 const char *name = NULL;
2372 if (DECL_NAME (var))
2373 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
2375 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
2376 name);
2377 gimple_add_tmp_var (x);
2378 TREE_ADDRESSABLE (x) = 1;
2379 x = build_fold_addr_expr_loc (clause_loc, x);
2381 else
2383 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2384 x = build_call_expr_loc (clause_loc, atmp, 1, x);
2387 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
2388 gimplify_assign (new_var, x, ilist);
2390 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2392 else if (c_kind == OMP_CLAUSE_REDUCTION
2393 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2395 if (pass == 0)
2396 continue;
2398 else if (pass != 0)
2399 continue;
2401 switch (OMP_CLAUSE_CODE (c))
2403 case OMP_CLAUSE_SHARED:
2404 /* Shared global vars are just accessed directly. */
2405 if (is_global_var (new_var))
2406 break;
2407 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2408 needs to be delayed until after fixup_child_record_type so
2409 that we get the correct type during the dereference. */
2410 by_ref = use_pointer_for_field (var, ctx);
2411 x = build_receiver_ref (var, by_ref, ctx);
2412 SET_DECL_VALUE_EXPR (new_var, x);
2413 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2415 /* ??? If VAR is not passed by reference, and the variable
2416 hasn't been initialized yet, then we'll get a warning for
2417 the store into the omp_data_s structure. Ideally, we'd be
2418 able to notice this and not store anything at all, but
2419 we're generating code too early. Suppress the warning. */
2420 if (!by_ref)
2421 TREE_NO_WARNING (var) = 1;
2422 break;
2424 case OMP_CLAUSE_LASTPRIVATE:
2425 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2426 break;
2427 /* FALLTHRU */
2429 case OMP_CLAUSE_PRIVATE:
2430 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
2431 x = build_outer_var_ref (var, ctx);
2432 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2434 if (is_task_ctx (ctx))
2435 x = build_receiver_ref (var, false, ctx);
2436 else
2437 x = build_outer_var_ref (var, ctx);
2439 else
2440 x = NULL;
2441 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
2442 if (x)
2443 gimplify_and_add (x, ilist);
2444 /* FALLTHRU */
2446 do_dtor:
2447 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
2448 if (x)
2450 gimple_seq tseq = NULL;
2452 dtor = x;
2453 gimplify_stmt (&dtor, &tseq);
2454 gimple_seq_add_seq (dlist, tseq);
2456 break;
2458 case OMP_CLAUSE_FIRSTPRIVATE:
2459 if (is_task_ctx (ctx))
2461 if (is_reference (var) || is_variable_sized (var))
2462 goto do_dtor;
2463 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
2464 ctx))
2465 || use_pointer_for_field (var, NULL))
2467 x = build_receiver_ref (var, false, ctx);
2468 SET_DECL_VALUE_EXPR (new_var, x);
2469 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2470 goto do_dtor;
2473 x = build_outer_var_ref (var, ctx);
2474 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
2475 gimplify_and_add (x, ilist);
2476 goto do_dtor;
2477 break;
2479 case OMP_CLAUSE_COPYIN:
2480 by_ref = use_pointer_for_field (var, NULL);
2481 x = build_receiver_ref (var, by_ref, ctx);
2482 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
2483 append_to_statement_list (x, &copyin_seq);
2484 copyin_by_ref |= by_ref;
2485 break;
2487 case OMP_CLAUSE_REDUCTION:
2488 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2490 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2491 x = build_outer_var_ref (var, ctx);
2493 if (is_reference (var))
2494 x = build_fold_addr_expr_loc (clause_loc, x);
2495 SET_DECL_VALUE_EXPR (placeholder, x);
2496 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2497 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2498 gimple_seq_add_seq (ilist,
2499 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
2500 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
2501 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
2503 else
2505 x = omp_reduction_init (c, TREE_TYPE (new_var));
2506 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
2507 gimplify_assign (new_var, x, ilist);
2509 break;
2511 default:
2512 gcc_unreachable ();
2517 /* The copyin sequence is not to be executed by the main thread, since
2518 that would result in self-copies. Perhaps not visible to scalars,
2519 but it certainly is to C++ operator=. */
2520 if (copyin_seq)
2522 x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
2524 x = build2 (NE_EXPR, boolean_type_node, x,
2525 build_int_cst (TREE_TYPE (x), 0));
2526 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
2527 gimplify_and_add (x, ilist);
2530 /* If any copyin variable is passed by reference, we must ensure the
2531 master thread doesn't modify it before it is copied over in all
2532 threads. Similarly for variables in both firstprivate and
2533 lastprivate clauses we need to ensure the lastprivate copying
2534 happens after firstprivate copying in all threads. */
2535 if (copyin_by_ref || lastprivate_firstprivate)
2536 gimplify_and_add (build_omp_barrier (), ilist);
2540 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2541 both parallel and workshare constructs. PREDICATE may be NULL if it's
2542 always true. */
2544 static void
2545 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
2546 omp_context *ctx)
2548 tree x, c, label = NULL;
2549 bool par_clauses = false;
2551 /* Early exit if there are no lastprivate clauses. */
2552 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
2553 if (clauses == NULL)
2555 /* If this was a workshare clause, see if it had been combined
2556 with its parallel. In that case, look for the clauses on the
2557 parallel statement itself. */
2558 if (is_parallel_ctx (ctx))
2559 return;
2561 ctx = ctx->outer;
2562 if (ctx == NULL || !is_parallel_ctx (ctx))
2563 return;
2565 clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2566 OMP_CLAUSE_LASTPRIVATE);
2567 if (clauses == NULL)
2568 return;
2569 par_clauses = true;
2572 if (predicate)
2574 gimple stmt;
2575 tree label_true, arm1, arm2;
2577 label = create_artificial_label (UNKNOWN_LOCATION);
2578 label_true = create_artificial_label (UNKNOWN_LOCATION);
2579 arm1 = TREE_OPERAND (predicate, 0);
2580 arm2 = TREE_OPERAND (predicate, 1);
2581 gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
2582 gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
2583 stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
2584 label_true, label);
2585 gimple_seq_add_stmt (stmt_list, stmt);
2586 gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
2589 for (c = clauses; c ;)
2591 tree var, new_var;
2592 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2594 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2596 var = OMP_CLAUSE_DECL (c);
2597 new_var = lookup_decl (var, ctx);
2599 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2601 lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2602 gimple_seq_add_seq (stmt_list,
2603 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
2605 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
2607 x = build_outer_var_ref (var, ctx);
2608 if (is_reference (var))
2609 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2610 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
2611 gimplify_and_add (x, stmt_list);
2613 c = OMP_CLAUSE_CHAIN (c);
2614 if (c == NULL && !par_clauses)
2616 /* If this was a workshare clause, see if it had been combined
2617 with its parallel. In that case, continue looking for the
2618 clauses also on the parallel statement itself. */
2619 if (is_parallel_ctx (ctx))
2620 break;
2622 ctx = ctx->outer;
2623 if (ctx == NULL || !is_parallel_ctx (ctx))
2624 break;
2626 c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2627 OMP_CLAUSE_LASTPRIVATE);
2628 par_clauses = true;
2632 if (label)
2633 gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
2637 /* Generate code to implement the REDUCTION clauses. */
2639 static void
2640 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
2642 gimple_seq sub_seq = NULL;
2643 gimple stmt;
2644 tree x, c;
2645 int count = 0;
2647 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2648 update in that case, otherwise use a lock. */
2649 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
2650 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
2652 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2654 /* Never use OMP_ATOMIC for array reductions. */
2655 count = -1;
2656 break;
2658 count++;
2661 if (count == 0)
2662 return;
2664 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2666 tree var, ref, new_var;
2667 enum tree_code code;
2668 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2670 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
2671 continue;
2673 var = OMP_CLAUSE_DECL (c);
2674 new_var = lookup_decl (var, ctx);
2675 if (is_reference (var))
2676 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2677 ref = build_outer_var_ref (var, ctx);
2678 code = OMP_CLAUSE_REDUCTION_CODE (c);
2680 /* reduction(-:var) sums up the partial results, so it acts
2681 identically to reduction(+:var). */
2682 if (code == MINUS_EXPR)
2683 code = PLUS_EXPR;
2685 if (count == 1)
2687 tree addr = build_fold_addr_expr_loc (clause_loc, ref);
2689 addr = save_expr (addr);
2690 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
2691 x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
2692 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
2693 gimplify_and_add (x, stmt_seqp);
2694 return;
2697 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2699 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2701 if (is_reference (var))
2702 ref = build_fold_addr_expr_loc (clause_loc, ref);
2703 SET_DECL_VALUE_EXPR (placeholder, ref);
2704 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2705 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2706 gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
2707 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
2708 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
2710 else
2712 x = build2 (code, TREE_TYPE (ref), ref, new_var);
2713 ref = build_outer_var_ref (var, ctx);
2714 gimplify_assign (ref, x, &sub_seq);
2718 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
2720 gimple_seq_add_stmt (stmt_seqp, stmt);
2722 gimple_seq_add_seq (stmt_seqp, sub_seq);
2724 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
2726 gimple_seq_add_stmt (stmt_seqp, stmt);
2730 /* Generate code to implement the COPYPRIVATE clauses. */
2732 static void
2733 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
2734 omp_context *ctx)
2736 tree c;
2738 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2740 tree var, new_var, ref, x;
2741 bool by_ref;
2742 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2744 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
2745 continue;
2747 var = OMP_CLAUSE_DECL (c);
2748 by_ref = use_pointer_for_field (var, NULL);
2750 ref = build_sender_ref (var, ctx);
2751 x = new_var = lookup_decl_in_outer_ctx (var, ctx);
2752 if (by_ref)
2754 x = build_fold_addr_expr_loc (clause_loc, new_var);
2755 x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
2757 gimplify_assign (ref, x, slist);
2759 ref = build_receiver_ref (var, false, ctx);
2760 if (by_ref)
2762 ref = fold_convert_loc (clause_loc,
2763 build_pointer_type (TREE_TYPE (new_var)),
2764 ref);
2765 ref = build_fold_indirect_ref_loc (clause_loc, ref);
2767 if (is_reference (var))
2769 ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
2770 ref = build_simple_mem_ref_loc (clause_loc, ref);
2771 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2773 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
2774 gimplify_and_add (x, rlist);
2779 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2780 and REDUCTION from the sender (aka parent) side. */
2782 static void
2783 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
2784 omp_context *ctx)
2786 tree c;
2788 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2790 tree val, ref, x, var;
2791 bool by_ref, do_in = false, do_out = false;
2792 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2794 switch (OMP_CLAUSE_CODE (c))
2796 case OMP_CLAUSE_PRIVATE:
2797 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2798 break;
2799 continue;
2800 case OMP_CLAUSE_FIRSTPRIVATE:
2801 case OMP_CLAUSE_COPYIN:
2802 case OMP_CLAUSE_LASTPRIVATE:
2803 case OMP_CLAUSE_REDUCTION:
2804 break;
2805 default:
2806 continue;
2809 val = OMP_CLAUSE_DECL (c);
2810 var = lookup_decl_in_outer_ctx (val, ctx);
2812 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2813 && is_global_var (var))
2814 continue;
2815 if (is_variable_sized (val))
2816 continue;
2817 by_ref = use_pointer_for_field (val, NULL);
2819 switch (OMP_CLAUSE_CODE (c))
2821 case OMP_CLAUSE_PRIVATE:
2822 case OMP_CLAUSE_FIRSTPRIVATE:
2823 case OMP_CLAUSE_COPYIN:
2824 do_in = true;
2825 break;
2827 case OMP_CLAUSE_LASTPRIVATE:
2828 if (by_ref || is_reference (val))
2830 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2831 continue;
2832 do_in = true;
2834 else
2836 do_out = true;
2837 if (lang_hooks.decls.omp_private_outer_ref (val))
2838 do_in = true;
2840 break;
2842 case OMP_CLAUSE_REDUCTION:
2843 do_in = true;
2844 do_out = !(by_ref || is_reference (val));
2845 break;
2847 default:
2848 gcc_unreachable ();
2851 if (do_in)
2853 ref = build_sender_ref (val, ctx);
2854 x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
2855 gimplify_assign (ref, x, ilist);
2856 if (is_task_ctx (ctx))
2857 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
2860 if (do_out)
2862 ref = build_sender_ref (val, ctx);
2863 gimplify_assign (var, ref, olist);
2868 /* Generate code to implement SHARED from the sender (aka parent)
2869 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2870 list things that got automatically shared. */
2872 static void
2873 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
2875 tree var, ovar, nvar, f, x, record_type;
2877 if (ctx->record_type == NULL)
2878 return;
2880 record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
2881 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
2883 ovar = DECL_ABSTRACT_ORIGIN (f);
2884 nvar = maybe_lookup_decl (ovar, ctx);
2885 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2886 continue;
2888 /* If CTX is a nested parallel directive. Find the immediately
2889 enclosing parallel or workshare construct that contains a
2890 mapping for OVAR. */
2891 var = lookup_decl_in_outer_ctx (ovar, ctx);
2893 if (use_pointer_for_field (ovar, ctx))
2895 x = build_sender_ref (ovar, ctx);
2896 var = build_fold_addr_expr (var);
2897 gimplify_assign (x, var, ilist);
2899 else
2901 x = build_sender_ref (ovar, ctx);
2902 gimplify_assign (x, var, ilist);
2904 if (!TREE_READONLY (var)
2905 /* We don't need to receive a new reference to a result
2906 or parm decl. In fact we may not store to it as we will
2907 invalidate any pending RSO and generate wrong gimple
2908 during inlining. */
2909 && !((TREE_CODE (var) == RESULT_DECL
2910 || TREE_CODE (var) == PARM_DECL)
2911 && DECL_BY_REFERENCE (var)))
2913 x = build_sender_ref (ovar, ctx);
2914 gimplify_assign (var, x, olist);
2921 /* A convenience function to build an empty GIMPLE_COND with just the
2922 condition. */
2924 static gimple
2925 gimple_build_cond_empty (tree cond)
2927 enum tree_code pred_code;
2928 tree lhs, rhs;
2930 gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
2931 return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
2935 /* Build the function calls to GOMP_parallel_start etc to actually
2936 generate the parallel operation. REGION is the parallel region
2937 being expanded. BB is the block where to insert the code. WS_ARGS
2938 will be set if this is a call to a combined parallel+workshare
2939 construct, it contains the list of additional arguments needed by
2940 the workshare construct. */
2942 static void
2943 expand_parallel_call (struct omp_region *region, basic_block bb,
2944 gimple entry_stmt, vec<tree, va_gc> *ws_args)
2946 tree t, t1, t2, val, cond, c, clauses;
2947 gimple_stmt_iterator gsi;
2948 gimple stmt;
2949 enum built_in_function start_ix;
2950 int start_ix2;
2951 location_t clause_loc;
2952 vec<tree, va_gc> *args;
2954 clauses = gimple_omp_parallel_clauses (entry_stmt);
2956 /* Determine what flavor of GOMP_parallel_start we will be
2957 emitting. */
2958 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2959 if (is_combined_parallel (region))
2961 switch (region->inner->type)
2963 case GIMPLE_OMP_FOR:
2964 gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
2965 start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2966 + (region->inner->sched_kind
2967 == OMP_CLAUSE_SCHEDULE_RUNTIME
2968 ? 3 : region->inner->sched_kind));
2969 start_ix = (enum built_in_function)start_ix2;
2970 break;
2971 case GIMPLE_OMP_SECTIONS:
2972 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2973 break;
2974 default:
2975 gcc_unreachable ();
2979 /* By default, the value of NUM_THREADS is zero (selected at run time)
2980 and there is no conditional. */
2981 cond = NULL_TREE;
2982 val = build_int_cst (unsigned_type_node, 0);
2984 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2985 if (c)
2986 cond = OMP_CLAUSE_IF_EXPR (c);
2988 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2989 if (c)
2991 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2992 clause_loc = OMP_CLAUSE_LOCATION (c);
2994 else
2995 clause_loc = gimple_location (entry_stmt);
2997 /* Ensure 'val' is of the correct type. */
2998 val = fold_convert_loc (clause_loc, unsigned_type_node, val);
3000 /* If we found the clause 'if (cond)', build either
3001 (cond != 0) or (cond ? val : 1u). */
3002 if (cond)
3004 gimple_stmt_iterator gsi;
3006 cond = gimple_boolify (cond);
3008 if (integer_zerop (val))
3009 val = fold_build2_loc (clause_loc,
3010 EQ_EXPR, unsigned_type_node, cond,
3011 build_int_cst (TREE_TYPE (cond), 0));
3012 else
3014 basic_block cond_bb, then_bb, else_bb;
3015 edge e, e_then, e_else;
3016 tree tmp_then, tmp_else, tmp_join, tmp_var;
3018 tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
3019 if (gimple_in_ssa_p (cfun))
3021 tmp_then = make_ssa_name (tmp_var, NULL);
3022 tmp_else = make_ssa_name (tmp_var, NULL);
3023 tmp_join = make_ssa_name (tmp_var, NULL);
3025 else
3027 tmp_then = tmp_var;
3028 tmp_else = tmp_var;
3029 tmp_join = tmp_var;
3032 e = split_block (bb, NULL);
3033 cond_bb = e->src;
3034 bb = e->dest;
3035 remove_edge (e);
3037 then_bb = create_empty_bb (cond_bb);
3038 else_bb = create_empty_bb (then_bb);
3039 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
3040 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
3042 stmt = gimple_build_cond_empty (cond);
3043 gsi = gsi_start_bb (cond_bb);
3044 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3046 gsi = gsi_start_bb (then_bb);
3047 stmt = gimple_build_assign (tmp_then, val);
3048 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3050 gsi = gsi_start_bb (else_bb);
3051 stmt = gimple_build_assign
3052 (tmp_else, build_int_cst (unsigned_type_node, 1));
3053 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3055 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
3056 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
3057 if (current_loops)
3059 add_bb_to_loop (then_bb, cond_bb->loop_father);
3060 add_bb_to_loop (else_bb, cond_bb->loop_father);
3062 e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
3063 e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
3065 if (gimple_in_ssa_p (cfun))
3067 gimple phi = create_phi_node (tmp_join, bb);
3068 add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
3069 add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
3072 val = tmp_join;
3075 gsi = gsi_start_bb (bb);
3076 val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
3077 false, GSI_CONTINUE_LINKING);
3080 gsi = gsi_last_bb (bb);
3081 t = gimple_omp_parallel_data_arg (entry_stmt);
3082 if (t == NULL)
3083 t1 = null_pointer_node;
3084 else
3085 t1 = build_fold_addr_expr (t);
3086 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
3088 vec_alloc (args, 3 + vec_safe_length (ws_args));
3089 args->quick_push (t2);
3090 args->quick_push (t1);
3091 args->quick_push (val);
3092 if (ws_args)
3093 args->splice (*ws_args);
3095 t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
3096 builtin_decl_explicit (start_ix), args);
3098 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3099 false, GSI_CONTINUE_LINKING);
3101 t = gimple_omp_parallel_data_arg (entry_stmt);
3102 if (t == NULL)
3103 t = null_pointer_node;
3104 else
3105 t = build_fold_addr_expr (t);
3106 t = build_call_expr_loc (gimple_location (entry_stmt),
3107 gimple_omp_parallel_child_fn (entry_stmt), 1, t);
3108 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3109 false, GSI_CONTINUE_LINKING);
3111 t = build_call_expr_loc (gimple_location (entry_stmt),
3112 builtin_decl_explicit (BUILT_IN_GOMP_PARALLEL_END),
3114 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3115 false, GSI_CONTINUE_LINKING);
3119 /* Build the function call to GOMP_task to actually
3120 generate the task operation. BB is the block where to insert the code. */
3122 static void
3123 expand_task_call (basic_block bb, gimple entry_stmt)
3125 tree t, t1, t2, t3, flags, cond, c, c2, clauses;
3126 gimple_stmt_iterator gsi;
3127 location_t loc = gimple_location (entry_stmt);
3129 clauses = gimple_omp_task_clauses (entry_stmt);
3131 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
3132 if (c)
3133 cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
3134 else
3135 cond = boolean_true_node;
3137 c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
3138 c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
3139 flags = build_int_cst (unsigned_type_node,
3140 (c ? 1 : 0) + (c2 ? 4 : 0));
3142 c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
3143 if (c)
3145 c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
3146 c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
3147 build_int_cst (unsigned_type_node, 2),
3148 build_int_cst (unsigned_type_node, 0));
3149 flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
3152 gsi = gsi_last_bb (bb);
3153 t = gimple_omp_task_data_arg (entry_stmt);
3154 if (t == NULL)
3155 t2 = null_pointer_node;
3156 else
3157 t2 = build_fold_addr_expr_loc (loc, t);
3158 t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
3159 t = gimple_omp_task_copy_fn (entry_stmt);
3160 if (t == NULL)
3161 t3 = null_pointer_node;
3162 else
3163 t3 = build_fold_addr_expr_loc (loc, t);
3165 t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
3166 7, t1, t2, t3,
3167 gimple_omp_task_arg_size (entry_stmt),
3168 gimple_omp_task_arg_align (entry_stmt), cond, flags);
3170 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3171 false, GSI_CONTINUE_LINKING);
3175 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3176 catch handler and return it. This prevents programs from violating the
3177 structured block semantics with throws. */
3179 static gimple_seq
3180 maybe_catch_exception (gimple_seq body)
3182 gimple g;
3183 tree decl;
3185 if (!flag_exceptions)
3186 return body;
3188 if (lang_hooks.eh_protect_cleanup_actions != NULL)
3189 decl = lang_hooks.eh_protect_cleanup_actions ();
3190 else
3191 decl = builtin_decl_explicit (BUILT_IN_TRAP);
3193 g = gimple_build_eh_must_not_throw (decl);
3194 g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
3195 GIMPLE_TRY_CATCH);
3197 return gimple_seq_alloc_with_stmt (g);
3200 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3202 static tree
3203 vec2chain (vec<tree, va_gc> *v)
3205 tree chain = NULL_TREE, t;
3206 unsigned ix;
3208 FOR_EACH_VEC_SAFE_ELT_REVERSE (v, ix, t)
3210 DECL_CHAIN (t) = chain;
3211 chain = t;
3214 return chain;
3218 /* Remove barriers in REGION->EXIT's block. Note that this is only
3219 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3220 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3221 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3222 removed. */
3224 static void
3225 remove_exit_barrier (struct omp_region *region)
3227 gimple_stmt_iterator gsi;
3228 basic_block exit_bb;
3229 edge_iterator ei;
3230 edge e;
3231 gimple stmt;
3232 int any_addressable_vars = -1;
3234 exit_bb = region->exit;
3236 /* If the parallel region doesn't return, we don't have REGION->EXIT
3237 block at all. */
3238 if (! exit_bb)
3239 return;
3241 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3242 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3243 statements that can appear in between are extremely limited -- no
3244 memory operations at all. Here, we allow nothing at all, so the
3245 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3246 gsi = gsi_last_bb (exit_bb);
3247 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3248 gsi_prev (&gsi);
3249 if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
3250 return;
3252 FOR_EACH_EDGE (e, ei, exit_bb->preds)
3254 gsi = gsi_last_bb (e->src);
3255 if (gsi_end_p (gsi))
3256 continue;
3257 stmt = gsi_stmt (gsi);
3258 if (gimple_code (stmt) == GIMPLE_OMP_RETURN
3259 && !gimple_omp_return_nowait_p (stmt))
3261 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3262 in many cases. If there could be tasks queued, the barrier
3263 might be needed to let the tasks run before some local
3264 variable of the parallel that the task uses as shared
3265 runs out of scope. The task can be spawned either
3266 from within current function (this would be easy to check)
3267 or from some function it calls and gets passed an address
3268 of such a variable. */
3269 if (any_addressable_vars < 0)
3271 gimple parallel_stmt = last_stmt (region->entry);
3272 tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
3273 tree local_decls, block, decl;
3274 unsigned ix;
3276 any_addressable_vars = 0;
3277 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
3278 if (TREE_ADDRESSABLE (decl))
3280 any_addressable_vars = 1;
3281 break;
3283 for (block = gimple_block (stmt);
3284 !any_addressable_vars
3285 && block
3286 && TREE_CODE (block) == BLOCK;
3287 block = BLOCK_SUPERCONTEXT (block))
3289 for (local_decls = BLOCK_VARS (block);
3290 local_decls;
3291 local_decls = DECL_CHAIN (local_decls))
3292 if (TREE_ADDRESSABLE (local_decls))
3294 any_addressable_vars = 1;
3295 break;
3297 if (block == gimple_block (parallel_stmt))
3298 break;
3301 if (!any_addressable_vars)
3302 gimple_omp_return_set_nowait (stmt);
3307 static void
3308 remove_exit_barriers (struct omp_region *region)
3310 if (region->type == GIMPLE_OMP_PARALLEL)
3311 remove_exit_barrier (region);
3313 if (region->inner)
3315 region = region->inner;
3316 remove_exit_barriers (region);
3317 while (region->next)
3319 region = region->next;
3320 remove_exit_barriers (region);
3325 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3326 calls. These can't be declared as const functions, but
3327 within one parallel body they are constant, so they can be
3328 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3329 which are declared const. Similarly for task body, except
3330 that in untied task omp_get_thread_num () can change at any task
3331 scheduling point. */
3333 static void
3334 optimize_omp_library_calls (gimple entry_stmt)
3336 basic_block bb;
3337 gimple_stmt_iterator gsi;
3338 tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3339 tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
3340 tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3341 tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
3342 bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
3343 && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
3344 OMP_CLAUSE_UNTIED) != NULL);
3346 FOR_EACH_BB (bb)
3347 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3349 gimple call = gsi_stmt (gsi);
3350 tree decl;
3352 if (is_gimple_call (call)
3353 && (decl = gimple_call_fndecl (call))
3354 && DECL_EXTERNAL (decl)
3355 && TREE_PUBLIC (decl)
3356 && DECL_INITIAL (decl) == NULL)
3358 tree built_in;
3360 if (DECL_NAME (decl) == thr_num_id)
3362 /* In #pragma omp task untied omp_get_thread_num () can change
3363 during the execution of the task region. */
3364 if (untied_task)
3365 continue;
3366 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3368 else if (DECL_NAME (decl) == num_thr_id)
3369 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3370 else
3371 continue;
3373 if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
3374 || gimple_call_num_args (call) != 0)
3375 continue;
3377 if (flag_exceptions && !TREE_NOTHROW (decl))
3378 continue;
3380 if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
3381 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
3382 TREE_TYPE (TREE_TYPE (built_in))))
3383 continue;
3385 gimple_call_set_fndecl (call, built_in);
3390 /* Expand the OpenMP parallel or task directive starting at REGION. */
3392 static void
3393 expand_omp_taskreg (struct omp_region *region)
3395 basic_block entry_bb, exit_bb, new_bb;
3396 struct function *child_cfun;
3397 tree child_fn, block, t;
3398 gimple_stmt_iterator gsi;
3399 gimple entry_stmt, stmt;
3400 edge e;
3401 vec<tree, va_gc> *ws_args;
3403 entry_stmt = last_stmt (region->entry);
3404 child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
3405 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
3407 entry_bb = region->entry;
3408 exit_bb = region->exit;
3410 if (is_combined_parallel (region))
3411 ws_args = region->ws_args;
3412 else
3413 ws_args = NULL;
3415 if (child_cfun->cfg)
3417 /* Due to inlining, it may happen that we have already outlined
3418 the region, in which case all we need to do is make the
3419 sub-graph unreachable and emit the parallel call. */
3420 edge entry_succ_e, exit_succ_e;
3421 gimple_stmt_iterator gsi;
3423 entry_succ_e = single_succ_edge (entry_bb);
3425 gsi = gsi_last_bb (entry_bb);
3426 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
3427 || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
3428 gsi_remove (&gsi, true);
3430 new_bb = entry_bb;
3431 if (exit_bb)
3433 exit_succ_e = single_succ_edge (exit_bb);
3434 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
3436 remove_edge_and_dominated_blocks (entry_succ_e);
3438 else
3440 unsigned srcidx, dstidx, num;
3442 /* If the parallel region needs data sent from the parent
3443 function, then the very first statement (except possible
3444 tree profile counter updates) of the parallel body
3445 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3446 &.OMP_DATA_O is passed as an argument to the child function,
3447 we need to replace it with the argument as seen by the child
3448 function.
3450 In most cases, this will end up being the identity assignment
3451 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3452 a function call that has been inlined, the original PARM_DECL
3453 .OMP_DATA_I may have been converted into a different local
3454 variable. In which case, we need to keep the assignment. */
3455 if (gimple_omp_taskreg_data_arg (entry_stmt))
3457 basic_block entry_succ_bb = single_succ (entry_bb);
3458 gimple_stmt_iterator gsi;
3459 tree arg, narg;
3460 gimple parcopy_stmt = NULL;
3462 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
3464 gimple stmt;
3466 gcc_assert (!gsi_end_p (gsi));
3467 stmt = gsi_stmt (gsi);
3468 if (gimple_code (stmt) != GIMPLE_ASSIGN)
3469 continue;
3471 if (gimple_num_ops (stmt) == 2)
3473 tree arg = gimple_assign_rhs1 (stmt);
3475 /* We're ignore the subcode because we're
3476 effectively doing a STRIP_NOPS. */
3478 if (TREE_CODE (arg) == ADDR_EXPR
3479 && TREE_OPERAND (arg, 0)
3480 == gimple_omp_taskreg_data_arg (entry_stmt))
3482 parcopy_stmt = stmt;
3483 break;
3488 gcc_assert (parcopy_stmt != NULL);
3489 arg = DECL_ARGUMENTS (child_fn);
3491 if (!gimple_in_ssa_p (cfun))
3493 if (gimple_assign_lhs (parcopy_stmt) == arg)
3494 gsi_remove (&gsi, true);
3495 else
3497 /* ?? Is setting the subcode really necessary ?? */
3498 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
3499 gimple_assign_set_rhs1 (parcopy_stmt, arg);
3502 else
3504 /* If we are in ssa form, we must load the value from the default
3505 definition of the argument. That should not be defined now,
3506 since the argument is not used uninitialized. */
3507 gcc_assert (ssa_default_def (cfun, arg) == NULL);
3508 narg = make_ssa_name (arg, gimple_build_nop ());
3509 set_ssa_default_def (cfun, arg, narg);
3510 /* ?? Is setting the subcode really necessary ?? */
3511 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
3512 gimple_assign_set_rhs1 (parcopy_stmt, narg);
3513 update_stmt (parcopy_stmt);
3517 /* Declare local variables needed in CHILD_CFUN. */
3518 block = DECL_INITIAL (child_fn);
3519 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
3520 /* The gimplifier could record temporaries in parallel/task block
3521 rather than in containing function's local_decls chain,
3522 which would mean cgraph missed finalizing them. Do it now. */
3523 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
3524 if (TREE_CODE (t) == VAR_DECL
3525 && TREE_STATIC (t)
3526 && !DECL_EXTERNAL (t))
3527 varpool_finalize_decl (t);
3528 DECL_SAVED_TREE (child_fn) = NULL;
3529 /* We'll create a CFG for child_fn, so no gimple body is needed. */
3530 gimple_set_body (child_fn, NULL);
3531 TREE_USED (block) = 1;
3533 /* Reset DECL_CONTEXT on function arguments. */
3534 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
3535 DECL_CONTEXT (t) = child_fn;
3537 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3538 so that it can be moved to the child function. */
3539 gsi = gsi_last_bb (entry_bb);
3540 stmt = gsi_stmt (gsi);
3541 gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
3542 || gimple_code (stmt) == GIMPLE_OMP_TASK));
3543 gsi_remove (&gsi, true);
3544 e = split_block (entry_bb, stmt);
3545 entry_bb = e->dest;
3546 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3548 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3549 if (exit_bb)
3551 gsi = gsi_last_bb (exit_bb);
3552 gcc_assert (!gsi_end_p (gsi)
3553 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3554 stmt = gimple_build_return (NULL);
3555 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
3556 gsi_remove (&gsi, true);
3559 /* Move the parallel region into CHILD_CFUN. */
3561 if (gimple_in_ssa_p (cfun))
3563 init_tree_ssa (child_cfun);
3564 init_ssa_operands (child_cfun);
3565 child_cfun->gimple_df->in_ssa_p = true;
3566 block = NULL_TREE;
3568 else
3569 block = gimple_block (entry_stmt);
3571 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
3572 if (exit_bb)
3573 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
3574 /* When the OMP expansion process cannot guarantee an up-to-date
3575 loop tree arrange for the child function to fixup loops. */
3576 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP))
3577 child_cfun->x_current_loops->state |= LOOPS_NEED_FIXUP;
3579 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3580 num = vec_safe_length (child_cfun->local_decls);
3581 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
3583 t = (*child_cfun->local_decls)[srcidx];
3584 if (DECL_CONTEXT (t) == cfun->decl)
3585 continue;
3586 if (srcidx != dstidx)
3587 (*child_cfun->local_decls)[dstidx] = t;
3588 dstidx++;
3590 if (dstidx != num)
3591 vec_safe_truncate (child_cfun->local_decls, dstidx);
3593 /* Inform the callgraph about the new function. */
3594 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
3595 cgraph_add_new_function (child_fn, true);
3597 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3598 fixed in a following pass. */
3599 push_cfun (child_cfun);
3600 if (optimize)
3601 optimize_omp_library_calls (entry_stmt);
3602 rebuild_cgraph_edges ();
3604 /* Some EH regions might become dead, see PR34608. If
3605 pass_cleanup_cfg isn't the first pass to happen with the
3606 new child, these dead EH edges might cause problems.
3607 Clean them up now. */
3608 if (flag_exceptions)
3610 basic_block bb;
3611 bool changed = false;
3613 FOR_EACH_BB (bb)
3614 changed |= gimple_purge_dead_eh_edges (bb);
3615 if (changed)
3616 cleanup_tree_cfg ();
3618 if (gimple_in_ssa_p (cfun))
3619 update_ssa (TODO_update_ssa);
3620 pop_cfun ();
3623 /* Emit a library call to launch the children threads. */
3624 if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
3625 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
3626 else
3627 expand_task_call (new_bb, entry_stmt);
3628 if (gimple_in_ssa_p (cfun))
3629 update_ssa (TODO_update_ssa_only_virtuals);
3633 /* A subroutine of expand_omp_for. Generate code for a parallel
3634 loop with any schedule. Given parameters:
3636 for (V = N1; V cond N2; V += STEP) BODY;
3638 where COND is "<" or ">", we generate pseudocode
3640 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3641 if (more) goto L0; else goto L3;
3643 V = istart0;
3644 iend = iend0;
3646 BODY;
3647 V += STEP;
3648 if (V cond iend) goto L1; else goto L2;
3650 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3653 If this is a combined omp parallel loop, instead of the call to
3654 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3656 For collapsed loops, given parameters:
3657 collapse(3)
3658 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3659 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3660 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3661 BODY;
3663 we generate pseudocode
3665 if (cond3 is <)
3666 adj = STEP3 - 1;
3667 else
3668 adj = STEP3 + 1;
3669 count3 = (adj + N32 - N31) / STEP3;
3670 if (cond2 is <)
3671 adj = STEP2 - 1;
3672 else
3673 adj = STEP2 + 1;
3674 count2 = (adj + N22 - N21) / STEP2;
3675 if (cond1 is <)
3676 adj = STEP1 - 1;
3677 else
3678 adj = STEP1 + 1;
3679 count1 = (adj + N12 - N11) / STEP1;
3680 count = count1 * count2 * count3;
3681 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3682 if (more) goto L0; else goto L3;
3684 V = istart0;
3685 T = V;
3686 V3 = N31 + (T % count3) * STEP3;
3687 T = T / count3;
3688 V2 = N21 + (T % count2) * STEP2;
3689 T = T / count2;
3690 V1 = N11 + T * STEP1;
3691 iend = iend0;
3693 BODY;
3694 V += 1;
3695 if (V < iend) goto L10; else goto L2;
3696 L10:
3697 V3 += STEP3;
3698 if (V3 cond3 N32) goto L1; else goto L11;
3699 L11:
3700 V3 = N31;
3701 V2 += STEP2;
3702 if (V2 cond2 N22) goto L1; else goto L12;
3703 L12:
3704 V2 = N21;
3705 V1 += STEP1;
3706 goto L1;
3708 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3713 static void
3714 expand_omp_for_generic (struct omp_region *region,
3715 struct omp_for_data *fd,
3716 enum built_in_function start_fn,
3717 enum built_in_function next_fn)
3719 tree type, istart0, iend0, iend;
3720 tree t, vmain, vback, bias = NULL_TREE;
3721 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
3722 basic_block l2_bb = NULL, l3_bb = NULL;
3723 gimple_stmt_iterator gsi;
3724 gimple stmt;
3725 bool in_combined_parallel = is_combined_parallel (region);
3726 bool broken_loop = region->cont == NULL;
3727 edge e, ne;
3728 tree *counts = NULL;
3729 int i;
3731 gcc_assert (!broken_loop || !in_combined_parallel);
3732 gcc_assert (fd->iter_type == long_integer_type_node
3733 || !in_combined_parallel);
3735 type = TREE_TYPE (fd->loop.v);
3736 istart0 = create_tmp_var (fd->iter_type, ".istart0");
3737 iend0 = create_tmp_var (fd->iter_type, ".iend0");
3738 TREE_ADDRESSABLE (istart0) = 1;
3739 TREE_ADDRESSABLE (iend0) = 1;
3741 /* See if we need to bias by LLONG_MIN. */
3742 if (fd->iter_type == long_long_unsigned_type_node
3743 && TREE_CODE (type) == INTEGER_TYPE
3744 && !TYPE_UNSIGNED (type))
3746 tree n1, n2;
3748 if (fd->loop.cond_code == LT_EXPR)
3750 n1 = fd->loop.n1;
3751 n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
3753 else
3755 n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
3756 n2 = fd->loop.n1;
3758 if (TREE_CODE (n1) != INTEGER_CST
3759 || TREE_CODE (n2) != INTEGER_CST
3760 || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
3761 bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
3764 entry_bb = region->entry;
3765 cont_bb = region->cont;
3766 collapse_bb = NULL;
3767 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
3768 gcc_assert (broken_loop
3769 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
3770 l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
3771 l1_bb = single_succ (l0_bb);
3772 if (!broken_loop)
3774 l2_bb = create_empty_bb (cont_bb);
3775 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
3776 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
3778 else
3779 l2_bb = NULL;
3780 l3_bb = BRANCH_EDGE (entry_bb)->dest;
3781 exit_bb = region->exit;
3783 gsi = gsi_last_bb (entry_bb);
3785 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
3786 if (fd->collapse > 1)
3788 /* collapsed loops need work for expansion in SSA form. */
3789 gcc_assert (!gimple_in_ssa_p (cfun));
3790 counts = (tree *) alloca (fd->collapse * sizeof (tree));
3791 for (i = 0; i < fd->collapse; i++)
3793 tree itype = TREE_TYPE (fd->loops[i].v);
3795 if (POINTER_TYPE_P (itype))
3796 itype = signed_type_for (itype);
3797 t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
3798 ? -1 : 1));
3799 t = fold_build2 (PLUS_EXPR, itype,
3800 fold_convert (itype, fd->loops[i].step), t);
3801 t = fold_build2 (PLUS_EXPR, itype, t,
3802 fold_convert (itype, fd->loops[i].n2));
3803 t = fold_build2 (MINUS_EXPR, itype, t,
3804 fold_convert (itype, fd->loops[i].n1));
3805 if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
3806 t = fold_build2 (TRUNC_DIV_EXPR, itype,
3807 fold_build1 (NEGATE_EXPR, itype, t),
3808 fold_build1 (NEGATE_EXPR, itype,
3809 fold_convert (itype,
3810 fd->loops[i].step)));
3811 else
3812 t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
3813 fold_convert (itype, fd->loops[i].step));
3814 t = fold_convert (type, t);
3815 if (TREE_CODE (t) == INTEGER_CST)
3816 counts[i] = t;
3817 else
3819 counts[i] = create_tmp_reg (type, ".count");
3820 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3821 true, GSI_SAME_STMT);
3822 stmt = gimple_build_assign (counts[i], t);
3823 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3825 if (SSA_VAR_P (fd->loop.n2))
3827 if (i == 0)
3828 t = counts[0];
3829 else
3831 t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
3832 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3833 true, GSI_SAME_STMT);
3835 stmt = gimple_build_assign (fd->loop.n2, t);
3836 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3840 if (in_combined_parallel)
3842 /* In a combined parallel loop, emit a call to
3843 GOMP_loop_foo_next. */
3844 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
3845 build_fold_addr_expr (istart0),
3846 build_fold_addr_expr (iend0));
3848 else
3850 tree t0, t1, t2, t3, t4;
3851 /* If this is not a combined parallel loop, emit a call to
3852 GOMP_loop_foo_start in ENTRY_BB. */
3853 t4 = build_fold_addr_expr (iend0);
3854 t3 = build_fold_addr_expr (istart0);
3855 t2 = fold_convert (fd->iter_type, fd->loop.step);
3856 if (POINTER_TYPE_P (type)
3857 && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
3859 /* Avoid casting pointers to integer of a different size. */
3860 tree itype = signed_type_for (type);
3861 t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
3862 t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
3864 else
3866 t1 = fold_convert (fd->iter_type, fd->loop.n2);
3867 t0 = fold_convert (fd->iter_type, fd->loop.n1);
3869 if (bias)
3871 t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
3872 t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
3874 if (fd->iter_type == long_integer_type_node)
3876 if (fd->chunk_size)
3878 t = fold_convert (fd->iter_type, fd->chunk_size);
3879 t = build_call_expr (builtin_decl_explicit (start_fn),
3880 6, t0, t1, t2, t, t3, t4);
3882 else
3883 t = build_call_expr (builtin_decl_explicit (start_fn),
3884 5, t0, t1, t2, t3, t4);
3886 else
3888 tree t5;
3889 tree c_bool_type;
3890 tree bfn_decl;
3892 /* The GOMP_loop_ull_*start functions have additional boolean
3893 argument, true for < loops and false for > loops.
3894 In Fortran, the C bool type can be different from
3895 boolean_type_node. */
3896 bfn_decl = builtin_decl_explicit (start_fn);
3897 c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
3898 t5 = build_int_cst (c_bool_type,
3899 fd->loop.cond_code == LT_EXPR ? 1 : 0);
3900 if (fd->chunk_size)
3902 tree bfn_decl = builtin_decl_explicit (start_fn);
3903 t = fold_convert (fd->iter_type, fd->chunk_size);
3904 t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
3906 else
3907 t = build_call_expr (builtin_decl_explicit (start_fn),
3908 6, t5, t0, t1, t2, t3, t4);
3911 if (TREE_TYPE (t) != boolean_type_node)
3912 t = fold_build2 (NE_EXPR, boolean_type_node,
3913 t, build_int_cst (TREE_TYPE (t), 0));
3914 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3915 true, GSI_SAME_STMT);
3916 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
3918 /* Remove the GIMPLE_OMP_FOR statement. */
3919 gsi_remove (&gsi, true);
3921 /* Iteration setup for sequential loop goes in L0_BB. */
3922 gsi = gsi_start_bb (l0_bb);
3923 t = istart0;
3924 if (bias)
3925 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3926 if (POINTER_TYPE_P (type))
3927 t = fold_convert (signed_type_for (type), t);
3928 t = fold_convert (type, t);
3929 t = force_gimple_operand_gsi (&gsi, t,
3930 DECL_P (fd->loop.v)
3931 && TREE_ADDRESSABLE (fd->loop.v),
3932 NULL_TREE, false, GSI_CONTINUE_LINKING);
3933 stmt = gimple_build_assign (fd->loop.v, t);
3934 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3936 t = iend0;
3937 if (bias)
3938 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3939 if (POINTER_TYPE_P (type))
3940 t = fold_convert (signed_type_for (type), t);
3941 t = fold_convert (type, t);
3942 iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3943 false, GSI_CONTINUE_LINKING);
3944 if (fd->collapse > 1)
3946 tree tem = create_tmp_reg (type, ".tem");
3947 stmt = gimple_build_assign (tem, fd->loop.v);
3948 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3949 for (i = fd->collapse - 1; i >= 0; i--)
3951 tree vtype = TREE_TYPE (fd->loops[i].v), itype;
3952 itype = vtype;
3953 if (POINTER_TYPE_P (vtype))
3954 itype = signed_type_for (vtype);
3955 t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
3956 t = fold_convert (itype, t);
3957 t = fold_build2 (MULT_EXPR, itype, t,
3958 fold_convert (itype, fd->loops[i].step));
3959 if (POINTER_TYPE_P (vtype))
3960 t = fold_build_pointer_plus (fd->loops[i].n1, t);
3961 else
3962 t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
3963 t = force_gimple_operand_gsi (&gsi, t,
3964 DECL_P (fd->loops[i].v)
3965 && TREE_ADDRESSABLE (fd->loops[i].v),
3966 NULL_TREE, false,
3967 GSI_CONTINUE_LINKING);
3968 stmt = gimple_build_assign (fd->loops[i].v, t);
3969 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3970 if (i != 0)
3972 t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
3973 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3974 false, GSI_CONTINUE_LINKING);
3975 stmt = gimple_build_assign (tem, t);
3976 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3981 if (!broken_loop)
3983 /* Code to control the increment and predicate for the sequential
3984 loop goes in the CONT_BB. */
3985 gsi = gsi_last_bb (cont_bb);
3986 stmt = gsi_stmt (gsi);
3987 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
3988 vmain = gimple_omp_continue_control_use (stmt);
3989 vback = gimple_omp_continue_control_def (stmt);
3991 if (POINTER_TYPE_P (type))
3992 t = fold_build_pointer_plus (vmain, fd->loop.step);
3993 else
3994 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
3995 t = force_gimple_operand_gsi (&gsi, t,
3996 DECL_P (vback) && TREE_ADDRESSABLE (vback),
3997 NULL_TREE, true, GSI_SAME_STMT);
3998 stmt = gimple_build_assign (vback, t);
3999 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4001 t = build2 (fd->loop.cond_code, boolean_type_node,
4002 DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
4003 iend);
4004 stmt = gimple_build_cond_empty (t);
4005 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4007 /* Remove GIMPLE_OMP_CONTINUE. */
4008 gsi_remove (&gsi, true);
4010 if (fd->collapse > 1)
4012 basic_block last_bb, bb;
4014 last_bb = cont_bb;
4015 for (i = fd->collapse - 1; i >= 0; i--)
4017 tree vtype = TREE_TYPE (fd->loops[i].v);
4019 bb = create_empty_bb (last_bb);
4020 if (current_loops)
4021 add_bb_to_loop (bb, last_bb->loop_father);
4022 gsi = gsi_start_bb (bb);
4024 if (i < fd->collapse - 1)
4026 e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
4027 e->probability = REG_BR_PROB_BASE / 8;
4029 t = fd->loops[i + 1].n1;
4030 t = force_gimple_operand_gsi (&gsi, t,
4031 DECL_P (fd->loops[i + 1].v)
4032 && TREE_ADDRESSABLE
4033 (fd->loops[i + 1].v),
4034 NULL_TREE, false,
4035 GSI_CONTINUE_LINKING);
4036 stmt = gimple_build_assign (fd->loops[i + 1].v, t);
4037 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4039 else
4040 collapse_bb = bb;
4042 set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
4044 if (POINTER_TYPE_P (vtype))
4045 t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
4046 else
4047 t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
4048 fd->loops[i].step);
4049 t = force_gimple_operand_gsi (&gsi, t,
4050 DECL_P (fd->loops[i].v)
4051 && TREE_ADDRESSABLE (fd->loops[i].v),
4052 NULL_TREE, false,
4053 GSI_CONTINUE_LINKING);
4054 stmt = gimple_build_assign (fd->loops[i].v, t);
4055 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4057 if (i > 0)
4059 t = fd->loops[i].n2;
4060 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4061 false, GSI_CONTINUE_LINKING);
4062 tree v = fd->loops[i].v;
4063 if (DECL_P (v) && TREE_ADDRESSABLE (v))
4064 v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
4065 false, GSI_CONTINUE_LINKING);
4066 t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
4067 v, t);
4068 stmt = gimple_build_cond_empty (t);
4069 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4070 e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
4071 e->probability = REG_BR_PROB_BASE * 7 / 8;
4073 else
4074 make_edge (bb, l1_bb, EDGE_FALLTHRU);
4075 last_bb = bb;
4079 /* Emit code to get the next parallel iteration in L2_BB. */
4080 gsi = gsi_start_bb (l2_bb);
4082 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
4083 build_fold_addr_expr (istart0),
4084 build_fold_addr_expr (iend0));
4085 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4086 false, GSI_CONTINUE_LINKING);
4087 if (TREE_TYPE (t) != boolean_type_node)
4088 t = fold_build2 (NE_EXPR, boolean_type_node,
4089 t, build_int_cst (TREE_TYPE (t), 0));
4090 stmt = gimple_build_cond_empty (t);
4091 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4094 /* Add the loop cleanup function. */
4095 gsi = gsi_last_bb (exit_bb);
4096 if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4097 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
4098 else
4099 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
4100 stmt = gimple_build_call (t, 0);
4101 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
4102 gsi_remove (&gsi, true);
4104 /* Connect the new blocks. */
4105 find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
4106 find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
4108 if (!broken_loop)
4110 gimple_seq phis;
4112 e = find_edge (cont_bb, l3_bb);
4113 ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
4115 phis = phi_nodes (l3_bb);
4116 for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
4118 gimple phi = gsi_stmt (gsi);
4119 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
4120 PHI_ARG_DEF_FROM_EDGE (phi, e));
4122 remove_edge (e);
4124 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
4125 if (current_loops)
4126 add_bb_to_loop (l2_bb, cont_bb->loop_father);
4127 if (fd->collapse > 1)
4129 e = find_edge (cont_bb, l1_bb);
4130 remove_edge (e);
4131 e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
4133 else
4135 e = find_edge (cont_bb, l1_bb);
4136 e->flags = EDGE_TRUE_VALUE;
4138 e->probability = REG_BR_PROB_BASE * 7 / 8;
4139 find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
4140 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
4142 set_immediate_dominator (CDI_DOMINATORS, l2_bb,
4143 recompute_dominator (CDI_DOMINATORS, l2_bb));
4144 set_immediate_dominator (CDI_DOMINATORS, l3_bb,
4145 recompute_dominator (CDI_DOMINATORS, l3_bb));
4146 set_immediate_dominator (CDI_DOMINATORS, l0_bb,
4147 recompute_dominator (CDI_DOMINATORS, l0_bb));
4148 set_immediate_dominator (CDI_DOMINATORS, l1_bb,
4149 recompute_dominator (CDI_DOMINATORS, l1_bb));
4151 struct loop *outer_loop = alloc_loop ();
4152 outer_loop->header = l0_bb;
4153 outer_loop->latch = l2_bb;
4154 add_loop (outer_loop, l0_bb->loop_father);
4156 struct loop *loop = alloc_loop ();
4157 loop->header = l1_bb;
4158 /* The loop may have multiple latches. */
4159 add_loop (loop, outer_loop);
4164 /* A subroutine of expand_omp_for. Generate code for a parallel
4165 loop with static schedule and no specified chunk size. Given
4166 parameters:
4168 for (V = N1; V cond N2; V += STEP) BODY;
4170 where COND is "<" or ">", we generate pseudocode
4172 if (cond is <)
4173 adj = STEP - 1;
4174 else
4175 adj = STEP + 1;
4176 if ((__typeof (V)) -1 > 0 && cond is >)
4177 n = -(adj + N2 - N1) / -STEP;
4178 else
4179 n = (adj + N2 - N1) / STEP;
4180 q = n / nthreads;
4181 tt = n % nthreads;
4182 if (threadid < tt) goto L3; else goto L4;
4184 tt = 0;
4185 q = q + 1;
4187 s0 = q * threadid + tt;
4188 e0 = s0 + q;
4189 V = s0 * STEP + N1;
4190 if (s0 >= e0) goto L2; else goto L0;
4192 e = e0 * STEP + N1;
4194 BODY;
4195 V += STEP;
4196 if (V cond e) goto L1;
4200 static void
4201 expand_omp_for_static_nochunk (struct omp_region *region,
4202 struct omp_for_data *fd)
4204 tree n, q, s0, e0, e, t, tt, nthreads, threadid;
4205 tree type, itype, vmain, vback;
4206 basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
4207 basic_block body_bb, cont_bb;
4208 basic_block fin_bb;
4209 gimple_stmt_iterator gsi;
4210 gimple stmt;
4211 edge ep;
4213 itype = type = TREE_TYPE (fd->loop.v);
4214 if (POINTER_TYPE_P (type))
4215 itype = signed_type_for (type);
4217 entry_bb = region->entry;
4218 cont_bb = region->cont;
4219 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
4220 gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
4221 seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
4222 body_bb = single_succ (seq_start_bb);
4223 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4224 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4225 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4226 exit_bb = region->exit;
4228 /* Iteration space partitioning goes in ENTRY_BB. */
4229 gsi = gsi_last_bb (entry_bb);
4230 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4232 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4233 t = fold_convert (itype, t);
4234 nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4235 true, GSI_SAME_STMT);
4237 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4238 t = fold_convert (itype, t);
4239 threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4240 true, GSI_SAME_STMT);
4242 fd->loop.n1
4243 = force_gimple_operand_gsi (&gsi, fold_convert (type, fd->loop.n1),
4244 true, NULL_TREE, true, GSI_SAME_STMT);
4245 fd->loop.n2
4246 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.n2),
4247 true, NULL_TREE, true, GSI_SAME_STMT);
4248 fd->loop.step
4249 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.step),
4250 true, NULL_TREE, true, GSI_SAME_STMT);
4252 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4253 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4254 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4255 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4256 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4257 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4258 fold_build1 (NEGATE_EXPR, itype, t),
4259 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4260 else
4261 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4262 t = fold_convert (itype, t);
4263 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4265 q = create_tmp_reg (itype, "q");
4266 t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
4267 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4268 gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
4270 tt = create_tmp_reg (itype, "tt");
4271 t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
4272 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4273 gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
4275 t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
4276 stmt = gimple_build_cond_empty (t);
4277 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4279 second_bb = split_block (entry_bb, stmt)->dest;
4280 gsi = gsi_last_bb (second_bb);
4281 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4283 gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
4284 GSI_SAME_STMT);
4285 stmt = gimple_build_assign_with_ops (PLUS_EXPR, q, q,
4286 build_int_cst (itype, 1));
4287 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4289 third_bb = split_block (second_bb, stmt)->dest;
4290 gsi = gsi_last_bb (third_bb);
4291 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4293 t = build2 (MULT_EXPR, itype, q, threadid);
4294 t = build2 (PLUS_EXPR, itype, t, tt);
4295 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4297 t = fold_build2 (PLUS_EXPR, itype, s0, q);
4298 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4300 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
4301 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4303 /* Remove the GIMPLE_OMP_FOR statement. */
4304 gsi_remove (&gsi, true);
4306 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4307 gsi = gsi_start_bb (seq_start_bb);
4309 t = fold_convert (itype, s0);
4310 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4311 if (POINTER_TYPE_P (type))
4312 t = fold_build_pointer_plus (fd->loop.n1, t);
4313 else
4314 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4315 t = force_gimple_operand_gsi (&gsi, t,
4316 DECL_P (fd->loop.v)
4317 && TREE_ADDRESSABLE (fd->loop.v),
4318 NULL_TREE, false, GSI_CONTINUE_LINKING);
4319 stmt = gimple_build_assign (fd->loop.v, t);
4320 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4322 t = fold_convert (itype, e0);
4323 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4324 if (POINTER_TYPE_P (type))
4325 t = fold_build_pointer_plus (fd->loop.n1, t);
4326 else
4327 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4328 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4329 false, GSI_CONTINUE_LINKING);
4331 /* The code controlling the sequential loop replaces the
4332 GIMPLE_OMP_CONTINUE. */
4333 gsi = gsi_last_bb (cont_bb);
4334 stmt = gsi_stmt (gsi);
4335 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4336 vmain = gimple_omp_continue_control_use (stmt);
4337 vback = gimple_omp_continue_control_def (stmt);
4339 if (POINTER_TYPE_P (type))
4340 t = fold_build_pointer_plus (vmain, fd->loop.step);
4341 else
4342 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
4343 t = force_gimple_operand_gsi (&gsi, t,
4344 DECL_P (vback) && TREE_ADDRESSABLE (vback),
4345 NULL_TREE, true, GSI_SAME_STMT);
4346 stmt = gimple_build_assign (vback, t);
4347 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4349 t = build2 (fd->loop.cond_code, boolean_type_node,
4350 DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback, e);
4351 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4353 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4354 gsi_remove (&gsi, true);
4356 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4357 gsi = gsi_last_bb (exit_bb);
4358 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4359 force_gimple_operand_gsi (&gsi, build_omp_barrier (), false, NULL_TREE,
4360 false, GSI_SAME_STMT);
4361 gsi_remove (&gsi, true);
4363 /* Connect all the blocks. */
4364 ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
4365 ep->probability = REG_BR_PROB_BASE / 4 * 3;
4366 ep = find_edge (entry_bb, second_bb);
4367 ep->flags = EDGE_TRUE_VALUE;
4368 ep->probability = REG_BR_PROB_BASE / 4;
4369 find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
4370 find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
4372 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4373 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4375 set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
4376 set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
4377 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
4378 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4379 recompute_dominator (CDI_DOMINATORS, body_bb));
4380 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4381 recompute_dominator (CDI_DOMINATORS, fin_bb));
4383 struct loop *loop = alloc_loop ();
4384 loop->header = body_bb;
4385 loop->latch = cont_bb;
4386 add_loop (loop, body_bb->loop_father);
4390 /* A subroutine of expand_omp_for. Generate code for a parallel
4391 loop with static schedule and a specified chunk size. Given
4392 parameters:
4394 for (V = N1; V cond N2; V += STEP) BODY;
4396 where COND is "<" or ">", we generate pseudocode
4398 if (cond is <)
4399 adj = STEP - 1;
4400 else
4401 adj = STEP + 1;
4402 if ((__typeof (V)) -1 > 0 && cond is >)
4403 n = -(adj + N2 - N1) / -STEP;
4404 else
4405 n = (adj + N2 - N1) / STEP;
4406 trip = 0;
4407 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4408 here so that V is defined
4409 if the loop is not entered
4411 s0 = (trip * nthreads + threadid) * CHUNK;
4412 e0 = min(s0 + CHUNK, n);
4413 if (s0 < n) goto L1; else goto L4;
4415 V = s0 * STEP + N1;
4416 e = e0 * STEP + N1;
4418 BODY;
4419 V += STEP;
4420 if (V cond e) goto L2; else goto L3;
4422 trip += 1;
4423 goto L0;
4427 static void
4428 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
4430 tree n, s0, e0, e, t;
4431 tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
4432 tree type, itype, v_main, v_back, v_extra;
4433 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
4434 basic_block trip_update_bb, cont_bb, fin_bb;
4435 gimple_stmt_iterator si;
4436 gimple stmt;
4437 edge se;
4439 itype = type = TREE_TYPE (fd->loop.v);
4440 if (POINTER_TYPE_P (type))
4441 itype = signed_type_for (type);
4443 entry_bb = region->entry;
4444 se = split_block (entry_bb, last_stmt (entry_bb));
4445 entry_bb = se->src;
4446 iter_part_bb = se->dest;
4447 cont_bb = region->cont;
4448 gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
4449 gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
4450 == FALLTHRU_EDGE (cont_bb)->dest);
4451 seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
4452 body_bb = single_succ (seq_start_bb);
4453 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4454 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4455 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4456 trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
4457 exit_bb = region->exit;
4459 /* Trip and adjustment setup goes in ENTRY_BB. */
4460 si = gsi_last_bb (entry_bb);
4461 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
4463 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4464 t = fold_convert (itype, t);
4465 nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4466 true, GSI_SAME_STMT);
4468 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4469 t = fold_convert (itype, t);
4470 threadid = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4471 true, GSI_SAME_STMT);
4473 fd->loop.n1
4474 = force_gimple_operand_gsi (&si, fold_convert (type, fd->loop.n1),
4475 true, NULL_TREE, true, GSI_SAME_STMT);
4476 fd->loop.n2
4477 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.n2),
4478 true, NULL_TREE, true, GSI_SAME_STMT);
4479 fd->loop.step
4480 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.step),
4481 true, NULL_TREE, true, GSI_SAME_STMT);
4482 fd->chunk_size
4483 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->chunk_size),
4484 true, NULL_TREE, true, GSI_SAME_STMT);
4486 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4487 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4488 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4489 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4490 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4491 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4492 fold_build1 (NEGATE_EXPR, itype, t),
4493 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4494 else
4495 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4496 t = fold_convert (itype, t);
4497 n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4498 true, GSI_SAME_STMT);
4500 trip_var = create_tmp_reg (itype, ".trip");
4501 if (gimple_in_ssa_p (cfun))
4503 trip_init = make_ssa_name (trip_var, NULL);
4504 trip_main = make_ssa_name (trip_var, NULL);
4505 trip_back = make_ssa_name (trip_var, NULL);
4507 else
4509 trip_init = trip_var;
4510 trip_main = trip_var;
4511 trip_back = trip_var;
4514 stmt = gimple_build_assign (trip_init, build_int_cst (itype, 0));
4515 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4517 t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
4518 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4519 if (POINTER_TYPE_P (type))
4520 t = fold_build_pointer_plus (fd->loop.n1, t);
4521 else
4522 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4523 v_extra = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4524 true, GSI_SAME_STMT);
4526 /* Remove the GIMPLE_OMP_FOR. */
4527 gsi_remove (&si, true);
4529 /* Iteration space partitioning goes in ITER_PART_BB. */
4530 si = gsi_last_bb (iter_part_bb);
4532 t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
4533 t = fold_build2 (PLUS_EXPR, itype, t, threadid);
4534 t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
4535 s0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4536 false, GSI_CONTINUE_LINKING);
4538 t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
4539 t = fold_build2 (MIN_EXPR, itype, t, n);
4540 e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4541 false, GSI_CONTINUE_LINKING);
4543 t = build2 (LT_EXPR, boolean_type_node, s0, n);
4544 gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
4546 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4547 si = gsi_start_bb (seq_start_bb);
4549 t = fold_convert (itype, s0);
4550 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4551 if (POINTER_TYPE_P (type))
4552 t = fold_build_pointer_plus (fd->loop.n1, t);
4553 else
4554 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4555 t = force_gimple_operand_gsi (&si, t,
4556 DECL_P (fd->loop.v)
4557 && TREE_ADDRESSABLE (fd->loop.v),
4558 NULL_TREE, false, GSI_CONTINUE_LINKING);
4559 stmt = gimple_build_assign (fd->loop.v, t);
4560 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4562 t = fold_convert (itype, e0);
4563 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4564 if (POINTER_TYPE_P (type))
4565 t = fold_build_pointer_plus (fd->loop.n1, t);
4566 else
4567 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4568 e = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4569 false, GSI_CONTINUE_LINKING);
4571 /* The code controlling the sequential loop goes in CONT_BB,
4572 replacing the GIMPLE_OMP_CONTINUE. */
4573 si = gsi_last_bb (cont_bb);
4574 stmt = gsi_stmt (si);
4575 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4576 v_main = gimple_omp_continue_control_use (stmt);
4577 v_back = gimple_omp_continue_control_def (stmt);
4579 if (POINTER_TYPE_P (type))
4580 t = fold_build_pointer_plus (v_main, fd->loop.step);
4581 else
4582 t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
4583 if (DECL_P (v_back) && TREE_ADDRESSABLE (v_back))
4584 t = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4585 true, GSI_SAME_STMT);
4586 stmt = gimple_build_assign (v_back, t);
4587 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4589 t = build2 (fd->loop.cond_code, boolean_type_node,
4590 DECL_P (v_back) && TREE_ADDRESSABLE (v_back)
4591 ? t : v_back, e);
4592 gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
4594 /* Remove GIMPLE_OMP_CONTINUE. */
4595 gsi_remove (&si, true);
4597 /* Trip update code goes into TRIP_UPDATE_BB. */
4598 si = gsi_start_bb (trip_update_bb);
4600 t = build_int_cst (itype, 1);
4601 t = build2 (PLUS_EXPR, itype, trip_main, t);
4602 stmt = gimple_build_assign (trip_back, t);
4603 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4605 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4606 si = gsi_last_bb (exit_bb);
4607 if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
4608 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4609 false, GSI_SAME_STMT);
4610 gsi_remove (&si, true);
4612 /* Connect the new blocks. */
4613 find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
4614 find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4616 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4617 find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
4619 redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
4621 if (gimple_in_ssa_p (cfun))
4623 gimple_stmt_iterator psi;
4624 gimple phi;
4625 edge re, ene;
4626 edge_var_map_vector *head;
4627 edge_var_map *vm;
4628 size_t i;
4630 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4631 remove arguments of the phi nodes in fin_bb. We need to create
4632 appropriate phi nodes in iter_part_bb instead. */
4633 se = single_pred_edge (fin_bb);
4634 re = single_succ_edge (trip_update_bb);
4635 head = redirect_edge_var_map_vector (re);
4636 ene = single_succ_edge (entry_bb);
4638 psi = gsi_start_phis (fin_bb);
4639 for (i = 0; !gsi_end_p (psi) && head->iterate (i, &vm);
4640 gsi_next (&psi), ++i)
4642 gimple nphi;
4643 source_location locus;
4645 phi = gsi_stmt (psi);
4646 t = gimple_phi_result (phi);
4647 gcc_assert (t == redirect_edge_var_map_result (vm));
4648 nphi = create_phi_node (t, iter_part_bb);
4650 t = PHI_ARG_DEF_FROM_EDGE (phi, se);
4651 locus = gimple_phi_arg_location_from_edge (phi, se);
4653 /* A special case -- fd->loop.v is not yet computed in
4654 iter_part_bb, we need to use v_extra instead. */
4655 if (t == fd->loop.v)
4656 t = v_extra;
4657 add_phi_arg (nphi, t, ene, locus);
4658 locus = redirect_edge_var_map_location (vm);
4659 add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
4661 gcc_assert (!gsi_end_p (psi) && i == head->length ());
4662 redirect_edge_var_map_clear (re);
4663 while (1)
4665 psi = gsi_start_phis (fin_bb);
4666 if (gsi_end_p (psi))
4667 break;
4668 remove_phi_node (&psi, false);
4671 /* Make phi node for trip. */
4672 phi = create_phi_node (trip_main, iter_part_bb);
4673 add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
4674 UNKNOWN_LOCATION);
4675 add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
4676 UNKNOWN_LOCATION);
4679 set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
4680 set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
4681 recompute_dominator (CDI_DOMINATORS, iter_part_bb));
4682 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4683 recompute_dominator (CDI_DOMINATORS, fin_bb));
4684 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
4685 recompute_dominator (CDI_DOMINATORS, seq_start_bb));
4686 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4687 recompute_dominator (CDI_DOMINATORS, body_bb));
4689 struct loop *trip_loop = alloc_loop ();
4690 trip_loop->header = iter_part_bb;
4691 trip_loop->latch = trip_update_bb;
4692 add_loop (trip_loop, iter_part_bb->loop_father);
4694 struct loop *loop = alloc_loop ();
4695 loop->header = body_bb;
4696 loop->latch = cont_bb;
4697 add_loop (loop, trip_loop);
4701 /* Expand the OpenMP loop defined by REGION. */
4703 static void
4704 expand_omp_for (struct omp_region *region)
4706 struct omp_for_data fd;
4707 struct omp_for_data_loop *loops;
4709 loops
4710 = (struct omp_for_data_loop *)
4711 alloca (gimple_omp_for_collapse (last_stmt (region->entry))
4712 * sizeof (struct omp_for_data_loop));
4713 extract_omp_for_data (last_stmt (region->entry), &fd, loops);
4714 region->sched_kind = fd.sched_kind;
4716 gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
4717 BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4718 FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4719 if (region->cont)
4721 gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
4722 BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4723 FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4725 else
4726 /* If there isnt a continue then this is a degerate case where
4727 the introduction of abnormal edges during lowering will prevent
4728 original loops from being detected. Fix that up. */
4729 loops_state_set (LOOPS_NEED_FIXUP);
4731 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
4732 && !fd.have_ordered
4733 && fd.collapse == 1
4734 && region->cont != NULL)
4736 if (fd.chunk_size == NULL)
4737 expand_omp_for_static_nochunk (region, &fd);
4738 else
4739 expand_omp_for_static_chunk (region, &fd);
4741 else
4743 int fn_index, start_ix, next_ix;
4745 if (fd.chunk_size == NULL
4746 && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
4747 fd.chunk_size = integer_zero_node;
4748 gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
4749 fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
4750 ? 3 : fd.sched_kind;
4751 fn_index += fd.have_ordered * 4;
4752 start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
4753 next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
4754 if (fd.iter_type == long_long_unsigned_type_node)
4756 start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4757 - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
4758 next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4759 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
4761 expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
4762 (enum built_in_function) next_ix);
4765 if (gimple_in_ssa_p (cfun))
4766 update_ssa (TODO_update_ssa_only_virtuals);
4770 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4772 v = GOMP_sections_start (n);
4774 switch (v)
4776 case 0:
4777 goto L2;
4778 case 1:
4779 section 1;
4780 goto L1;
4781 case 2:
4783 case n:
4785 default:
4786 abort ();
4789 v = GOMP_sections_next ();
4790 goto L0;
4792 reduction;
4794 If this is a combined parallel sections, replace the call to
4795 GOMP_sections_start with call to GOMP_sections_next. */
4797 static void
4798 expand_omp_sections (struct omp_region *region)
4800 tree t, u, vin = NULL, vmain, vnext, l2;
4801 vec<tree> label_vec;
4802 unsigned len;
4803 basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
4804 gimple_stmt_iterator si, switch_si;
4805 gimple sections_stmt, stmt, cont;
4806 edge_iterator ei;
4807 edge e;
4808 struct omp_region *inner;
4809 unsigned i, casei;
4810 bool exit_reachable = region->cont != NULL;
4812 gcc_assert (region->exit != NULL);
4813 entry_bb = region->entry;
4814 l0_bb = single_succ (entry_bb);
4815 l1_bb = region->cont;
4816 l2_bb = region->exit;
4817 if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
4818 l2 = gimple_block_label (l2_bb);
4819 else
4821 /* This can happen if there are reductions. */
4822 len = EDGE_COUNT (l0_bb->succs);
4823 gcc_assert (len > 0);
4824 e = EDGE_SUCC (l0_bb, len - 1);
4825 si = gsi_last_bb (e->dest);
4826 l2 = NULL_TREE;
4827 if (gsi_end_p (si)
4828 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4829 l2 = gimple_block_label (e->dest);
4830 else
4831 FOR_EACH_EDGE (e, ei, l0_bb->succs)
4833 si = gsi_last_bb (e->dest);
4834 if (gsi_end_p (si)
4835 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4837 l2 = gimple_block_label (e->dest);
4838 break;
4842 if (exit_reachable)
4843 default_bb = create_empty_bb (l1_bb->prev_bb);
4844 else
4845 default_bb = create_empty_bb (l0_bb);
4847 /* We will build a switch() with enough cases for all the
4848 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4849 and a default case to abort if something goes wrong. */
4850 len = EDGE_COUNT (l0_bb->succs);
4852 /* Use vec::quick_push on label_vec throughout, since we know the size
4853 in advance. */
4854 label_vec.create (len);
4856 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4857 GIMPLE_OMP_SECTIONS statement. */
4858 si = gsi_last_bb (entry_bb);
4859 sections_stmt = gsi_stmt (si);
4860 gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
4861 vin = gimple_omp_sections_control (sections_stmt);
4862 if (!is_combined_parallel (region))
4864 /* If we are not inside a combined parallel+sections region,
4865 call GOMP_sections_start. */
4866 t = build_int_cst (unsigned_type_node,
4867 exit_reachable ? len - 1 : len);
4868 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
4869 stmt = gimple_build_call (u, 1, t);
4871 else
4873 /* Otherwise, call GOMP_sections_next. */
4874 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4875 stmt = gimple_build_call (u, 0);
4877 gimple_call_set_lhs (stmt, vin);
4878 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4879 gsi_remove (&si, true);
4881 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4882 L0_BB. */
4883 switch_si = gsi_last_bb (l0_bb);
4884 gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
4885 if (exit_reachable)
4887 cont = last_stmt (l1_bb);
4888 gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
4889 vmain = gimple_omp_continue_control_use (cont);
4890 vnext = gimple_omp_continue_control_def (cont);
4892 else
4894 vmain = vin;
4895 vnext = NULL_TREE;
4898 t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
4899 label_vec.quick_push (t);
4900 i = 1;
4902 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4903 for (inner = region->inner, casei = 1;
4904 inner;
4905 inner = inner->next, i++, casei++)
4907 basic_block s_entry_bb, s_exit_bb;
4909 /* Skip optional reduction region. */
4910 if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
4912 --i;
4913 --casei;
4914 continue;
4917 s_entry_bb = inner->entry;
4918 s_exit_bb = inner->exit;
4920 t = gimple_block_label (s_entry_bb);
4921 u = build_int_cst (unsigned_type_node, casei);
4922 u = build_case_label (u, NULL, t);
4923 label_vec.quick_push (u);
4925 si = gsi_last_bb (s_entry_bb);
4926 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
4927 gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
4928 gsi_remove (&si, true);
4929 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
4931 if (s_exit_bb == NULL)
4932 continue;
4934 si = gsi_last_bb (s_exit_bb);
4935 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4936 gsi_remove (&si, true);
4938 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
4941 /* Error handling code goes in DEFAULT_BB. */
4942 t = gimple_block_label (default_bb);
4943 u = build_case_label (NULL, NULL, t);
4944 make_edge (l0_bb, default_bb, 0);
4945 if (current_loops)
4946 add_bb_to_loop (default_bb, current_loops->tree_root);
4948 stmt = gimple_build_switch (vmain, u, label_vec);
4949 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4950 gsi_remove (&switch_si, true);
4951 label_vec.release ();
4953 si = gsi_start_bb (default_bb);
4954 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
4955 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4957 if (exit_reachable)
4959 tree bfn_decl;
4961 /* Code to get the next section goes in L1_BB. */
4962 si = gsi_last_bb (l1_bb);
4963 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
4965 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4966 stmt = gimple_build_call (bfn_decl, 0);
4967 gimple_call_set_lhs (stmt, vnext);
4968 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4969 gsi_remove (&si, true);
4971 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
4974 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4975 si = gsi_last_bb (l2_bb);
4976 if (gimple_omp_return_nowait_p (gsi_stmt (si)))
4977 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
4978 else
4979 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
4980 stmt = gimple_build_call (t, 0);
4981 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4982 gsi_remove (&si, true);
4984 set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
4988 /* Expand code for an OpenMP single directive. We've already expanded
4989 much of the code, here we simply place the GOMP_barrier call. */
4991 static void
4992 expand_omp_single (struct omp_region *region)
4994 basic_block entry_bb, exit_bb;
4995 gimple_stmt_iterator si;
4996 bool need_barrier = false;
4998 entry_bb = region->entry;
4999 exit_bb = region->exit;
5001 si = gsi_last_bb (entry_bb);
5002 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
5003 be removed. We need to ensure that the thread that entered the single
5004 does not exit before the data is copied out by the other threads. */
5005 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
5006 OMP_CLAUSE_COPYPRIVATE))
5007 need_barrier = true;
5008 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
5009 gsi_remove (&si, true);
5010 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
5012 si = gsi_last_bb (exit_bb);
5013 if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
5014 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
5015 false, GSI_SAME_STMT);
5016 gsi_remove (&si, true);
5017 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
5021 /* Generic expansion for OpenMP synchronization directives: master,
5022 ordered and critical. All we need to do here is remove the entry
5023 and exit markers for REGION. */
5025 static void
5026 expand_omp_synch (struct omp_region *region)
5028 basic_block entry_bb, exit_bb;
5029 gimple_stmt_iterator si;
5031 entry_bb = region->entry;
5032 exit_bb = region->exit;
5034 si = gsi_last_bb (entry_bb);
5035 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
5036 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
5037 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
5038 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
5039 gsi_remove (&si, true);
5040 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
5042 if (exit_bb)
5044 si = gsi_last_bb (exit_bb);
5045 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
5046 gsi_remove (&si, true);
5047 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
5051 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5052 operation as a normal volatile load. */
5054 static bool
5055 expand_omp_atomic_load (basic_block load_bb, tree addr,
5056 tree loaded_val, int index)
5058 enum built_in_function tmpbase;
5059 gimple_stmt_iterator gsi;
5060 basic_block store_bb;
5061 location_t loc;
5062 gimple stmt;
5063 tree decl, call, type, itype;
5065 gsi = gsi_last_bb (load_bb);
5066 stmt = gsi_stmt (gsi);
5067 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5068 loc = gimple_location (stmt);
5070 /* ??? If the target does not implement atomic_load_optab[mode], and mode
5071 is smaller than word size, then expand_atomic_load assumes that the load
5072 is atomic. We could avoid the builtin entirely in this case. */
5074 tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
5075 decl = builtin_decl_explicit (tmpbase);
5076 if (decl == NULL_TREE)
5077 return false;
5079 type = TREE_TYPE (loaded_val);
5080 itype = TREE_TYPE (TREE_TYPE (decl));
5082 call = build_call_expr_loc (loc, decl, 2, addr,
5083 build_int_cst (NULL, MEMMODEL_RELAXED));
5084 if (!useless_type_conversion_p (type, itype))
5085 call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5086 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5088 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5089 gsi_remove (&gsi, true);
5091 store_bb = single_succ (load_bb);
5092 gsi = gsi_last_bb (store_bb);
5093 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5094 gsi_remove (&gsi, true);
5096 if (gimple_in_ssa_p (cfun))
5097 update_ssa (TODO_update_ssa_no_phi);
5099 return true;
5102 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5103 operation as a normal volatile store. */
5105 static bool
5106 expand_omp_atomic_store (basic_block load_bb, tree addr,
5107 tree loaded_val, tree stored_val, int index)
5109 enum built_in_function tmpbase;
5110 gimple_stmt_iterator gsi;
5111 basic_block store_bb = single_succ (load_bb);
5112 location_t loc;
5113 gimple stmt;
5114 tree decl, call, type, itype;
5115 enum machine_mode imode;
5116 bool exchange;
5118 gsi = gsi_last_bb (load_bb);
5119 stmt = gsi_stmt (gsi);
5120 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5122 /* If the load value is needed, then this isn't a store but an exchange. */
5123 exchange = gimple_omp_atomic_need_value_p (stmt);
5125 gsi = gsi_last_bb (store_bb);
5126 stmt = gsi_stmt (gsi);
5127 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
5128 loc = gimple_location (stmt);
5130 /* ??? If the target does not implement atomic_store_optab[mode], and mode
5131 is smaller than word size, then expand_atomic_store assumes that the store
5132 is atomic. We could avoid the builtin entirely in this case. */
5134 tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
5135 tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
5136 decl = builtin_decl_explicit (tmpbase);
5137 if (decl == NULL_TREE)
5138 return false;
5140 type = TREE_TYPE (stored_val);
5142 /* Dig out the type of the function's second argument. */
5143 itype = TREE_TYPE (decl);
5144 itype = TYPE_ARG_TYPES (itype);
5145 itype = TREE_CHAIN (itype);
5146 itype = TREE_VALUE (itype);
5147 imode = TYPE_MODE (itype);
5149 if (exchange && !can_atomic_exchange_p (imode, true))
5150 return false;
5152 if (!useless_type_conversion_p (itype, type))
5153 stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
5154 call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
5155 build_int_cst (NULL, MEMMODEL_RELAXED));
5156 if (exchange)
5158 if (!useless_type_conversion_p (type, itype))
5159 call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5160 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5163 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5164 gsi_remove (&gsi, true);
5166 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
5167 gsi = gsi_last_bb (load_bb);
5168 gsi_remove (&gsi, true);
5170 if (gimple_in_ssa_p (cfun))
5171 update_ssa (TODO_update_ssa_no_phi);
5173 return true;
5176 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5177 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
5178 size of the data type, and thus usable to find the index of the builtin
5179 decl. Returns false if the expression is not of the proper form. */
5181 static bool
5182 expand_omp_atomic_fetch_op (basic_block load_bb,
5183 tree addr, tree loaded_val,
5184 tree stored_val, int index)
5186 enum built_in_function oldbase, newbase, tmpbase;
5187 tree decl, itype, call;
5188 tree lhs, rhs;
5189 basic_block store_bb = single_succ (load_bb);
5190 gimple_stmt_iterator gsi;
5191 gimple stmt;
5192 location_t loc;
5193 enum tree_code code;
5194 bool need_old, need_new;
5195 enum machine_mode imode;
5197 /* We expect to find the following sequences:
5199 load_bb:
5200 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5202 store_bb:
5203 val = tmp OP something; (or: something OP tmp)
5204 GIMPLE_OMP_STORE (val)
5206 ???FIXME: Allow a more flexible sequence.
5207 Perhaps use data flow to pick the statements.
5211 gsi = gsi_after_labels (store_bb);
5212 stmt = gsi_stmt (gsi);
5213 loc = gimple_location (stmt);
5214 if (!is_gimple_assign (stmt))
5215 return false;
5216 gsi_next (&gsi);
5217 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
5218 return false;
5219 need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
5220 need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
5221 gcc_checking_assert (!need_old || !need_new);
5223 if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
5224 return false;
5226 /* Check for one of the supported fetch-op operations. */
5227 code = gimple_assign_rhs_code (stmt);
5228 switch (code)
5230 case PLUS_EXPR:
5231 case POINTER_PLUS_EXPR:
5232 oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
5233 newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
5234 break;
5235 case MINUS_EXPR:
5236 oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
5237 newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
5238 break;
5239 case BIT_AND_EXPR:
5240 oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
5241 newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
5242 break;
5243 case BIT_IOR_EXPR:
5244 oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
5245 newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
5246 break;
5247 case BIT_XOR_EXPR:
5248 oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
5249 newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
5250 break;
5251 default:
5252 return false;
5255 /* Make sure the expression is of the proper form. */
5256 if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
5257 rhs = gimple_assign_rhs2 (stmt);
5258 else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
5259 && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
5260 rhs = gimple_assign_rhs1 (stmt);
5261 else
5262 return false;
5264 tmpbase = ((enum built_in_function)
5265 ((need_new ? newbase : oldbase) + index + 1));
5266 decl = builtin_decl_explicit (tmpbase);
5267 if (decl == NULL_TREE)
5268 return false;
5269 itype = TREE_TYPE (TREE_TYPE (decl));
5270 imode = TYPE_MODE (itype);
5272 /* We could test all of the various optabs involved, but the fact of the
5273 matter is that (with the exception of i486 vs i586 and xadd) all targets
5274 that support any atomic operaton optab also implements compare-and-swap.
5275 Let optabs.c take care of expanding any compare-and-swap loop. */
5276 if (!can_compare_and_swap_p (imode, true))
5277 return false;
5279 gsi = gsi_last_bb (load_bb);
5280 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
5282 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5283 It only requires that the operation happen atomically. Thus we can
5284 use the RELAXED memory model. */
5285 call = build_call_expr_loc (loc, decl, 3, addr,
5286 fold_convert_loc (loc, itype, rhs),
5287 build_int_cst (NULL, MEMMODEL_RELAXED));
5289 if (need_old || need_new)
5291 lhs = need_old ? loaded_val : stored_val;
5292 call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
5293 call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
5295 else
5296 call = fold_convert_loc (loc, void_type_node, call);
5297 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5298 gsi_remove (&gsi, true);
5300 gsi = gsi_last_bb (store_bb);
5301 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5302 gsi_remove (&gsi, true);
5303 gsi = gsi_last_bb (store_bb);
5304 gsi_remove (&gsi, true);
5306 if (gimple_in_ssa_p (cfun))
5307 update_ssa (TODO_update_ssa_no_phi);
5309 return true;
5312 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5314 oldval = *addr;
5315 repeat:
5316 newval = rhs; // with oldval replacing *addr in rhs
5317 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5318 if (oldval != newval)
5319 goto repeat;
5321 INDEX is log2 of the size of the data type, and thus usable to find the
5322 index of the builtin decl. */
5324 static bool
5325 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
5326 tree addr, tree loaded_val, tree stored_val,
5327 int index)
5329 tree loadedi, storedi, initial, new_storedi, old_vali;
5330 tree type, itype, cmpxchg, iaddr;
5331 gimple_stmt_iterator si;
5332 basic_block loop_header = single_succ (load_bb);
5333 gimple phi, stmt;
5334 edge e;
5335 enum built_in_function fncode;
5337 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5338 order to use the RELAXED memory model effectively. */
5339 fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5340 + index + 1);
5341 cmpxchg = builtin_decl_explicit (fncode);
5342 if (cmpxchg == NULL_TREE)
5343 return false;
5344 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5345 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5347 if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
5348 return false;
5350 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5351 si = gsi_last_bb (load_bb);
5352 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5354 /* For floating-point values, we'll need to view-convert them to integers
5355 so that we can perform the atomic compare and swap. Simplify the
5356 following code by always setting up the "i"ntegral variables. */
5357 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
5359 tree iaddr_val;
5361 iaddr = create_tmp_reg (build_pointer_type_for_mode (itype, ptr_mode,
5362 true), NULL);
5363 iaddr_val
5364 = force_gimple_operand_gsi (&si,
5365 fold_convert (TREE_TYPE (iaddr), addr),
5366 false, NULL_TREE, true, GSI_SAME_STMT);
5367 stmt = gimple_build_assign (iaddr, iaddr_val);
5368 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5369 loadedi = create_tmp_var (itype, NULL);
5370 if (gimple_in_ssa_p (cfun))
5371 loadedi = make_ssa_name (loadedi, NULL);
5373 else
5375 iaddr = addr;
5376 loadedi = loaded_val;
5379 initial
5380 = force_gimple_operand_gsi (&si,
5381 build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
5382 iaddr,
5383 build_int_cst (TREE_TYPE (iaddr), 0)),
5384 true, NULL_TREE, true, GSI_SAME_STMT);
5386 /* Move the value to the LOADEDI temporary. */
5387 if (gimple_in_ssa_p (cfun))
5389 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
5390 phi = create_phi_node (loadedi, loop_header);
5391 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
5392 initial);
5394 else
5395 gsi_insert_before (&si,
5396 gimple_build_assign (loadedi, initial),
5397 GSI_SAME_STMT);
5398 if (loadedi != loaded_val)
5400 gimple_stmt_iterator gsi2;
5401 tree x;
5403 x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
5404 gsi2 = gsi_start_bb (loop_header);
5405 if (gimple_in_ssa_p (cfun))
5407 gimple stmt;
5408 x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5409 true, GSI_SAME_STMT);
5410 stmt = gimple_build_assign (loaded_val, x);
5411 gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
5413 else
5415 x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
5416 force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5417 true, GSI_SAME_STMT);
5420 gsi_remove (&si, true);
5422 si = gsi_last_bb (store_bb);
5423 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5425 if (iaddr == addr)
5426 storedi = stored_val;
5427 else
5428 storedi =
5429 force_gimple_operand_gsi (&si,
5430 build1 (VIEW_CONVERT_EXPR, itype,
5431 stored_val), true, NULL_TREE, true,
5432 GSI_SAME_STMT);
5434 /* Build the compare&swap statement. */
5435 new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
5436 new_storedi = force_gimple_operand_gsi (&si,
5437 fold_convert (TREE_TYPE (loadedi),
5438 new_storedi),
5439 true, NULL_TREE,
5440 true, GSI_SAME_STMT);
5442 if (gimple_in_ssa_p (cfun))
5443 old_vali = loadedi;
5444 else
5446 old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
5447 stmt = gimple_build_assign (old_vali, loadedi);
5448 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5450 stmt = gimple_build_assign (loadedi, new_storedi);
5451 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5454 /* Note that we always perform the comparison as an integer, even for
5455 floating point. This allows the atomic operation to properly
5456 succeed even with NaNs and -0.0. */
5457 stmt = gimple_build_cond_empty
5458 (build2 (NE_EXPR, boolean_type_node,
5459 new_storedi, old_vali));
5460 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5462 /* Update cfg. */
5463 e = single_succ_edge (store_bb);
5464 e->flags &= ~EDGE_FALLTHRU;
5465 e->flags |= EDGE_FALSE_VALUE;
5467 e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
5469 /* Copy the new value to loadedi (we already did that before the condition
5470 if we are not in SSA). */
5471 if (gimple_in_ssa_p (cfun))
5473 phi = gimple_seq_first_stmt (phi_nodes (loop_header));
5474 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
5477 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5478 gsi_remove (&si, true);
5480 struct loop *loop = alloc_loop ();
5481 loop->header = loop_header;
5482 loop->latch = loop_header;
5483 add_loop (loop, loop_header->loop_father);
5485 if (gimple_in_ssa_p (cfun))
5486 update_ssa (TODO_update_ssa_no_phi);
5488 return true;
5491 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5493 GOMP_atomic_start ();
5494 *addr = rhs;
5495 GOMP_atomic_end ();
5497 The result is not globally atomic, but works so long as all parallel
5498 references are within #pragma omp atomic directives. According to
5499 responses received from omp@openmp.org, appears to be within spec.
5500 Which makes sense, since that's how several other compilers handle
5501 this situation as well.
5502 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5503 expanding. STORED_VAL is the operand of the matching
5504 GIMPLE_OMP_ATOMIC_STORE.
5506 We replace
5507 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5508 loaded_val = *addr;
5510 and replace
5511 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
5512 *addr = stored_val;
5515 static bool
5516 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
5517 tree addr, tree loaded_val, tree stored_val)
5519 gimple_stmt_iterator si;
5520 gimple stmt;
5521 tree t;
5523 si = gsi_last_bb (load_bb);
5524 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5526 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
5527 t = build_call_expr (t, 0);
5528 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5530 stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
5531 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5532 gsi_remove (&si, true);
5534 si = gsi_last_bb (store_bb);
5535 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5537 stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
5538 stored_val);
5539 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5541 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
5542 t = build_call_expr (t, 0);
5543 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5544 gsi_remove (&si, true);
5546 if (gimple_in_ssa_p (cfun))
5547 update_ssa (TODO_update_ssa_no_phi);
5548 return true;
5551 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5552 using expand_omp_atomic_fetch_op. If it failed, we try to
5553 call expand_omp_atomic_pipeline, and if it fails too, the
5554 ultimate fallback is wrapping the operation in a mutex
5555 (expand_omp_atomic_mutex). REGION is the atomic region built
5556 by build_omp_regions_1(). */
5558 static void
5559 expand_omp_atomic (struct omp_region *region)
5561 basic_block load_bb = region->entry, store_bb = region->exit;
5562 gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
5563 tree loaded_val = gimple_omp_atomic_load_lhs (load);
5564 tree addr = gimple_omp_atomic_load_rhs (load);
5565 tree stored_val = gimple_omp_atomic_store_val (store);
5566 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5567 HOST_WIDE_INT index;
5569 /* Make sure the type is one of the supported sizes. */
5570 index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5571 index = exact_log2 (index);
5572 if (index >= 0 && index <= 4)
5574 unsigned int align = TYPE_ALIGN_UNIT (type);
5576 /* __sync builtins require strict data alignment. */
5577 if (exact_log2 (align) >= index)
5579 /* Atomic load. */
5580 if (loaded_val == stored_val
5581 && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5582 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5583 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5584 && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
5585 return;
5587 /* Atomic store. */
5588 if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5589 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5590 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5591 && store_bb == single_succ (load_bb)
5592 && first_stmt (store_bb) == store
5593 && expand_omp_atomic_store (load_bb, addr, loaded_val,
5594 stored_val, index))
5595 return;
5597 /* When possible, use specialized atomic update functions. */
5598 if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5599 && store_bb == single_succ (load_bb)
5600 && expand_omp_atomic_fetch_op (load_bb, addr,
5601 loaded_val, stored_val, index))
5602 return;
5604 /* If we don't have specialized __sync builtins, try and implement
5605 as a compare and swap loop. */
5606 if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
5607 loaded_val, stored_val, index))
5608 return;
5612 /* The ultimate fallback is wrapping the operation in a mutex. */
5613 expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
5617 /* Expand the parallel region tree rooted at REGION. Expansion
5618 proceeds in depth-first order. Innermost regions are expanded
5619 first. This way, parallel regions that require a new function to
5620 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5621 internal dependencies in their body. */
5623 static void
5624 expand_omp (struct omp_region *region)
5626 while (region)
5628 location_t saved_location;
5630 /* First, determine whether this is a combined parallel+workshare
5631 region. */
5632 if (region->type == GIMPLE_OMP_PARALLEL)
5633 determine_parallel_type (region);
5635 if (region->inner)
5636 expand_omp (region->inner);
5638 saved_location = input_location;
5639 if (gimple_has_location (last_stmt (region->entry)))
5640 input_location = gimple_location (last_stmt (region->entry));
5642 switch (region->type)
5644 case GIMPLE_OMP_PARALLEL:
5645 case GIMPLE_OMP_TASK:
5646 expand_omp_taskreg (region);
5647 break;
5649 case GIMPLE_OMP_FOR:
5650 expand_omp_for (region);
5651 break;
5653 case GIMPLE_OMP_SECTIONS:
5654 expand_omp_sections (region);
5655 break;
5657 case GIMPLE_OMP_SECTION:
5658 /* Individual omp sections are handled together with their
5659 parent GIMPLE_OMP_SECTIONS region. */
5660 break;
5662 case GIMPLE_OMP_SINGLE:
5663 expand_omp_single (region);
5664 break;
5666 case GIMPLE_OMP_MASTER:
5667 case GIMPLE_OMP_ORDERED:
5668 case GIMPLE_OMP_CRITICAL:
5669 expand_omp_synch (region);
5670 break;
5672 case GIMPLE_OMP_ATOMIC_LOAD:
5673 expand_omp_atomic (region);
5674 break;
5676 default:
5677 gcc_unreachable ();
5680 input_location = saved_location;
5681 region = region->next;
5686 /* Helper for build_omp_regions. Scan the dominator tree starting at
5687 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5688 true, the function ends once a single tree is built (otherwise, whole
5689 forest of OMP constructs may be built). */
5691 static void
5692 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
5693 bool single_tree)
5695 gimple_stmt_iterator gsi;
5696 gimple stmt;
5697 basic_block son;
5699 gsi = gsi_last_bb (bb);
5700 if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
5702 struct omp_region *region;
5703 enum gimple_code code;
5705 stmt = gsi_stmt (gsi);
5706 code = gimple_code (stmt);
5707 if (code == GIMPLE_OMP_RETURN)
5709 /* STMT is the return point out of region PARENT. Mark it
5710 as the exit point and make PARENT the immediately
5711 enclosing region. */
5712 gcc_assert (parent);
5713 region = parent;
5714 region->exit = bb;
5715 parent = parent->outer;
5717 else if (code == GIMPLE_OMP_ATOMIC_STORE)
5719 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5720 GIMPLE_OMP_RETURN, but matches with
5721 GIMPLE_OMP_ATOMIC_LOAD. */
5722 gcc_assert (parent);
5723 gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
5724 region = parent;
5725 region->exit = bb;
5726 parent = parent->outer;
5729 else if (code == GIMPLE_OMP_CONTINUE)
5731 gcc_assert (parent);
5732 parent->cont = bb;
5734 else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
5736 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5737 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5740 else
5742 /* Otherwise, this directive becomes the parent for a new
5743 region. */
5744 region = new_omp_region (bb, code, parent);
5745 parent = region;
5749 if (single_tree && !parent)
5750 return;
5752 for (son = first_dom_son (CDI_DOMINATORS, bb);
5753 son;
5754 son = next_dom_son (CDI_DOMINATORS, son))
5755 build_omp_regions_1 (son, parent, single_tree);
5758 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5759 root_omp_region. */
5761 static void
5762 build_omp_regions_root (basic_block root)
5764 gcc_assert (root_omp_region == NULL);
5765 build_omp_regions_1 (root, NULL, true);
5766 gcc_assert (root_omp_region != NULL);
5769 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5771 void
5772 omp_expand_local (basic_block head)
5774 build_omp_regions_root (head);
5775 if (dump_file && (dump_flags & TDF_DETAILS))
5777 fprintf (dump_file, "\nOMP region tree\n\n");
5778 dump_omp_region (dump_file, root_omp_region, 0);
5779 fprintf (dump_file, "\n");
5782 remove_exit_barriers (root_omp_region);
5783 expand_omp (root_omp_region);
5785 free_omp_regions ();
5788 /* Scan the CFG and build a tree of OMP regions. Return the root of
5789 the OMP region tree. */
5791 static void
5792 build_omp_regions (void)
5794 gcc_assert (root_omp_region == NULL);
5795 calculate_dominance_info (CDI_DOMINATORS);
5796 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
5799 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5801 static unsigned int
5802 execute_expand_omp (void)
5804 build_omp_regions ();
5806 if (!root_omp_region)
5807 return 0;
5809 if (dump_file)
5811 fprintf (dump_file, "\nOMP region tree\n\n");
5812 dump_omp_region (dump_file, root_omp_region, 0);
5813 fprintf (dump_file, "\n");
5816 remove_exit_barriers (root_omp_region);
5818 expand_omp (root_omp_region);
5820 cleanup_tree_cfg ();
5822 free_omp_regions ();
5824 return 0;
5827 /* OMP expansion -- the default pass, run before creation of SSA form. */
5829 static bool
5830 gate_expand_omp (void)
5832 return (flag_openmp != 0 && !seen_error ());
5835 struct gimple_opt_pass pass_expand_omp =
5838 GIMPLE_PASS,
5839 "ompexp", /* name */
5840 OPTGROUP_NONE, /* optinfo_flags */
5841 gate_expand_omp, /* gate */
5842 execute_expand_omp, /* execute */
5843 NULL, /* sub */
5844 NULL, /* next */
5845 0, /* static_pass_number */
5846 TV_NONE, /* tv_id */
5847 PROP_gimple_any, /* properties_required */
5848 0, /* properties_provided */
5849 0, /* properties_destroyed */
5850 0, /* todo_flags_start */
5851 0 /* todo_flags_finish */
5855 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5857 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5858 CTX is the enclosing OMP context for the current statement. */
5860 static void
5861 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5863 tree block, control;
5864 gimple_stmt_iterator tgsi;
5865 gimple stmt, new_stmt, bind, t;
5866 gimple_seq ilist, dlist, olist, new_body;
5867 struct gimplify_ctx gctx;
5869 stmt = gsi_stmt (*gsi_p);
5871 push_gimplify_context (&gctx);
5873 dlist = NULL;
5874 ilist = NULL;
5875 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5876 &ilist, &dlist, ctx);
5878 new_body = gimple_omp_body (stmt);
5879 gimple_omp_set_body (stmt, NULL);
5880 tgsi = gsi_start (new_body);
5881 for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
5883 omp_context *sctx;
5884 gimple sec_start;
5886 sec_start = gsi_stmt (tgsi);
5887 sctx = maybe_lookup_ctx (sec_start);
5888 gcc_assert (sctx);
5890 lower_omp (gimple_omp_body_ptr (sec_start), sctx);
5891 gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
5892 GSI_CONTINUE_LINKING);
5893 gimple_omp_set_body (sec_start, NULL);
5895 if (gsi_one_before_end_p (tgsi))
5897 gimple_seq l = NULL;
5898 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5899 &l, ctx);
5900 gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
5901 gimple_omp_section_set_last (sec_start);
5904 gsi_insert_after (&tgsi, gimple_build_omp_return (false),
5905 GSI_CONTINUE_LINKING);
5908 block = make_node (BLOCK);
5909 bind = gimple_build_bind (NULL, new_body, block);
5911 olist = NULL;
5912 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5914 block = make_node (BLOCK);
5915 new_stmt = gimple_build_bind (NULL, NULL, block);
5916 gsi_replace (gsi_p, new_stmt, true);
5918 pop_gimplify_context (new_stmt);
5919 gimple_bind_append_vars (new_stmt, ctx->block_vars);
5920 BLOCK_VARS (block) = gimple_bind_vars (bind);
5921 if (BLOCK_VARS (block))
5922 TREE_USED (block) = 1;
5924 new_body = NULL;
5925 gimple_seq_add_seq (&new_body, ilist);
5926 gimple_seq_add_stmt (&new_body, stmt);
5927 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5928 gimple_seq_add_stmt (&new_body, bind);
5930 control = create_tmp_var (unsigned_type_node, ".section");
5931 t = gimple_build_omp_continue (control, control);
5932 gimple_omp_sections_set_control (stmt, control);
5933 gimple_seq_add_stmt (&new_body, t);
5935 gimple_seq_add_seq (&new_body, olist);
5936 gimple_seq_add_seq (&new_body, dlist);
5938 new_body = maybe_catch_exception (new_body);
5940 t = gimple_build_omp_return
5941 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5942 OMP_CLAUSE_NOWAIT));
5943 gimple_seq_add_stmt (&new_body, t);
5945 gimple_bind_set_body (new_stmt, new_body);
5949 /* A subroutine of lower_omp_single. Expand the simple form of
5950 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5952 if (GOMP_single_start ())
5953 BODY;
5954 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5956 FIXME. It may be better to delay expanding the logic of this until
5957 pass_expand_omp. The expanded logic may make the job more difficult
5958 to a synchronization analysis pass. */
5960 static void
5961 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5963 location_t loc = gimple_location (single_stmt);
5964 tree tlabel = create_artificial_label (loc);
5965 tree flabel = create_artificial_label (loc);
5966 gimple call, cond;
5967 tree lhs, decl;
5969 decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
5970 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5971 call = gimple_build_call (decl, 0);
5972 gimple_call_set_lhs (call, lhs);
5973 gimple_seq_add_stmt (pre_p, call);
5975 cond = gimple_build_cond (EQ_EXPR, lhs,
5976 fold_convert_loc (loc, TREE_TYPE (lhs),
5977 boolean_true_node),
5978 tlabel, flabel);
5979 gimple_seq_add_stmt (pre_p, cond);
5980 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5981 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5982 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5986 /* A subroutine of lower_omp_single. Expand the simple form of
5987 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5989 #pragma omp single copyprivate (a, b, c)
5991 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5994 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5996 BODY;
5997 copyout.a = a;
5998 copyout.b = b;
5999 copyout.c = c;
6000 GOMP_single_copy_end (&copyout);
6002 else
6004 a = copyout_p->a;
6005 b = copyout_p->b;
6006 c = copyout_p->c;
6008 GOMP_barrier ();
6011 FIXME. It may be better to delay expanding the logic of this until
6012 pass_expand_omp. The expanded logic may make the job more difficult
6013 to a synchronization analysis pass. */
6015 static void
6016 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
6018 tree ptr_type, t, l0, l1, l2, bfn_decl;
6019 gimple_seq copyin_seq;
6020 location_t loc = gimple_location (single_stmt);
6022 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
6024 ptr_type = build_pointer_type (ctx->record_type);
6025 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
6027 l0 = create_artificial_label (loc);
6028 l1 = create_artificial_label (loc);
6029 l2 = create_artificial_label (loc);
6031 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
6032 t = build_call_expr_loc (loc, bfn_decl, 0);
6033 t = fold_convert_loc (loc, ptr_type, t);
6034 gimplify_assign (ctx->receiver_decl, t, pre_p);
6036 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
6037 build_int_cst (ptr_type, 0));
6038 t = build3 (COND_EXPR, void_type_node, t,
6039 build_and_jump (&l0), build_and_jump (&l1));
6040 gimplify_and_add (t, pre_p);
6042 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
6044 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
6046 copyin_seq = NULL;
6047 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
6048 &copyin_seq, ctx);
6050 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6051 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
6052 t = build_call_expr_loc (loc, bfn_decl, 1, t);
6053 gimplify_and_add (t, pre_p);
6055 t = build_and_jump (&l2);
6056 gimplify_and_add (t, pre_p);
6058 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
6060 gimple_seq_add_seq (pre_p, copyin_seq);
6062 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
6066 /* Expand code for an OpenMP single directive. */
6068 static void
6069 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6071 tree block;
6072 gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
6073 gimple_seq bind_body, dlist;
6074 struct gimplify_ctx gctx;
6076 push_gimplify_context (&gctx);
6078 block = make_node (BLOCK);
6079 bind = gimple_build_bind (NULL, NULL, block);
6080 gsi_replace (gsi_p, bind, true);
6081 bind_body = NULL;
6082 dlist = NULL;
6083 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
6084 &bind_body, &dlist, ctx);
6085 lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
6087 gimple_seq_add_stmt (&bind_body, single_stmt);
6089 if (ctx->record_type)
6090 lower_omp_single_copy (single_stmt, &bind_body, ctx);
6091 else
6092 lower_omp_single_simple (single_stmt, &bind_body);
6094 gimple_omp_set_body (single_stmt, NULL);
6096 gimple_seq_add_seq (&bind_body, dlist);
6098 bind_body = maybe_catch_exception (bind_body);
6100 t = gimple_build_omp_return
6101 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
6102 OMP_CLAUSE_NOWAIT));
6103 gimple_seq_add_stmt (&bind_body, t);
6104 gimple_bind_set_body (bind, bind_body);
6106 pop_gimplify_context (bind);
6108 gimple_bind_append_vars (bind, ctx->block_vars);
6109 BLOCK_VARS (block) = ctx->block_vars;
6110 if (BLOCK_VARS (block))
6111 TREE_USED (block) = 1;
6115 /* Expand code for an OpenMP master directive. */
6117 static void
6118 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6120 tree block, lab = NULL, x, bfn_decl;
6121 gimple stmt = gsi_stmt (*gsi_p), bind;
6122 location_t loc = gimple_location (stmt);
6123 gimple_seq tseq;
6124 struct gimplify_ctx gctx;
6126 push_gimplify_context (&gctx);
6128 block = make_node (BLOCK);
6129 bind = gimple_build_bind (NULL, NULL, block);
6130 gsi_replace (gsi_p, bind, true);
6131 gimple_bind_add_stmt (bind, stmt);
6133 bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6134 x = build_call_expr_loc (loc, bfn_decl, 0);
6135 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
6136 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
6137 tseq = NULL;
6138 gimplify_and_add (x, &tseq);
6139 gimple_bind_add_seq (bind, tseq);
6141 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6142 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6143 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6144 gimple_omp_set_body (stmt, NULL);
6146 gimple_bind_add_stmt (bind, gimple_build_label (lab));
6148 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6150 pop_gimplify_context (bind);
6152 gimple_bind_append_vars (bind, ctx->block_vars);
6153 BLOCK_VARS (block) = ctx->block_vars;
6157 /* Expand code for an OpenMP ordered directive. */
6159 static void
6160 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6162 tree block;
6163 gimple stmt = gsi_stmt (*gsi_p), bind, x;
6164 struct gimplify_ctx gctx;
6166 push_gimplify_context (&gctx);
6168 block = make_node (BLOCK);
6169 bind = gimple_build_bind (NULL, NULL, block);
6170 gsi_replace (gsi_p, bind, true);
6171 gimple_bind_add_stmt (bind, stmt);
6173 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
6175 gimple_bind_add_stmt (bind, x);
6177 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6178 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6179 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6180 gimple_omp_set_body (stmt, NULL);
6182 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
6183 gimple_bind_add_stmt (bind, x);
6185 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6187 pop_gimplify_context (bind);
6189 gimple_bind_append_vars (bind, ctx->block_vars);
6190 BLOCK_VARS (block) = gimple_bind_vars (bind);
6194 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
6195 substitution of a couple of function calls. But in the NAMED case,
6196 requires that languages coordinate a symbol name. It is therefore
6197 best put here in common code. */
6199 static GTY((param1_is (tree), param2_is (tree)))
6200 splay_tree critical_name_mutexes;
6202 static void
6203 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6205 tree block;
6206 tree name, lock, unlock;
6207 gimple stmt = gsi_stmt (*gsi_p), bind;
6208 location_t loc = gimple_location (stmt);
6209 gimple_seq tbody;
6210 struct gimplify_ctx gctx;
6212 name = gimple_omp_critical_name (stmt);
6213 if (name)
6215 tree decl;
6216 splay_tree_node n;
6218 if (!critical_name_mutexes)
6219 critical_name_mutexes
6220 = splay_tree_new_ggc (splay_tree_compare_pointers,
6221 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
6222 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
6224 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
6225 if (n == NULL)
6227 char *new_str;
6229 decl = create_tmp_var_raw (ptr_type_node, NULL);
6231 new_str = ACONCAT ((".gomp_critical_user_",
6232 IDENTIFIER_POINTER (name), NULL));
6233 DECL_NAME (decl) = get_identifier (new_str);
6234 TREE_PUBLIC (decl) = 1;
6235 TREE_STATIC (decl) = 1;
6236 DECL_COMMON (decl) = 1;
6237 DECL_ARTIFICIAL (decl) = 1;
6238 DECL_IGNORED_P (decl) = 1;
6239 varpool_finalize_decl (decl);
6241 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
6242 (splay_tree_value) decl);
6244 else
6245 decl = (tree) n->value;
6247 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
6248 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
6250 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
6251 unlock = build_call_expr_loc (loc, unlock, 1,
6252 build_fold_addr_expr_loc (loc, decl));
6254 else
6256 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
6257 lock = build_call_expr_loc (loc, lock, 0);
6259 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
6260 unlock = build_call_expr_loc (loc, unlock, 0);
6263 push_gimplify_context (&gctx);
6265 block = make_node (BLOCK);
6266 bind = gimple_build_bind (NULL, NULL, block);
6267 gsi_replace (gsi_p, bind, true);
6268 gimple_bind_add_stmt (bind, stmt);
6270 tbody = gimple_bind_body (bind);
6271 gimplify_and_add (lock, &tbody);
6272 gimple_bind_set_body (bind, tbody);
6274 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6275 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6276 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6277 gimple_omp_set_body (stmt, NULL);
6279 tbody = gimple_bind_body (bind);
6280 gimplify_and_add (unlock, &tbody);
6281 gimple_bind_set_body (bind, tbody);
6283 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6285 pop_gimplify_context (bind);
6286 gimple_bind_append_vars (bind, ctx->block_vars);
6287 BLOCK_VARS (block) = gimple_bind_vars (bind);
6291 /* A subroutine of lower_omp_for. Generate code to emit the predicate
6292 for a lastprivate clause. Given a loop control predicate of (V
6293 cond N2), we gate the clause on (!(V cond N2)). The lowered form
6294 is appended to *DLIST, iterator initialization is appended to
6295 *BODY_P. */
6297 static void
6298 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
6299 gimple_seq *dlist, struct omp_context *ctx)
6301 tree clauses, cond, vinit;
6302 enum tree_code cond_code;
6303 gimple_seq stmts;
6305 cond_code = fd->loop.cond_code;
6306 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
6308 /* When possible, use a strict equality expression. This can let VRP
6309 type optimizations deduce the value and remove a copy. */
6310 if (host_integerp (fd->loop.step, 0))
6312 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
6313 if (step == 1 || step == -1)
6314 cond_code = EQ_EXPR;
6317 cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
6319 clauses = gimple_omp_for_clauses (fd->for_stmt);
6320 stmts = NULL;
6321 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
6322 if (!gimple_seq_empty_p (stmts))
6324 gimple_seq_add_seq (&stmts, *dlist);
6325 *dlist = stmts;
6327 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6328 vinit = fd->loop.n1;
6329 if (cond_code == EQ_EXPR
6330 && host_integerp (fd->loop.n2, 0)
6331 && ! integer_zerop (fd->loop.n2))
6332 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6334 /* Initialize the iterator variable, so that threads that don't execute
6335 any iterations don't execute the lastprivate clauses by accident. */
6336 gimplify_assign (fd->loop.v, vinit, body_p);
6341 /* Lower code for an OpenMP loop directive. */
6343 static void
6344 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6346 tree *rhs_p, block;
6347 struct omp_for_data fd;
6348 gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6349 gimple_seq omp_for_body, body, dlist;
6350 size_t i;
6351 struct gimplify_ctx gctx;
6353 push_gimplify_context (&gctx);
6355 lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
6356 lower_omp (gimple_omp_body_ptr (stmt), ctx);
6358 block = make_node (BLOCK);
6359 new_stmt = gimple_build_bind (NULL, NULL, block);
6360 /* Replace at gsi right away, so that 'stmt' is no member
6361 of a sequence anymore as we're going to add to to a different
6362 one below. */
6363 gsi_replace (gsi_p, new_stmt, true);
6365 /* Move declaration of temporaries in the loop body before we make
6366 it go away. */
6367 omp_for_body = gimple_omp_body (stmt);
6368 if (!gimple_seq_empty_p (omp_for_body)
6369 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6371 tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6372 gimple_bind_append_vars (new_stmt, vars);
6375 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6376 dlist = NULL;
6377 body = NULL;
6378 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6379 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6381 /* Lower the header expressions. At this point, we can assume that
6382 the header is of the form:
6384 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6386 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6387 using the .omp_data_s mapping, if needed. */
6388 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6390 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6391 if (!is_gimple_min_invariant (*rhs_p))
6392 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6394 rhs_p = gimple_omp_for_final_ptr (stmt, i);
6395 if (!is_gimple_min_invariant (*rhs_p))
6396 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6398 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6399 if (!is_gimple_min_invariant (*rhs_p))
6400 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6403 /* Once lowered, extract the bounds and clauses. */
6404 extract_omp_for_data (stmt, &fd, NULL);
6406 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6408 gimple_seq_add_stmt (&body, stmt);
6409 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6411 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6412 fd.loop.v));
6414 /* After the loop, add exit clauses. */
6415 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6416 gimple_seq_add_seq (&body, dlist);
6418 body = maybe_catch_exception (body);
6420 /* Region exit marker goes at the end of the loop body. */
6421 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6423 pop_gimplify_context (new_stmt);
6425 gimple_bind_append_vars (new_stmt, ctx->block_vars);
6426 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6427 if (BLOCK_VARS (block))
6428 TREE_USED (block) = 1;
6430 gimple_bind_set_body (new_stmt, body);
6431 gimple_omp_set_body (stmt, NULL);
6432 gimple_omp_for_set_pre_body (stmt, NULL);
6435 /* Callback for walk_stmts. Check if the current statement only contains
6436 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6438 static tree
6439 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6440 bool *handled_ops_p,
6441 struct walk_stmt_info *wi)
6443 int *info = (int *) wi->info;
6444 gimple stmt = gsi_stmt (*gsi_p);
6446 *handled_ops_p = true;
6447 switch (gimple_code (stmt))
6449 WALK_SUBSTMTS;
6451 case GIMPLE_OMP_FOR:
6452 case GIMPLE_OMP_SECTIONS:
6453 *info = *info == 0 ? 1 : -1;
6454 break;
6455 default:
6456 *info = -1;
6457 break;
6459 return NULL;
6462 struct omp_taskcopy_context
6464 /* This field must be at the beginning, as we do "inheritance": Some
6465 callback functions for tree-inline.c (e.g., omp_copy_decl)
6466 receive a copy_body_data pointer that is up-casted to an
6467 omp_context pointer. */
6468 copy_body_data cb;
6469 omp_context *ctx;
6472 static tree
6473 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6475 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6477 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6478 return create_tmp_var (TREE_TYPE (var), NULL);
6480 return var;
6483 static tree
6484 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6486 tree name, new_fields = NULL, type, f;
6488 type = lang_hooks.types.make_type (RECORD_TYPE);
6489 name = DECL_NAME (TYPE_NAME (orig_type));
6490 name = build_decl (gimple_location (tcctx->ctx->stmt),
6491 TYPE_DECL, name, type);
6492 TYPE_NAME (type) = name;
6494 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6496 tree new_f = copy_node (f);
6497 DECL_CONTEXT (new_f) = type;
6498 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6499 TREE_CHAIN (new_f) = new_fields;
6500 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6501 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6502 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6503 &tcctx->cb, NULL);
6504 new_fields = new_f;
6505 *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6507 TYPE_FIELDS (type) = nreverse (new_fields);
6508 layout_type (type);
6509 return type;
6512 /* Create task copyfn. */
6514 static void
6515 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6517 struct function *child_cfun;
6518 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6519 tree record_type, srecord_type, bind, list;
6520 bool record_needs_remap = false, srecord_needs_remap = false;
6521 splay_tree_node n;
6522 struct omp_taskcopy_context tcctx;
6523 struct gimplify_ctx gctx;
6524 location_t loc = gimple_location (task_stmt);
6526 child_fn = gimple_omp_task_copy_fn (task_stmt);
6527 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6528 gcc_assert (child_cfun->cfg == NULL);
6529 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6531 /* Reset DECL_CONTEXT on function arguments. */
6532 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
6533 DECL_CONTEXT (t) = child_fn;
6535 /* Populate the function. */
6536 push_gimplify_context (&gctx);
6537 push_cfun (child_cfun);
6539 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6540 TREE_SIDE_EFFECTS (bind) = 1;
6541 list = NULL;
6542 DECL_SAVED_TREE (child_fn) = bind;
6543 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6545 /* Remap src and dst argument types if needed. */
6546 record_type = ctx->record_type;
6547 srecord_type = ctx->srecord_type;
6548 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6549 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6551 record_needs_remap = true;
6552 break;
6554 for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
6555 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6557 srecord_needs_remap = true;
6558 break;
6561 if (record_needs_remap || srecord_needs_remap)
6563 memset (&tcctx, '\0', sizeof (tcctx));
6564 tcctx.cb.src_fn = ctx->cb.src_fn;
6565 tcctx.cb.dst_fn = child_fn;
6566 tcctx.cb.src_node = cgraph_get_node (tcctx.cb.src_fn);
6567 gcc_checking_assert (tcctx.cb.src_node);
6568 tcctx.cb.dst_node = tcctx.cb.src_node;
6569 tcctx.cb.src_cfun = ctx->cb.src_cfun;
6570 tcctx.cb.copy_decl = task_copyfn_copy_decl;
6571 tcctx.cb.eh_lp_nr = 0;
6572 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6573 tcctx.cb.decl_map = pointer_map_create ();
6574 tcctx.ctx = ctx;
6576 if (record_needs_remap)
6577 record_type = task_copyfn_remap_type (&tcctx, record_type);
6578 if (srecord_needs_remap)
6579 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6581 else
6582 tcctx.cb.decl_map = NULL;
6584 arg = DECL_ARGUMENTS (child_fn);
6585 TREE_TYPE (arg) = build_pointer_type (record_type);
6586 sarg = DECL_CHAIN (arg);
6587 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6589 /* First pass: initialize temporaries used in record_type and srecord_type
6590 sizes and field offsets. */
6591 if (tcctx.cb.decl_map)
6592 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6593 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6595 tree *p;
6597 decl = OMP_CLAUSE_DECL (c);
6598 p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6599 if (p == NULL)
6600 continue;
6601 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6602 sf = (tree) n->value;
6603 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6604 src = build_simple_mem_ref_loc (loc, sarg);
6605 src = omp_build_component_ref (src, sf);
6606 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6607 append_to_statement_list (t, &list);
6610 /* Second pass: copy shared var pointers and copy construct non-VLA
6611 firstprivate vars. */
6612 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6613 switch (OMP_CLAUSE_CODE (c))
6615 case OMP_CLAUSE_SHARED:
6616 decl = OMP_CLAUSE_DECL (c);
6617 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6618 if (n == NULL)
6619 break;
6620 f = (tree) n->value;
6621 if (tcctx.cb.decl_map)
6622 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6623 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6624 sf = (tree) n->value;
6625 if (tcctx.cb.decl_map)
6626 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6627 src = build_simple_mem_ref_loc (loc, sarg);
6628 src = omp_build_component_ref (src, sf);
6629 dst = build_simple_mem_ref_loc (loc, arg);
6630 dst = omp_build_component_ref (dst, f);
6631 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6632 append_to_statement_list (t, &list);
6633 break;
6634 case OMP_CLAUSE_FIRSTPRIVATE:
6635 decl = OMP_CLAUSE_DECL (c);
6636 if (is_variable_sized (decl))
6637 break;
6638 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6639 if (n == NULL)
6640 break;
6641 f = (tree) n->value;
6642 if (tcctx.cb.decl_map)
6643 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6644 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6645 if (n != NULL)
6647 sf = (tree) n->value;
6648 if (tcctx.cb.decl_map)
6649 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6650 src = build_simple_mem_ref_loc (loc, sarg);
6651 src = omp_build_component_ref (src, sf);
6652 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6653 src = build_simple_mem_ref_loc (loc, src);
6655 else
6656 src = decl;
6657 dst = build_simple_mem_ref_loc (loc, arg);
6658 dst = omp_build_component_ref (dst, f);
6659 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6660 append_to_statement_list (t, &list);
6661 break;
6662 case OMP_CLAUSE_PRIVATE:
6663 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6664 break;
6665 decl = OMP_CLAUSE_DECL (c);
6666 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6667 f = (tree) n->value;
6668 if (tcctx.cb.decl_map)
6669 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6670 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6671 if (n != NULL)
6673 sf = (tree) n->value;
6674 if (tcctx.cb.decl_map)
6675 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6676 src = build_simple_mem_ref_loc (loc, sarg);
6677 src = omp_build_component_ref (src, sf);
6678 if (use_pointer_for_field (decl, NULL))
6679 src = build_simple_mem_ref_loc (loc, src);
6681 else
6682 src = decl;
6683 dst = build_simple_mem_ref_loc (loc, arg);
6684 dst = omp_build_component_ref (dst, f);
6685 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6686 append_to_statement_list (t, &list);
6687 break;
6688 default:
6689 break;
6692 /* Last pass: handle VLA firstprivates. */
6693 if (tcctx.cb.decl_map)
6694 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6695 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6697 tree ind, ptr, df;
6699 decl = OMP_CLAUSE_DECL (c);
6700 if (!is_variable_sized (decl))
6701 continue;
6702 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6703 if (n == NULL)
6704 continue;
6705 f = (tree) n->value;
6706 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6707 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6708 ind = DECL_VALUE_EXPR (decl);
6709 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6710 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6711 n = splay_tree_lookup (ctx->sfield_map,
6712 (splay_tree_key) TREE_OPERAND (ind, 0));
6713 sf = (tree) n->value;
6714 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6715 src = build_simple_mem_ref_loc (loc, sarg);
6716 src = omp_build_component_ref (src, sf);
6717 src = build_simple_mem_ref_loc (loc, src);
6718 dst = build_simple_mem_ref_loc (loc, arg);
6719 dst = omp_build_component_ref (dst, f);
6720 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6721 append_to_statement_list (t, &list);
6722 n = splay_tree_lookup (ctx->field_map,
6723 (splay_tree_key) TREE_OPERAND (ind, 0));
6724 df = (tree) n->value;
6725 df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6726 ptr = build_simple_mem_ref_loc (loc, arg);
6727 ptr = omp_build_component_ref (ptr, df);
6728 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6729 build_fold_addr_expr_loc (loc, dst));
6730 append_to_statement_list (t, &list);
6733 t = build1 (RETURN_EXPR, void_type_node, NULL);
6734 append_to_statement_list (t, &list);
6736 if (tcctx.cb.decl_map)
6737 pointer_map_destroy (tcctx.cb.decl_map);
6738 pop_gimplify_context (NULL);
6739 BIND_EXPR_BODY (bind) = list;
6740 pop_cfun ();
6743 /* Lower the OpenMP parallel or task directive in the current statement
6744 in GSI_P. CTX holds context information for the directive. */
6746 static void
6747 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6749 tree clauses;
6750 tree child_fn, t;
6751 gimple stmt = gsi_stmt (*gsi_p);
6752 gimple par_bind, bind;
6753 gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6754 struct gimplify_ctx gctx;
6755 location_t loc = gimple_location (stmt);
6757 clauses = gimple_omp_taskreg_clauses (stmt);
6758 par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6759 par_body = gimple_bind_body (par_bind);
6760 child_fn = ctx->cb.dst_fn;
6761 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6762 && !gimple_omp_parallel_combined_p (stmt))
6764 struct walk_stmt_info wi;
6765 int ws_num = 0;
6767 memset (&wi, 0, sizeof (wi));
6768 wi.info = &ws_num;
6769 wi.val_only = true;
6770 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6771 if (ws_num == 1)
6772 gimple_omp_parallel_set_combined_p (stmt, true);
6774 if (ctx->srecord_type)
6775 create_task_copyfn (stmt, ctx);
6777 push_gimplify_context (&gctx);
6779 par_olist = NULL;
6780 par_ilist = NULL;
6781 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6782 lower_omp (&par_body, ctx);
6783 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6784 lower_reduction_clauses (clauses, &par_olist, ctx);
6786 /* Declare all the variables created by mapping and the variables
6787 declared in the scope of the parallel body. */
6788 record_vars_into (ctx->block_vars, child_fn);
6789 record_vars_into (gimple_bind_vars (par_bind), child_fn);
6791 if (ctx->record_type)
6793 ctx->sender_decl
6794 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6795 : ctx->record_type, ".omp_data_o");
6796 DECL_NAMELESS (ctx->sender_decl) = 1;
6797 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6798 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6801 olist = NULL;
6802 ilist = NULL;
6803 lower_send_clauses (clauses, &ilist, &olist, ctx);
6804 lower_send_shared_vars (&ilist, &olist, ctx);
6806 /* Once all the expansions are done, sequence all the different
6807 fragments inside gimple_omp_body. */
6809 new_body = NULL;
6811 if (ctx->record_type)
6813 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6814 /* fixup_child_record_type might have changed receiver_decl's type. */
6815 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6816 gimple_seq_add_stmt (&new_body,
6817 gimple_build_assign (ctx->receiver_decl, t));
6820 gimple_seq_add_seq (&new_body, par_ilist);
6821 gimple_seq_add_seq (&new_body, par_body);
6822 gimple_seq_add_seq (&new_body, par_olist);
6823 new_body = maybe_catch_exception (new_body);
6824 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6825 gimple_omp_set_body (stmt, new_body);
6827 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6828 gsi_replace (gsi_p, bind, true);
6829 gimple_bind_add_seq (bind, ilist);
6830 gimple_bind_add_stmt (bind, stmt);
6831 gimple_bind_add_seq (bind, olist);
6833 pop_gimplify_context (NULL);
6836 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6837 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6838 of OpenMP context, but with task_shared_vars set. */
6840 static tree
6841 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6842 void *data)
6844 tree t = *tp;
6846 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6847 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6848 return t;
6850 if (task_shared_vars
6851 && DECL_P (t)
6852 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6853 return t;
6855 /* If a global variable has been privatized, TREE_CONSTANT on
6856 ADDR_EXPR might be wrong. */
6857 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6858 recompute_tree_invariant_for_addr_expr (t);
6860 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6861 return NULL_TREE;
6864 static void
6865 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6867 gimple stmt = gsi_stmt (*gsi_p);
6868 struct walk_stmt_info wi;
6870 if (gimple_has_location (stmt))
6871 input_location = gimple_location (stmt);
6873 if (task_shared_vars)
6874 memset (&wi, '\0', sizeof (wi));
6876 /* If we have issued syntax errors, avoid doing any heavy lifting.
6877 Just replace the OpenMP directives with a NOP to avoid
6878 confusing RTL expansion. */
6879 if (seen_error () && is_gimple_omp (stmt))
6881 gsi_replace (gsi_p, gimple_build_nop (), true);
6882 return;
6885 switch (gimple_code (stmt))
6887 case GIMPLE_COND:
6888 if ((ctx || task_shared_vars)
6889 && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6890 ctx ? NULL : &wi, NULL)
6891 || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6892 ctx ? NULL : &wi, NULL)))
6893 gimple_regimplify_operands (stmt, gsi_p);
6894 break;
6895 case GIMPLE_CATCH:
6896 lower_omp (gimple_catch_handler_ptr (stmt), ctx);
6897 break;
6898 case GIMPLE_EH_FILTER:
6899 lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
6900 break;
6901 case GIMPLE_TRY:
6902 lower_omp (gimple_try_eval_ptr (stmt), ctx);
6903 lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
6904 break;
6905 case GIMPLE_TRANSACTION:
6906 lower_omp (gimple_transaction_body_ptr (stmt), ctx);
6907 break;
6908 case GIMPLE_BIND:
6909 lower_omp (gimple_bind_body_ptr (stmt), ctx);
6910 break;
6911 case GIMPLE_OMP_PARALLEL:
6912 case GIMPLE_OMP_TASK:
6913 ctx = maybe_lookup_ctx (stmt);
6914 lower_omp_taskreg (gsi_p, ctx);
6915 break;
6916 case GIMPLE_OMP_FOR:
6917 ctx = maybe_lookup_ctx (stmt);
6918 gcc_assert (ctx);
6919 lower_omp_for (gsi_p, ctx);
6920 break;
6921 case GIMPLE_OMP_SECTIONS:
6922 ctx = maybe_lookup_ctx (stmt);
6923 gcc_assert (ctx);
6924 lower_omp_sections (gsi_p, ctx);
6925 break;
6926 case GIMPLE_OMP_SINGLE:
6927 ctx = maybe_lookup_ctx (stmt);
6928 gcc_assert (ctx);
6929 lower_omp_single (gsi_p, ctx);
6930 break;
6931 case GIMPLE_OMP_MASTER:
6932 ctx = maybe_lookup_ctx (stmt);
6933 gcc_assert (ctx);
6934 lower_omp_master (gsi_p, ctx);
6935 break;
6936 case GIMPLE_OMP_ORDERED:
6937 ctx = maybe_lookup_ctx (stmt);
6938 gcc_assert (ctx);
6939 lower_omp_ordered (gsi_p, ctx);
6940 break;
6941 case GIMPLE_OMP_CRITICAL:
6942 ctx = maybe_lookup_ctx (stmt);
6943 gcc_assert (ctx);
6944 lower_omp_critical (gsi_p, ctx);
6945 break;
6946 case GIMPLE_OMP_ATOMIC_LOAD:
6947 if ((ctx || task_shared_vars)
6948 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6949 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6950 gimple_regimplify_operands (stmt, gsi_p);
6951 break;
6952 default:
6953 if ((ctx || task_shared_vars)
6954 && walk_gimple_op (stmt, lower_omp_regimplify_p,
6955 ctx ? NULL : &wi))
6956 gimple_regimplify_operands (stmt, gsi_p);
6957 break;
6961 static void
6962 lower_omp (gimple_seq *body, omp_context *ctx)
6964 location_t saved_location = input_location;
6965 gimple_stmt_iterator gsi;
6966 for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
6967 lower_omp_1 (&gsi, ctx);
6968 input_location = saved_location;
6971 /* Main entry point. */
6973 static unsigned int
6974 execute_lower_omp (void)
6976 gimple_seq body;
6978 /* This pass always runs, to provide PROP_gimple_lomp.
6979 But there is nothing to do unless -fopenmp is given. */
6980 if (flag_openmp == 0)
6981 return 0;
6983 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6984 delete_omp_context);
6986 body = gimple_body (current_function_decl);
6987 scan_omp (&body, NULL);
6988 gcc_assert (taskreg_nesting_level == 0);
6990 if (all_contexts->root)
6992 struct gimplify_ctx gctx;
6994 if (task_shared_vars)
6995 push_gimplify_context (&gctx);
6996 lower_omp (&body, NULL);
6997 if (task_shared_vars)
6998 pop_gimplify_context (NULL);
7001 if (all_contexts)
7003 splay_tree_delete (all_contexts);
7004 all_contexts = NULL;
7006 BITMAP_FREE (task_shared_vars);
7007 return 0;
7010 struct gimple_opt_pass pass_lower_omp =
7013 GIMPLE_PASS,
7014 "omplower", /* name */
7015 OPTGROUP_NONE, /* optinfo_flags */
7016 NULL, /* gate */
7017 execute_lower_omp, /* execute */
7018 NULL, /* sub */
7019 NULL, /* next */
7020 0, /* static_pass_number */
7021 TV_NONE, /* tv_id */
7022 PROP_gimple_any, /* properties_required */
7023 PROP_gimple_lomp, /* properties_provided */
7024 0, /* properties_destroyed */
7025 0, /* todo_flags_start */
7026 0 /* todo_flags_finish */
7030 /* The following is a utility to diagnose OpenMP structured block violations.
7031 It is not part of the "omplower" pass, as that's invoked too late. It
7032 should be invoked by the respective front ends after gimplification. */
7034 static splay_tree all_labels;
7036 /* Check for mismatched contexts and generate an error if needed. Return
7037 true if an error is detected. */
7039 static bool
7040 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
7041 gimple branch_ctx, gimple label_ctx)
7043 if (label_ctx == branch_ctx)
7044 return false;
7048 Previously we kept track of the label's entire context in diagnose_sb_[12]
7049 so we could traverse it and issue a correct "exit" or "enter" error
7050 message upon a structured block violation.
7052 We built the context by building a list with tree_cons'ing, but there is
7053 no easy counterpart in gimple tuples. It seems like far too much work
7054 for issuing exit/enter error messages. If someone really misses the
7055 distinct error message... patches welcome.
7058 #if 0
7059 /* Try to avoid confusing the user by producing and error message
7060 with correct "exit" or "enter" verbiage. We prefer "exit"
7061 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
7062 if (branch_ctx == NULL)
7063 exit_p = false;
7064 else
7066 while (label_ctx)
7068 if (TREE_VALUE (label_ctx) == branch_ctx)
7070 exit_p = false;
7071 break;
7073 label_ctx = TREE_CHAIN (label_ctx);
7077 if (exit_p)
7078 error ("invalid exit from OpenMP structured block");
7079 else
7080 error ("invalid entry to OpenMP structured block");
7081 #endif
7083 /* If it's obvious we have an invalid entry, be specific about the error. */
7084 if (branch_ctx == NULL)
7085 error ("invalid entry to OpenMP structured block");
7086 else
7087 /* Otherwise, be vague and lazy, but efficient. */
7088 error ("invalid branch to/from an OpenMP structured block");
7090 gsi_replace (gsi_p, gimple_build_nop (), false);
7091 return true;
7094 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7095 where each label is found. */
7097 static tree
7098 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7099 struct walk_stmt_info *wi)
7101 gimple context = (gimple) wi->info;
7102 gimple inner_context;
7103 gimple stmt = gsi_stmt (*gsi_p);
7105 *handled_ops_p = true;
7107 switch (gimple_code (stmt))
7109 WALK_SUBSTMTS;
7111 case GIMPLE_OMP_PARALLEL:
7112 case GIMPLE_OMP_TASK:
7113 case GIMPLE_OMP_SECTIONS:
7114 case GIMPLE_OMP_SINGLE:
7115 case GIMPLE_OMP_SECTION:
7116 case GIMPLE_OMP_MASTER:
7117 case GIMPLE_OMP_ORDERED:
7118 case GIMPLE_OMP_CRITICAL:
7119 /* The minimal context here is just the current OMP construct. */
7120 inner_context = stmt;
7121 wi->info = inner_context;
7122 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7123 wi->info = context;
7124 break;
7126 case GIMPLE_OMP_FOR:
7127 inner_context = stmt;
7128 wi->info = inner_context;
7129 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7130 walk them. */
7131 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7132 diagnose_sb_1, NULL, wi);
7133 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7134 wi->info = context;
7135 break;
7137 case GIMPLE_LABEL:
7138 splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
7139 (splay_tree_value) context);
7140 break;
7142 default:
7143 break;
7146 return NULL_TREE;
7149 /* Pass 2: Check each branch and see if its context differs from that of
7150 the destination label's context. */
7152 static tree
7153 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7154 struct walk_stmt_info *wi)
7156 gimple context = (gimple) wi->info;
7157 splay_tree_node n;
7158 gimple stmt = gsi_stmt (*gsi_p);
7160 *handled_ops_p = true;
7162 switch (gimple_code (stmt))
7164 WALK_SUBSTMTS;
7166 case GIMPLE_OMP_PARALLEL:
7167 case GIMPLE_OMP_TASK:
7168 case GIMPLE_OMP_SECTIONS:
7169 case GIMPLE_OMP_SINGLE:
7170 case GIMPLE_OMP_SECTION:
7171 case GIMPLE_OMP_MASTER:
7172 case GIMPLE_OMP_ORDERED:
7173 case GIMPLE_OMP_CRITICAL:
7174 wi->info = stmt;
7175 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
7176 wi->info = context;
7177 break;
7179 case GIMPLE_OMP_FOR:
7180 wi->info = stmt;
7181 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7182 walk them. */
7183 walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
7184 diagnose_sb_2, NULL, wi);
7185 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
7186 wi->info = context;
7187 break;
7189 case GIMPLE_COND:
7191 tree lab = gimple_cond_true_label (stmt);
7192 if (lab)
7194 n = splay_tree_lookup (all_labels,
7195 (splay_tree_key) lab);
7196 diagnose_sb_0 (gsi_p, context,
7197 n ? (gimple) n->value : NULL);
7199 lab = gimple_cond_false_label (stmt);
7200 if (lab)
7202 n = splay_tree_lookup (all_labels,
7203 (splay_tree_key) lab);
7204 diagnose_sb_0 (gsi_p, context,
7205 n ? (gimple) n->value : NULL);
7208 break;
7210 case GIMPLE_GOTO:
7212 tree lab = gimple_goto_dest (stmt);
7213 if (TREE_CODE (lab) != LABEL_DECL)
7214 break;
7216 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7217 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
7219 break;
7221 case GIMPLE_SWITCH:
7223 unsigned int i;
7224 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
7226 tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
7227 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7228 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
7229 break;
7232 break;
7234 case GIMPLE_RETURN:
7235 diagnose_sb_0 (gsi_p, context, NULL);
7236 break;
7238 default:
7239 break;
7242 return NULL_TREE;
7245 static unsigned int
7246 diagnose_omp_structured_block_errors (void)
7248 struct walk_stmt_info wi;
7249 gimple_seq body = gimple_body (current_function_decl);
7251 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
7253 memset (&wi, 0, sizeof (wi));
7254 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
7256 memset (&wi, 0, sizeof (wi));
7257 wi.want_locations = true;
7258 walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
7260 gimple_set_body (current_function_decl, body);
7262 splay_tree_delete (all_labels);
7263 all_labels = NULL;
7265 return 0;
7268 static bool
7269 gate_diagnose_omp_blocks (void)
7271 return flag_openmp != 0;
7274 struct gimple_opt_pass pass_diagnose_omp_blocks =
7277 GIMPLE_PASS,
7278 "*diagnose_omp_blocks", /* name */
7279 OPTGROUP_NONE, /* optinfo_flags */
7280 gate_diagnose_omp_blocks, /* gate */
7281 diagnose_omp_structured_block_errors, /* execute */
7282 NULL, /* sub */
7283 NULL, /* next */
7284 0, /* static_pass_number */
7285 TV_NONE, /* tv_id */
7286 PROP_gimple_any, /* properties_required */
7287 0, /* properties_provided */
7288 0, /* properties_destroyed */
7289 0, /* todo_flags_start */
7290 0, /* todo_flags_finish */
7294 #include "gt-omp-low.h"