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, 2006, 2007, 2008, 2009, 2010, 2011, 2012
7 Free Software Foundation, Inc.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
27 #include "coretypes.h"
32 #include "tree-iterator.h"
33 #include "tree-inline.h"
34 #include "langhooks.h"
35 #include "diagnostic-core.h"
36 #include "tree-flow.h"
41 #include "tree-pass.h"
44 #include "splay-tree.h"
49 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
50 phases. The first phase scans the function looking for OMP statements
51 and then for variables that must be replaced to satisfy data sharing
52 clauses. The second phase expands code for the constructs, as well as
53 re-gimplifying things when variables have been replaced with complex
56 Final code generation is done by pass_expand_omp. The flowgraph is
57 scanned for parallel regions which are then moved to a new
58 function, to be invoked by the thread library. */
60 /* Context structure. Used to store information about each parallel
61 directive in the code. */
63 typedef struct omp_context
65 /* This field must be at the beginning, as we do "inheritance": Some
66 callback functions for tree-inline.c (e.g., omp_copy_decl)
67 receive a copy_body_data pointer that is up-casted to an
68 omp_context pointer. */
71 /* The tree of contexts corresponding to the encountered constructs. */
72 struct omp_context *outer;
75 /* Map variables to fields in a structure that allows communication
76 between sending and receiving threads. */
82 /* These are used just by task contexts, if task firstprivate fn is
83 needed. srecord_type is used to communicate from the thread
84 that encountered the task construct to task firstprivate fn,
85 record_type is allocated by GOMP_task, initialized by task firstprivate
86 fn and passed to the task body fn. */
87 splay_tree sfield_map;
90 /* A chain of variables to add to the top-level block surrounding the
91 construct. In the case of a parallel, this is in the child function. */
94 /* What to do with variables with implicitly determined sharing
96 enum omp_clause_default_kind default_kind;
98 /* Nesting depth of this context. Used to beautify error messages re
99 invalid gotos. The outermost ctx is depth 1, with depth 0 being
100 reserved for the main body of the function. */
103 /* True if this parallel directive is nested within another. */
108 struct omp_for_data_loop
110 tree v, n1, n2, step;
111 enum tree_code cond_code;
114 /* A structure describing the main elements of a parallel loop. */
118 struct omp_for_data_loop loop;
123 bool have_nowait, have_ordered;
124 enum omp_clause_schedule_kind sched_kind;
125 struct omp_for_data_loop *loops;
129 static splay_tree all_contexts;
130 static int taskreg_nesting_level;
131 struct omp_region *root_omp_region;
132 static bitmap task_shared_vars;
134 static void scan_omp (gimple_seq, omp_context *);
135 static tree scan_omp_1_op (tree *, int *, void *);
137 #define WALK_SUBSTMTS \
141 case GIMPLE_EH_FILTER: \
142 case GIMPLE_TRANSACTION: \
143 /* The sub-statements for these should be walked. */ \
144 *handled_ops_p = false; \
147 /* Convenience function for calling scan_omp_1_op on tree operands. */
150 scan_omp_op (tree *tp, omp_context *ctx)
152 struct walk_stmt_info wi;
154 memset (&wi, 0, sizeof (wi));
156 wi.want_locations = true;
158 return walk_tree (tp, scan_omp_1_op, &wi, NULL);
161 static void lower_omp (gimple_seq, omp_context *);
162 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
163 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
165 /* Find an OpenMP clause of type KIND within CLAUSES. */
168 find_omp_clause (tree clauses, enum omp_clause_code kind)
170 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
171 if (OMP_CLAUSE_CODE (clauses) == kind)
177 /* Return true if CTX is for an omp parallel. */
180 is_parallel_ctx (omp_context *ctx)
182 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
186 /* Return true if CTX is for an omp task. */
189 is_task_ctx (omp_context *ctx)
191 return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
195 /* Return true if CTX is for an omp parallel or omp task. */
198 is_taskreg_ctx (omp_context *ctx)
200 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
201 || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
205 /* Return true if REGION is a combined parallel+workshare region. */
208 is_combined_parallel (struct omp_region *region)
210 return region->is_combined_parallel;
214 /* Extract the header elements of parallel loop FOR_STMT and store
218 extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
219 struct omp_for_data_loop *loops)
221 tree t, var, *collapse_iter, *collapse_count;
222 tree count = NULL_TREE, iter_type = long_integer_type_node;
223 struct omp_for_data_loop *loop;
225 struct omp_for_data_loop dummy_loop;
226 location_t loc = gimple_location (for_stmt);
228 fd->for_stmt = for_stmt;
230 fd->collapse = gimple_omp_for_collapse (for_stmt);
231 if (fd->collapse > 1)
234 fd->loops = &fd->loop;
236 fd->have_nowait = fd->have_ordered = false;
237 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
238 fd->chunk_size = NULL_TREE;
239 collapse_iter = NULL;
240 collapse_count = NULL;
242 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
243 switch (OMP_CLAUSE_CODE (t))
245 case OMP_CLAUSE_NOWAIT:
246 fd->have_nowait = true;
248 case OMP_CLAUSE_ORDERED:
249 fd->have_ordered = true;
251 case OMP_CLAUSE_SCHEDULE:
252 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
253 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
255 case OMP_CLAUSE_COLLAPSE:
256 if (fd->collapse > 1)
258 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
259 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
265 /* FIXME: for now map schedule(auto) to schedule(static).
266 There should be analysis to determine whether all iterations
267 are approximately the same amount of work (then schedule(static)
268 is best) or if it varies (then schedule(dynamic,N) is better). */
269 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
271 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
272 gcc_assert (fd->chunk_size == NULL);
274 gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
275 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
276 gcc_assert (fd->chunk_size == NULL);
277 else if (fd->chunk_size == NULL)
279 /* We only need to compute a default chunk size for ordered
280 static loops and dynamic loops. */
281 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
284 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
285 ? integer_zero_node : integer_one_node;
288 for (i = 0; i < fd->collapse; i++)
290 if (fd->collapse == 1)
292 else if (loops != NULL)
298 loop->v = gimple_omp_for_index (for_stmt, i);
299 gcc_assert (SSA_VAR_P (loop->v));
300 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
301 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
302 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
303 loop->n1 = gimple_omp_for_initial (for_stmt, i);
305 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
306 loop->n2 = gimple_omp_for_final (for_stmt, i);
307 switch (loop->cond_code)
313 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
314 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
316 loop->n2 = fold_build2_loc (loc,
317 PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
318 build_int_cst (TREE_TYPE (loop->n2), 1));
319 loop->cond_code = LT_EXPR;
322 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
323 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
325 loop->n2 = fold_build2_loc (loc,
326 MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
327 build_int_cst (TREE_TYPE (loop->n2), 1));
328 loop->cond_code = GT_EXPR;
334 t = gimple_omp_for_incr (for_stmt, i);
335 gcc_assert (TREE_OPERAND (t, 0) == var);
336 switch (TREE_CODE (t))
339 case POINTER_PLUS_EXPR:
340 loop->step = TREE_OPERAND (t, 1);
343 loop->step = TREE_OPERAND (t, 1);
344 loop->step = fold_build1_loc (loc,
345 NEGATE_EXPR, TREE_TYPE (loop->step),
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))
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);
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))
377 if (loop->cond_code == LT_EXPR)
380 n2 = fold_build2_loc (loc,
381 PLUS_EXPR, TREE_TYPE (loop->v),
382 loop->n2, loop->step);
386 n1 = fold_build2_loc (loc,
387 MINUS_EXPR, TREE_TYPE (loop->v),
388 loop->n2, loop->step);
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))
411 = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
412 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
413 t = fold_build2_loc (loc,
415 fold_convert_loc (loc, itype, loop->step), t);
416 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
417 fold_convert_loc (loc, itype, loop->n2));
418 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
419 fold_convert_loc (loc, itype, loop->n1));
420 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
421 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
422 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
423 fold_build1_loc (loc, NEGATE_EXPR, itype,
424 fold_convert_loc (loc, itype,
427 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
428 fold_convert_loc (loc, itype, loop->step));
429 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
430 if (count != NULL_TREE)
431 count = fold_build2_loc (loc,
432 MULT_EXPR, long_long_unsigned_type_node,
436 if (TREE_CODE (count) != INTEGER_CST)
446 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
447 iter_type = long_long_unsigned_type_node;
449 iter_type = long_integer_type_node;
451 else if (collapse_iter && *collapse_iter != NULL)
452 iter_type = TREE_TYPE (*collapse_iter);
453 fd->iter_type = iter_type;
454 if (collapse_iter && *collapse_iter == NULL)
455 *collapse_iter = create_tmp_var (iter_type, ".iter");
456 if (collapse_count && *collapse_count == NULL)
459 *collapse_count = fold_convert_loc (loc, iter_type, count);
461 *collapse_count = create_tmp_var (iter_type, ".count");
464 if (fd->collapse > 1)
466 fd->loop.v = *collapse_iter;
467 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
468 fd->loop.n2 = *collapse_count;
469 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
470 fd->loop.cond_code = LT_EXPR;
475 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
476 is the immediate dominator of PAR_ENTRY_BB, return true if there
477 are no data dependencies that would prevent expanding the parallel
478 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
480 When expanding a combined parallel+workshare region, the call to
481 the child function may need additional arguments in the case of
482 GIMPLE_OMP_FOR regions. In some cases, these arguments are
483 computed out of variables passed in from the parent to the child
484 via 'struct .omp_data_s'. For instance:
486 #pragma omp parallel for schedule (guided, i * 4)
491 # BLOCK 2 (PAR_ENTRY_BB)
493 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
495 # BLOCK 3 (WS_ENTRY_BB)
496 .omp_data_i = &.omp_data_o;
497 D.1667 = .omp_data_i->i;
499 #pragma omp for schedule (guided, D.1598)
501 When we outline the parallel region, the call to the child function
502 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
503 that value is computed *after* the call site. So, in principle we
504 cannot do the transformation.
506 To see whether the code in WS_ENTRY_BB blocks the combined
507 parallel+workshare call, we collect all the variables used in the
508 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
509 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
512 FIXME. If we had the SSA form built at this point, we could merely
513 hoist the code in block 3 into block 2 and be done with it. But at
514 this point we don't have dataflow information and though we could
515 hack something up here, it is really not worth the aggravation. */
518 workshare_safe_to_combine_p (basic_block ws_entry_bb)
520 struct omp_for_data fd;
521 gimple ws_stmt = last_stmt (ws_entry_bb);
523 if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
526 gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
528 extract_omp_for_data (ws_stmt, &fd, NULL);
530 if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
532 if (fd.iter_type != long_integer_type_node)
535 /* FIXME. We give up too easily here. If any of these arguments
536 are not constants, they will likely involve variables that have
537 been mapped into fields of .omp_data_s for sharing with the child
538 function. With appropriate data flow, it would be possible to
540 if (!is_gimple_min_invariant (fd.loop.n1)
541 || !is_gimple_min_invariant (fd.loop.n2)
542 || !is_gimple_min_invariant (fd.loop.step)
543 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
550 /* Collect additional arguments needed to emit a combined
551 parallel+workshare call. WS_STMT is the workshare directive being
554 static VEC(tree,gc) *
555 get_ws_args_for (gimple ws_stmt)
558 location_t loc = gimple_location (ws_stmt);
559 VEC(tree,gc) *ws_args;
561 if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
563 struct omp_for_data fd;
565 extract_omp_for_data (ws_stmt, &fd, NULL);
567 ws_args = VEC_alloc (tree, gc, 3 + (fd.chunk_size != 0));
569 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
570 VEC_quick_push (tree, ws_args, t);
572 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
573 VEC_quick_push (tree, ws_args, t);
575 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
576 VEC_quick_push (tree, ws_args, t);
580 t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
581 VEC_quick_push (tree, ws_args, t);
586 else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
588 /* Number of sections is equal to the number of edges from the
589 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
590 the exit of the sections region. */
591 basic_block bb = single_succ (gimple_bb (ws_stmt));
592 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
593 ws_args = VEC_alloc (tree, gc, 1);
594 VEC_quick_push (tree, ws_args, t);
602 /* Discover whether REGION is a combined parallel+workshare region. */
605 determine_parallel_type (struct omp_region *region)
607 basic_block par_entry_bb, par_exit_bb;
608 basic_block ws_entry_bb, ws_exit_bb;
610 if (region == NULL || region->inner == NULL
611 || region->exit == NULL || region->inner->exit == NULL
612 || region->inner->cont == NULL)
615 /* We only support parallel+for and parallel+sections. */
616 if (region->type != GIMPLE_OMP_PARALLEL
617 || (region->inner->type != GIMPLE_OMP_FOR
618 && region->inner->type != GIMPLE_OMP_SECTIONS))
621 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
622 WS_EXIT_BB -> PAR_EXIT_BB. */
623 par_entry_bb = region->entry;
624 par_exit_bb = region->exit;
625 ws_entry_bb = region->inner->entry;
626 ws_exit_bb = region->inner->exit;
628 if (single_succ (par_entry_bb) == ws_entry_bb
629 && single_succ (ws_exit_bb) == par_exit_bb
630 && workshare_safe_to_combine_p (ws_entry_bb)
631 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
632 || (last_and_only_stmt (ws_entry_bb)
633 && last_and_only_stmt (par_exit_bb))))
635 gimple ws_stmt = last_stmt (ws_entry_bb);
637 if (region->inner->type == GIMPLE_OMP_FOR)
639 /* If this is a combined parallel loop, we need to determine
640 whether or not to use the combined library calls. There
641 are two cases where we do not apply the transformation:
642 static loops and any kind of ordered loop. In the first
643 case, we already open code the loop so there is no need
644 to do anything else. In the latter case, the combined
645 parallel loop call would still need extra synchronization
646 to implement ordered semantics, so there would not be any
647 gain in using the combined call. */
648 tree clauses = gimple_omp_for_clauses (ws_stmt);
649 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
651 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
652 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
654 region->is_combined_parallel = false;
655 region->inner->is_combined_parallel = false;
660 region->is_combined_parallel = true;
661 region->inner->is_combined_parallel = true;
662 region->ws_args = get_ws_args_for (ws_stmt);
667 /* Return true if EXPR is variable sized. */
670 is_variable_sized (const_tree expr)
672 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
675 /* Return true if DECL is a reference type. */
678 is_reference (tree decl)
680 return lang_hooks.decls.omp_privatize_by_reference (decl);
683 /* Lookup variables in the decl or field splay trees. The "maybe" form
684 allows for the variable form to not have been entered, otherwise we
685 assert that the variable must have been entered. */
688 lookup_decl (tree var, omp_context *ctx)
691 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
696 maybe_lookup_decl (const_tree var, omp_context *ctx)
699 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
700 return n ? *n : NULL_TREE;
704 lookup_field (tree var, omp_context *ctx)
707 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
708 return (tree) n->value;
712 lookup_sfield (tree var, omp_context *ctx)
715 n = splay_tree_lookup (ctx->sfield_map
716 ? ctx->sfield_map : ctx->field_map,
717 (splay_tree_key) var);
718 return (tree) n->value;
722 maybe_lookup_field (tree var, omp_context *ctx)
725 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
726 return n ? (tree) n->value : NULL_TREE;
729 /* Return true if DECL should be copied by pointer. SHARED_CTX is
730 the parallel context if DECL is to be shared. */
733 use_pointer_for_field (tree decl, omp_context *shared_ctx)
735 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
738 /* We can only use copy-in/copy-out semantics for shared variables
739 when we know the value is not accessible from an outer scope. */
742 /* ??? Trivially accessible from anywhere. But why would we even
743 be passing an address in this case? Should we simply assert
744 this to be false, or should we have a cleanup pass that removes
745 these from the list of mappings? */
746 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
749 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
750 without analyzing the expression whether or not its location
751 is accessible to anyone else. In the case of nested parallel
752 regions it certainly may be. */
753 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
756 /* Do not use copy-in/copy-out for variables that have their
758 if (TREE_ADDRESSABLE (decl))
761 /* Disallow copy-in/out in nested parallel if
762 decl is shared in outer parallel, otherwise
763 each thread could store the shared variable
764 in its own copy-in location, making the
765 variable no longer really shared. */
766 if (!TREE_READONLY (decl) && shared_ctx->is_nested)
770 for (up = shared_ctx->outer; up; up = up->outer)
771 if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
778 for (c = gimple_omp_taskreg_clauses (up->stmt);
779 c; c = OMP_CLAUSE_CHAIN (c))
780 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
781 && OMP_CLAUSE_DECL (c) == decl)
785 goto maybe_mark_addressable_and_ret;
789 /* For tasks avoid using copy-in/out, unless they are readonly
790 (in which case just copy-in is used). As tasks can be
791 deferred or executed in different thread, when GOMP_task
792 returns, the task hasn't necessarily terminated. */
793 if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx))
796 maybe_mark_addressable_and_ret:
797 outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
798 if (is_gimple_reg (outer))
800 /* Taking address of OUTER in lower_send_shared_vars
801 might need regimplification of everything that uses the
803 if (!task_shared_vars)
804 task_shared_vars = BITMAP_ALLOC (NULL);
805 bitmap_set_bit (task_shared_vars, DECL_UID (outer));
806 TREE_ADDRESSABLE (outer) = 1;
815 /* Create a new VAR_DECL and copy information from VAR to it. */
818 copy_var_decl (tree var, tree name, tree type)
820 tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
822 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
823 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
824 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
825 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
826 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
827 DECL_CONTEXT (copy) = DECL_CONTEXT (var);
828 TREE_USED (copy) = 1;
829 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
834 /* Construct a new automatic decl similar to VAR. */
837 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
839 tree copy = copy_var_decl (var, name, type);
841 DECL_CONTEXT (copy) = current_function_decl;
842 DECL_CHAIN (copy) = ctx->block_vars;
843 ctx->block_vars = copy;
849 omp_copy_decl_1 (tree var, omp_context *ctx)
851 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
854 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
857 omp_build_component_ref (tree obj, tree field)
859 tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
860 if (TREE_THIS_VOLATILE (field))
861 TREE_THIS_VOLATILE (ret) |= 1;
862 if (TREE_READONLY (field))
863 TREE_READONLY (ret) |= 1;
867 /* Build tree nodes to access the field for VAR on the receiver side. */
870 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
872 tree x, field = lookup_field (var, ctx);
874 /* If the receiver record type was remapped in the child function,
875 remap the field into the new record type. */
876 x = maybe_lookup_field (field, ctx);
880 x = build_simple_mem_ref (ctx->receiver_decl);
881 x = omp_build_component_ref (x, field);
883 x = build_simple_mem_ref (x);
888 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
889 of a parallel, this is a component reference; for workshare constructs
890 this is some variable. */
893 build_outer_var_ref (tree var, omp_context *ctx)
897 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
899 else if (is_variable_sized (var))
901 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
902 x = build_outer_var_ref (x, ctx);
903 x = build_simple_mem_ref (x);
905 else if (is_taskreg_ctx (ctx))
907 bool by_ref = use_pointer_for_field (var, NULL);
908 x = build_receiver_ref (var, by_ref, ctx);
911 x = lookup_decl (var, ctx->outer);
912 else if (is_reference (var))
913 /* This can happen with orphaned constructs. If var is reference, it is
914 possible it is shared and as such valid. */
919 if (is_reference (var))
920 x = build_simple_mem_ref (x);
925 /* Build tree nodes to access the field for VAR on the sender side. */
928 build_sender_ref (tree var, omp_context *ctx)
930 tree field = lookup_sfield (var, ctx);
931 return omp_build_component_ref (ctx->sender_decl, field);
934 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
937 install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
939 tree field, type, sfield = NULL_TREE;
941 gcc_assert ((mask & 1) == 0
942 || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
943 gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
944 || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
946 type = TREE_TYPE (var);
948 type = build_pointer_type (type);
949 else if ((mask & 3) == 1 && is_reference (var))
950 type = TREE_TYPE (type);
952 field = build_decl (DECL_SOURCE_LOCATION (var),
953 FIELD_DECL, DECL_NAME (var), type);
955 /* Remember what variable this field was created for. This does have a
956 side effect of making dwarf2out ignore this member, so for helpful
957 debugging we clear it later in delete_omp_context. */
958 DECL_ABSTRACT_ORIGIN (field) = var;
959 if (type == TREE_TYPE (var))
961 DECL_ALIGN (field) = DECL_ALIGN (var);
962 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
963 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
966 DECL_ALIGN (field) = TYPE_ALIGN (type);
970 insert_field_into_struct (ctx->record_type, field);
971 if (ctx->srecord_type)
973 sfield = build_decl (DECL_SOURCE_LOCATION (var),
974 FIELD_DECL, DECL_NAME (var), type);
975 DECL_ABSTRACT_ORIGIN (sfield) = var;
976 DECL_ALIGN (sfield) = DECL_ALIGN (field);
977 DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
978 TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
979 insert_field_into_struct (ctx->srecord_type, sfield);
984 if (ctx->srecord_type == NULL_TREE)
988 ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
989 ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
990 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
992 sfield = build_decl (DECL_SOURCE_LOCATION (var),
993 FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
994 DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
995 insert_field_into_struct (ctx->srecord_type, sfield);
996 splay_tree_insert (ctx->sfield_map,
997 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
998 (splay_tree_value) sfield);
1002 insert_field_into_struct ((mask & 1) ? ctx->record_type
1003 : ctx->srecord_type, field);
1007 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
1008 (splay_tree_value) field);
1009 if ((mask & 2) && ctx->sfield_map)
1010 splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1011 (splay_tree_value) sfield);
1015 install_var_local (tree var, omp_context *ctx)
1017 tree new_var = omp_copy_decl_1 (var, ctx);
1018 insert_decl_map (&ctx->cb, var, new_var);
1022 /* Adjust the replacement for DECL in CTX for the new context. This means
1023 copying the DECL_VALUE_EXPR, and fixing up the type. */
1026 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1028 tree new_decl, size;
1030 new_decl = lookup_decl (decl, ctx);
1032 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1034 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1035 && DECL_HAS_VALUE_EXPR_P (decl))
1037 tree ve = DECL_VALUE_EXPR (decl);
1038 walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1039 SET_DECL_VALUE_EXPR (new_decl, ve);
1040 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1043 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1045 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1046 if (size == error_mark_node)
1047 size = TYPE_SIZE (TREE_TYPE (new_decl));
1048 DECL_SIZE (new_decl) = size;
1050 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1051 if (size == error_mark_node)
1052 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1053 DECL_SIZE_UNIT (new_decl) = size;
1057 /* The callback for remap_decl. Search all containing contexts for a
1058 mapping of the variable; this avoids having to duplicate the splay
1059 tree ahead of time. We know a mapping doesn't already exist in the
1060 given context. Create new mappings to implement default semantics. */
1063 omp_copy_decl (tree var, copy_body_data *cb)
1065 omp_context *ctx = (omp_context *) cb;
1068 if (TREE_CODE (var) == LABEL_DECL)
1070 new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1071 DECL_CONTEXT (new_var) = current_function_decl;
1072 insert_decl_map (&ctx->cb, var, new_var);
1076 while (!is_taskreg_ctx (ctx))
1081 new_var = maybe_lookup_decl (var, ctx);
1086 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1089 return error_mark_node;
1093 /* Return the parallel region associated with STMT. */
1095 /* Debugging dumps for parallel regions. */
1096 void dump_omp_region (FILE *, struct omp_region *, int);
1097 void debug_omp_region (struct omp_region *);
1098 void debug_all_omp_regions (void);
1100 /* Dump the parallel region tree rooted at REGION. */
1103 dump_omp_region (FILE *file, struct omp_region *region, int indent)
1105 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1106 gimple_code_name[region->type]);
1109 dump_omp_region (file, region->inner, indent + 4);
1113 fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1114 region->cont->index);
1118 fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1119 region->exit->index);
1121 fprintf (file, "%*s[no exit marker]\n", indent, "");
1124 dump_omp_region (file, region->next, indent);
1128 debug_omp_region (struct omp_region *region)
1130 dump_omp_region (stderr, region, 0);
1134 debug_all_omp_regions (void)
1136 dump_omp_region (stderr, root_omp_region, 0);
1140 /* Create a new parallel region starting at STMT inside region PARENT. */
1143 new_omp_region (basic_block bb, enum gimple_code type,
1144 struct omp_region *parent)
1146 struct omp_region *region = XCNEW (struct omp_region);
1148 region->outer = parent;
1150 region->type = type;
1154 /* This is a nested region. Add it to the list of inner
1155 regions in PARENT. */
1156 region->next = parent->inner;
1157 parent->inner = region;
1161 /* This is a toplevel region. Add it to the list of toplevel
1162 regions in ROOT_OMP_REGION. */
1163 region->next = root_omp_region;
1164 root_omp_region = region;
1170 /* Release the memory associated with the region tree rooted at REGION. */
1173 free_omp_region_1 (struct omp_region *region)
1175 struct omp_region *i, *n;
1177 for (i = region->inner; i ; i = n)
1180 free_omp_region_1 (i);
1186 /* Release the memory for the entire omp region tree. */
1189 free_omp_regions (void)
1191 struct omp_region *r, *n;
1192 for (r = root_omp_region; r ; r = n)
1195 free_omp_region_1 (r);
1197 root_omp_region = NULL;
1201 /* Create a new context, with OUTER_CTX being the surrounding context. */
1203 static omp_context *
1204 new_omp_context (gimple stmt, omp_context *outer_ctx)
1206 omp_context *ctx = XCNEW (omp_context);
1208 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1209 (splay_tree_value) ctx);
1214 ctx->outer = outer_ctx;
1215 ctx->cb = outer_ctx->cb;
1216 ctx->cb.block = NULL;
1217 ctx->depth = outer_ctx->depth + 1;
1221 ctx->cb.src_fn = current_function_decl;
1222 ctx->cb.dst_fn = current_function_decl;
1223 ctx->cb.src_node = cgraph_get_node (current_function_decl);
1224 gcc_checking_assert (ctx->cb.src_node);
1225 ctx->cb.dst_node = ctx->cb.src_node;
1226 ctx->cb.src_cfun = cfun;
1227 ctx->cb.copy_decl = omp_copy_decl;
1228 ctx->cb.eh_lp_nr = 0;
1229 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1233 ctx->cb.decl_map = pointer_map_create ();
1238 static gimple_seq maybe_catch_exception (gimple_seq);
1240 /* Finalize task copyfn. */
1243 finalize_task_copyfn (gimple task_stmt)
1245 struct function *child_cfun;
1246 tree child_fn, old_fn;
1247 gimple_seq seq, new_seq;
1250 child_fn = gimple_omp_task_copy_fn (task_stmt);
1251 if (child_fn == NULL_TREE)
1254 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1256 /* Inform the callgraph about the new function. */
1257 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
1258 = cfun->curr_properties;
1260 old_fn = current_function_decl;
1261 push_cfun (child_cfun);
1262 current_function_decl = child_fn;
1263 bind = gimplify_body (child_fn, false);
1264 seq = gimple_seq_alloc ();
1265 gimple_seq_add_stmt (&seq, bind);
1266 new_seq = maybe_catch_exception (seq);
1269 bind = gimple_build_bind (NULL, new_seq, NULL);
1270 seq = gimple_seq_alloc ();
1271 gimple_seq_add_stmt (&seq, bind);
1273 gimple_set_body (child_fn, seq);
1275 current_function_decl = old_fn;
1277 cgraph_add_new_function (child_fn, false);
1280 /* Destroy a omp_context data structures. Called through the splay tree
1281 value delete callback. */
1284 delete_omp_context (splay_tree_value value)
1286 omp_context *ctx = (omp_context *) value;
1288 pointer_map_destroy (ctx->cb.decl_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)
1300 for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
1301 DECL_ABSTRACT_ORIGIN (t) = NULL;
1303 if (ctx->srecord_type)
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);
1316 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
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))
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,
1350 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
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);
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. */
1370 scan_sharing_clauses (tree clauses, omp_context *ctx)
1373 bool scan_array_reductions = false;
1375 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
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))
1385 else if (!is_variable_sized (decl))
1386 install_var_local (decl, ctx);
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)))
1398 by_ref = use_pointer_for_field (decl, ctx);
1399 if (! TREE_READONLY (decl)
1400 || TREE_ADDRESSABLE (decl)
1402 || is_reference (decl))
1404 install_var_field (decl, by_ref, 3, ctx);
1405 install_var_local (decl, ctx);
1408 /* We don't need to copy const scalar vars back. */
1409 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1412 case OMP_CLAUSE_LASTPRIVATE:
1413 /* Let the corresponding firstprivate clause create
1415 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1419 case OMP_CLAUSE_FIRSTPRIVATE:
1420 case OMP_CLAUSE_REDUCTION:
1421 decl = OMP_CLAUSE_DECL (c);
1423 if (is_variable_sized (decl))
1425 if (is_task_ctx (ctx))
1426 install_var_field (decl, false, 1, ctx);
1429 else if (is_taskreg_ctx (ctx))
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);
1440 install_var_field (decl, by_ref, 2, ctx);
1443 install_var_field (decl, by_ref, 3, ctx);
1445 install_var_local (decl, ctx);
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);
1455 case OMP_CLAUSE_DEFAULT:
1456 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1459 case OMP_CLAUSE_FINAL:
1461 case OMP_CLAUSE_NUM_THREADS:
1462 case OMP_CLAUSE_SCHEDULE:
1464 scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
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:
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
1486 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1487 scan_array_reductions = true;
1488 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
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;
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);
1512 case OMP_CLAUSE_COPYPRIVATE:
1513 case OMP_CLAUSE_COPYIN:
1514 case OMP_CLAUSE_DEFAULT:
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:
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;
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. */
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);
1565 type = build_function_type_list (void_type_node, ptr_type_node,
1566 ptr_type_node, NULL_TREE);
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);
1574 ctx->cb.dst_fn = decl;
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;
1603 DECL_ARGUMENTS (decl) = t;
1605 ctx->receiver_decl = t;
1608 t = build_decl (DECL_SOURCE_LOCATION (decl),
1609 PARM_DECL, get_identifier (".omp_data_o"),
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;
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
1624 push_struct_function (decl);
1625 cfun->function_end_locus = gimple_location (ctx->stmt);
1630 /* Scan an OpenMP parallel directive. */
1633 scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1637 gimple stmt = gsi_stmt (*gsi);
1639 /* Ignore parallel directives with empty bodies, unless there
1640 are copyin clauses. */
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);
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 (stmt), ctx);
1668 if (TYPE_FIELDS (ctx->record_type) == NULL)
1669 ctx->record_type = ctx->receiver_decl = NULL;
1672 layout_type (ctx->record_type);
1673 fixup_child_record_type (ctx);
1677 /* Scan an OpenMP task directive. */
1680 scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1684 gimple stmt = gsi_stmt (*gsi);
1685 location_t loc = gimple_location (stmt);
1687 /* Ignore task directives with empty bodies. */
1689 && empty_body_p (gimple_omp_body (stmt)))
1691 gsi_replace (gsi, gimple_build_nop (), false);
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 (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);
1735 tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
1736 /* Move VLA fields to the end. */
1737 p = &TYPE_FIELDS (ctx->record_type);
1739 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
1740 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
1743 *p = TREE_CHAIN (*p);
1744 TREE_CHAIN (*q) = NULL_TREE;
1745 q = &TREE_CHAIN (*q);
1748 p = &DECL_CHAIN (*p);
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. */
1767 scan_omp_for (gimple stmt, omp_context *outer_ctx)
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 (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 (stmt), ctx);
1787 /* Scan an OpenMP sections directive. */
1790 scan_omp_sections (gimple stmt, omp_context *outer_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 (stmt), ctx);
1799 /* Scan an OpenMP single directive. */
1802 scan_omp_single (gimple stmt, omp_context *outer_ctx)
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 (stmt), ctx);
1818 if (TYPE_FIELDS (ctx->record_type) == NULL)
1819 ctx->record_type = NULL;
1821 layout_type (ctx->record_type);
1825 /* Check OpenMP nesting restrictions. */
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:
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 warning (0, "barrier region may not be closely nested inside "
1847 "of work-sharing, critical, ordered, master or "
1848 "explicit task region");
1851 warning (0, "work-sharing region may not be closely nested inside "
1852 "of work-sharing, critical, ordered, master or explicit "
1855 case GIMPLE_OMP_PARALLEL:
1861 case GIMPLE_OMP_MASTER:
1862 for (; ctx != NULL; ctx = ctx->outer)
1863 switch (gimple_code (ctx->stmt))
1865 case GIMPLE_OMP_FOR:
1866 case GIMPLE_OMP_SECTIONS:
1867 case GIMPLE_OMP_SINGLE:
1868 case GIMPLE_OMP_TASK:
1869 warning (0, "master region may not be closely nested inside "
1870 "of work-sharing or explicit task region");
1872 case GIMPLE_OMP_PARALLEL:
1878 case GIMPLE_OMP_ORDERED:
1879 for (; ctx != NULL; ctx = ctx->outer)
1880 switch (gimple_code (ctx->stmt))
1882 case GIMPLE_OMP_CRITICAL:
1883 case GIMPLE_OMP_TASK:
1884 warning (0, "ordered region may not be closely nested inside "
1885 "of critical or explicit task region");
1887 case GIMPLE_OMP_FOR:
1888 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
1889 OMP_CLAUSE_ORDERED) == NULL)
1890 warning (0, "ordered region must be closely nested inside "
1891 "a loop region with an ordered clause");
1893 case GIMPLE_OMP_PARALLEL:
1899 case GIMPLE_OMP_CRITICAL:
1900 for (; ctx != NULL; ctx = ctx->outer)
1901 if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
1902 && (gimple_omp_critical_name (stmt)
1903 == gimple_omp_critical_name (ctx->stmt)))
1905 warning (0, "critical region may not be nested inside a critical "
1906 "region with the same name");
1916 /* Helper function scan_omp.
1918 Callback for walk_tree or operators in walk_gimple_stmt used to
1919 scan for OpenMP directives in TP. */
1922 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
1924 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1925 omp_context *ctx = (omp_context *) wi->info;
1928 switch (TREE_CODE (t))
1935 *tp = remap_decl (t, &ctx->cb);
1939 if (ctx && TYPE_P (t))
1940 *tp = remap_type (t, &ctx->cb);
1941 else if (!DECL_P (t))
1946 tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
1947 if (tem != TREE_TYPE (t))
1949 if (TREE_CODE (t) == INTEGER_CST)
1950 *tp = build_int_cst_wide (tem,
1951 TREE_INT_CST_LOW (t),
1952 TREE_INT_CST_HIGH (t));
1954 TREE_TYPE (t) = tem;
1965 /* Helper function for scan_omp.
1967 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1968 the current statement in GSI. */
1971 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1972 struct walk_stmt_info *wi)
1974 gimple stmt = gsi_stmt (*gsi);
1975 omp_context *ctx = (omp_context *) wi->info;
1977 if (gimple_has_location (stmt))
1978 input_location = gimple_location (stmt);
1980 /* Check the OpenMP nesting restrictions. */
1983 if (is_gimple_omp (stmt))
1984 check_omp_nesting_restrictions (stmt, ctx);
1985 else if (is_gimple_call (stmt))
1987 tree fndecl = gimple_call_fndecl (stmt);
1988 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
1989 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
1990 check_omp_nesting_restrictions (stmt, ctx);
1994 *handled_ops_p = true;
1996 switch (gimple_code (stmt))
1998 case GIMPLE_OMP_PARALLEL:
1999 taskreg_nesting_level++;
2000 scan_omp_parallel (gsi, ctx);
2001 taskreg_nesting_level--;
2004 case GIMPLE_OMP_TASK:
2005 taskreg_nesting_level++;
2006 scan_omp_task (gsi, ctx);
2007 taskreg_nesting_level--;
2010 case GIMPLE_OMP_FOR:
2011 scan_omp_for (stmt, ctx);
2014 case GIMPLE_OMP_SECTIONS:
2015 scan_omp_sections (stmt, ctx);
2018 case GIMPLE_OMP_SINGLE:
2019 scan_omp_single (stmt, ctx);
2022 case GIMPLE_OMP_SECTION:
2023 case GIMPLE_OMP_MASTER:
2024 case GIMPLE_OMP_ORDERED:
2025 case GIMPLE_OMP_CRITICAL:
2026 ctx = new_omp_context (stmt, ctx);
2027 scan_omp (gimple_omp_body (stmt), ctx);
2034 *handled_ops_p = false;
2036 for (var = gimple_bind_vars (stmt); var ; var = DECL_CHAIN (var))
2037 insert_decl_map (&ctx->cb, var, var);
2041 *handled_ops_p = false;
2049 /* Scan all the statements starting at the current statement. CTX
2050 contains context information about the OpenMP directives and
2051 clauses found during the scan. */
2054 scan_omp (gimple_seq body, omp_context *ctx)
2056 location_t saved_location;
2057 struct walk_stmt_info wi;
2059 memset (&wi, 0, sizeof (wi));
2061 wi.want_locations = true;
2063 saved_location = input_location;
2064 walk_gimple_seq (body, scan_omp_1_stmt, scan_omp_1_op, &wi);
2065 input_location = saved_location;
2068 /* Re-gimplification and code generation routines. */
2070 /* Build a call to GOMP_barrier. */
2073 build_omp_barrier (void)
2075 return build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_BARRIER), 0);
2078 /* If a context was created for STMT when it was scanned, return it. */
2080 static omp_context *
2081 maybe_lookup_ctx (gimple stmt)
2084 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
2085 return n ? (omp_context *) n->value : NULL;
2089 /* Find the mapping for DECL in CTX or the immediately enclosing
2090 context that has a mapping for DECL.
2092 If CTX is a nested parallel directive, we may have to use the decl
2093 mappings created in CTX's parent context. Suppose that we have the
2094 following parallel nesting (variable UIDs showed for clarity):
2097 #omp parallel shared(iD.1562) -> outer parallel
2098 iD.1562 = iD.1562 + 1;
2100 #omp parallel shared (iD.1562) -> inner parallel
2101 iD.1562 = iD.1562 - 1;
2103 Each parallel structure will create a distinct .omp_data_s structure
2104 for copying iD.1562 in/out of the directive:
2106 outer parallel .omp_data_s.1.i -> iD.1562
2107 inner parallel .omp_data_s.2.i -> iD.1562
2109 A shared variable mapping will produce a copy-out operation before
2110 the parallel directive and a copy-in operation after it. So, in
2111 this case we would have:
2114 .omp_data_o.1.i = iD.1562;
2115 #omp parallel shared(iD.1562) -> outer parallel
2116 .omp_data_i.1 = &.omp_data_o.1
2117 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2119 .omp_data_o.2.i = iD.1562; -> **
2120 #omp parallel shared(iD.1562) -> inner parallel
2121 .omp_data_i.2 = &.omp_data_o.2
2122 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2125 ** This is a problem. The symbol iD.1562 cannot be referenced
2126 inside the body of the outer parallel region. But since we are
2127 emitting this copy operation while expanding the inner parallel
2128 directive, we need to access the CTX structure of the outer
2129 parallel directive to get the correct mapping:
2131 .omp_data_o.2.i = .omp_data_i.1->i
2133 Since there may be other workshare or parallel directives enclosing
2134 the parallel directive, it may be necessary to walk up the context
2135 parent chain. This is not a problem in general because nested
2136 parallelism happens only rarely. */
2139 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2144 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2145 t = maybe_lookup_decl (decl, up);
2147 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
2149 return t ? t : decl;
2153 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2154 in outer contexts. */
2157 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2162 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2163 t = maybe_lookup_decl (decl, up);
2165 return t ? t : decl;
2169 /* Construct the initialization value for reduction CLAUSE. */
2172 omp_reduction_init (tree clause, tree type)
2174 location_t loc = OMP_CLAUSE_LOCATION (clause);
2175 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
2182 case TRUTH_ORIF_EXPR:
2183 case TRUTH_XOR_EXPR:
2185 return build_zero_cst (type);
2188 case TRUTH_AND_EXPR:
2189 case TRUTH_ANDIF_EXPR:
2191 return fold_convert_loc (loc, type, integer_one_node);
2194 return fold_convert_loc (loc, type, integer_minus_one_node);
2197 if (SCALAR_FLOAT_TYPE_P (type))
2199 REAL_VALUE_TYPE max, min;
2200 if (HONOR_INFINITIES (TYPE_MODE (type)))
2203 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
2206 real_maxval (&min, 1, TYPE_MODE (type));
2207 return build_real (type, min);
2211 gcc_assert (INTEGRAL_TYPE_P (type));
2212 return TYPE_MIN_VALUE (type);
2216 if (SCALAR_FLOAT_TYPE_P (type))
2218 REAL_VALUE_TYPE max;
2219 if (HONOR_INFINITIES (TYPE_MODE (type)))
2222 real_maxval (&max, 0, TYPE_MODE (type));
2223 return build_real (type, max);
2227 gcc_assert (INTEGRAL_TYPE_P (type));
2228 return TYPE_MAX_VALUE (type);
2236 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2237 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2238 private variables. Initialization statements go in ILIST, while calls
2239 to destructors go in DLIST. */
2242 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
2245 gimple_stmt_iterator diter;
2246 tree c, dtor, copyin_seq, x, ptr;
2247 bool copyin_by_ref = false;
2248 bool lastprivate_firstprivate = false;
2251 *dlist = gimple_seq_alloc ();
2252 diter = gsi_start (*dlist);
2255 /* Do all the fixed sized types in the first pass, and the variable sized
2256 types in the second pass. This makes sure that the scalar arguments to
2257 the variable sized types are processed before we use them in the
2258 variable sized operations. */
2259 for (pass = 0; pass < 2; ++pass)
2261 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2263 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
2266 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2270 case OMP_CLAUSE_PRIVATE:
2271 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
2274 case OMP_CLAUSE_SHARED:
2275 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
2277 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
2280 case OMP_CLAUSE_FIRSTPRIVATE:
2281 case OMP_CLAUSE_COPYIN:
2282 case OMP_CLAUSE_REDUCTION:
2284 case OMP_CLAUSE_LASTPRIVATE:
2285 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2287 lastprivate_firstprivate = true;
2296 new_var = var = OMP_CLAUSE_DECL (c);
2297 if (c_kind != OMP_CLAUSE_COPYIN)
2298 new_var = lookup_decl (var, ctx);
2300 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
2305 else if (is_variable_sized (var))
2307 /* For variable sized types, we need to allocate the
2308 actual storage here. Call alloca and store the
2309 result in the pointer decl that we created elsewhere. */
2313 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
2318 ptr = DECL_VALUE_EXPR (new_var);
2319 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
2320 ptr = TREE_OPERAND (ptr, 0);
2321 gcc_assert (DECL_P (ptr));
2322 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
2324 /* void *tmp = __builtin_alloca */
2325 atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2326 stmt = gimple_build_call (atmp, 1, x);
2327 tmp = create_tmp_var_raw (ptr_type_node, NULL);
2328 gimple_add_tmp_var (tmp);
2329 gimple_call_set_lhs (stmt, tmp);
2331 gimple_seq_add_stmt (ilist, stmt);
2333 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
2334 gimplify_assign (ptr, x, ilist);
2337 else if (is_reference (var))
2339 /* For references that are being privatized for Fortran,
2340 allocate new backing storage for the new pointer
2341 variable. This allows us to avoid changing all the
2342 code that expects a pointer to something that expects
2343 a direct variable. Note that this doesn't apply to
2344 C++, since reference types are disallowed in data
2345 sharing clauses there, except for NRV optimized
2350 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
2351 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
2353 x = build_receiver_ref (var, false, ctx);
2354 x = build_fold_addr_expr_loc (clause_loc, x);
2356 else if (TREE_CONSTANT (x))
2358 const char *name = NULL;
2359 if (DECL_NAME (var))
2360 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
2362 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
2364 gimple_add_tmp_var (x);
2365 TREE_ADDRESSABLE (x) = 1;
2366 x = build_fold_addr_expr_loc (clause_loc, x);
2370 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2371 x = build_call_expr_loc (clause_loc, atmp, 1, x);
2374 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
2375 gimplify_assign (new_var, x, ilist);
2377 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2379 else if (c_kind == OMP_CLAUSE_REDUCTION
2380 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2388 switch (OMP_CLAUSE_CODE (c))
2390 case OMP_CLAUSE_SHARED:
2391 /* Shared global vars are just accessed directly. */
2392 if (is_global_var (new_var))
2394 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2395 needs to be delayed until after fixup_child_record_type so
2396 that we get the correct type during the dereference. */
2397 by_ref = use_pointer_for_field (var, ctx);
2398 x = build_receiver_ref (var, by_ref, ctx);
2399 SET_DECL_VALUE_EXPR (new_var, x);
2400 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2402 /* ??? If VAR is not passed by reference, and the variable
2403 hasn't been initialized yet, then we'll get a warning for
2404 the store into the omp_data_s structure. Ideally, we'd be
2405 able to notice this and not store anything at all, but
2406 we're generating code too early. Suppress the warning. */
2408 TREE_NO_WARNING (var) = 1;
2411 case OMP_CLAUSE_LASTPRIVATE:
2412 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2416 case OMP_CLAUSE_PRIVATE:
2417 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
2418 x = build_outer_var_ref (var, ctx);
2419 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2421 if (is_task_ctx (ctx))
2422 x = build_receiver_ref (var, false, ctx);
2424 x = build_outer_var_ref (var, ctx);
2428 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
2430 gimplify_and_add (x, ilist);
2434 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
2437 gimple_seq tseq = NULL;
2440 gimplify_stmt (&dtor, &tseq);
2441 gsi_insert_seq_before (&diter, tseq, GSI_SAME_STMT);
2445 case OMP_CLAUSE_FIRSTPRIVATE:
2446 if (is_task_ctx (ctx))
2448 if (is_reference (var) || is_variable_sized (var))
2450 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
2452 || use_pointer_for_field (var, NULL))
2454 x = build_receiver_ref (var, false, ctx);
2455 SET_DECL_VALUE_EXPR (new_var, x);
2456 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2460 x = build_outer_var_ref (var, ctx);
2461 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
2462 gimplify_and_add (x, ilist);
2466 case OMP_CLAUSE_COPYIN:
2467 by_ref = use_pointer_for_field (var, NULL);
2468 x = build_receiver_ref (var, by_ref, ctx);
2469 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
2470 append_to_statement_list (x, ©in_seq);
2471 copyin_by_ref |= by_ref;
2474 case OMP_CLAUSE_REDUCTION:
2475 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2477 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2478 x = build_outer_var_ref (var, ctx);
2480 if (is_reference (var))
2481 x = build_fold_addr_expr_loc (clause_loc, x);
2482 SET_DECL_VALUE_EXPR (placeholder, x);
2483 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2484 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2485 gimple_seq_add_seq (ilist,
2486 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
2487 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
2488 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
2492 x = omp_reduction_init (c, TREE_TYPE (new_var));
2493 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
2494 gimplify_assign (new_var, x, ilist);
2504 /* The copyin sequence is not to be executed by the main thread, since
2505 that would result in self-copies. Perhaps not visible to scalars,
2506 but it certainly is to C++ operator=. */
2509 x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
2511 x = build2 (NE_EXPR, boolean_type_node, x,
2512 build_int_cst (TREE_TYPE (x), 0));
2513 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
2514 gimplify_and_add (x, ilist);
2517 /* If any copyin variable is passed by reference, we must ensure the
2518 master thread doesn't modify it before it is copied over in all
2519 threads. Similarly for variables in both firstprivate and
2520 lastprivate clauses we need to ensure the lastprivate copying
2521 happens after firstprivate copying in all threads. */
2522 if (copyin_by_ref || lastprivate_firstprivate)
2523 gimplify_and_add (build_omp_barrier (), ilist);
2527 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2528 both parallel and workshare constructs. PREDICATE may be NULL if it's
2532 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
2535 tree x, c, label = NULL;
2536 bool par_clauses = false;
2538 /* Early exit if there are no lastprivate clauses. */
2539 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
2540 if (clauses == NULL)
2542 /* If this was a workshare clause, see if it had been combined
2543 with its parallel. In that case, look for the clauses on the
2544 parallel statement itself. */
2545 if (is_parallel_ctx (ctx))
2549 if (ctx == NULL || !is_parallel_ctx (ctx))
2552 clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2553 OMP_CLAUSE_LASTPRIVATE);
2554 if (clauses == NULL)
2562 tree label_true, arm1, arm2;
2564 label = create_artificial_label (UNKNOWN_LOCATION);
2565 label_true = create_artificial_label (UNKNOWN_LOCATION);
2566 arm1 = TREE_OPERAND (predicate, 0);
2567 arm2 = TREE_OPERAND (predicate, 1);
2568 gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
2569 gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
2570 stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
2572 gimple_seq_add_stmt (stmt_list, stmt);
2573 gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
2576 for (c = clauses; c ;)
2579 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2581 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2583 var = OMP_CLAUSE_DECL (c);
2584 new_var = lookup_decl (var, ctx);
2586 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2588 lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2589 gimple_seq_add_seq (stmt_list,
2590 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
2592 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
2594 x = build_outer_var_ref (var, ctx);
2595 if (is_reference (var))
2596 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2597 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
2598 gimplify_and_add (x, stmt_list);
2600 c = OMP_CLAUSE_CHAIN (c);
2601 if (c == NULL && !par_clauses)
2603 /* If this was a workshare clause, see if it had been combined
2604 with its parallel. In that case, continue looking for the
2605 clauses also on the parallel statement itself. */
2606 if (is_parallel_ctx (ctx))
2610 if (ctx == NULL || !is_parallel_ctx (ctx))
2613 c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2614 OMP_CLAUSE_LASTPRIVATE);
2620 gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
2624 /* Generate code to implement the REDUCTION clauses. */
2627 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
2629 gimple_seq sub_seq = NULL;
2634 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2635 update in that case, otherwise use a lock. */
2636 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
2637 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
2639 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2641 /* Never use OMP_ATOMIC for array reductions. */
2651 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2653 tree var, ref, new_var;
2654 enum tree_code code;
2655 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2657 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
2660 var = OMP_CLAUSE_DECL (c);
2661 new_var = lookup_decl (var, ctx);
2662 if (is_reference (var))
2663 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2664 ref = build_outer_var_ref (var, ctx);
2665 code = OMP_CLAUSE_REDUCTION_CODE (c);
2667 /* reduction(-:var) sums up the partial results, so it acts
2668 identically to reduction(+:var). */
2669 if (code == MINUS_EXPR)
2674 tree addr = build_fold_addr_expr_loc (clause_loc, ref);
2676 addr = save_expr (addr);
2677 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
2678 x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
2679 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
2680 gimplify_and_add (x, stmt_seqp);
2684 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2686 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2688 if (is_reference (var))
2689 ref = build_fold_addr_expr_loc (clause_loc, ref);
2690 SET_DECL_VALUE_EXPR (placeholder, ref);
2691 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2692 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2693 gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
2694 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
2695 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
2699 x = build2 (code, TREE_TYPE (ref), ref, new_var);
2700 ref = build_outer_var_ref (var, ctx);
2701 gimplify_assign (ref, x, &sub_seq);
2705 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
2707 gimple_seq_add_stmt (stmt_seqp, stmt);
2709 gimple_seq_add_seq (stmt_seqp, sub_seq);
2711 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
2713 gimple_seq_add_stmt (stmt_seqp, stmt);
2717 /* Generate code to implement the COPYPRIVATE clauses. */
2720 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
2725 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2727 tree var, new_var, ref, x;
2729 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2731 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
2734 var = OMP_CLAUSE_DECL (c);
2735 by_ref = use_pointer_for_field (var, NULL);
2737 ref = build_sender_ref (var, ctx);
2738 x = new_var = lookup_decl_in_outer_ctx (var, ctx);
2741 x = build_fold_addr_expr_loc (clause_loc, new_var);
2742 x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
2744 gimplify_assign (ref, x, slist);
2746 ref = build_receiver_ref (var, false, ctx);
2749 ref = fold_convert_loc (clause_loc,
2750 build_pointer_type (TREE_TYPE (new_var)),
2752 ref = build_fold_indirect_ref_loc (clause_loc, ref);
2754 if (is_reference (var))
2756 ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
2757 ref = build_simple_mem_ref_loc (clause_loc, ref);
2758 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2760 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
2761 gimplify_and_add (x, rlist);
2766 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2767 and REDUCTION from the sender (aka parent) side. */
2770 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
2775 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2777 tree val, ref, x, var;
2778 bool by_ref, do_in = false, do_out = false;
2779 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2781 switch (OMP_CLAUSE_CODE (c))
2783 case OMP_CLAUSE_PRIVATE:
2784 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2787 case OMP_CLAUSE_FIRSTPRIVATE:
2788 case OMP_CLAUSE_COPYIN:
2789 case OMP_CLAUSE_LASTPRIVATE:
2790 case OMP_CLAUSE_REDUCTION:
2796 val = OMP_CLAUSE_DECL (c);
2797 var = lookup_decl_in_outer_ctx (val, ctx);
2799 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2800 && is_global_var (var))
2802 if (is_variable_sized (val))
2804 by_ref = use_pointer_for_field (val, NULL);
2806 switch (OMP_CLAUSE_CODE (c))
2808 case OMP_CLAUSE_PRIVATE:
2809 case OMP_CLAUSE_FIRSTPRIVATE:
2810 case OMP_CLAUSE_COPYIN:
2814 case OMP_CLAUSE_LASTPRIVATE:
2815 if (by_ref || is_reference (val))
2817 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2824 if (lang_hooks.decls.omp_private_outer_ref (val))
2829 case OMP_CLAUSE_REDUCTION:
2831 do_out = !(by_ref || is_reference (val));
2840 ref = build_sender_ref (val, ctx);
2841 x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
2842 gimplify_assign (ref, x, ilist);
2843 if (is_task_ctx (ctx))
2844 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
2849 ref = build_sender_ref (val, ctx);
2850 gimplify_assign (var, ref, olist);
2855 /* Generate code to implement SHARED from the sender (aka parent)
2856 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2857 list things that got automatically shared. */
2860 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
2862 tree var, ovar, nvar, f, x, record_type;
2864 if (ctx->record_type == NULL)
2867 record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
2868 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
2870 ovar = DECL_ABSTRACT_ORIGIN (f);
2871 nvar = maybe_lookup_decl (ovar, ctx);
2872 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2875 /* If CTX is a nested parallel directive. Find the immediately
2876 enclosing parallel or workshare construct that contains a
2877 mapping for OVAR. */
2878 var = lookup_decl_in_outer_ctx (ovar, ctx);
2880 if (use_pointer_for_field (ovar, ctx))
2882 x = build_sender_ref (ovar, ctx);
2883 var = build_fold_addr_expr (var);
2884 gimplify_assign (x, var, ilist);
2888 x = build_sender_ref (ovar, ctx);
2889 gimplify_assign (x, var, ilist);
2891 if (!TREE_READONLY (var)
2892 /* We don't need to receive a new reference to a result
2893 or parm decl. In fact we may not store to it as we will
2894 invalidate any pending RSO and generate wrong gimple
2896 && !((TREE_CODE (var) == RESULT_DECL
2897 || TREE_CODE (var) == PARM_DECL)
2898 && DECL_BY_REFERENCE (var)))
2900 x = build_sender_ref (ovar, ctx);
2901 gimplify_assign (var, x, olist);
2908 /* A convenience function to build an empty GIMPLE_COND with just the
2912 gimple_build_cond_empty (tree cond)
2914 enum tree_code pred_code;
2917 gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
2918 return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
2922 /* Build the function calls to GOMP_parallel_start etc to actually
2923 generate the parallel operation. REGION is the parallel region
2924 being expanded. BB is the block where to insert the code. WS_ARGS
2925 will be set if this is a call to a combined parallel+workshare
2926 construct, it contains the list of additional arguments needed by
2927 the workshare construct. */
2930 expand_parallel_call (struct omp_region *region, basic_block bb,
2931 gimple entry_stmt, VEC(tree,gc) *ws_args)
2933 tree t, t1, t2, val, cond, c, clauses;
2934 gimple_stmt_iterator gsi;
2936 enum built_in_function start_ix;
2938 location_t clause_loc;
2941 clauses = gimple_omp_parallel_clauses (entry_stmt);
2943 /* Determine what flavor of GOMP_parallel_start we will be
2945 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2946 if (is_combined_parallel (region))
2948 switch (region->inner->type)
2950 case GIMPLE_OMP_FOR:
2951 gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
2952 start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2953 + (region->inner->sched_kind
2954 == OMP_CLAUSE_SCHEDULE_RUNTIME
2955 ? 3 : region->inner->sched_kind));
2956 start_ix = (enum built_in_function)start_ix2;
2958 case GIMPLE_OMP_SECTIONS:
2959 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2966 /* By default, the value of NUM_THREADS is zero (selected at run time)
2967 and there is no conditional. */
2969 val = build_int_cst (unsigned_type_node, 0);
2971 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2973 cond = OMP_CLAUSE_IF_EXPR (c);
2975 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2978 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2979 clause_loc = OMP_CLAUSE_LOCATION (c);
2982 clause_loc = gimple_location (entry_stmt);
2984 /* Ensure 'val' is of the correct type. */
2985 val = fold_convert_loc (clause_loc, unsigned_type_node, val);
2987 /* If we found the clause 'if (cond)', build either
2988 (cond != 0) or (cond ? val : 1u). */
2991 gimple_stmt_iterator gsi;
2993 cond = gimple_boolify (cond);
2995 if (integer_zerop (val))
2996 val = fold_build2_loc (clause_loc,
2997 EQ_EXPR, unsigned_type_node, cond,
2998 build_int_cst (TREE_TYPE (cond), 0));
3001 basic_block cond_bb, then_bb, else_bb;
3002 edge e, e_then, e_else;
3003 tree tmp_then, tmp_else, tmp_join, tmp_var;
3005 tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
3006 if (gimple_in_ssa_p (cfun))
3008 tmp_then = make_ssa_name (tmp_var, NULL);
3009 tmp_else = make_ssa_name (tmp_var, NULL);
3010 tmp_join = make_ssa_name (tmp_var, NULL);
3019 e = split_block (bb, NULL);
3024 then_bb = create_empty_bb (cond_bb);
3025 else_bb = create_empty_bb (then_bb);
3026 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
3027 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
3029 stmt = gimple_build_cond_empty (cond);
3030 gsi = gsi_start_bb (cond_bb);
3031 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3033 gsi = gsi_start_bb (then_bb);
3034 stmt = gimple_build_assign (tmp_then, val);
3035 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3037 gsi = gsi_start_bb (else_bb);
3038 stmt = gimple_build_assign
3039 (tmp_else, build_int_cst (unsigned_type_node, 1));
3040 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3042 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
3043 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
3044 e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
3045 e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
3047 if (gimple_in_ssa_p (cfun))
3049 gimple phi = create_phi_node (tmp_join, bb);
3050 SSA_NAME_DEF_STMT (tmp_join) = phi;
3051 add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
3052 add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
3058 gsi = gsi_start_bb (bb);
3059 val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
3060 false, GSI_CONTINUE_LINKING);
3063 gsi = gsi_last_bb (bb);
3064 t = gimple_omp_parallel_data_arg (entry_stmt);
3066 t1 = null_pointer_node;
3068 t1 = build_fold_addr_expr (t);
3069 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
3071 args = VEC_alloc (tree, gc, 3 + VEC_length (tree, ws_args));
3072 VEC_quick_push (tree, args, t2);
3073 VEC_quick_push (tree, args, t1);
3074 VEC_quick_push (tree, args, val);
3075 VEC_splice (tree, args, ws_args);
3077 t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
3078 builtin_decl_explicit (start_ix), args);
3080 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3081 false, GSI_CONTINUE_LINKING);
3083 t = gimple_omp_parallel_data_arg (entry_stmt);
3085 t = null_pointer_node;
3087 t = build_fold_addr_expr (t);
3088 t = build_call_expr_loc (gimple_location (entry_stmt),
3089 gimple_omp_parallel_child_fn (entry_stmt), 1, t);
3090 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3091 false, GSI_CONTINUE_LINKING);
3093 t = build_call_expr_loc (gimple_location (entry_stmt),
3094 builtin_decl_explicit (BUILT_IN_GOMP_PARALLEL_END),
3096 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3097 false, GSI_CONTINUE_LINKING);
3101 /* Build the function call to GOMP_task to actually
3102 generate the task operation. BB is the block where to insert the code. */
3105 expand_task_call (basic_block bb, gimple entry_stmt)
3107 tree t, t1, t2, t3, flags, cond, c, c2, clauses;
3108 gimple_stmt_iterator gsi;
3109 location_t loc = gimple_location (entry_stmt);
3111 clauses = gimple_omp_task_clauses (entry_stmt);
3113 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
3115 cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
3117 cond = boolean_true_node;
3119 c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
3120 c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
3121 flags = build_int_cst (unsigned_type_node,
3122 (c ? 1 : 0) + (c2 ? 4 : 0));
3124 c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
3127 c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
3128 c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
3129 build_int_cst (unsigned_type_node, 2),
3130 build_int_cst (unsigned_type_node, 0));
3131 flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
3134 gsi = gsi_last_bb (bb);
3135 t = gimple_omp_task_data_arg (entry_stmt);
3137 t2 = null_pointer_node;
3139 t2 = build_fold_addr_expr_loc (loc, t);
3140 t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
3141 t = gimple_omp_task_copy_fn (entry_stmt);
3143 t3 = null_pointer_node;
3145 t3 = build_fold_addr_expr_loc (loc, t);
3147 t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
3149 gimple_omp_task_arg_size (entry_stmt),
3150 gimple_omp_task_arg_align (entry_stmt), cond, flags);
3152 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3153 false, GSI_CONTINUE_LINKING);
3157 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3158 catch handler and return it. This prevents programs from violating the
3159 structured block semantics with throws. */
3162 maybe_catch_exception (gimple_seq body)
3167 if (!flag_exceptions)
3170 if (lang_hooks.eh_protect_cleanup_actions != NULL)
3171 decl = lang_hooks.eh_protect_cleanup_actions ();
3173 decl = builtin_decl_explicit (BUILT_IN_TRAP);
3175 g = gimple_build_eh_must_not_throw (decl);
3176 g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
3179 return gimple_seq_alloc_with_stmt (g);
3182 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3185 vec2chain (VEC(tree,gc) *v)
3187 tree chain = NULL_TREE, t;
3190 FOR_EACH_VEC_ELT_REVERSE (tree, v, ix, t)
3192 DECL_CHAIN (t) = chain;
3200 /* Remove barriers in REGION->EXIT's block. Note that this is only
3201 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3202 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3203 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3207 remove_exit_barrier (struct omp_region *region)
3209 gimple_stmt_iterator gsi;
3210 basic_block exit_bb;
3214 int any_addressable_vars = -1;
3216 exit_bb = region->exit;
3218 /* If the parallel region doesn't return, we don't have REGION->EXIT
3223 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3224 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3225 statements that can appear in between are extremely limited -- no
3226 memory operations at all. Here, we allow nothing at all, so the
3227 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3228 gsi = gsi_last_bb (exit_bb);
3229 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3231 if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
3234 FOR_EACH_EDGE (e, ei, exit_bb->preds)
3236 gsi = gsi_last_bb (e->src);
3237 if (gsi_end_p (gsi))
3239 stmt = gsi_stmt (gsi);
3240 if (gimple_code (stmt) == GIMPLE_OMP_RETURN
3241 && !gimple_omp_return_nowait_p (stmt))
3243 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3244 in many cases. If there could be tasks queued, the barrier
3245 might be needed to let the tasks run before some local
3246 variable of the parallel that the task uses as shared
3247 runs out of scope. The task can be spawned either
3248 from within current function (this would be easy to check)
3249 or from some function it calls and gets passed an address
3250 of such a variable. */
3251 if (any_addressable_vars < 0)
3253 gimple parallel_stmt = last_stmt (region->entry);
3254 tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
3255 tree local_decls, block, decl;
3258 any_addressable_vars = 0;
3259 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
3260 if (TREE_ADDRESSABLE (decl))
3262 any_addressable_vars = 1;
3265 for (block = gimple_block (stmt);
3266 !any_addressable_vars
3268 && TREE_CODE (block) == BLOCK;
3269 block = BLOCK_SUPERCONTEXT (block))
3271 for (local_decls = BLOCK_VARS (block);
3273 local_decls = DECL_CHAIN (local_decls))
3274 if (TREE_ADDRESSABLE (local_decls))
3276 any_addressable_vars = 1;
3279 if (block == gimple_block (parallel_stmt))
3283 if (!any_addressable_vars)
3284 gimple_omp_return_set_nowait (stmt);
3290 remove_exit_barriers (struct omp_region *region)
3292 if (region->type == GIMPLE_OMP_PARALLEL)
3293 remove_exit_barrier (region);
3297 region = region->inner;
3298 remove_exit_barriers (region);
3299 while (region->next)
3301 region = region->next;
3302 remove_exit_barriers (region);
3307 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3308 calls. These can't be declared as const functions, but
3309 within one parallel body they are constant, so they can be
3310 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3311 which are declared const. Similarly for task body, except
3312 that in untied task omp_get_thread_num () can change at any task
3313 scheduling point. */
3316 optimize_omp_library_calls (gimple entry_stmt)
3319 gimple_stmt_iterator gsi;
3320 tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3321 tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
3322 tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3323 tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
3324 bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
3325 && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
3326 OMP_CLAUSE_UNTIED) != NULL);
3329 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3331 gimple call = gsi_stmt (gsi);
3334 if (is_gimple_call (call)
3335 && (decl = gimple_call_fndecl (call))
3336 && DECL_EXTERNAL (decl)
3337 && TREE_PUBLIC (decl)
3338 && DECL_INITIAL (decl) == NULL)
3342 if (DECL_NAME (decl) == thr_num_id)
3344 /* In #pragma omp task untied omp_get_thread_num () can change
3345 during the execution of the task region. */
3348 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3350 else if (DECL_NAME (decl) == num_thr_id)
3351 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3355 if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
3356 || gimple_call_num_args (call) != 0)
3359 if (flag_exceptions && !TREE_NOTHROW (decl))
3362 if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
3363 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
3364 TREE_TYPE (TREE_TYPE (built_in))))
3367 gimple_call_set_fndecl (call, built_in);
3372 /* Expand the OpenMP parallel or task directive starting at REGION. */
3375 expand_omp_taskreg (struct omp_region *region)
3377 basic_block entry_bb, exit_bb, new_bb;
3378 struct function *child_cfun;
3379 tree child_fn, block, t;
3381 gimple_stmt_iterator gsi;
3382 gimple entry_stmt, stmt;
3384 VEC(tree,gc) *ws_args;
3386 entry_stmt = last_stmt (region->entry);
3387 child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
3388 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
3389 /* If this function has been already instrumented, make sure
3390 the child function isn't instrumented again. */
3391 child_cfun->after_tree_profile = cfun->after_tree_profile;
3393 entry_bb = region->entry;
3394 exit_bb = region->exit;
3396 if (is_combined_parallel (region))
3397 ws_args = region->ws_args;
3401 if (child_cfun->cfg)
3403 /* Due to inlining, it may happen that we have already outlined
3404 the region, in which case all we need to do is make the
3405 sub-graph unreachable and emit the parallel call. */
3406 edge entry_succ_e, exit_succ_e;
3407 gimple_stmt_iterator gsi;
3409 entry_succ_e = single_succ_edge (entry_bb);
3411 gsi = gsi_last_bb (entry_bb);
3412 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
3413 || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
3414 gsi_remove (&gsi, true);
3419 exit_succ_e = single_succ_edge (exit_bb);
3420 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
3422 remove_edge_and_dominated_blocks (entry_succ_e);
3426 unsigned srcidx, dstidx, num;
3428 /* If the parallel region needs data sent from the parent
3429 function, then the very first statement (except possible
3430 tree profile counter updates) of the parallel body
3431 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3432 &.OMP_DATA_O is passed as an argument to the child function,
3433 we need to replace it with the argument as seen by the child
3436 In most cases, this will end up being the identity assignment
3437 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3438 a function call that has been inlined, the original PARM_DECL
3439 .OMP_DATA_I may have been converted into a different local
3440 variable. In which case, we need to keep the assignment. */
3441 if (gimple_omp_taskreg_data_arg (entry_stmt))
3443 basic_block entry_succ_bb = single_succ (entry_bb);
3444 gimple_stmt_iterator gsi;
3446 gimple parcopy_stmt = NULL;
3448 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
3452 gcc_assert (!gsi_end_p (gsi));
3453 stmt = gsi_stmt (gsi);
3454 if (gimple_code (stmt) != GIMPLE_ASSIGN)
3457 if (gimple_num_ops (stmt) == 2)
3459 tree arg = gimple_assign_rhs1 (stmt);
3461 /* We're ignore the subcode because we're
3462 effectively doing a STRIP_NOPS. */
3464 if (TREE_CODE (arg) == ADDR_EXPR
3465 && TREE_OPERAND (arg, 0)
3466 == gimple_omp_taskreg_data_arg (entry_stmt))
3468 parcopy_stmt = stmt;
3474 gcc_assert (parcopy_stmt != NULL);
3475 arg = DECL_ARGUMENTS (child_fn);
3477 if (!gimple_in_ssa_p (cfun))
3479 if (gimple_assign_lhs (parcopy_stmt) == arg)
3480 gsi_remove (&gsi, true);
3483 /* ?? Is setting the subcode really necessary ?? */
3484 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
3485 gimple_assign_set_rhs1 (parcopy_stmt, arg);
3490 /* If we are in ssa form, we must load the value from the default
3491 definition of the argument. That should not be defined now,
3492 since the argument is not used uninitialized. */
3493 gcc_assert (gimple_default_def (cfun, arg) == NULL);
3494 narg = make_ssa_name (arg, gimple_build_nop ());
3495 set_default_def (arg, narg);
3496 /* ?? Is setting the subcode really necessary ?? */
3497 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
3498 gimple_assign_set_rhs1 (parcopy_stmt, narg);
3499 update_stmt (parcopy_stmt);
3503 /* Declare local variables needed in CHILD_CFUN. */
3504 block = DECL_INITIAL (child_fn);
3505 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
3506 /* The gimplifier could record temporaries in parallel/task block
3507 rather than in containing function's local_decls chain,
3508 which would mean cgraph missed finalizing them. Do it now. */
3509 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
3510 if (TREE_CODE (t) == VAR_DECL
3512 && !DECL_EXTERNAL (t))
3513 varpool_finalize_decl (t);
3514 DECL_SAVED_TREE (child_fn) = NULL;
3515 gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
3516 TREE_USED (block) = 1;
3518 /* Reset DECL_CONTEXT on function arguments. */
3519 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
3520 DECL_CONTEXT (t) = child_fn;
3522 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3523 so that it can be moved to the child function. */
3524 gsi = gsi_last_bb (entry_bb);
3525 stmt = gsi_stmt (gsi);
3526 gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
3527 || gimple_code (stmt) == GIMPLE_OMP_TASK));
3528 gsi_remove (&gsi, true);
3529 e = split_block (entry_bb, stmt);
3531 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3533 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3536 gsi = gsi_last_bb (exit_bb);
3537 gcc_assert (!gsi_end_p (gsi)
3538 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3539 stmt = gimple_build_return (NULL);
3540 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
3541 gsi_remove (&gsi, true);
3544 /* Move the parallel region into CHILD_CFUN. */
3546 if (gimple_in_ssa_p (cfun))
3548 push_cfun (child_cfun);
3549 init_tree_ssa (child_cfun);
3550 init_ssa_operands ();
3551 cfun->gimple_df->in_ssa_p = true;
3556 block = gimple_block (entry_stmt);
3558 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
3560 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
3562 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3563 num = VEC_length (tree, child_cfun->local_decls);
3564 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
3566 t = VEC_index (tree, child_cfun->local_decls, srcidx);
3567 if (DECL_CONTEXT (t) == cfun->decl)
3569 if (srcidx != dstidx)
3570 VEC_replace (tree, child_cfun->local_decls, dstidx, t);
3574 VEC_truncate (tree, child_cfun->local_decls, dstidx);
3576 /* Inform the callgraph about the new function. */
3577 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
3578 = cfun->curr_properties;
3579 cgraph_add_new_function (child_fn, true);
3581 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3582 fixed in a following pass. */
3583 push_cfun (child_cfun);
3584 save_current = current_function_decl;
3585 current_function_decl = child_fn;
3587 optimize_omp_library_calls (entry_stmt);
3588 rebuild_cgraph_edges ();
3590 /* Some EH regions might become dead, see PR34608. If
3591 pass_cleanup_cfg isn't the first pass to happen with the
3592 new child, these dead EH edges might cause problems.
3593 Clean them up now. */
3594 if (flag_exceptions)
3597 bool changed = false;
3600 changed |= gimple_purge_dead_eh_edges (bb);
3602 cleanup_tree_cfg ();
3604 if (gimple_in_ssa_p (cfun))
3605 update_ssa (TODO_update_ssa);
3606 current_function_decl = save_current;
3610 /* Emit a library call to launch the children threads. */
3611 if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
3612 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
3614 expand_task_call (new_bb, entry_stmt);
3615 update_ssa (TODO_update_ssa_only_virtuals);
3619 /* A subroutine of expand_omp_for. Generate code for a parallel
3620 loop with any schedule. Given parameters:
3622 for (V = N1; V cond N2; V += STEP) BODY;
3624 where COND is "<" or ">", we generate pseudocode
3626 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3627 if (more) goto L0; else goto L3;
3634 if (V cond iend) goto L1; else goto L2;
3636 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3639 If this is a combined omp parallel loop, instead of the call to
3640 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3642 For collapsed loops, given parameters:
3644 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3645 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3646 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3649 we generate pseudocode
3655 count3 = (adj + N32 - N31) / STEP3;
3660 count2 = (adj + N22 - N21) / STEP2;
3665 count1 = (adj + N12 - N11) / STEP1;
3666 count = count1 * count2 * count3;
3667 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3668 if (more) goto L0; else goto L3;
3672 V3 = N31 + (T % count3) * STEP3;
3674 V2 = N21 + (T % count2) * STEP2;
3676 V1 = N11 + T * STEP1;
3681 if (V < iend) goto L10; else goto L2;
3684 if (V3 cond3 N32) goto L1; else goto L11;
3688 if (V2 cond2 N22) goto L1; else goto L12;
3694 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3700 expand_omp_for_generic (struct omp_region *region,
3701 struct omp_for_data *fd,
3702 enum built_in_function start_fn,
3703 enum built_in_function next_fn)
3705 tree type, istart0, iend0, iend;
3706 tree t, vmain, vback, bias = NULL_TREE;
3707 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
3708 basic_block l2_bb = NULL, l3_bb = NULL;
3709 gimple_stmt_iterator gsi;
3711 bool in_combined_parallel = is_combined_parallel (region);
3712 bool broken_loop = region->cont == NULL;
3714 tree *counts = NULL;
3717 gcc_assert (!broken_loop || !in_combined_parallel);
3718 gcc_assert (fd->iter_type == long_integer_type_node
3719 || !in_combined_parallel);
3721 type = TREE_TYPE (fd->loop.v);
3722 istart0 = create_tmp_var (fd->iter_type, ".istart0");
3723 iend0 = create_tmp_var (fd->iter_type, ".iend0");
3724 TREE_ADDRESSABLE (istart0) = 1;
3725 TREE_ADDRESSABLE (iend0) = 1;
3726 if (gimple_in_ssa_p (cfun))
3728 add_referenced_var (istart0);
3729 add_referenced_var (iend0);
3732 /* See if we need to bias by LLONG_MIN. */
3733 if (fd->iter_type == long_long_unsigned_type_node
3734 && TREE_CODE (type) == INTEGER_TYPE
3735 && !TYPE_UNSIGNED (type))
3739 if (fd->loop.cond_code == LT_EXPR)
3742 n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
3746 n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
3749 if (TREE_CODE (n1) != INTEGER_CST
3750 || TREE_CODE (n2) != INTEGER_CST
3751 || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
3752 bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
3755 entry_bb = region->entry;
3756 cont_bb = region->cont;
3758 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
3759 gcc_assert (broken_loop
3760 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
3761 l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
3762 l1_bb = single_succ (l0_bb);
3765 l2_bb = create_empty_bb (cont_bb);
3766 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
3767 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
3771 l3_bb = BRANCH_EDGE (entry_bb)->dest;
3772 exit_bb = region->exit;
3774 gsi = gsi_last_bb (entry_bb);
3776 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
3777 if (fd->collapse > 1)
3779 /* collapsed loops need work for expansion in SSA form. */
3780 gcc_assert (!gimple_in_ssa_p (cfun));
3781 counts = (tree *) alloca (fd->collapse * sizeof (tree));
3782 for (i = 0; i < fd->collapse; i++)
3784 tree itype = TREE_TYPE (fd->loops[i].v);
3786 if (POINTER_TYPE_P (itype))
3787 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
3788 t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
3790 t = fold_build2 (PLUS_EXPR, itype,
3791 fold_convert (itype, fd->loops[i].step), t);
3792 t = fold_build2 (PLUS_EXPR, itype, t,
3793 fold_convert (itype, fd->loops[i].n2));
3794 t = fold_build2 (MINUS_EXPR, itype, t,
3795 fold_convert (itype, fd->loops[i].n1));
3796 if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
3797 t = fold_build2 (TRUNC_DIV_EXPR, itype,
3798 fold_build1 (NEGATE_EXPR, itype, t),
3799 fold_build1 (NEGATE_EXPR, itype,
3800 fold_convert (itype,
3801 fd->loops[i].step)));
3803 t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
3804 fold_convert (itype, fd->loops[i].step));
3805 t = fold_convert (type, t);
3806 if (TREE_CODE (t) == INTEGER_CST)
3810 counts[i] = create_tmp_var (type, ".count");
3811 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3812 true, GSI_SAME_STMT);
3813 stmt = gimple_build_assign (counts[i], t);
3814 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3816 if (SSA_VAR_P (fd->loop.n2))
3822 t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
3823 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3824 true, GSI_SAME_STMT);
3826 stmt = gimple_build_assign (fd->loop.n2, t);
3827 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3831 if (in_combined_parallel)
3833 /* In a combined parallel loop, emit a call to
3834 GOMP_loop_foo_next. */
3835 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
3836 build_fold_addr_expr (istart0),
3837 build_fold_addr_expr (iend0));
3841 tree t0, t1, t2, t3, t4;
3842 /* If this is not a combined parallel loop, emit a call to
3843 GOMP_loop_foo_start in ENTRY_BB. */
3844 t4 = build_fold_addr_expr (iend0);
3845 t3 = build_fold_addr_expr (istart0);
3846 t2 = fold_convert (fd->iter_type, fd->loop.step);
3847 if (POINTER_TYPE_P (type)
3848 && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
3850 /* Avoid casting pointers to integer of a different size. */
3852 = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
3853 t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
3854 t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
3858 t1 = fold_convert (fd->iter_type, fd->loop.n2);
3859 t0 = fold_convert (fd->iter_type, fd->loop.n1);
3863 t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
3864 t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
3866 if (fd->iter_type == long_integer_type_node)
3870 t = fold_convert (fd->iter_type, fd->chunk_size);
3871 t = build_call_expr (builtin_decl_explicit (start_fn),
3872 6, t0, t1, t2, t, t3, t4);
3875 t = build_call_expr (builtin_decl_explicit (start_fn),
3876 5, t0, t1, t2, t3, t4);
3884 /* The GOMP_loop_ull_*start functions have additional boolean
3885 argument, true for < loops and false for > loops.
3886 In Fortran, the C bool type can be different from
3887 boolean_type_node. */
3888 bfn_decl = builtin_decl_explicit (start_fn);
3889 c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
3890 t5 = build_int_cst (c_bool_type,
3891 fd->loop.cond_code == LT_EXPR ? 1 : 0);
3894 tree bfn_decl = builtin_decl_explicit (start_fn);
3895 t = fold_convert (fd->iter_type, fd->chunk_size);
3896 t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
3899 t = build_call_expr (builtin_decl_explicit (start_fn),
3900 6, t5, t0, t1, t2, t3, t4);
3903 if (TREE_TYPE (t) != boolean_type_node)
3904 t = fold_build2 (NE_EXPR, boolean_type_node,
3905 t, build_int_cst (TREE_TYPE (t), 0));
3906 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3907 true, GSI_SAME_STMT);
3908 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
3910 /* Remove the GIMPLE_OMP_FOR statement. */
3911 gsi_remove (&gsi, true);
3913 /* Iteration setup for sequential loop goes in L0_BB. */
3914 gsi = gsi_start_bb (l0_bb);
3917 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3918 if (POINTER_TYPE_P (type))
3919 t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
3921 t = fold_convert (type, t);
3922 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3923 false, GSI_CONTINUE_LINKING);
3924 stmt = gimple_build_assign (fd->loop.v, t);
3925 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3929 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3930 if (POINTER_TYPE_P (type))
3931 t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
3933 t = fold_convert (type, t);
3934 iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3935 false, GSI_CONTINUE_LINKING);
3936 if (fd->collapse > 1)
3938 tree tem = create_tmp_var (type, ".tem");
3940 stmt = gimple_build_assign (tem, fd->loop.v);
3941 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3942 for (i = fd->collapse - 1; i >= 0; i--)
3944 tree vtype = TREE_TYPE (fd->loops[i].v), itype;
3946 if (POINTER_TYPE_P (vtype))
3947 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (vtype), 0);
3948 t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
3949 t = fold_convert (itype, t);
3950 t = fold_build2 (MULT_EXPR, itype, t,
3951 fold_convert (itype, fd->loops[i].step));
3952 if (POINTER_TYPE_P (vtype))
3953 t = fold_build_pointer_plus (fd->loops[i].n1, t);
3955 t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
3956 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3957 false, GSI_CONTINUE_LINKING);
3958 stmt = gimple_build_assign (fd->loops[i].v, t);
3959 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3962 t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
3963 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3964 false, GSI_CONTINUE_LINKING);
3965 stmt = gimple_build_assign (tem, t);
3966 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3973 /* Code to control the increment and predicate for the sequential
3974 loop goes in the CONT_BB. */
3975 gsi = gsi_last_bb (cont_bb);
3976 stmt = gsi_stmt (gsi);
3977 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
3978 vmain = gimple_omp_continue_control_use (stmt);
3979 vback = gimple_omp_continue_control_def (stmt);
3981 if (POINTER_TYPE_P (type))
3982 t = fold_build_pointer_plus (vmain, fd->loop.step);
3984 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
3985 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3986 true, GSI_SAME_STMT);
3987 stmt = gimple_build_assign (vback, t);
3988 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3990 t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
3991 stmt = gimple_build_cond_empty (t);
3992 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3994 /* Remove GIMPLE_OMP_CONTINUE. */
3995 gsi_remove (&gsi, true);
3997 if (fd->collapse > 1)
3999 basic_block last_bb, bb;
4002 for (i = fd->collapse - 1; i >= 0; i--)
4004 tree vtype = TREE_TYPE (fd->loops[i].v);
4006 bb = create_empty_bb (last_bb);
4007 gsi = gsi_start_bb (bb);
4009 if (i < fd->collapse - 1)
4011 e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
4012 e->probability = REG_BR_PROB_BASE / 8;
4014 t = fd->loops[i + 1].n1;
4015 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4016 false, GSI_CONTINUE_LINKING);
4017 stmt = gimple_build_assign (fd->loops[i + 1].v, t);
4018 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4023 set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
4025 if (POINTER_TYPE_P (vtype))
4026 t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
4028 t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
4030 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4031 false, GSI_CONTINUE_LINKING);
4032 stmt = gimple_build_assign (fd->loops[i].v, t);
4033 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4037 t = fd->loops[i].n2;
4038 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4039 false, GSI_CONTINUE_LINKING);
4040 t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
4042 stmt = gimple_build_cond_empty (t);
4043 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4044 e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
4045 e->probability = REG_BR_PROB_BASE * 7 / 8;
4048 make_edge (bb, l1_bb, EDGE_FALLTHRU);
4053 /* Emit code to get the next parallel iteration in L2_BB. */
4054 gsi = gsi_start_bb (l2_bb);
4056 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
4057 build_fold_addr_expr (istart0),
4058 build_fold_addr_expr (iend0));
4059 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4060 false, GSI_CONTINUE_LINKING);
4061 if (TREE_TYPE (t) != boolean_type_node)
4062 t = fold_build2 (NE_EXPR, boolean_type_node,
4063 t, build_int_cst (TREE_TYPE (t), 0));
4064 stmt = gimple_build_cond_empty (t);
4065 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4068 /* Add the loop cleanup function. */
4069 gsi = gsi_last_bb (exit_bb);
4070 if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4071 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
4073 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
4074 stmt = gimple_build_call (t, 0);
4075 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
4076 gsi_remove (&gsi, true);
4078 /* Connect the new blocks. */
4079 find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
4080 find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
4086 e = find_edge (cont_bb, l3_bb);
4087 ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
4089 phis = phi_nodes (l3_bb);
4090 for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
4092 gimple phi = gsi_stmt (gsi);
4093 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
4094 PHI_ARG_DEF_FROM_EDGE (phi, e));
4098 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
4099 if (fd->collapse > 1)
4101 e = find_edge (cont_bb, l1_bb);
4103 e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
4107 e = find_edge (cont_bb, l1_bb);
4108 e->flags = EDGE_TRUE_VALUE;
4110 e->probability = REG_BR_PROB_BASE * 7 / 8;
4111 find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
4112 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
4114 set_immediate_dominator (CDI_DOMINATORS, l2_bb,
4115 recompute_dominator (CDI_DOMINATORS, l2_bb));
4116 set_immediate_dominator (CDI_DOMINATORS, l3_bb,
4117 recompute_dominator (CDI_DOMINATORS, l3_bb));
4118 set_immediate_dominator (CDI_DOMINATORS, l0_bb,
4119 recompute_dominator (CDI_DOMINATORS, l0_bb));
4120 set_immediate_dominator (CDI_DOMINATORS, l1_bb,
4121 recompute_dominator (CDI_DOMINATORS, l1_bb));
4126 /* A subroutine of expand_omp_for. Generate code for a parallel
4127 loop with static schedule and no specified chunk size. Given
4130 for (V = N1; V cond N2; V += STEP) BODY;
4132 where COND is "<" or ">", we generate pseudocode
4138 if ((__typeof (V)) -1 > 0 && cond is >)
4139 n = -(adj + N2 - N1) / -STEP;
4141 n = (adj + N2 - N1) / STEP;
4144 if (threadid < tt) goto L3; else goto L4;
4149 s0 = q * threadid + tt;
4152 if (s0 >= e0) goto L2; else goto L0;
4158 if (V cond e) goto L1;
4163 expand_omp_for_static_nochunk (struct omp_region *region,
4164 struct omp_for_data *fd)
4166 tree n, q, s0, e0, e, t, tt, nthreads, threadid;
4167 tree type, itype, vmain, vback;
4168 basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
4169 basic_block body_bb, cont_bb;
4171 gimple_stmt_iterator gsi;
4175 itype = type = TREE_TYPE (fd->loop.v);
4176 if (POINTER_TYPE_P (type))
4177 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
4179 entry_bb = region->entry;
4180 cont_bb = region->cont;
4181 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
4182 gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
4183 seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
4184 body_bb = single_succ (seq_start_bb);
4185 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4186 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4187 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4188 exit_bb = region->exit;
4190 /* Iteration space partitioning goes in ENTRY_BB. */
4191 gsi = gsi_last_bb (entry_bb);
4192 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4194 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4195 t = fold_convert (itype, t);
4196 nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4197 true, GSI_SAME_STMT);
4199 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4200 t = fold_convert (itype, t);
4201 threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4202 true, GSI_SAME_STMT);
4205 = force_gimple_operand_gsi (&gsi, fold_convert (type, fd->loop.n1),
4206 true, NULL_TREE, true, GSI_SAME_STMT);
4208 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.n2),
4209 true, NULL_TREE, true, GSI_SAME_STMT);
4211 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.step),
4212 true, NULL_TREE, true, GSI_SAME_STMT);
4214 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4215 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4216 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4217 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4218 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4219 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4220 fold_build1 (NEGATE_EXPR, itype, t),
4221 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4223 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4224 t = fold_convert (itype, t);
4225 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4227 q = create_tmp_var (itype, "q");
4228 t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
4229 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4230 gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
4232 tt = create_tmp_var (itype, "tt");
4233 t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
4234 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4235 gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
4237 t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
4238 stmt = gimple_build_cond_empty (t);
4239 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4241 second_bb = split_block (entry_bb, stmt)->dest;
4242 gsi = gsi_last_bb (second_bb);
4243 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4245 gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
4247 stmt = gimple_build_assign_with_ops (PLUS_EXPR, q, q,
4248 build_int_cst (itype, 1));
4249 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4251 third_bb = split_block (second_bb, stmt)->dest;
4252 gsi = gsi_last_bb (third_bb);
4253 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4255 t = build2 (MULT_EXPR, itype, q, threadid);
4256 t = build2 (PLUS_EXPR, itype, t, tt);
4257 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4259 t = fold_build2 (PLUS_EXPR, itype, s0, q);
4260 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4262 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
4263 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4265 /* Remove the GIMPLE_OMP_FOR statement. */
4266 gsi_remove (&gsi, true);
4268 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4269 gsi = gsi_start_bb (seq_start_bb);
4271 t = fold_convert (itype, s0);
4272 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4273 if (POINTER_TYPE_P (type))
4274 t = fold_build_pointer_plus (fd->loop.n1, t);
4276 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4277 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4278 false, GSI_CONTINUE_LINKING);
4279 stmt = gimple_build_assign (fd->loop.v, t);
4280 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4282 t = fold_convert (itype, e0);
4283 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4284 if (POINTER_TYPE_P (type))
4285 t = fold_build_pointer_plus (fd->loop.n1, t);
4287 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4288 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4289 false, GSI_CONTINUE_LINKING);
4291 /* The code controlling the sequential loop replaces the
4292 GIMPLE_OMP_CONTINUE. */
4293 gsi = gsi_last_bb (cont_bb);
4294 stmt = gsi_stmt (gsi);
4295 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4296 vmain = gimple_omp_continue_control_use (stmt);
4297 vback = gimple_omp_continue_control_def (stmt);
4299 if (POINTER_TYPE_P (type))
4300 t = fold_build_pointer_plus (vmain, fd->loop.step);
4302 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
4303 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4304 true, GSI_SAME_STMT);
4305 stmt = gimple_build_assign (vback, t);
4306 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4308 t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
4309 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4311 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4312 gsi_remove (&gsi, true);
4314 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4315 gsi = gsi_last_bb (exit_bb);
4316 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4317 force_gimple_operand_gsi (&gsi, build_omp_barrier (), false, NULL_TREE,
4318 false, GSI_SAME_STMT);
4319 gsi_remove (&gsi, true);
4321 /* Connect all the blocks. */
4322 ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
4323 ep->probability = REG_BR_PROB_BASE / 4 * 3;
4324 ep = find_edge (entry_bb, second_bb);
4325 ep->flags = EDGE_TRUE_VALUE;
4326 ep->probability = REG_BR_PROB_BASE / 4;
4327 find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
4328 find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
4330 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4331 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4333 set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
4334 set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
4335 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
4336 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4337 recompute_dominator (CDI_DOMINATORS, body_bb));
4338 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4339 recompute_dominator (CDI_DOMINATORS, fin_bb));
4343 /* A subroutine of expand_omp_for. Generate code for a parallel
4344 loop with static schedule and a specified chunk size. Given
4347 for (V = N1; V cond N2; V += STEP) BODY;
4349 where COND is "<" or ">", we generate pseudocode
4355 if ((__typeof (V)) -1 > 0 && cond is >)
4356 n = -(adj + N2 - N1) / -STEP;
4358 n = (adj + N2 - N1) / STEP;
4360 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4361 here so that V is defined
4362 if the loop is not entered
4364 s0 = (trip * nthreads + threadid) * CHUNK;
4365 e0 = min(s0 + CHUNK, n);
4366 if (s0 < n) goto L1; else goto L4;
4373 if (V cond e) goto L2; else goto L3;
4381 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
4383 tree n, s0, e0, e, t;
4384 tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
4385 tree type, itype, v_main, v_back, v_extra;
4386 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
4387 basic_block trip_update_bb, cont_bb, fin_bb;
4388 gimple_stmt_iterator si;
4392 itype = type = TREE_TYPE (fd->loop.v);
4393 if (POINTER_TYPE_P (type))
4394 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
4396 entry_bb = region->entry;
4397 se = split_block (entry_bb, last_stmt (entry_bb));
4399 iter_part_bb = se->dest;
4400 cont_bb = region->cont;
4401 gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
4402 gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
4403 == FALLTHRU_EDGE (cont_bb)->dest);
4404 seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
4405 body_bb = single_succ (seq_start_bb);
4406 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4407 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4408 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4409 trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
4410 exit_bb = region->exit;
4412 /* Trip and adjustment setup goes in ENTRY_BB. */
4413 si = gsi_last_bb (entry_bb);
4414 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
4416 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4417 t = fold_convert (itype, t);
4418 nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4419 true, GSI_SAME_STMT);
4421 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4422 t = fold_convert (itype, t);
4423 threadid = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4424 true, GSI_SAME_STMT);
4427 = force_gimple_operand_gsi (&si, fold_convert (type, fd->loop.n1),
4428 true, NULL_TREE, true, GSI_SAME_STMT);
4430 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.n2),
4431 true, NULL_TREE, true, GSI_SAME_STMT);
4433 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.step),
4434 true, NULL_TREE, true, GSI_SAME_STMT);
4436 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->chunk_size),
4437 true, NULL_TREE, true, GSI_SAME_STMT);
4439 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4440 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4441 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4442 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4443 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4444 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4445 fold_build1 (NEGATE_EXPR, itype, t),
4446 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4448 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4449 t = fold_convert (itype, t);
4450 n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4451 true, GSI_SAME_STMT);
4453 trip_var = create_tmp_var (itype, ".trip");
4454 if (gimple_in_ssa_p (cfun))
4456 add_referenced_var (trip_var);
4457 trip_init = make_ssa_name (trip_var, NULL);
4458 trip_main = make_ssa_name (trip_var, NULL);
4459 trip_back = make_ssa_name (trip_var, NULL);
4463 trip_init = trip_var;
4464 trip_main = trip_var;
4465 trip_back = trip_var;
4468 stmt = gimple_build_assign (trip_init, build_int_cst (itype, 0));
4469 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4471 t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
4472 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4473 if (POINTER_TYPE_P (type))
4474 t = fold_build_pointer_plus (fd->loop.n1, t);
4476 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4477 v_extra = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4478 true, GSI_SAME_STMT);
4480 /* Remove the GIMPLE_OMP_FOR. */
4481 gsi_remove (&si, true);
4483 /* Iteration space partitioning goes in ITER_PART_BB. */
4484 si = gsi_last_bb (iter_part_bb);
4486 t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
4487 t = fold_build2 (PLUS_EXPR, itype, t, threadid);
4488 t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
4489 s0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4490 false, GSI_CONTINUE_LINKING);
4492 t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
4493 t = fold_build2 (MIN_EXPR, itype, t, n);
4494 e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4495 false, GSI_CONTINUE_LINKING);
4497 t = build2 (LT_EXPR, boolean_type_node, s0, n);
4498 gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
4500 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4501 si = gsi_start_bb (seq_start_bb);
4503 t = fold_convert (itype, s0);
4504 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4505 if (POINTER_TYPE_P (type))
4506 t = fold_build_pointer_plus (fd->loop.n1, t);
4508 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4509 t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
4510 false, GSI_CONTINUE_LINKING);
4511 stmt = gimple_build_assign (fd->loop.v, t);
4512 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4514 t = fold_convert (itype, e0);
4515 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4516 if (POINTER_TYPE_P (type))
4517 t = fold_build_pointer_plus (fd->loop.n1, t);
4519 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4520 e = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4521 false, GSI_CONTINUE_LINKING);
4523 /* The code controlling the sequential loop goes in CONT_BB,
4524 replacing the GIMPLE_OMP_CONTINUE. */
4525 si = gsi_last_bb (cont_bb);
4526 stmt = gsi_stmt (si);
4527 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4528 v_main = gimple_omp_continue_control_use (stmt);
4529 v_back = gimple_omp_continue_control_def (stmt);
4531 if (POINTER_TYPE_P (type))
4532 t = fold_build_pointer_plus (v_main, fd->loop.step);
4534 t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
4535 stmt = gimple_build_assign (v_back, t);
4536 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4538 t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
4539 gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
4541 /* Remove GIMPLE_OMP_CONTINUE. */
4542 gsi_remove (&si, true);
4544 /* Trip update code goes into TRIP_UPDATE_BB. */
4545 si = gsi_start_bb (trip_update_bb);
4547 t = build_int_cst (itype, 1);
4548 t = build2 (PLUS_EXPR, itype, trip_main, t);
4549 stmt = gimple_build_assign (trip_back, t);
4550 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4552 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4553 si = gsi_last_bb (exit_bb);
4554 if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
4555 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4556 false, GSI_SAME_STMT);
4557 gsi_remove (&si, true);
4559 /* Connect the new blocks. */
4560 find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
4561 find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4563 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4564 find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
4566 redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
4568 if (gimple_in_ssa_p (cfun))
4570 gimple_stmt_iterator psi;
4573 edge_var_map_vector head;
4577 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4578 remove arguments of the phi nodes in fin_bb. We need to create
4579 appropriate phi nodes in iter_part_bb instead. */
4580 se = single_pred_edge (fin_bb);
4581 re = single_succ_edge (trip_update_bb);
4582 head = redirect_edge_var_map_vector (re);
4583 ene = single_succ_edge (entry_bb);
4585 psi = gsi_start_phis (fin_bb);
4586 for (i = 0; !gsi_end_p (psi) && VEC_iterate (edge_var_map, head, i, vm);
4587 gsi_next (&psi), ++i)
4590 source_location locus;
4592 phi = gsi_stmt (psi);
4593 t = gimple_phi_result (phi);
4594 gcc_assert (t == redirect_edge_var_map_result (vm));
4595 nphi = create_phi_node (t, iter_part_bb);
4596 SSA_NAME_DEF_STMT (t) = nphi;
4598 t = PHI_ARG_DEF_FROM_EDGE (phi, se);
4599 locus = gimple_phi_arg_location_from_edge (phi, se);
4601 /* A special case -- fd->loop.v is not yet computed in
4602 iter_part_bb, we need to use v_extra instead. */
4603 if (t == fd->loop.v)
4605 add_phi_arg (nphi, t, ene, locus);
4606 locus = redirect_edge_var_map_location (vm);
4607 add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
4609 gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
4610 redirect_edge_var_map_clear (re);
4613 psi = gsi_start_phis (fin_bb);
4614 if (gsi_end_p (psi))
4616 remove_phi_node (&psi, false);
4619 /* Make phi node for trip. */
4620 phi = create_phi_node (trip_main, iter_part_bb);
4621 SSA_NAME_DEF_STMT (trip_main) = phi;
4622 add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
4624 add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
4628 set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
4629 set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
4630 recompute_dominator (CDI_DOMINATORS, iter_part_bb));
4631 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4632 recompute_dominator (CDI_DOMINATORS, fin_bb));
4633 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
4634 recompute_dominator (CDI_DOMINATORS, seq_start_bb));
4635 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4636 recompute_dominator (CDI_DOMINATORS, body_bb));
4640 /* Expand the OpenMP loop defined by REGION. */
4643 expand_omp_for (struct omp_region *region)
4645 struct omp_for_data fd;
4646 struct omp_for_data_loop *loops;
4649 = (struct omp_for_data_loop *)
4650 alloca (gimple_omp_for_collapse (last_stmt (region->entry))
4651 * sizeof (struct omp_for_data_loop));
4652 extract_omp_for_data (last_stmt (region->entry), &fd, loops);
4653 region->sched_kind = fd.sched_kind;
4655 gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
4656 BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4657 FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4660 gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
4661 BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4662 FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4665 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
4668 && region->cont != NULL)
4670 if (fd.chunk_size == NULL)
4671 expand_omp_for_static_nochunk (region, &fd);
4673 expand_omp_for_static_chunk (region, &fd);
4677 int fn_index, start_ix, next_ix;
4679 if (fd.chunk_size == NULL
4680 && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
4681 fd.chunk_size = integer_zero_node;
4682 gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
4683 fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
4684 ? 3 : fd.sched_kind;
4685 fn_index += fd.have_ordered * 4;
4686 start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
4687 next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
4688 if (fd.iter_type == long_long_unsigned_type_node)
4690 start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4691 - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
4692 next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4693 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
4695 expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
4696 (enum built_in_function) next_ix);
4699 update_ssa (TODO_update_ssa_only_virtuals);
4703 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4705 v = GOMP_sections_start (n);
4722 v = GOMP_sections_next ();
4727 If this is a combined parallel sections, replace the call to
4728 GOMP_sections_start with call to GOMP_sections_next. */
4731 expand_omp_sections (struct omp_region *region)
4733 tree t, u, vin = NULL, vmain, vnext, l2;
4734 VEC (tree,heap) *label_vec;
4736 basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
4737 gimple_stmt_iterator si, switch_si;
4738 gimple sections_stmt, stmt, cont;
4741 struct omp_region *inner;
4743 bool exit_reachable = region->cont != NULL;
4745 gcc_assert (exit_reachable == (region->exit != NULL));
4746 entry_bb = region->entry;
4747 l0_bb = single_succ (entry_bb);
4748 l1_bb = region->cont;
4749 l2_bb = region->exit;
4752 if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
4753 l2 = gimple_block_label (l2_bb);
4756 /* This can happen if there are reductions. */
4757 len = EDGE_COUNT (l0_bb->succs);
4758 gcc_assert (len > 0);
4759 e = EDGE_SUCC (l0_bb, len - 1);
4760 si = gsi_last_bb (e->dest);
4763 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4764 l2 = gimple_block_label (e->dest);
4766 FOR_EACH_EDGE (e, ei, l0_bb->succs)
4768 si = gsi_last_bb (e->dest);
4770 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4772 l2 = gimple_block_label (e->dest);
4777 default_bb = create_empty_bb (l1_bb->prev_bb);
4781 default_bb = create_empty_bb (l0_bb);
4782 l2 = gimple_block_label (default_bb);
4785 /* We will build a switch() with enough cases for all the
4786 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4787 and a default case to abort if something goes wrong. */
4788 len = EDGE_COUNT (l0_bb->succs);
4790 /* Use VEC_quick_push on label_vec throughout, since we know the size
4792 label_vec = VEC_alloc (tree, heap, len);
4794 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4795 GIMPLE_OMP_SECTIONS statement. */
4796 si = gsi_last_bb (entry_bb);
4797 sections_stmt = gsi_stmt (si);
4798 gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
4799 vin = gimple_omp_sections_control (sections_stmt);
4800 if (!is_combined_parallel (region))
4802 /* If we are not inside a combined parallel+sections region,
4803 call GOMP_sections_start. */
4804 t = build_int_cst (unsigned_type_node,
4805 exit_reachable ? len - 1 : len);
4806 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
4807 stmt = gimple_build_call (u, 1, t);
4811 /* Otherwise, call GOMP_sections_next. */
4812 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4813 stmt = gimple_build_call (u, 0);
4815 gimple_call_set_lhs (stmt, vin);
4816 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4817 gsi_remove (&si, true);
4819 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4821 switch_si = gsi_last_bb (l0_bb);
4822 gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
4825 cont = last_stmt (l1_bb);
4826 gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
4827 vmain = gimple_omp_continue_control_use (cont);
4828 vnext = gimple_omp_continue_control_def (cont);
4839 t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
4840 VEC_quick_push (tree, label_vec, t);
4844 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4845 for (inner = region->inner, casei = 1;
4847 inner = inner->next, i++, casei++)
4849 basic_block s_entry_bb, s_exit_bb;
4851 /* Skip optional reduction region. */
4852 if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
4859 s_entry_bb = inner->entry;
4860 s_exit_bb = inner->exit;
4862 t = gimple_block_label (s_entry_bb);
4863 u = build_int_cst (unsigned_type_node, casei);
4864 u = build_case_label (u, NULL, t);
4865 VEC_quick_push (tree, label_vec, u);
4867 si = gsi_last_bb (s_entry_bb);
4868 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
4869 gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
4870 gsi_remove (&si, true);
4871 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
4873 if (s_exit_bb == NULL)
4876 si = gsi_last_bb (s_exit_bb);
4877 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4878 gsi_remove (&si, true);
4880 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
4883 /* Error handling code goes in DEFAULT_BB. */
4884 t = gimple_block_label (default_bb);
4885 u = build_case_label (NULL, NULL, t);
4886 make_edge (l0_bb, default_bb, 0);
4888 stmt = gimple_build_switch_vec (vmain, u, label_vec);
4889 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4890 gsi_remove (&switch_si, true);
4891 VEC_free (tree, heap, label_vec);
4893 si = gsi_start_bb (default_bb);
4894 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
4895 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4901 /* Code to get the next section goes in L1_BB. */
4902 si = gsi_last_bb (l1_bb);
4903 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
4905 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4906 stmt = gimple_build_call (bfn_decl, 0);
4907 gimple_call_set_lhs (stmt, vnext);
4908 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4909 gsi_remove (&si, true);
4911 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
4913 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4914 si = gsi_last_bb (l2_bb);
4915 if (gimple_omp_return_nowait_p (gsi_stmt (si)))
4916 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
4918 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
4919 stmt = gimple_build_call (t, 0);
4920 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4921 gsi_remove (&si, true);
4924 set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
4928 /* Expand code for an OpenMP single directive. We've already expanded
4929 much of the code, here we simply place the GOMP_barrier call. */
4932 expand_omp_single (struct omp_region *region)
4934 basic_block entry_bb, exit_bb;
4935 gimple_stmt_iterator si;
4936 bool need_barrier = false;
4938 entry_bb = region->entry;
4939 exit_bb = region->exit;
4941 si = gsi_last_bb (entry_bb);
4942 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4943 be removed. We need to ensure that the thread that entered the single
4944 does not exit before the data is copied out by the other threads. */
4945 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
4946 OMP_CLAUSE_COPYPRIVATE))
4947 need_barrier = true;
4948 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
4949 gsi_remove (&si, true);
4950 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4952 si = gsi_last_bb (exit_bb);
4953 if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
4954 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4955 false, GSI_SAME_STMT);
4956 gsi_remove (&si, true);
4957 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4961 /* Generic expansion for OpenMP synchronization directives: master,
4962 ordered and critical. All we need to do here is remove the entry
4963 and exit markers for REGION. */
4966 expand_omp_synch (struct omp_region *region)
4968 basic_block entry_bb, exit_bb;
4969 gimple_stmt_iterator si;
4971 entry_bb = region->entry;
4972 exit_bb = region->exit;
4974 si = gsi_last_bb (entry_bb);
4975 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
4976 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
4977 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
4978 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
4979 gsi_remove (&si, true);
4980 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4984 si = gsi_last_bb (exit_bb);
4985 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4986 gsi_remove (&si, true);
4987 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4991 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
4992 operation as a normal volatile load. */
4995 expand_omp_atomic_load (basic_block load_bb, tree addr,
4996 tree loaded_val, int index)
4998 enum built_in_function tmpbase;
4999 gimple_stmt_iterator gsi;
5000 basic_block store_bb;
5003 tree decl, call, type, itype;
5005 gsi = gsi_last_bb (load_bb);
5006 stmt = gsi_stmt (gsi);
5007 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5008 loc = gimple_location (stmt);
5010 /* ??? If the target does not implement atomic_load_optab[mode], and mode
5011 is smaller than word size, then expand_atomic_load assumes that the load
5012 is atomic. We could avoid the builtin entirely in this case. */
5014 tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
5015 decl = builtin_decl_explicit (tmpbase);
5016 if (decl == NULL_TREE)
5019 type = TREE_TYPE (loaded_val);
5020 itype = TREE_TYPE (TREE_TYPE (decl));
5022 call = build_call_expr_loc (loc, decl, 2, addr,
5023 build_int_cst (NULL, MEMMODEL_RELAXED));
5024 if (!useless_type_conversion_p (type, itype))
5025 call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5026 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5028 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5029 gsi_remove (&gsi, true);
5031 store_bb = single_succ (load_bb);
5032 gsi = gsi_last_bb (store_bb);
5033 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5034 gsi_remove (&gsi, true);
5036 if (gimple_in_ssa_p (cfun))
5037 update_ssa (TODO_update_ssa_no_phi);
5042 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5043 operation as a normal volatile store. */
5046 expand_omp_atomic_store (basic_block load_bb, tree addr,
5047 tree loaded_val, tree stored_val, int index)
5049 enum built_in_function tmpbase;
5050 gimple_stmt_iterator gsi;
5051 basic_block store_bb = single_succ (load_bb);
5054 tree decl, call, type, itype;
5055 enum machine_mode imode;
5058 gsi = gsi_last_bb (load_bb);
5059 stmt = gsi_stmt (gsi);
5060 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5062 /* If the load value is needed, then this isn't a store but an exchange. */
5063 exchange = gimple_omp_atomic_need_value_p (stmt);
5065 gsi = gsi_last_bb (store_bb);
5066 stmt = gsi_stmt (gsi);
5067 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
5068 loc = gimple_location (stmt);
5070 /* ??? If the target does not implement atomic_store_optab[mode], and mode
5071 is smaller than word size, then expand_atomic_store assumes that the store
5072 is atomic. We could avoid the builtin entirely in this case. */
5074 tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
5075 tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
5076 decl = builtin_decl_explicit (tmpbase);
5077 if (decl == NULL_TREE)
5080 type = TREE_TYPE (stored_val);
5082 /* Dig out the type of the function's second argument. */
5083 itype = TREE_TYPE (decl);
5084 itype = TYPE_ARG_TYPES (itype);
5085 itype = TREE_CHAIN (itype);
5086 itype = TREE_VALUE (itype);
5087 imode = TYPE_MODE (itype);
5089 if (exchange && !can_atomic_exchange_p (imode, true))
5092 if (!useless_type_conversion_p (itype, type))
5093 stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
5094 call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
5095 build_int_cst (NULL, MEMMODEL_RELAXED));
5098 if (!useless_type_conversion_p (type, itype))
5099 call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5100 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5103 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5104 gsi_remove (&gsi, true);
5106 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
5107 gsi = gsi_last_bb (load_bb);
5108 gsi_remove (&gsi, true);
5110 if (gimple_in_ssa_p (cfun))
5111 update_ssa (TODO_update_ssa_no_phi);
5116 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5117 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
5118 size of the data type, and thus usable to find the index of the builtin
5119 decl. Returns false if the expression is not of the proper form. */
5122 expand_omp_atomic_fetch_op (basic_block load_bb,
5123 tree addr, tree loaded_val,
5124 tree stored_val, int index)
5126 enum built_in_function oldbase, newbase, tmpbase;
5127 tree decl, itype, call;
5129 basic_block store_bb = single_succ (load_bb);
5130 gimple_stmt_iterator gsi;
5133 enum tree_code code;
5134 bool need_old, need_new;
5135 enum machine_mode imode;
5137 /* We expect to find the following sequences:
5140 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5143 val = tmp OP something; (or: something OP tmp)
5144 GIMPLE_OMP_STORE (val)
5146 ???FIXME: Allow a more flexible sequence.
5147 Perhaps use data flow to pick the statements.
5151 gsi = gsi_after_labels (store_bb);
5152 stmt = gsi_stmt (gsi);
5153 loc = gimple_location (stmt);
5154 if (!is_gimple_assign (stmt))
5157 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
5159 need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
5160 need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
5161 gcc_checking_assert (!need_old || !need_new);
5163 if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
5166 /* Check for one of the supported fetch-op operations. */
5167 code = gimple_assign_rhs_code (stmt);
5171 case POINTER_PLUS_EXPR:
5172 oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
5173 newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
5176 oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
5177 newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
5180 oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
5181 newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
5184 oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
5185 newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
5188 oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
5189 newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
5195 /* Make sure the expression is of the proper form. */
5196 if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
5197 rhs = gimple_assign_rhs2 (stmt);
5198 else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
5199 && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
5200 rhs = gimple_assign_rhs1 (stmt);
5204 tmpbase = ((enum built_in_function)
5205 ((need_new ? newbase : oldbase) + index + 1));
5206 decl = builtin_decl_explicit (tmpbase);
5207 if (decl == NULL_TREE)
5209 itype = TREE_TYPE (TREE_TYPE (decl));
5210 imode = TYPE_MODE (itype);
5212 /* We could test all of the various optabs involved, but the fact of the
5213 matter is that (with the exception of i486 vs i586 and xadd) all targets
5214 that support any atomic operaton optab also implements compare-and-swap.
5215 Let optabs.c take care of expanding any compare-and-swap loop. */
5216 if (!can_compare_and_swap_p (imode, true))
5219 gsi = gsi_last_bb (load_bb);
5220 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
5222 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5223 It only requires that the operation happen atomically. Thus we can
5224 use the RELAXED memory model. */
5225 call = build_call_expr_loc (loc, decl, 3, addr,
5226 fold_convert_loc (loc, itype, rhs),
5227 build_int_cst (NULL, MEMMODEL_RELAXED));
5229 if (need_old || need_new)
5231 lhs = need_old ? loaded_val : stored_val;
5232 call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
5233 call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
5236 call = fold_convert_loc (loc, void_type_node, call);
5237 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5238 gsi_remove (&gsi, true);
5240 gsi = gsi_last_bb (store_bb);
5241 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5242 gsi_remove (&gsi, true);
5243 gsi = gsi_last_bb (store_bb);
5244 gsi_remove (&gsi, true);
5246 if (gimple_in_ssa_p (cfun))
5247 update_ssa (TODO_update_ssa_no_phi);
5252 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5256 newval = rhs; // with oldval replacing *addr in rhs
5257 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5258 if (oldval != newval)
5261 INDEX is log2 of the size of the data type, and thus usable to find the
5262 index of the builtin decl. */
5265 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
5266 tree addr, tree loaded_val, tree stored_val,
5269 tree loadedi, storedi, initial, new_storedi, old_vali;
5270 tree type, itype, cmpxchg, iaddr;
5271 gimple_stmt_iterator si;
5272 basic_block loop_header = single_succ (load_bb);
5275 enum built_in_function fncode;
5277 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5278 order to use the RELAXED memory model effectively. */
5279 fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5281 cmpxchg = builtin_decl_explicit (fncode);
5282 if (cmpxchg == NULL_TREE)
5284 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5285 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5287 if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
5290 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5291 si = gsi_last_bb (load_bb);
5292 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5294 /* For floating-point values, we'll need to view-convert them to integers
5295 so that we can perform the atomic compare and swap. Simplify the
5296 following code by always setting up the "i"ntegral variables. */
5297 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
5301 iaddr = create_tmp_var (build_pointer_type_for_mode (itype, ptr_mode,
5304 = force_gimple_operand_gsi (&si,
5305 fold_convert (TREE_TYPE (iaddr), addr),
5306 false, NULL_TREE, true, GSI_SAME_STMT);
5307 stmt = gimple_build_assign (iaddr, iaddr_val);
5308 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5309 loadedi = create_tmp_var (itype, NULL);
5310 if (gimple_in_ssa_p (cfun))
5312 add_referenced_var (iaddr);
5313 add_referenced_var (loadedi);
5314 loadedi = make_ssa_name (loadedi, NULL);
5320 loadedi = loaded_val;
5324 = force_gimple_operand_gsi (&si,
5325 build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
5327 build_int_cst (TREE_TYPE (iaddr), 0)),
5328 true, NULL_TREE, true, GSI_SAME_STMT);
5330 /* Move the value to the LOADEDI temporary. */
5331 if (gimple_in_ssa_p (cfun))
5333 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
5334 phi = create_phi_node (loadedi, loop_header);
5335 SSA_NAME_DEF_STMT (loadedi) = phi;
5336 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
5340 gsi_insert_before (&si,
5341 gimple_build_assign (loadedi, initial),
5343 if (loadedi != loaded_val)
5345 gimple_stmt_iterator gsi2;
5348 x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
5349 gsi2 = gsi_start_bb (loop_header);
5350 if (gimple_in_ssa_p (cfun))
5353 x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5354 true, GSI_SAME_STMT);
5355 stmt = gimple_build_assign (loaded_val, x);
5356 gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
5360 x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
5361 force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5362 true, GSI_SAME_STMT);
5365 gsi_remove (&si, true);
5367 si = gsi_last_bb (store_bb);
5368 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5371 storedi = stored_val;
5374 force_gimple_operand_gsi (&si,
5375 build1 (VIEW_CONVERT_EXPR, itype,
5376 stored_val), true, NULL_TREE, true,
5379 /* Build the compare&swap statement. */
5380 new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
5381 new_storedi = force_gimple_operand_gsi (&si,
5382 fold_convert (TREE_TYPE (loadedi),
5385 true, GSI_SAME_STMT);
5387 if (gimple_in_ssa_p (cfun))
5391 old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
5392 if (gimple_in_ssa_p (cfun))
5393 add_referenced_var (old_vali);
5394 stmt = gimple_build_assign (old_vali, loadedi);
5395 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5397 stmt = gimple_build_assign (loadedi, new_storedi);
5398 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5401 /* Note that we always perform the comparison as an integer, even for
5402 floating point. This allows the atomic operation to properly
5403 succeed even with NaNs and -0.0. */
5404 stmt = gimple_build_cond_empty
5405 (build2 (NE_EXPR, boolean_type_node,
5406 new_storedi, old_vali));
5407 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5410 e = single_succ_edge (store_bb);
5411 e->flags &= ~EDGE_FALLTHRU;
5412 e->flags |= EDGE_FALSE_VALUE;
5414 e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
5416 /* Copy the new value to loadedi (we already did that before the condition
5417 if we are not in SSA). */
5418 if (gimple_in_ssa_p (cfun))
5420 phi = gimple_seq_first_stmt (phi_nodes (loop_header));
5421 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
5424 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5425 gsi_remove (&si, true);
5427 if (gimple_in_ssa_p (cfun))
5428 update_ssa (TODO_update_ssa_no_phi);
5433 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5435 GOMP_atomic_start ();
5439 The result is not globally atomic, but works so long as all parallel
5440 references are within #pragma omp atomic directives. According to
5441 responses received from omp@openmp.org, appears to be within spec.
5442 Which makes sense, since that's how several other compilers handle
5443 this situation as well.
5444 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5445 expanding. STORED_VAL is the operand of the matching
5446 GIMPLE_OMP_ATOMIC_STORE.
5449 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5453 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
5458 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
5459 tree addr, tree loaded_val, tree stored_val)
5461 gimple_stmt_iterator si;
5465 si = gsi_last_bb (load_bb);
5466 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5468 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
5469 t = build_call_expr (t, 0);
5470 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5472 stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
5473 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5474 gsi_remove (&si, true);
5476 si = gsi_last_bb (store_bb);
5477 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5479 stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
5481 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5483 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
5484 t = build_call_expr (t, 0);
5485 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5486 gsi_remove (&si, true);
5488 if (gimple_in_ssa_p (cfun))
5489 update_ssa (TODO_update_ssa_no_phi);
5493 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5494 using expand_omp_atomic_fetch_op. If it failed, we try to
5495 call expand_omp_atomic_pipeline, and if it fails too, the
5496 ultimate fallback is wrapping the operation in a mutex
5497 (expand_omp_atomic_mutex). REGION is the atomic region built
5498 by build_omp_regions_1(). */
5501 expand_omp_atomic (struct omp_region *region)
5503 basic_block load_bb = region->entry, store_bb = region->exit;
5504 gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
5505 tree loaded_val = gimple_omp_atomic_load_lhs (load);
5506 tree addr = gimple_omp_atomic_load_rhs (load);
5507 tree stored_val = gimple_omp_atomic_store_val (store);
5508 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5509 HOST_WIDE_INT index;
5511 /* Make sure the type is one of the supported sizes. */
5512 index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5513 index = exact_log2 (index);
5514 if (index >= 0 && index <= 4)
5516 unsigned int align = TYPE_ALIGN_UNIT (type);
5518 /* __sync builtins require strict data alignment. */
5519 if (exact_log2 (align) >= index)
5522 if (loaded_val == stored_val
5523 && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5524 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5525 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5526 && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
5530 if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5531 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5532 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5533 && store_bb == single_succ (load_bb)
5534 && first_stmt (store_bb) == store
5535 && expand_omp_atomic_store (load_bb, addr, loaded_val,
5539 /* When possible, use specialized atomic update functions. */
5540 if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5541 && store_bb == single_succ (load_bb)
5542 && expand_omp_atomic_fetch_op (load_bb, addr,
5543 loaded_val, stored_val, index))
5546 /* If we don't have specialized __sync builtins, try and implement
5547 as a compare and swap loop. */
5548 if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
5549 loaded_val, stored_val, index))
5554 /* The ultimate fallback is wrapping the operation in a mutex. */
5555 expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
5559 /* Expand the parallel region tree rooted at REGION. Expansion
5560 proceeds in depth-first order. Innermost regions are expanded
5561 first. This way, parallel regions that require a new function to
5562 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5563 internal dependencies in their body. */
5566 expand_omp (struct omp_region *region)
5570 location_t saved_location;
5572 /* First, determine whether this is a combined parallel+workshare
5574 if (region->type == GIMPLE_OMP_PARALLEL)
5575 determine_parallel_type (region);
5578 expand_omp (region->inner);
5580 saved_location = input_location;
5581 if (gimple_has_location (last_stmt (region->entry)))
5582 input_location = gimple_location (last_stmt (region->entry));
5584 switch (region->type)
5586 case GIMPLE_OMP_PARALLEL:
5587 case GIMPLE_OMP_TASK:
5588 expand_omp_taskreg (region);
5591 case GIMPLE_OMP_FOR:
5592 expand_omp_for (region);
5595 case GIMPLE_OMP_SECTIONS:
5596 expand_omp_sections (region);
5599 case GIMPLE_OMP_SECTION:
5600 /* Individual omp sections are handled together with their
5601 parent GIMPLE_OMP_SECTIONS region. */
5604 case GIMPLE_OMP_SINGLE:
5605 expand_omp_single (region);
5608 case GIMPLE_OMP_MASTER:
5609 case GIMPLE_OMP_ORDERED:
5610 case GIMPLE_OMP_CRITICAL:
5611 expand_omp_synch (region);
5614 case GIMPLE_OMP_ATOMIC_LOAD:
5615 expand_omp_atomic (region);
5622 input_location = saved_location;
5623 region = region->next;
5628 /* Helper for build_omp_regions. Scan the dominator tree starting at
5629 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5630 true, the function ends once a single tree is built (otherwise, whole
5631 forest of OMP constructs may be built). */
5634 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
5637 gimple_stmt_iterator gsi;
5641 gsi = gsi_last_bb (bb);
5642 if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
5644 struct omp_region *region;
5645 enum gimple_code code;
5647 stmt = gsi_stmt (gsi);
5648 code = gimple_code (stmt);
5649 if (code == GIMPLE_OMP_RETURN)
5651 /* STMT is the return point out of region PARENT. Mark it
5652 as the exit point and make PARENT the immediately
5653 enclosing region. */
5654 gcc_assert (parent);
5657 parent = parent->outer;
5659 else if (code == GIMPLE_OMP_ATOMIC_STORE)
5661 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5662 GIMPLE_OMP_RETURN, but matches with
5663 GIMPLE_OMP_ATOMIC_LOAD. */
5664 gcc_assert (parent);
5665 gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
5668 parent = parent->outer;
5671 else if (code == GIMPLE_OMP_CONTINUE)
5673 gcc_assert (parent);
5676 else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
5678 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5679 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5684 /* Otherwise, this directive becomes the parent for a new
5686 region = new_omp_region (bb, code, parent);
5691 if (single_tree && !parent)
5694 for (son = first_dom_son (CDI_DOMINATORS, bb);
5696 son = next_dom_son (CDI_DOMINATORS, son))
5697 build_omp_regions_1 (son, parent, single_tree);
5700 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5704 build_omp_regions_root (basic_block root)
5706 gcc_assert (root_omp_region == NULL);
5707 build_omp_regions_1 (root, NULL, true);
5708 gcc_assert (root_omp_region != NULL);
5711 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5714 omp_expand_local (basic_block head)
5716 build_omp_regions_root (head);
5717 if (dump_file && (dump_flags & TDF_DETAILS))
5719 fprintf (dump_file, "\nOMP region tree\n\n");
5720 dump_omp_region (dump_file, root_omp_region, 0);
5721 fprintf (dump_file, "\n");
5724 remove_exit_barriers (root_omp_region);
5725 expand_omp (root_omp_region);
5727 free_omp_regions ();
5730 /* Scan the CFG and build a tree of OMP regions. Return the root of
5731 the OMP region tree. */
5734 build_omp_regions (void)
5736 gcc_assert (root_omp_region == NULL);
5737 calculate_dominance_info (CDI_DOMINATORS);
5738 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
5741 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5744 execute_expand_omp (void)
5746 build_omp_regions ();
5748 if (!root_omp_region)
5753 fprintf (dump_file, "\nOMP region tree\n\n");
5754 dump_omp_region (dump_file, root_omp_region, 0);
5755 fprintf (dump_file, "\n");
5758 remove_exit_barriers (root_omp_region);
5760 expand_omp (root_omp_region);
5762 cleanup_tree_cfg ();
5764 free_omp_regions ();
5769 /* OMP expansion -- the default pass, run before creation of SSA form. */
5772 gate_expand_omp (void)
5774 return (flag_openmp != 0 && !seen_error ());
5777 struct gimple_opt_pass pass_expand_omp =
5781 "ompexp", /* name */
5782 gate_expand_omp, /* gate */
5783 execute_expand_omp, /* execute */
5786 0, /* static_pass_number */
5787 TV_NONE, /* tv_id */
5788 PROP_gimple_any, /* properties_required */
5789 0, /* properties_provided */
5790 0, /* properties_destroyed */
5791 0, /* todo_flags_start */
5792 0 /* todo_flags_finish */
5796 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5798 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5799 CTX is the enclosing OMP context for the current statement. */
5802 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5804 tree block, control;
5805 gimple_stmt_iterator tgsi;
5807 gimple stmt, new_stmt, bind, t;
5808 gimple_seq ilist, dlist, olist, new_body, body;
5809 struct gimplify_ctx gctx;
5811 stmt = gsi_stmt (*gsi_p);
5813 push_gimplify_context (&gctx);
5817 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5818 &ilist, &dlist, ctx);
5820 tgsi = gsi_start (gimple_omp_body (stmt));
5821 for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
5824 tgsi = gsi_start (gimple_omp_body (stmt));
5826 for (i = 0; i < len; i++, gsi_next (&tgsi))
5831 sec_start = gsi_stmt (tgsi);
5832 sctx = maybe_lookup_ctx (sec_start);
5835 gimple_seq_add_stmt (&body, sec_start);
5837 lower_omp (gimple_omp_body (sec_start), sctx);
5838 gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
5839 gimple_omp_set_body (sec_start, NULL);
5843 gimple_seq l = NULL;
5844 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5846 gimple_seq_add_seq (&body, l);
5847 gimple_omp_section_set_last (sec_start);
5850 gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
5853 block = make_node (BLOCK);
5854 bind = gimple_build_bind (NULL, body, block);
5857 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5859 block = make_node (BLOCK);
5860 new_stmt = gimple_build_bind (NULL, NULL, block);
5862 pop_gimplify_context (new_stmt);
5863 gimple_bind_append_vars (new_stmt, ctx->block_vars);
5864 BLOCK_VARS (block) = gimple_bind_vars (bind);
5865 if (BLOCK_VARS (block))
5866 TREE_USED (block) = 1;
5869 gimple_seq_add_seq (&new_body, ilist);
5870 gimple_seq_add_stmt (&new_body, stmt);
5871 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5872 gimple_seq_add_stmt (&new_body, bind);
5874 control = create_tmp_var (unsigned_type_node, ".section");
5875 t = gimple_build_omp_continue (control, control);
5876 gimple_omp_sections_set_control (stmt, control);
5877 gimple_seq_add_stmt (&new_body, t);
5879 gimple_seq_add_seq (&new_body, olist);
5880 gimple_seq_add_seq (&new_body, dlist);
5882 new_body = maybe_catch_exception (new_body);
5884 t = gimple_build_omp_return
5885 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5886 OMP_CLAUSE_NOWAIT));
5887 gimple_seq_add_stmt (&new_body, t);
5889 gimple_bind_set_body (new_stmt, new_body);
5890 gimple_omp_set_body (stmt, NULL);
5892 gsi_replace (gsi_p, new_stmt, true);
5896 /* A subroutine of lower_omp_single. Expand the simple form of
5897 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5899 if (GOMP_single_start ())
5901 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5903 FIXME. It may be better to delay expanding the logic of this until
5904 pass_expand_omp. The expanded logic may make the job more difficult
5905 to a synchronization analysis pass. */
5908 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5910 location_t loc = gimple_location (single_stmt);
5911 tree tlabel = create_artificial_label (loc);
5912 tree flabel = create_artificial_label (loc);
5916 decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
5917 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5918 call = gimple_build_call (decl, 0);
5919 gimple_call_set_lhs (call, lhs);
5920 gimple_seq_add_stmt (pre_p, call);
5922 cond = gimple_build_cond (EQ_EXPR, lhs,
5923 fold_convert_loc (loc, TREE_TYPE (lhs),
5926 gimple_seq_add_stmt (pre_p, cond);
5927 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5928 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5929 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5933 /* A subroutine of lower_omp_single. Expand the simple form of
5934 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5936 #pragma omp single copyprivate (a, b, c)
5938 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5941 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5947 GOMP_single_copy_end (©out);
5958 FIXME. It may be better to delay expanding the logic of this until
5959 pass_expand_omp. The expanded logic may make the job more difficult
5960 to a synchronization analysis pass. */
5963 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
5965 tree ptr_type, t, l0, l1, l2, bfn_decl;
5966 gimple_seq copyin_seq;
5967 location_t loc = gimple_location (single_stmt);
5969 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
5971 ptr_type = build_pointer_type (ctx->record_type);
5972 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
5974 l0 = create_artificial_label (loc);
5975 l1 = create_artificial_label (loc);
5976 l2 = create_artificial_label (loc);
5978 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
5979 t = build_call_expr_loc (loc, bfn_decl, 0);
5980 t = fold_convert_loc (loc, ptr_type, t);
5981 gimplify_assign (ctx->receiver_decl, t, pre_p);
5983 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
5984 build_int_cst (ptr_type, 0));
5985 t = build3 (COND_EXPR, void_type_node, t,
5986 build_and_jump (&l0), build_and_jump (&l1));
5987 gimplify_and_add (t, pre_p);
5989 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
5991 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5994 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
5997 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
5998 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
5999 t = build_call_expr_loc (loc, bfn_decl, 1, t);
6000 gimplify_and_add (t, pre_p);
6002 t = build_and_jump (&l2);
6003 gimplify_and_add (t, pre_p);
6005 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
6007 gimple_seq_add_seq (pre_p, copyin_seq);
6009 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
6013 /* Expand code for an OpenMP single directive. */
6016 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6019 gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
6020 gimple_seq bind_body, dlist;
6021 struct gimplify_ctx gctx;
6023 push_gimplify_context (&gctx);
6026 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
6027 &bind_body, &dlist, ctx);
6028 lower_omp (gimple_omp_body (single_stmt), ctx);
6030 gimple_seq_add_stmt (&bind_body, single_stmt);
6032 if (ctx->record_type)
6033 lower_omp_single_copy (single_stmt, &bind_body, ctx);
6035 lower_omp_single_simple (single_stmt, &bind_body);
6037 gimple_omp_set_body (single_stmt, NULL);
6039 gimple_seq_add_seq (&bind_body, dlist);
6041 bind_body = maybe_catch_exception (bind_body);
6043 t = gimple_build_omp_return
6044 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
6045 OMP_CLAUSE_NOWAIT));
6046 gimple_seq_add_stmt (&bind_body, t);
6048 block = make_node (BLOCK);
6049 bind = gimple_build_bind (NULL, bind_body, block);
6051 pop_gimplify_context (bind);
6053 gimple_bind_append_vars (bind, ctx->block_vars);
6054 BLOCK_VARS (block) = ctx->block_vars;
6055 gsi_replace (gsi_p, bind, true);
6056 if (BLOCK_VARS (block))
6057 TREE_USED (block) = 1;
6061 /* Expand code for an OpenMP master directive. */
6064 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6066 tree block, lab = NULL, x, bfn_decl;
6067 gimple stmt = gsi_stmt (*gsi_p), bind;
6068 location_t loc = gimple_location (stmt);
6070 struct gimplify_ctx gctx;
6072 push_gimplify_context (&gctx);
6074 block = make_node (BLOCK);
6075 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6078 bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6079 x = build_call_expr_loc (loc, bfn_decl, 0);
6080 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
6081 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
6083 gimplify_and_add (x, &tseq);
6084 gimple_bind_add_seq (bind, tseq);
6086 lower_omp (gimple_omp_body (stmt), ctx);
6087 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6088 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6089 gimple_omp_set_body (stmt, NULL);
6091 gimple_bind_add_stmt (bind, gimple_build_label (lab));
6093 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6095 pop_gimplify_context (bind);
6097 gimple_bind_append_vars (bind, ctx->block_vars);
6098 BLOCK_VARS (block) = ctx->block_vars;
6099 gsi_replace (gsi_p, bind, true);
6103 /* Expand code for an OpenMP ordered directive. */
6106 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6109 gimple stmt = gsi_stmt (*gsi_p), bind, x;
6110 struct gimplify_ctx gctx;
6112 push_gimplify_context (&gctx);
6114 block = make_node (BLOCK);
6115 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6118 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
6120 gimple_bind_add_stmt (bind, x);
6122 lower_omp (gimple_omp_body (stmt), ctx);
6123 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6124 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6125 gimple_omp_set_body (stmt, NULL);
6127 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
6128 gimple_bind_add_stmt (bind, x);
6130 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6132 pop_gimplify_context (bind);
6134 gimple_bind_append_vars (bind, ctx->block_vars);
6135 BLOCK_VARS (block) = gimple_bind_vars (bind);
6136 gsi_replace (gsi_p, bind, true);
6140 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
6141 substitution of a couple of function calls. But in the NAMED case,
6142 requires that languages coordinate a symbol name. It is therefore
6143 best put here in common code. */
6145 static GTY((param1_is (tree), param2_is (tree)))
6146 splay_tree critical_name_mutexes;
6149 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6152 tree name, lock, unlock;
6153 gimple stmt = gsi_stmt (*gsi_p), bind;
6154 location_t loc = gimple_location (stmt);
6156 struct gimplify_ctx gctx;
6158 name = gimple_omp_critical_name (stmt);
6164 if (!critical_name_mutexes)
6165 critical_name_mutexes
6166 = splay_tree_new_ggc (splay_tree_compare_pointers,
6167 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
6168 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
6170 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
6175 decl = create_tmp_var_raw (ptr_type_node, NULL);
6177 new_str = ACONCAT ((".gomp_critical_user_",
6178 IDENTIFIER_POINTER (name), NULL));
6179 DECL_NAME (decl) = get_identifier (new_str);
6180 TREE_PUBLIC (decl) = 1;
6181 TREE_STATIC (decl) = 1;
6182 DECL_COMMON (decl) = 1;
6183 DECL_ARTIFICIAL (decl) = 1;
6184 DECL_IGNORED_P (decl) = 1;
6185 varpool_finalize_decl (decl);
6187 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
6188 (splay_tree_value) decl);
6191 decl = (tree) n->value;
6193 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
6194 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
6196 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
6197 unlock = build_call_expr_loc (loc, unlock, 1,
6198 build_fold_addr_expr_loc (loc, decl));
6202 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
6203 lock = build_call_expr_loc (loc, lock, 0);
6205 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
6206 unlock = build_call_expr_loc (loc, unlock, 0);
6209 push_gimplify_context (&gctx);
6211 block = make_node (BLOCK);
6212 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
6214 tbody = gimple_bind_body (bind);
6215 gimplify_and_add (lock, &tbody);
6216 gimple_bind_set_body (bind, tbody);
6218 lower_omp (gimple_omp_body (stmt), ctx);
6219 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6220 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6221 gimple_omp_set_body (stmt, NULL);
6223 tbody = gimple_bind_body (bind);
6224 gimplify_and_add (unlock, &tbody);
6225 gimple_bind_set_body (bind, tbody);
6227 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6229 pop_gimplify_context (bind);
6230 gimple_bind_append_vars (bind, ctx->block_vars);
6231 BLOCK_VARS (block) = gimple_bind_vars (bind);
6232 gsi_replace (gsi_p, bind, true);
6236 /* A subroutine of lower_omp_for. Generate code to emit the predicate
6237 for a lastprivate clause. Given a loop control predicate of (V
6238 cond N2), we gate the clause on (!(V cond N2)). The lowered form
6239 is appended to *DLIST, iterator initialization is appended to
6243 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
6244 gimple_seq *dlist, struct omp_context *ctx)
6246 tree clauses, cond, vinit;
6247 enum tree_code cond_code;
6250 cond_code = fd->loop.cond_code;
6251 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
6253 /* When possible, use a strict equality expression. This can let VRP
6254 type optimizations deduce the value and remove a copy. */
6255 if (host_integerp (fd->loop.step, 0))
6257 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
6258 if (step == 1 || step == -1)
6259 cond_code = EQ_EXPR;
6262 cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
6264 clauses = gimple_omp_for_clauses (fd->for_stmt);
6266 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
6267 if (!gimple_seq_empty_p (stmts))
6269 gimple_seq_add_seq (&stmts, *dlist);
6272 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6273 vinit = fd->loop.n1;
6274 if (cond_code == EQ_EXPR
6275 && host_integerp (fd->loop.n2, 0)
6276 && ! integer_zerop (fd->loop.n2))
6277 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6279 /* Initialize the iterator variable, so that threads that don't execute
6280 any iterations don't execute the lastprivate clauses by accident. */
6281 gimplify_assign (fd->loop.v, vinit, body_p);
6286 /* Lower code for an OpenMP loop directive. */
6289 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6292 struct omp_for_data fd;
6293 gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6294 gimple_seq omp_for_body, body, dlist;
6296 struct gimplify_ctx gctx;
6298 push_gimplify_context (&gctx);
6300 lower_omp (gimple_omp_for_pre_body (stmt), ctx);
6301 lower_omp (gimple_omp_body (stmt), ctx);
6303 block = make_node (BLOCK);
6304 new_stmt = gimple_build_bind (NULL, NULL, block);
6306 /* Move declaration of temporaries in the loop body before we make
6308 omp_for_body = gimple_omp_body (stmt);
6309 if (!gimple_seq_empty_p (omp_for_body)
6310 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6312 tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6313 gimple_bind_append_vars (new_stmt, vars);
6316 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6319 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6320 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6322 /* Lower the header expressions. At this point, we can assume that
6323 the header is of the form:
6325 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6327 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6328 using the .omp_data_s mapping, if needed. */
6329 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6331 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6332 if (!is_gimple_min_invariant (*rhs_p))
6333 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6335 rhs_p = gimple_omp_for_final_ptr (stmt, i);
6336 if (!is_gimple_min_invariant (*rhs_p))
6337 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6339 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6340 if (!is_gimple_min_invariant (*rhs_p))
6341 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6344 /* Once lowered, extract the bounds and clauses. */
6345 extract_omp_for_data (stmt, &fd, NULL);
6347 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6349 gimple_seq_add_stmt (&body, stmt);
6350 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6352 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6355 /* After the loop, add exit clauses. */
6356 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6357 gimple_seq_add_seq (&body, dlist);
6359 body = maybe_catch_exception (body);
6361 /* Region exit marker goes at the end of the loop body. */
6362 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6364 pop_gimplify_context (new_stmt);
6366 gimple_bind_append_vars (new_stmt, ctx->block_vars);
6367 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6368 if (BLOCK_VARS (block))
6369 TREE_USED (block) = 1;
6371 gimple_bind_set_body (new_stmt, body);
6372 gimple_omp_set_body (stmt, NULL);
6373 gimple_omp_for_set_pre_body (stmt, NULL);
6374 gsi_replace (gsi_p, new_stmt, true);
6377 /* Callback for walk_stmts. Check if the current statement only contains
6378 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6381 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6382 bool *handled_ops_p,
6383 struct walk_stmt_info *wi)
6385 int *info = (int *) wi->info;
6386 gimple stmt = gsi_stmt (*gsi_p);
6388 *handled_ops_p = true;
6389 switch (gimple_code (stmt))
6393 case GIMPLE_OMP_FOR:
6394 case GIMPLE_OMP_SECTIONS:
6395 *info = *info == 0 ? 1 : -1;
6404 struct omp_taskcopy_context
6406 /* This field must be at the beginning, as we do "inheritance": Some
6407 callback functions for tree-inline.c (e.g., omp_copy_decl)
6408 receive a copy_body_data pointer that is up-casted to an
6409 omp_context pointer. */
6415 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6417 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6419 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6420 return create_tmp_var (TREE_TYPE (var), NULL);
6426 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6428 tree name, new_fields = NULL, type, f;
6430 type = lang_hooks.types.make_type (RECORD_TYPE);
6431 name = DECL_NAME (TYPE_NAME (orig_type));
6432 name = build_decl (gimple_location (tcctx->ctx->stmt),
6433 TYPE_DECL, name, type);
6434 TYPE_NAME (type) = name;
6436 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6438 tree new_f = copy_node (f);
6439 DECL_CONTEXT (new_f) = type;
6440 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6441 TREE_CHAIN (new_f) = new_fields;
6442 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6443 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6444 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6447 *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6449 TYPE_FIELDS (type) = nreverse (new_fields);
6454 /* Create task copyfn. */
6457 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6459 struct function *child_cfun;
6460 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6461 tree record_type, srecord_type, bind, list;
6462 bool record_needs_remap = false, srecord_needs_remap = false;
6464 struct omp_taskcopy_context tcctx;
6465 struct gimplify_ctx gctx;
6466 location_t loc = gimple_location (task_stmt);
6468 child_fn = gimple_omp_task_copy_fn (task_stmt);
6469 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6470 gcc_assert (child_cfun->cfg == NULL);
6471 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6473 /* Reset DECL_CONTEXT on function arguments. */
6474 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
6475 DECL_CONTEXT (t) = child_fn;
6477 /* Populate the function. */
6478 push_gimplify_context (&gctx);
6479 current_function_decl = child_fn;
6481 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6482 TREE_SIDE_EFFECTS (bind) = 1;
6484 DECL_SAVED_TREE (child_fn) = bind;
6485 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6487 /* Remap src and dst argument types if needed. */
6488 record_type = ctx->record_type;
6489 srecord_type = ctx->srecord_type;
6490 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6491 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6493 record_needs_remap = true;
6496 for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
6497 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6499 srecord_needs_remap = true;
6503 if (record_needs_remap || srecord_needs_remap)
6505 memset (&tcctx, '\0', sizeof (tcctx));
6506 tcctx.cb.src_fn = ctx->cb.src_fn;
6507 tcctx.cb.dst_fn = child_fn;
6508 tcctx.cb.src_node = cgraph_get_node (tcctx.cb.src_fn);
6509 gcc_checking_assert (tcctx.cb.src_node);
6510 tcctx.cb.dst_node = tcctx.cb.src_node;
6511 tcctx.cb.src_cfun = ctx->cb.src_cfun;
6512 tcctx.cb.copy_decl = task_copyfn_copy_decl;
6513 tcctx.cb.eh_lp_nr = 0;
6514 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6515 tcctx.cb.decl_map = pointer_map_create ();
6518 if (record_needs_remap)
6519 record_type = task_copyfn_remap_type (&tcctx, record_type);
6520 if (srecord_needs_remap)
6521 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6524 tcctx.cb.decl_map = NULL;
6526 push_cfun (child_cfun);
6528 arg = DECL_ARGUMENTS (child_fn);
6529 TREE_TYPE (arg) = build_pointer_type (record_type);
6530 sarg = DECL_CHAIN (arg);
6531 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6533 /* First pass: initialize temporaries used in record_type and srecord_type
6534 sizes and field offsets. */
6535 if (tcctx.cb.decl_map)
6536 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6537 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6541 decl = OMP_CLAUSE_DECL (c);
6542 p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6545 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6546 sf = (tree) n->value;
6547 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6548 src = build_simple_mem_ref_loc (loc, sarg);
6549 src = omp_build_component_ref (src, sf);
6550 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6551 append_to_statement_list (t, &list);
6554 /* Second pass: copy shared var pointers and copy construct non-VLA
6555 firstprivate vars. */
6556 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6557 switch (OMP_CLAUSE_CODE (c))
6559 case OMP_CLAUSE_SHARED:
6560 decl = OMP_CLAUSE_DECL (c);
6561 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6564 f = (tree) n->value;
6565 if (tcctx.cb.decl_map)
6566 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6567 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6568 sf = (tree) n->value;
6569 if (tcctx.cb.decl_map)
6570 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6571 src = build_simple_mem_ref_loc (loc, sarg);
6572 src = omp_build_component_ref (src, sf);
6573 dst = build_simple_mem_ref_loc (loc, arg);
6574 dst = omp_build_component_ref (dst, f);
6575 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6576 append_to_statement_list (t, &list);
6578 case OMP_CLAUSE_FIRSTPRIVATE:
6579 decl = OMP_CLAUSE_DECL (c);
6580 if (is_variable_sized (decl))
6582 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6585 f = (tree) n->value;
6586 if (tcctx.cb.decl_map)
6587 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6588 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6591 sf = (tree) n->value;
6592 if (tcctx.cb.decl_map)
6593 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6594 src = build_simple_mem_ref_loc (loc, sarg);
6595 src = omp_build_component_ref (src, sf);
6596 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6597 src = build_simple_mem_ref_loc (loc, src);
6601 dst = build_simple_mem_ref_loc (loc, arg);
6602 dst = omp_build_component_ref (dst, f);
6603 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6604 append_to_statement_list (t, &list);
6606 case OMP_CLAUSE_PRIVATE:
6607 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6609 decl = OMP_CLAUSE_DECL (c);
6610 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6611 f = (tree) n->value;
6612 if (tcctx.cb.decl_map)
6613 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6614 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6617 sf = (tree) n->value;
6618 if (tcctx.cb.decl_map)
6619 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6620 src = build_simple_mem_ref_loc (loc, sarg);
6621 src = omp_build_component_ref (src, sf);
6622 if (use_pointer_for_field (decl, NULL))
6623 src = build_simple_mem_ref_loc (loc, src);
6627 dst = build_simple_mem_ref_loc (loc, arg);
6628 dst = omp_build_component_ref (dst, f);
6629 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6630 append_to_statement_list (t, &list);
6636 /* Last pass: handle VLA firstprivates. */
6637 if (tcctx.cb.decl_map)
6638 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6639 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6643 decl = OMP_CLAUSE_DECL (c);
6644 if (!is_variable_sized (decl))
6646 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6649 f = (tree) n->value;
6650 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6651 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6652 ind = DECL_VALUE_EXPR (decl);
6653 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6654 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6655 n = splay_tree_lookup (ctx->sfield_map,
6656 (splay_tree_key) TREE_OPERAND (ind, 0));
6657 sf = (tree) n->value;
6658 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6659 src = build_simple_mem_ref_loc (loc, sarg);
6660 src = omp_build_component_ref (src, sf);
6661 src = build_simple_mem_ref_loc (loc, src);
6662 dst = build_simple_mem_ref_loc (loc, arg);
6663 dst = omp_build_component_ref (dst, f);
6664 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6665 append_to_statement_list (t, &list);
6666 n = splay_tree_lookup (ctx->field_map,
6667 (splay_tree_key) TREE_OPERAND (ind, 0));
6668 df = (tree) n->value;
6669 df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6670 ptr = build_simple_mem_ref_loc (loc, arg);
6671 ptr = omp_build_component_ref (ptr, df);
6672 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6673 build_fold_addr_expr_loc (loc, dst));
6674 append_to_statement_list (t, &list);
6677 t = build1 (RETURN_EXPR, void_type_node, NULL);
6678 append_to_statement_list (t, &list);
6680 if (tcctx.cb.decl_map)
6681 pointer_map_destroy (tcctx.cb.decl_map);
6682 pop_gimplify_context (NULL);
6683 BIND_EXPR_BODY (bind) = list;
6685 current_function_decl = ctx->cb.src_fn;
6688 /* Lower the OpenMP parallel or task directive in the current statement
6689 in GSI_P. CTX holds context information for the directive. */
6692 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6696 gimple stmt = gsi_stmt (*gsi_p);
6697 gimple par_bind, bind;
6698 gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6699 struct gimplify_ctx gctx;
6700 location_t loc = gimple_location (stmt);
6702 clauses = gimple_omp_taskreg_clauses (stmt);
6703 par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6704 par_body = gimple_bind_body (par_bind);
6705 child_fn = ctx->cb.dst_fn;
6706 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6707 && !gimple_omp_parallel_combined_p (stmt))
6709 struct walk_stmt_info wi;
6712 memset (&wi, 0, sizeof (wi));
6715 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6717 gimple_omp_parallel_set_combined_p (stmt, true);
6719 if (ctx->srecord_type)
6720 create_task_copyfn (stmt, ctx);
6722 push_gimplify_context (&gctx);
6726 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6727 lower_omp (par_body, ctx);
6728 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6729 lower_reduction_clauses (clauses, &par_olist, ctx);
6731 /* Declare all the variables created by mapping and the variables
6732 declared in the scope of the parallel body. */
6733 record_vars_into (ctx->block_vars, child_fn);
6734 record_vars_into (gimple_bind_vars (par_bind), child_fn);
6736 if (ctx->record_type)
6739 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6740 : ctx->record_type, ".omp_data_o");
6741 DECL_NAMELESS (ctx->sender_decl) = 1;
6742 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6743 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6748 lower_send_clauses (clauses, &ilist, &olist, ctx);
6749 lower_send_shared_vars (&ilist, &olist, ctx);
6751 /* Once all the expansions are done, sequence all the different
6752 fragments inside gimple_omp_body. */
6756 if (ctx->record_type)
6758 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6759 /* fixup_child_record_type might have changed receiver_decl's type. */
6760 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6761 gimple_seq_add_stmt (&new_body,
6762 gimple_build_assign (ctx->receiver_decl, t));
6765 gimple_seq_add_seq (&new_body, par_ilist);
6766 gimple_seq_add_seq (&new_body, par_body);
6767 gimple_seq_add_seq (&new_body, par_olist);
6768 new_body = maybe_catch_exception (new_body);
6769 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6770 gimple_omp_set_body (stmt, new_body);
6772 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6773 gimple_bind_add_stmt (bind, stmt);
6776 gimple_seq_add_stmt (&ilist, bind);
6777 gimple_seq_add_seq (&ilist, olist);
6778 bind = gimple_build_bind (NULL, ilist, NULL);
6781 gsi_replace (gsi_p, bind, true);
6783 pop_gimplify_context (NULL);
6786 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6787 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6788 of OpenMP context, but with task_shared_vars set. */
6791 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6796 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6797 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6800 if (task_shared_vars
6802 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6805 /* If a global variable has been privatized, TREE_CONSTANT on
6806 ADDR_EXPR might be wrong. */
6807 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6808 recompute_tree_invariant_for_addr_expr (t);
6810 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6815 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6817 gimple stmt = gsi_stmt (*gsi_p);
6818 struct walk_stmt_info wi;
6820 if (gimple_has_location (stmt))
6821 input_location = gimple_location (stmt);
6823 if (task_shared_vars)
6824 memset (&wi, '\0', sizeof (wi));
6826 /* If we have issued syntax errors, avoid doing any heavy lifting.
6827 Just replace the OpenMP directives with a NOP to avoid
6828 confusing RTL expansion. */
6829 if (seen_error () && is_gimple_omp (stmt))
6831 gsi_replace (gsi_p, gimple_build_nop (), true);
6835 switch (gimple_code (stmt))
6838 if ((ctx || task_shared_vars)
6839 && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6840 ctx ? NULL : &wi, NULL)
6841 || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6842 ctx ? NULL : &wi, NULL)))
6843 gimple_regimplify_operands (stmt, gsi_p);
6846 lower_omp (gimple_catch_handler (stmt), ctx);
6848 case GIMPLE_EH_FILTER:
6849 lower_omp (gimple_eh_filter_failure (stmt), ctx);
6852 lower_omp (gimple_try_eval (stmt), ctx);
6853 lower_omp (gimple_try_cleanup (stmt), ctx);
6856 lower_omp (gimple_bind_body (stmt), ctx);
6858 case GIMPLE_OMP_PARALLEL:
6859 case GIMPLE_OMP_TASK:
6860 ctx = maybe_lookup_ctx (stmt);
6861 lower_omp_taskreg (gsi_p, ctx);
6863 case GIMPLE_OMP_FOR:
6864 ctx = maybe_lookup_ctx (stmt);
6866 lower_omp_for (gsi_p, ctx);
6868 case GIMPLE_OMP_SECTIONS:
6869 ctx = maybe_lookup_ctx (stmt);
6871 lower_omp_sections (gsi_p, ctx);
6873 case GIMPLE_OMP_SINGLE:
6874 ctx = maybe_lookup_ctx (stmt);
6876 lower_omp_single (gsi_p, ctx);
6878 case GIMPLE_OMP_MASTER:
6879 ctx = maybe_lookup_ctx (stmt);
6881 lower_omp_master (gsi_p, ctx);
6883 case GIMPLE_OMP_ORDERED:
6884 ctx = maybe_lookup_ctx (stmt);
6886 lower_omp_ordered (gsi_p, ctx);
6888 case GIMPLE_OMP_CRITICAL:
6889 ctx = maybe_lookup_ctx (stmt);
6891 lower_omp_critical (gsi_p, ctx);
6893 case GIMPLE_OMP_ATOMIC_LOAD:
6894 if ((ctx || task_shared_vars)
6895 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6896 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6897 gimple_regimplify_operands (stmt, gsi_p);
6900 if ((ctx || task_shared_vars)
6901 && walk_gimple_op (stmt, lower_omp_regimplify_p,
6903 gimple_regimplify_operands (stmt, gsi_p);
6909 lower_omp (gimple_seq body, omp_context *ctx)
6911 location_t saved_location = input_location;
6912 gimple_stmt_iterator gsi = gsi_start (body);
6913 for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
6914 lower_omp_1 (&gsi, ctx);
6915 input_location = saved_location;
6918 /* Main entry point. */
6921 execute_lower_omp (void)
6925 /* This pass always runs, to provide PROP_gimple_lomp.
6926 But there is nothing to do unless -fopenmp is given. */
6927 if (flag_openmp == 0)
6930 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6931 delete_omp_context);
6933 body = gimple_body (current_function_decl);
6934 scan_omp (body, NULL);
6935 gcc_assert (taskreg_nesting_level == 0);
6937 if (all_contexts->root)
6939 struct gimplify_ctx gctx;
6941 if (task_shared_vars)
6942 push_gimplify_context (&gctx);
6943 lower_omp (body, NULL);
6944 if (task_shared_vars)
6945 pop_gimplify_context (NULL);
6950 splay_tree_delete (all_contexts);
6951 all_contexts = NULL;
6953 BITMAP_FREE (task_shared_vars);
6957 struct gimple_opt_pass pass_lower_omp =
6961 "omplower", /* name */
6963 execute_lower_omp, /* execute */
6966 0, /* static_pass_number */
6967 TV_NONE, /* tv_id */
6968 PROP_gimple_any, /* properties_required */
6969 PROP_gimple_lomp, /* properties_provided */
6970 0, /* properties_destroyed */
6971 0, /* todo_flags_start */
6972 0 /* todo_flags_finish */
6976 /* The following is a utility to diagnose OpenMP structured block violations.
6977 It is not part of the "omplower" pass, as that's invoked too late. It
6978 should be invoked by the respective front ends after gimplification. */
6980 static splay_tree all_labels;
6982 /* Check for mismatched contexts and generate an error if needed. Return
6983 true if an error is detected. */
6986 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
6987 gimple branch_ctx, gimple label_ctx)
6989 if (label_ctx == branch_ctx)
6994 Previously we kept track of the label's entire context in diagnose_sb_[12]
6995 so we could traverse it and issue a correct "exit" or "enter" error
6996 message upon a structured block violation.
6998 We built the context by building a list with tree_cons'ing, but there is
6999 no easy counterpart in gimple tuples. It seems like far too much work
7000 for issuing exit/enter error messages. If someone really misses the
7001 distinct error message... patches welcome.
7005 /* Try to avoid confusing the user by producing and error message
7006 with correct "exit" or "enter" verbiage. We prefer "exit"
7007 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
7008 if (branch_ctx == NULL)
7014 if (TREE_VALUE (label_ctx) == branch_ctx)
7019 label_ctx = TREE_CHAIN (label_ctx);
7024 error ("invalid exit from OpenMP structured block");
7026 error ("invalid entry to OpenMP structured block");
7029 /* If it's obvious we have an invalid entry, be specific about the error. */
7030 if (branch_ctx == NULL)
7031 error ("invalid entry to OpenMP structured block");
7033 /* Otherwise, be vague and lazy, but efficient. */
7034 error ("invalid branch to/from an OpenMP structured block");
7036 gsi_replace (gsi_p, gimple_build_nop (), false);
7040 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7041 where each label is found. */
7044 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7045 struct walk_stmt_info *wi)
7047 gimple context = (gimple) wi->info;
7048 gimple inner_context;
7049 gimple stmt = gsi_stmt (*gsi_p);
7051 *handled_ops_p = true;
7053 switch (gimple_code (stmt))
7057 case GIMPLE_OMP_PARALLEL:
7058 case GIMPLE_OMP_TASK:
7059 case GIMPLE_OMP_SECTIONS:
7060 case GIMPLE_OMP_SINGLE:
7061 case GIMPLE_OMP_SECTION:
7062 case GIMPLE_OMP_MASTER:
7063 case GIMPLE_OMP_ORDERED:
7064 case GIMPLE_OMP_CRITICAL:
7065 /* The minimal context here is just the current OMP construct. */
7066 inner_context = stmt;
7067 wi->info = inner_context;
7068 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7072 case GIMPLE_OMP_FOR:
7073 inner_context = stmt;
7074 wi->info = inner_context;
7075 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7077 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7078 diagnose_sb_1, NULL, wi);
7079 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7084 splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
7085 (splay_tree_value) context);
7095 /* Pass 2: Check each branch and see if its context differs from that of
7096 the destination label's context. */
7099 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7100 struct walk_stmt_info *wi)
7102 gimple context = (gimple) wi->info;
7104 gimple stmt = gsi_stmt (*gsi_p);
7106 *handled_ops_p = true;
7108 switch (gimple_code (stmt))
7112 case GIMPLE_OMP_PARALLEL:
7113 case GIMPLE_OMP_TASK:
7114 case GIMPLE_OMP_SECTIONS:
7115 case GIMPLE_OMP_SINGLE:
7116 case GIMPLE_OMP_SECTION:
7117 case GIMPLE_OMP_MASTER:
7118 case GIMPLE_OMP_ORDERED:
7119 case GIMPLE_OMP_CRITICAL:
7121 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7125 case GIMPLE_OMP_FOR:
7127 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7129 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7130 diagnose_sb_2, NULL, wi);
7131 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7137 tree lab = gimple_cond_true_label (stmt);
7140 n = splay_tree_lookup (all_labels,
7141 (splay_tree_key) lab);
7142 diagnose_sb_0 (gsi_p, context,
7143 n ? (gimple) n->value : NULL);
7145 lab = gimple_cond_false_label (stmt);
7148 n = splay_tree_lookup (all_labels,
7149 (splay_tree_key) lab);
7150 diagnose_sb_0 (gsi_p, context,
7151 n ? (gimple) n->value : NULL);
7158 tree lab = gimple_goto_dest (stmt);
7159 if (TREE_CODE (lab) != LABEL_DECL)
7162 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7163 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
7170 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
7172 tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
7173 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7174 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
7181 diagnose_sb_0 (gsi_p, context, NULL);
7192 diagnose_omp_structured_block_errors (void)
7194 struct walk_stmt_info wi;
7195 gimple_seq body = gimple_body (current_function_decl);
7197 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
7199 memset (&wi, 0, sizeof (wi));
7200 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
7202 memset (&wi, 0, sizeof (wi));
7203 wi.want_locations = true;
7204 walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
7206 splay_tree_delete (all_labels);
7213 gate_diagnose_omp_blocks (void)
7215 return flag_openmp != 0;
7218 struct gimple_opt_pass pass_diagnose_omp_blocks =
7222 "*diagnose_omp_blocks", /* name */
7223 gate_diagnose_omp_blocks, /* gate */
7224 diagnose_omp_structured_block_errors, /* execute */
7227 0, /* static_pass_number */
7228 TV_NONE, /* tv_id */
7229 PROP_gimple_any, /* properties_required */
7230 0, /* properties_provided */
7231 0, /* properties_destroyed */
7232 0, /* todo_flags_start */
7233 0, /* todo_flags_finish */
7237 #include "gt-omp-low.h"