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 error_at (gimple_location (stmt),
1847 "barrier region may not be closely nested inside "
1848 "of work-sharing, critical, ordered, master or "
1849 "explicit task region");
1852 error_at (gimple_location (stmt),
1853 "work-sharing region may not be closely nested inside "
1854 "of work-sharing, critical, ordered, master or explicit "
1857 case GIMPLE_OMP_PARALLEL:
1863 case GIMPLE_OMP_MASTER:
1864 for (; ctx != NULL; ctx = ctx->outer)
1865 switch (gimple_code (ctx->stmt))
1867 case GIMPLE_OMP_FOR:
1868 case GIMPLE_OMP_SECTIONS:
1869 case GIMPLE_OMP_SINGLE:
1870 case GIMPLE_OMP_TASK:
1871 error_at (gimple_location (stmt),
1872 "master region may not be closely nested inside "
1873 "of work-sharing or explicit task region");
1875 case GIMPLE_OMP_PARALLEL:
1881 case GIMPLE_OMP_ORDERED:
1882 for (; ctx != NULL; ctx = ctx->outer)
1883 switch (gimple_code (ctx->stmt))
1885 case GIMPLE_OMP_CRITICAL:
1886 case GIMPLE_OMP_TASK:
1887 error_at (gimple_location (stmt),
1888 "ordered region may not be closely nested inside "
1889 "of critical or explicit task region");
1891 case GIMPLE_OMP_FOR:
1892 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
1893 OMP_CLAUSE_ORDERED) == NULL)
1895 error_at (gimple_location (stmt),
1896 "ordered region must be closely nested inside "
1897 "a loop region with an ordered clause");
1901 case GIMPLE_OMP_PARALLEL:
1907 case GIMPLE_OMP_CRITICAL:
1908 for (; ctx != NULL; ctx = ctx->outer)
1909 if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
1910 && (gimple_omp_critical_name (stmt)
1911 == gimple_omp_critical_name (ctx->stmt)))
1913 error_at (gimple_location (stmt),
1914 "critical region may not be nested inside a critical "
1915 "region with the same name");
1926 /* Helper function scan_omp.
1928 Callback for walk_tree or operators in walk_gimple_stmt used to
1929 scan for OpenMP directives in TP. */
1932 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
1934 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1935 omp_context *ctx = (omp_context *) wi->info;
1938 switch (TREE_CODE (t))
1945 *tp = remap_decl (t, &ctx->cb);
1949 if (ctx && TYPE_P (t))
1950 *tp = remap_type (t, &ctx->cb);
1951 else if (!DECL_P (t))
1956 tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
1957 if (tem != TREE_TYPE (t))
1959 if (TREE_CODE (t) == INTEGER_CST)
1960 *tp = build_int_cst_wide (tem,
1961 TREE_INT_CST_LOW (t),
1962 TREE_INT_CST_HIGH (t));
1964 TREE_TYPE (t) = tem;
1975 /* Helper function for scan_omp.
1977 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1978 the current statement in GSI. */
1981 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1982 struct walk_stmt_info *wi)
1984 gimple stmt = gsi_stmt (*gsi);
1985 omp_context *ctx = (omp_context *) wi->info;
1987 if (gimple_has_location (stmt))
1988 input_location = gimple_location (stmt);
1990 /* Check the OpenMP nesting restrictions. */
1993 bool remove = false;
1994 if (is_gimple_omp (stmt))
1995 remove = !check_omp_nesting_restrictions (stmt, ctx);
1996 else if (is_gimple_call (stmt))
1998 tree fndecl = gimple_call_fndecl (stmt);
1999 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
2000 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
2001 remove = !check_omp_nesting_restrictions (stmt, ctx);
2005 stmt = gimple_build_nop ();
2006 gsi_replace (gsi, stmt, false);
2010 *handled_ops_p = true;
2012 switch (gimple_code (stmt))
2014 case GIMPLE_OMP_PARALLEL:
2015 taskreg_nesting_level++;
2016 scan_omp_parallel (gsi, ctx);
2017 taskreg_nesting_level--;
2020 case GIMPLE_OMP_TASK:
2021 taskreg_nesting_level++;
2022 scan_omp_task (gsi, ctx);
2023 taskreg_nesting_level--;
2026 case GIMPLE_OMP_FOR:
2027 scan_omp_for (stmt, ctx);
2030 case GIMPLE_OMP_SECTIONS:
2031 scan_omp_sections (stmt, ctx);
2034 case GIMPLE_OMP_SINGLE:
2035 scan_omp_single (stmt, ctx);
2038 case GIMPLE_OMP_SECTION:
2039 case GIMPLE_OMP_MASTER:
2040 case GIMPLE_OMP_ORDERED:
2041 case GIMPLE_OMP_CRITICAL:
2042 ctx = new_omp_context (stmt, ctx);
2043 scan_omp (gimple_omp_body (stmt), ctx);
2050 *handled_ops_p = false;
2052 for (var = gimple_bind_vars (stmt); var ; var = DECL_CHAIN (var))
2053 insert_decl_map (&ctx->cb, var, var);
2057 *handled_ops_p = false;
2065 /* Scan all the statements starting at the current statement. CTX
2066 contains context information about the OpenMP directives and
2067 clauses found during the scan. */
2070 scan_omp (gimple_seq body, omp_context *ctx)
2072 location_t saved_location;
2073 struct walk_stmt_info wi;
2075 memset (&wi, 0, sizeof (wi));
2077 wi.want_locations = true;
2079 saved_location = input_location;
2080 walk_gimple_seq (body, scan_omp_1_stmt, scan_omp_1_op, &wi);
2081 input_location = saved_location;
2084 /* Re-gimplification and code generation routines. */
2086 /* Build a call to GOMP_barrier. */
2089 build_omp_barrier (void)
2091 return build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_BARRIER), 0);
2094 /* If a context was created for STMT when it was scanned, return it. */
2096 static omp_context *
2097 maybe_lookup_ctx (gimple stmt)
2100 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
2101 return n ? (omp_context *) n->value : NULL;
2105 /* Find the mapping for DECL in CTX or the immediately enclosing
2106 context that has a mapping for DECL.
2108 If CTX is a nested parallel directive, we may have to use the decl
2109 mappings created in CTX's parent context. Suppose that we have the
2110 following parallel nesting (variable UIDs showed for clarity):
2113 #omp parallel shared(iD.1562) -> outer parallel
2114 iD.1562 = iD.1562 + 1;
2116 #omp parallel shared (iD.1562) -> inner parallel
2117 iD.1562 = iD.1562 - 1;
2119 Each parallel structure will create a distinct .omp_data_s structure
2120 for copying iD.1562 in/out of the directive:
2122 outer parallel .omp_data_s.1.i -> iD.1562
2123 inner parallel .omp_data_s.2.i -> iD.1562
2125 A shared variable mapping will produce a copy-out operation before
2126 the parallel directive and a copy-in operation after it. So, in
2127 this case we would have:
2130 .omp_data_o.1.i = iD.1562;
2131 #omp parallel shared(iD.1562) -> outer parallel
2132 .omp_data_i.1 = &.omp_data_o.1
2133 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2135 .omp_data_o.2.i = iD.1562; -> **
2136 #omp parallel shared(iD.1562) -> inner parallel
2137 .omp_data_i.2 = &.omp_data_o.2
2138 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2141 ** This is a problem. The symbol iD.1562 cannot be referenced
2142 inside the body of the outer parallel region. But since we are
2143 emitting this copy operation while expanding the inner parallel
2144 directive, we need to access the CTX structure of the outer
2145 parallel directive to get the correct mapping:
2147 .omp_data_o.2.i = .omp_data_i.1->i
2149 Since there may be other workshare or parallel directives enclosing
2150 the parallel directive, it may be necessary to walk up the context
2151 parent chain. This is not a problem in general because nested
2152 parallelism happens only rarely. */
2155 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2160 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2161 t = maybe_lookup_decl (decl, up);
2163 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
2165 return t ? t : decl;
2169 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2170 in outer contexts. */
2173 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2178 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2179 t = maybe_lookup_decl (decl, up);
2181 return t ? t : decl;
2185 /* Construct the initialization value for reduction CLAUSE. */
2188 omp_reduction_init (tree clause, tree type)
2190 location_t loc = OMP_CLAUSE_LOCATION (clause);
2191 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
2198 case TRUTH_ORIF_EXPR:
2199 case TRUTH_XOR_EXPR:
2201 return build_zero_cst (type);
2204 case TRUTH_AND_EXPR:
2205 case TRUTH_ANDIF_EXPR:
2207 return fold_convert_loc (loc, type, integer_one_node);
2210 return fold_convert_loc (loc, type, integer_minus_one_node);
2213 if (SCALAR_FLOAT_TYPE_P (type))
2215 REAL_VALUE_TYPE max, min;
2216 if (HONOR_INFINITIES (TYPE_MODE (type)))
2219 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
2222 real_maxval (&min, 1, TYPE_MODE (type));
2223 return build_real (type, min);
2227 gcc_assert (INTEGRAL_TYPE_P (type));
2228 return TYPE_MIN_VALUE (type);
2232 if (SCALAR_FLOAT_TYPE_P (type))
2234 REAL_VALUE_TYPE max;
2235 if (HONOR_INFINITIES (TYPE_MODE (type)))
2238 real_maxval (&max, 0, TYPE_MODE (type));
2239 return build_real (type, max);
2243 gcc_assert (INTEGRAL_TYPE_P (type));
2244 return TYPE_MAX_VALUE (type);
2252 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2253 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2254 private variables. Initialization statements go in ILIST, while calls
2255 to destructors go in DLIST. */
2258 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
2261 gimple_stmt_iterator diter;
2262 tree c, dtor, copyin_seq, x, ptr;
2263 bool copyin_by_ref = false;
2264 bool lastprivate_firstprivate = false;
2267 *dlist = gimple_seq_alloc ();
2268 diter = gsi_start (*dlist);
2271 /* Do all the fixed sized types in the first pass, and the variable sized
2272 types in the second pass. This makes sure that the scalar arguments to
2273 the variable sized types are processed before we use them in the
2274 variable sized operations. */
2275 for (pass = 0; pass < 2; ++pass)
2277 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2279 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
2282 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2286 case OMP_CLAUSE_PRIVATE:
2287 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
2290 case OMP_CLAUSE_SHARED:
2291 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
2293 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
2296 case OMP_CLAUSE_FIRSTPRIVATE:
2297 case OMP_CLAUSE_COPYIN:
2298 case OMP_CLAUSE_REDUCTION:
2300 case OMP_CLAUSE_LASTPRIVATE:
2301 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2303 lastprivate_firstprivate = true;
2312 new_var = var = OMP_CLAUSE_DECL (c);
2313 if (c_kind != OMP_CLAUSE_COPYIN)
2314 new_var = lookup_decl (var, ctx);
2316 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
2321 else if (is_variable_sized (var))
2323 /* For variable sized types, we need to allocate the
2324 actual storage here. Call alloca and store the
2325 result in the pointer decl that we created elsewhere. */
2329 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
2334 ptr = DECL_VALUE_EXPR (new_var);
2335 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
2336 ptr = TREE_OPERAND (ptr, 0);
2337 gcc_assert (DECL_P (ptr));
2338 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
2340 /* void *tmp = __builtin_alloca */
2341 atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2342 stmt = gimple_build_call (atmp, 1, x);
2343 tmp = create_tmp_var_raw (ptr_type_node, NULL);
2344 gimple_add_tmp_var (tmp);
2345 gimple_call_set_lhs (stmt, tmp);
2347 gimple_seq_add_stmt (ilist, stmt);
2349 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
2350 gimplify_assign (ptr, x, ilist);
2353 else if (is_reference (var))
2355 /* For references that are being privatized for Fortran,
2356 allocate new backing storage for the new pointer
2357 variable. This allows us to avoid changing all the
2358 code that expects a pointer to something that expects
2359 a direct variable. Note that this doesn't apply to
2360 C++, since reference types are disallowed in data
2361 sharing clauses there, except for NRV optimized
2366 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
2367 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
2369 x = build_receiver_ref (var, false, ctx);
2370 x = build_fold_addr_expr_loc (clause_loc, x);
2372 else if (TREE_CONSTANT (x))
2374 const char *name = NULL;
2375 if (DECL_NAME (var))
2376 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
2378 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
2380 gimple_add_tmp_var (x);
2381 TREE_ADDRESSABLE (x) = 1;
2382 x = build_fold_addr_expr_loc (clause_loc, x);
2386 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
2387 x = build_call_expr_loc (clause_loc, atmp, 1, x);
2390 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
2391 gimplify_assign (new_var, x, ilist);
2393 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2395 else if (c_kind == OMP_CLAUSE_REDUCTION
2396 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2404 switch (OMP_CLAUSE_CODE (c))
2406 case OMP_CLAUSE_SHARED:
2407 /* Shared global vars are just accessed directly. */
2408 if (is_global_var (new_var))
2410 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2411 needs to be delayed until after fixup_child_record_type so
2412 that we get the correct type during the dereference. */
2413 by_ref = use_pointer_for_field (var, ctx);
2414 x = build_receiver_ref (var, by_ref, ctx);
2415 SET_DECL_VALUE_EXPR (new_var, x);
2416 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2418 /* ??? If VAR is not passed by reference, and the variable
2419 hasn't been initialized yet, then we'll get a warning for
2420 the store into the omp_data_s structure. Ideally, we'd be
2421 able to notice this and not store anything at all, but
2422 we're generating code too early. Suppress the warning. */
2424 TREE_NO_WARNING (var) = 1;
2427 case OMP_CLAUSE_LASTPRIVATE:
2428 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2432 case OMP_CLAUSE_PRIVATE:
2433 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
2434 x = build_outer_var_ref (var, ctx);
2435 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2437 if (is_task_ctx (ctx))
2438 x = build_receiver_ref (var, false, ctx);
2440 x = build_outer_var_ref (var, ctx);
2444 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
2446 gimplify_and_add (x, ilist);
2450 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
2453 gimple_seq tseq = NULL;
2456 gimplify_stmt (&dtor, &tseq);
2457 gsi_insert_seq_before (&diter, tseq, GSI_SAME_STMT);
2461 case OMP_CLAUSE_FIRSTPRIVATE:
2462 if (is_task_ctx (ctx))
2464 if (is_reference (var) || is_variable_sized (var))
2466 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
2468 || use_pointer_for_field (var, NULL))
2470 x = build_receiver_ref (var, false, ctx);
2471 SET_DECL_VALUE_EXPR (new_var, x);
2472 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2476 x = build_outer_var_ref (var, ctx);
2477 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
2478 gimplify_and_add (x, ilist);
2482 case OMP_CLAUSE_COPYIN:
2483 by_ref = use_pointer_for_field (var, NULL);
2484 x = build_receiver_ref (var, by_ref, ctx);
2485 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
2486 append_to_statement_list (x, ©in_seq);
2487 copyin_by_ref |= by_ref;
2490 case OMP_CLAUSE_REDUCTION:
2491 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2493 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2494 x = build_outer_var_ref (var, ctx);
2496 if (is_reference (var))
2497 x = build_fold_addr_expr_loc (clause_loc, x);
2498 SET_DECL_VALUE_EXPR (placeholder, x);
2499 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2500 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2501 gimple_seq_add_seq (ilist,
2502 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
2503 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
2504 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
2508 x = omp_reduction_init (c, TREE_TYPE (new_var));
2509 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
2510 gimplify_assign (new_var, x, ilist);
2520 /* The copyin sequence is not to be executed by the main thread, since
2521 that would result in self-copies. Perhaps not visible to scalars,
2522 but it certainly is to C++ operator=. */
2525 x = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM),
2527 x = build2 (NE_EXPR, boolean_type_node, x,
2528 build_int_cst (TREE_TYPE (x), 0));
2529 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
2530 gimplify_and_add (x, ilist);
2533 /* If any copyin variable is passed by reference, we must ensure the
2534 master thread doesn't modify it before it is copied over in all
2535 threads. Similarly for variables in both firstprivate and
2536 lastprivate clauses we need to ensure the lastprivate copying
2537 happens after firstprivate copying in all threads. */
2538 if (copyin_by_ref || lastprivate_firstprivate)
2539 gimplify_and_add (build_omp_barrier (), ilist);
2543 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2544 both parallel and workshare constructs. PREDICATE may be NULL if it's
2548 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
2551 tree x, c, label = NULL;
2552 bool par_clauses = false;
2554 /* Early exit if there are no lastprivate clauses. */
2555 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
2556 if (clauses == NULL)
2558 /* If this was a workshare clause, see if it had been combined
2559 with its parallel. In that case, look for the clauses on the
2560 parallel statement itself. */
2561 if (is_parallel_ctx (ctx))
2565 if (ctx == NULL || !is_parallel_ctx (ctx))
2568 clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2569 OMP_CLAUSE_LASTPRIVATE);
2570 if (clauses == NULL)
2578 tree label_true, arm1, arm2;
2580 label = create_artificial_label (UNKNOWN_LOCATION);
2581 label_true = create_artificial_label (UNKNOWN_LOCATION);
2582 arm1 = TREE_OPERAND (predicate, 0);
2583 arm2 = TREE_OPERAND (predicate, 1);
2584 gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
2585 gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
2586 stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
2588 gimple_seq_add_stmt (stmt_list, stmt);
2589 gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
2592 for (c = clauses; c ;)
2595 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2597 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2599 var = OMP_CLAUSE_DECL (c);
2600 new_var = lookup_decl (var, ctx);
2602 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2604 lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2605 gimple_seq_add_seq (stmt_list,
2606 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
2608 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
2610 x = build_outer_var_ref (var, ctx);
2611 if (is_reference (var))
2612 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2613 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
2614 gimplify_and_add (x, stmt_list);
2616 c = OMP_CLAUSE_CHAIN (c);
2617 if (c == NULL && !par_clauses)
2619 /* If this was a workshare clause, see if it had been combined
2620 with its parallel. In that case, continue looking for the
2621 clauses also on the parallel statement itself. */
2622 if (is_parallel_ctx (ctx))
2626 if (ctx == NULL || !is_parallel_ctx (ctx))
2629 c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2630 OMP_CLAUSE_LASTPRIVATE);
2636 gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
2640 /* Generate code to implement the REDUCTION clauses. */
2643 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
2645 gimple_seq sub_seq = NULL;
2650 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2651 update in that case, otherwise use a lock. */
2652 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
2653 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
2655 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2657 /* Never use OMP_ATOMIC for array reductions. */
2667 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2669 tree var, ref, new_var;
2670 enum tree_code code;
2671 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2673 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
2676 var = OMP_CLAUSE_DECL (c);
2677 new_var = lookup_decl (var, ctx);
2678 if (is_reference (var))
2679 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2680 ref = build_outer_var_ref (var, ctx);
2681 code = OMP_CLAUSE_REDUCTION_CODE (c);
2683 /* reduction(-:var) sums up the partial results, so it acts
2684 identically to reduction(+:var). */
2685 if (code == MINUS_EXPR)
2690 tree addr = build_fold_addr_expr_loc (clause_loc, ref);
2692 addr = save_expr (addr);
2693 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
2694 x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
2695 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
2696 gimplify_and_add (x, stmt_seqp);
2700 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2702 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2704 if (is_reference (var))
2705 ref = build_fold_addr_expr_loc (clause_loc, ref);
2706 SET_DECL_VALUE_EXPR (placeholder, ref);
2707 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2708 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2709 gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
2710 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
2711 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
2715 x = build2 (code, TREE_TYPE (ref), ref, new_var);
2716 ref = build_outer_var_ref (var, ctx);
2717 gimplify_assign (ref, x, &sub_seq);
2721 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START),
2723 gimple_seq_add_stmt (stmt_seqp, stmt);
2725 gimple_seq_add_seq (stmt_seqp, sub_seq);
2727 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END),
2729 gimple_seq_add_stmt (stmt_seqp, stmt);
2733 /* Generate code to implement the COPYPRIVATE clauses. */
2736 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
2741 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2743 tree var, new_var, ref, x;
2745 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2747 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
2750 var = OMP_CLAUSE_DECL (c);
2751 by_ref = use_pointer_for_field (var, NULL);
2753 ref = build_sender_ref (var, ctx);
2754 x = new_var = lookup_decl_in_outer_ctx (var, ctx);
2757 x = build_fold_addr_expr_loc (clause_loc, new_var);
2758 x = fold_convert_loc (clause_loc, TREE_TYPE (ref), x);
2760 gimplify_assign (ref, x, slist);
2762 ref = build_receiver_ref (var, false, ctx);
2765 ref = fold_convert_loc (clause_loc,
2766 build_pointer_type (TREE_TYPE (new_var)),
2768 ref = build_fold_indirect_ref_loc (clause_loc, ref);
2770 if (is_reference (var))
2772 ref = fold_convert_loc (clause_loc, TREE_TYPE (new_var), ref);
2773 ref = build_simple_mem_ref_loc (clause_loc, ref);
2774 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
2776 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, ref);
2777 gimplify_and_add (x, rlist);
2782 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2783 and REDUCTION from the sender (aka parent) side. */
2786 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
2791 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2793 tree val, ref, x, var;
2794 bool by_ref, do_in = false, do_out = false;
2795 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2797 switch (OMP_CLAUSE_CODE (c))
2799 case OMP_CLAUSE_PRIVATE:
2800 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2803 case OMP_CLAUSE_FIRSTPRIVATE:
2804 case OMP_CLAUSE_COPYIN:
2805 case OMP_CLAUSE_LASTPRIVATE:
2806 case OMP_CLAUSE_REDUCTION:
2812 val = OMP_CLAUSE_DECL (c);
2813 var = lookup_decl_in_outer_ctx (val, ctx);
2815 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2816 && is_global_var (var))
2818 if (is_variable_sized (val))
2820 by_ref = use_pointer_for_field (val, NULL);
2822 switch (OMP_CLAUSE_CODE (c))
2824 case OMP_CLAUSE_PRIVATE:
2825 case OMP_CLAUSE_FIRSTPRIVATE:
2826 case OMP_CLAUSE_COPYIN:
2830 case OMP_CLAUSE_LASTPRIVATE:
2831 if (by_ref || is_reference (val))
2833 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2840 if (lang_hooks.decls.omp_private_outer_ref (val))
2845 case OMP_CLAUSE_REDUCTION:
2847 do_out = !(by_ref || is_reference (val));
2856 ref = build_sender_ref (val, ctx);
2857 x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
2858 gimplify_assign (ref, x, ilist);
2859 if (is_task_ctx (ctx))
2860 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
2865 ref = build_sender_ref (val, ctx);
2866 gimplify_assign (var, ref, olist);
2871 /* Generate code to implement SHARED from the sender (aka parent)
2872 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2873 list things that got automatically shared. */
2876 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
2878 tree var, ovar, nvar, f, x, record_type;
2880 if (ctx->record_type == NULL)
2883 record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
2884 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
2886 ovar = DECL_ABSTRACT_ORIGIN (f);
2887 nvar = maybe_lookup_decl (ovar, ctx);
2888 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2891 /* If CTX is a nested parallel directive. Find the immediately
2892 enclosing parallel or workshare construct that contains a
2893 mapping for OVAR. */
2894 var = lookup_decl_in_outer_ctx (ovar, ctx);
2896 if (use_pointer_for_field (ovar, ctx))
2898 x = build_sender_ref (ovar, ctx);
2899 var = build_fold_addr_expr (var);
2900 gimplify_assign (x, var, ilist);
2904 x = build_sender_ref (ovar, ctx);
2905 gimplify_assign (x, var, ilist);
2907 if (!TREE_READONLY (var)
2908 /* We don't need to receive a new reference to a result
2909 or parm decl. In fact we may not store to it as we will
2910 invalidate any pending RSO and generate wrong gimple
2912 && !((TREE_CODE (var) == RESULT_DECL
2913 || TREE_CODE (var) == PARM_DECL)
2914 && DECL_BY_REFERENCE (var)))
2916 x = build_sender_ref (ovar, ctx);
2917 gimplify_assign (var, x, olist);
2924 /* A convenience function to build an empty GIMPLE_COND with just the
2928 gimple_build_cond_empty (tree cond)
2930 enum tree_code pred_code;
2933 gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
2934 return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
2938 /* Build the function calls to GOMP_parallel_start etc to actually
2939 generate the parallel operation. REGION is the parallel region
2940 being expanded. BB is the block where to insert the code. WS_ARGS
2941 will be set if this is a call to a combined parallel+workshare
2942 construct, it contains the list of additional arguments needed by
2943 the workshare construct. */
2946 expand_parallel_call (struct omp_region *region, basic_block bb,
2947 gimple entry_stmt, VEC(tree,gc) *ws_args)
2949 tree t, t1, t2, val, cond, c, clauses;
2950 gimple_stmt_iterator gsi;
2952 enum built_in_function start_ix;
2954 location_t clause_loc;
2957 clauses = gimple_omp_parallel_clauses (entry_stmt);
2959 /* Determine what flavor of GOMP_parallel_start we will be
2961 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2962 if (is_combined_parallel (region))
2964 switch (region->inner->type)
2966 case GIMPLE_OMP_FOR:
2967 gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
2968 start_ix2 = ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2969 + (region->inner->sched_kind
2970 == OMP_CLAUSE_SCHEDULE_RUNTIME
2971 ? 3 : region->inner->sched_kind));
2972 start_ix = (enum built_in_function)start_ix2;
2974 case GIMPLE_OMP_SECTIONS:
2975 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2982 /* By default, the value of NUM_THREADS is zero (selected at run time)
2983 and there is no conditional. */
2985 val = build_int_cst (unsigned_type_node, 0);
2987 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2989 cond = OMP_CLAUSE_IF_EXPR (c);
2991 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2994 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2995 clause_loc = OMP_CLAUSE_LOCATION (c);
2998 clause_loc = gimple_location (entry_stmt);
3000 /* Ensure 'val' is of the correct type. */
3001 val = fold_convert_loc (clause_loc, unsigned_type_node, val);
3003 /* If we found the clause 'if (cond)', build either
3004 (cond != 0) or (cond ? val : 1u). */
3007 gimple_stmt_iterator gsi;
3009 cond = gimple_boolify (cond);
3011 if (integer_zerop (val))
3012 val = fold_build2_loc (clause_loc,
3013 EQ_EXPR, unsigned_type_node, cond,
3014 build_int_cst (TREE_TYPE (cond), 0));
3017 basic_block cond_bb, then_bb, else_bb;
3018 edge e, e_then, e_else;
3019 tree tmp_then, tmp_else, tmp_join, tmp_var;
3021 tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
3022 if (gimple_in_ssa_p (cfun))
3024 tmp_then = make_ssa_name (tmp_var, NULL);
3025 tmp_else = make_ssa_name (tmp_var, NULL);
3026 tmp_join = make_ssa_name (tmp_var, NULL);
3035 e = split_block (bb, NULL);
3040 then_bb = create_empty_bb (cond_bb);
3041 else_bb = create_empty_bb (then_bb);
3042 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
3043 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
3045 stmt = gimple_build_cond_empty (cond);
3046 gsi = gsi_start_bb (cond_bb);
3047 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3049 gsi = gsi_start_bb (then_bb);
3050 stmt = gimple_build_assign (tmp_then, val);
3051 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3053 gsi = gsi_start_bb (else_bb);
3054 stmt = gimple_build_assign
3055 (tmp_else, build_int_cst (unsigned_type_node, 1));
3056 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3058 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
3059 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
3060 e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
3061 e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
3063 if (gimple_in_ssa_p (cfun))
3065 gimple phi = create_phi_node (tmp_join, bb);
3066 SSA_NAME_DEF_STMT (tmp_join) = phi;
3067 add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
3068 add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
3074 gsi = gsi_start_bb (bb);
3075 val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
3076 false, GSI_CONTINUE_LINKING);
3079 gsi = gsi_last_bb (bb);
3080 t = gimple_omp_parallel_data_arg (entry_stmt);
3082 t1 = null_pointer_node;
3084 t1 = build_fold_addr_expr (t);
3085 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
3087 args = VEC_alloc (tree, gc, 3 + VEC_length (tree, ws_args));
3088 VEC_quick_push (tree, args, t2);
3089 VEC_quick_push (tree, args, t1);
3090 VEC_quick_push (tree, args, val);
3091 VEC_splice (tree, args, ws_args);
3093 t = build_call_expr_loc_vec (UNKNOWN_LOCATION,
3094 builtin_decl_explicit (start_ix), args);
3096 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3097 false, GSI_CONTINUE_LINKING);
3099 t = gimple_omp_parallel_data_arg (entry_stmt);
3101 t = null_pointer_node;
3103 t = build_fold_addr_expr (t);
3104 t = build_call_expr_loc (gimple_location (entry_stmt),
3105 gimple_omp_parallel_child_fn (entry_stmt), 1, t);
3106 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3107 false, GSI_CONTINUE_LINKING);
3109 t = build_call_expr_loc (gimple_location (entry_stmt),
3110 builtin_decl_explicit (BUILT_IN_GOMP_PARALLEL_END),
3112 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3113 false, GSI_CONTINUE_LINKING);
3117 /* Build the function call to GOMP_task to actually
3118 generate the task operation. BB is the block where to insert the code. */
3121 expand_task_call (basic_block bb, gimple entry_stmt)
3123 tree t, t1, t2, t3, flags, cond, c, c2, clauses;
3124 gimple_stmt_iterator gsi;
3125 location_t loc = gimple_location (entry_stmt);
3127 clauses = gimple_omp_task_clauses (entry_stmt);
3129 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
3131 cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
3133 cond = boolean_true_node;
3135 c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
3136 c2 = find_omp_clause (clauses, OMP_CLAUSE_MERGEABLE);
3137 flags = build_int_cst (unsigned_type_node,
3138 (c ? 1 : 0) + (c2 ? 4 : 0));
3140 c = find_omp_clause (clauses, OMP_CLAUSE_FINAL);
3143 c = gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c));
3144 c = fold_build3_loc (loc, COND_EXPR, unsigned_type_node, c,
3145 build_int_cst (unsigned_type_node, 2),
3146 build_int_cst (unsigned_type_node, 0));
3147 flags = fold_build2_loc (loc, PLUS_EXPR, unsigned_type_node, flags, c);
3150 gsi = gsi_last_bb (bb);
3151 t = gimple_omp_task_data_arg (entry_stmt);
3153 t2 = null_pointer_node;
3155 t2 = build_fold_addr_expr_loc (loc, t);
3156 t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
3157 t = gimple_omp_task_copy_fn (entry_stmt);
3159 t3 = null_pointer_node;
3161 t3 = build_fold_addr_expr_loc (loc, t);
3163 t = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK),
3165 gimple_omp_task_arg_size (entry_stmt),
3166 gimple_omp_task_arg_align (entry_stmt), cond, flags);
3168 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3169 false, GSI_CONTINUE_LINKING);
3173 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3174 catch handler and return it. This prevents programs from violating the
3175 structured block semantics with throws. */
3178 maybe_catch_exception (gimple_seq body)
3183 if (!flag_exceptions)
3186 if (lang_hooks.eh_protect_cleanup_actions != NULL)
3187 decl = lang_hooks.eh_protect_cleanup_actions ();
3189 decl = builtin_decl_explicit (BUILT_IN_TRAP);
3191 g = gimple_build_eh_must_not_throw (decl);
3192 g = gimple_build_try (body, gimple_seq_alloc_with_stmt (g),
3195 return gimple_seq_alloc_with_stmt (g);
3198 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3201 vec2chain (VEC(tree,gc) *v)
3203 tree chain = NULL_TREE, t;
3206 FOR_EACH_VEC_ELT_REVERSE (tree, v, ix, t)
3208 DECL_CHAIN (t) = chain;
3216 /* Remove barriers in REGION->EXIT's block. Note that this is only
3217 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3218 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3219 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3223 remove_exit_barrier (struct omp_region *region)
3225 gimple_stmt_iterator gsi;
3226 basic_block exit_bb;
3230 int any_addressable_vars = -1;
3232 exit_bb = region->exit;
3234 /* If the parallel region doesn't return, we don't have REGION->EXIT
3239 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3240 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3241 statements that can appear in between are extremely limited -- no
3242 memory operations at all. Here, we allow nothing at all, so the
3243 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3244 gsi = gsi_last_bb (exit_bb);
3245 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3247 if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
3250 FOR_EACH_EDGE (e, ei, exit_bb->preds)
3252 gsi = gsi_last_bb (e->src);
3253 if (gsi_end_p (gsi))
3255 stmt = gsi_stmt (gsi);
3256 if (gimple_code (stmt) == GIMPLE_OMP_RETURN
3257 && !gimple_omp_return_nowait_p (stmt))
3259 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3260 in many cases. If there could be tasks queued, the barrier
3261 might be needed to let the tasks run before some local
3262 variable of the parallel that the task uses as shared
3263 runs out of scope. The task can be spawned either
3264 from within current function (this would be easy to check)
3265 or from some function it calls and gets passed an address
3266 of such a variable. */
3267 if (any_addressable_vars < 0)
3269 gimple parallel_stmt = last_stmt (region->entry);
3270 tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
3271 tree local_decls, block, decl;
3274 any_addressable_vars = 0;
3275 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun), ix, decl)
3276 if (TREE_ADDRESSABLE (decl))
3278 any_addressable_vars = 1;
3281 for (block = gimple_block (stmt);
3282 !any_addressable_vars
3284 && TREE_CODE (block) == BLOCK;
3285 block = BLOCK_SUPERCONTEXT (block))
3287 for (local_decls = BLOCK_VARS (block);
3289 local_decls = DECL_CHAIN (local_decls))
3290 if (TREE_ADDRESSABLE (local_decls))
3292 any_addressable_vars = 1;
3295 if (block == gimple_block (parallel_stmt))
3299 if (!any_addressable_vars)
3300 gimple_omp_return_set_nowait (stmt);
3306 remove_exit_barriers (struct omp_region *region)
3308 if (region->type == GIMPLE_OMP_PARALLEL)
3309 remove_exit_barrier (region);
3313 region = region->inner;
3314 remove_exit_barriers (region);
3315 while (region->next)
3317 region = region->next;
3318 remove_exit_barriers (region);
3323 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3324 calls. These can't be declared as const functions, but
3325 within one parallel body they are constant, so they can be
3326 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3327 which are declared const. Similarly for task body, except
3328 that in untied task omp_get_thread_num () can change at any task
3329 scheduling point. */
3332 optimize_omp_library_calls (gimple entry_stmt)
3335 gimple_stmt_iterator gsi;
3336 tree thr_num_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3337 tree thr_num_id = DECL_ASSEMBLER_NAME (thr_num_tree);
3338 tree num_thr_tree = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3339 tree num_thr_id = DECL_ASSEMBLER_NAME (num_thr_tree);
3340 bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
3341 && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
3342 OMP_CLAUSE_UNTIED) != NULL);
3345 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3347 gimple call = gsi_stmt (gsi);
3350 if (is_gimple_call (call)
3351 && (decl = gimple_call_fndecl (call))
3352 && DECL_EXTERNAL (decl)
3353 && TREE_PUBLIC (decl)
3354 && DECL_INITIAL (decl) == NULL)
3358 if (DECL_NAME (decl) == thr_num_id)
3360 /* In #pragma omp task untied omp_get_thread_num () can change
3361 during the execution of the task region. */
3364 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
3366 else if (DECL_NAME (decl) == num_thr_id)
3367 built_in = builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS);
3371 if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
3372 || gimple_call_num_args (call) != 0)
3375 if (flag_exceptions && !TREE_NOTHROW (decl))
3378 if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
3379 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl)),
3380 TREE_TYPE (TREE_TYPE (built_in))))
3383 gimple_call_set_fndecl (call, built_in);
3388 /* Expand the OpenMP parallel or task directive starting at REGION. */
3391 expand_omp_taskreg (struct omp_region *region)
3393 basic_block entry_bb, exit_bb, new_bb;
3394 struct function *child_cfun;
3395 tree child_fn, block, t;
3397 gimple_stmt_iterator gsi;
3398 gimple entry_stmt, stmt;
3400 VEC(tree,gc) *ws_args;
3402 entry_stmt = last_stmt (region->entry);
3403 child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
3404 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
3405 /* If this function has been already instrumented, make sure
3406 the child function isn't instrumented again. */
3407 child_cfun->after_tree_profile = cfun->after_tree_profile;
3409 entry_bb = region->entry;
3410 exit_bb = region->exit;
3412 if (is_combined_parallel (region))
3413 ws_args = region->ws_args;
3417 if (child_cfun->cfg)
3419 /* Due to inlining, it may happen that we have already outlined
3420 the region, in which case all we need to do is make the
3421 sub-graph unreachable and emit the parallel call. */
3422 edge entry_succ_e, exit_succ_e;
3423 gimple_stmt_iterator gsi;
3425 entry_succ_e = single_succ_edge (entry_bb);
3427 gsi = gsi_last_bb (entry_bb);
3428 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
3429 || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
3430 gsi_remove (&gsi, true);
3435 exit_succ_e = single_succ_edge (exit_bb);
3436 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
3438 remove_edge_and_dominated_blocks (entry_succ_e);
3442 unsigned srcidx, dstidx, num;
3444 /* If the parallel region needs data sent from the parent
3445 function, then the very first statement (except possible
3446 tree profile counter updates) of the parallel body
3447 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3448 &.OMP_DATA_O is passed as an argument to the child function,
3449 we need to replace it with the argument as seen by the child
3452 In most cases, this will end up being the identity assignment
3453 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3454 a function call that has been inlined, the original PARM_DECL
3455 .OMP_DATA_I may have been converted into a different local
3456 variable. In which case, we need to keep the assignment. */
3457 if (gimple_omp_taskreg_data_arg (entry_stmt))
3459 basic_block entry_succ_bb = single_succ (entry_bb);
3460 gimple_stmt_iterator gsi;
3462 gimple parcopy_stmt = NULL;
3464 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
3468 gcc_assert (!gsi_end_p (gsi));
3469 stmt = gsi_stmt (gsi);
3470 if (gimple_code (stmt) != GIMPLE_ASSIGN)
3473 if (gimple_num_ops (stmt) == 2)
3475 tree arg = gimple_assign_rhs1 (stmt);
3477 /* We're ignore the subcode because we're
3478 effectively doing a STRIP_NOPS. */
3480 if (TREE_CODE (arg) == ADDR_EXPR
3481 && TREE_OPERAND (arg, 0)
3482 == gimple_omp_taskreg_data_arg (entry_stmt))
3484 parcopy_stmt = stmt;
3490 gcc_assert (parcopy_stmt != NULL);
3491 arg = DECL_ARGUMENTS (child_fn);
3493 if (!gimple_in_ssa_p (cfun))
3495 if (gimple_assign_lhs (parcopy_stmt) == arg)
3496 gsi_remove (&gsi, true);
3499 /* ?? Is setting the subcode really necessary ?? */
3500 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
3501 gimple_assign_set_rhs1 (parcopy_stmt, arg);
3506 /* If we are in ssa form, we must load the value from the default
3507 definition of the argument. That should not be defined now,
3508 since the argument is not used uninitialized. */
3509 gcc_assert (gimple_default_def (cfun, arg) == NULL);
3510 narg = make_ssa_name (arg, gimple_build_nop ());
3511 set_default_def (arg, narg);
3512 /* ?? Is setting the subcode really necessary ?? */
3513 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
3514 gimple_assign_set_rhs1 (parcopy_stmt, narg);
3515 update_stmt (parcopy_stmt);
3519 /* Declare local variables needed in CHILD_CFUN. */
3520 block = DECL_INITIAL (child_fn);
3521 BLOCK_VARS (block) = vec2chain (child_cfun->local_decls);
3522 /* The gimplifier could record temporaries in parallel/task block
3523 rather than in containing function's local_decls chain,
3524 which would mean cgraph missed finalizing them. Do it now. */
3525 for (t = BLOCK_VARS (block); t; t = DECL_CHAIN (t))
3526 if (TREE_CODE (t) == VAR_DECL
3528 && !DECL_EXTERNAL (t))
3529 varpool_finalize_decl (t);
3530 DECL_SAVED_TREE (child_fn) = NULL;
3531 gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
3532 TREE_USED (block) = 1;
3534 /* Reset DECL_CONTEXT on function arguments. */
3535 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
3536 DECL_CONTEXT (t) = child_fn;
3538 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3539 so that it can be moved to the child function. */
3540 gsi = gsi_last_bb (entry_bb);
3541 stmt = gsi_stmt (gsi);
3542 gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
3543 || gimple_code (stmt) == GIMPLE_OMP_TASK));
3544 gsi_remove (&gsi, true);
3545 e = split_block (entry_bb, stmt);
3547 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3549 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3552 gsi = gsi_last_bb (exit_bb);
3553 gcc_assert (!gsi_end_p (gsi)
3554 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3555 stmt = gimple_build_return (NULL);
3556 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
3557 gsi_remove (&gsi, true);
3560 /* Move the parallel region into CHILD_CFUN. */
3562 if (gimple_in_ssa_p (cfun))
3564 push_cfun (child_cfun);
3565 init_tree_ssa (child_cfun);
3566 init_ssa_operands ();
3567 cfun->gimple_df->in_ssa_p = true;
3572 block = gimple_block (entry_stmt);
3574 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
3576 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
3578 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3579 num = VEC_length (tree, child_cfun->local_decls);
3580 for (srcidx = 0, dstidx = 0; srcidx < num; srcidx++)
3582 t = VEC_index (tree, child_cfun->local_decls, srcidx);
3583 if (DECL_CONTEXT (t) == cfun->decl)
3585 if (srcidx != dstidx)
3586 VEC_replace (tree, child_cfun->local_decls, dstidx, t);
3590 VEC_truncate (tree, child_cfun->local_decls, dstidx);
3592 /* Inform the callgraph about the new function. */
3593 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
3594 = cfun->curr_properties;
3595 cgraph_add_new_function (child_fn, true);
3597 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3598 fixed in a following pass. */
3599 push_cfun (child_cfun);
3600 save_current = current_function_decl;
3601 current_function_decl = child_fn;
3603 optimize_omp_library_calls (entry_stmt);
3604 rebuild_cgraph_edges ();
3606 /* Some EH regions might become dead, see PR34608. If
3607 pass_cleanup_cfg isn't the first pass to happen with the
3608 new child, these dead EH edges might cause problems.
3609 Clean them up now. */
3610 if (flag_exceptions)
3613 bool changed = false;
3616 changed |= gimple_purge_dead_eh_edges (bb);
3618 cleanup_tree_cfg ();
3620 if (gimple_in_ssa_p (cfun))
3621 update_ssa (TODO_update_ssa);
3622 current_function_decl = save_current;
3626 /* Emit a library call to launch the children threads. */
3627 if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
3628 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
3630 expand_task_call (new_bb, entry_stmt);
3631 update_ssa (TODO_update_ssa_only_virtuals);
3635 /* A subroutine of expand_omp_for. Generate code for a parallel
3636 loop with any schedule. Given parameters:
3638 for (V = N1; V cond N2; V += STEP) BODY;
3640 where COND is "<" or ">", we generate pseudocode
3642 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3643 if (more) goto L0; else goto L3;
3650 if (V cond iend) goto L1; else goto L2;
3652 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3655 If this is a combined omp parallel loop, instead of the call to
3656 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3658 For collapsed loops, given parameters:
3660 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3661 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3662 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3665 we generate pseudocode
3671 count3 = (adj + N32 - N31) / STEP3;
3676 count2 = (adj + N22 - N21) / STEP2;
3681 count1 = (adj + N12 - N11) / STEP1;
3682 count = count1 * count2 * count3;
3683 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3684 if (more) goto L0; else goto L3;
3688 V3 = N31 + (T % count3) * STEP3;
3690 V2 = N21 + (T % count2) * STEP2;
3692 V1 = N11 + T * STEP1;
3697 if (V < iend) goto L10; else goto L2;
3700 if (V3 cond3 N32) goto L1; else goto L11;
3704 if (V2 cond2 N22) goto L1; else goto L12;
3710 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3716 expand_omp_for_generic (struct omp_region *region,
3717 struct omp_for_data *fd,
3718 enum built_in_function start_fn,
3719 enum built_in_function next_fn)
3721 tree type, istart0, iend0, iend;
3722 tree t, vmain, vback, bias = NULL_TREE;
3723 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
3724 basic_block l2_bb = NULL, l3_bb = NULL;
3725 gimple_stmt_iterator gsi;
3727 bool in_combined_parallel = is_combined_parallel (region);
3728 bool broken_loop = region->cont == NULL;
3730 tree *counts = NULL;
3733 gcc_assert (!broken_loop || !in_combined_parallel);
3734 gcc_assert (fd->iter_type == long_integer_type_node
3735 || !in_combined_parallel);
3737 type = TREE_TYPE (fd->loop.v);
3738 istart0 = create_tmp_var (fd->iter_type, ".istart0");
3739 iend0 = create_tmp_var (fd->iter_type, ".iend0");
3740 TREE_ADDRESSABLE (istart0) = 1;
3741 TREE_ADDRESSABLE (iend0) = 1;
3742 if (gimple_in_ssa_p (cfun))
3744 add_referenced_var (istart0);
3745 add_referenced_var (iend0);
3748 /* See if we need to bias by LLONG_MIN. */
3749 if (fd->iter_type == long_long_unsigned_type_node
3750 && TREE_CODE (type) == INTEGER_TYPE
3751 && !TYPE_UNSIGNED (type))
3755 if (fd->loop.cond_code == LT_EXPR)
3758 n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
3762 n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
3765 if (TREE_CODE (n1) != INTEGER_CST
3766 || TREE_CODE (n2) != INTEGER_CST
3767 || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
3768 bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
3771 entry_bb = region->entry;
3772 cont_bb = region->cont;
3774 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
3775 gcc_assert (broken_loop
3776 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
3777 l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
3778 l1_bb = single_succ (l0_bb);
3781 l2_bb = create_empty_bb (cont_bb);
3782 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
3783 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
3787 l3_bb = BRANCH_EDGE (entry_bb)->dest;
3788 exit_bb = region->exit;
3790 gsi = gsi_last_bb (entry_bb);
3792 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
3793 if (fd->collapse > 1)
3795 /* collapsed loops need work for expansion in SSA form. */
3796 gcc_assert (!gimple_in_ssa_p (cfun));
3797 counts = (tree *) alloca (fd->collapse * sizeof (tree));
3798 for (i = 0; i < fd->collapse; i++)
3800 tree itype = TREE_TYPE (fd->loops[i].v);
3802 if (POINTER_TYPE_P (itype))
3803 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
3804 t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
3806 t = fold_build2 (PLUS_EXPR, itype,
3807 fold_convert (itype, fd->loops[i].step), t);
3808 t = fold_build2 (PLUS_EXPR, itype, t,
3809 fold_convert (itype, fd->loops[i].n2));
3810 t = fold_build2 (MINUS_EXPR, itype, t,
3811 fold_convert (itype, fd->loops[i].n1));
3812 if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
3813 t = fold_build2 (TRUNC_DIV_EXPR, itype,
3814 fold_build1 (NEGATE_EXPR, itype, t),
3815 fold_build1 (NEGATE_EXPR, itype,
3816 fold_convert (itype,
3817 fd->loops[i].step)));
3819 t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
3820 fold_convert (itype, fd->loops[i].step));
3821 t = fold_convert (type, t);
3822 if (TREE_CODE (t) == INTEGER_CST)
3826 counts[i] = create_tmp_var (type, ".count");
3827 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3828 true, GSI_SAME_STMT);
3829 stmt = gimple_build_assign (counts[i], t);
3830 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3832 if (SSA_VAR_P (fd->loop.n2))
3838 t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
3839 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3840 true, GSI_SAME_STMT);
3842 stmt = gimple_build_assign (fd->loop.n2, t);
3843 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3847 if (in_combined_parallel)
3849 /* In a combined parallel loop, emit a call to
3850 GOMP_loop_foo_next. */
3851 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
3852 build_fold_addr_expr (istart0),
3853 build_fold_addr_expr (iend0));
3857 tree t0, t1, t2, t3, t4;
3858 /* If this is not a combined parallel loop, emit a call to
3859 GOMP_loop_foo_start in ENTRY_BB. */
3860 t4 = build_fold_addr_expr (iend0);
3861 t3 = build_fold_addr_expr (istart0);
3862 t2 = fold_convert (fd->iter_type, fd->loop.step);
3863 if (POINTER_TYPE_P (type)
3864 && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
3866 /* Avoid casting pointers to integer of a different size. */
3868 = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
3869 t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
3870 t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
3874 t1 = fold_convert (fd->iter_type, fd->loop.n2);
3875 t0 = fold_convert (fd->iter_type, fd->loop.n1);
3879 t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
3880 t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
3882 if (fd->iter_type == long_integer_type_node)
3886 t = fold_convert (fd->iter_type, fd->chunk_size);
3887 t = build_call_expr (builtin_decl_explicit (start_fn),
3888 6, t0, t1, t2, t, t3, t4);
3891 t = build_call_expr (builtin_decl_explicit (start_fn),
3892 5, t0, t1, t2, t3, t4);
3900 /* The GOMP_loop_ull_*start functions have additional boolean
3901 argument, true for < loops and false for > loops.
3902 In Fortran, the C bool type can be different from
3903 boolean_type_node. */
3904 bfn_decl = builtin_decl_explicit (start_fn);
3905 c_bool_type = TREE_TYPE (TREE_TYPE (bfn_decl));
3906 t5 = build_int_cst (c_bool_type,
3907 fd->loop.cond_code == LT_EXPR ? 1 : 0);
3910 tree bfn_decl = builtin_decl_explicit (start_fn);
3911 t = fold_convert (fd->iter_type, fd->chunk_size);
3912 t = build_call_expr (bfn_decl, 7, t5, t0, t1, t2, t, t3, t4);
3915 t = build_call_expr (builtin_decl_explicit (start_fn),
3916 6, t5, t0, t1, t2, t3, t4);
3919 if (TREE_TYPE (t) != boolean_type_node)
3920 t = fold_build2 (NE_EXPR, boolean_type_node,
3921 t, build_int_cst (TREE_TYPE (t), 0));
3922 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3923 true, GSI_SAME_STMT);
3924 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
3926 /* Remove the GIMPLE_OMP_FOR statement. */
3927 gsi_remove (&gsi, true);
3929 /* Iteration setup for sequential loop goes in L0_BB. */
3930 gsi = gsi_start_bb (l0_bb);
3933 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3934 if (POINTER_TYPE_P (type))
3935 t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
3937 t = fold_convert (type, t);
3938 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3939 false, GSI_CONTINUE_LINKING);
3940 stmt = gimple_build_assign (fd->loop.v, t);
3941 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3945 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3946 if (POINTER_TYPE_P (type))
3947 t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
3949 t = fold_convert (type, t);
3950 iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3951 false, GSI_CONTINUE_LINKING);
3952 if (fd->collapse > 1)
3954 tree tem = create_tmp_var (type, ".tem");
3956 stmt = gimple_build_assign (tem, fd->loop.v);
3957 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3958 for (i = fd->collapse - 1; i >= 0; i--)
3960 tree vtype = TREE_TYPE (fd->loops[i].v), itype;
3962 if (POINTER_TYPE_P (vtype))
3963 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (vtype), 0);
3964 t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
3965 t = fold_convert (itype, t);
3966 t = fold_build2 (MULT_EXPR, itype, t,
3967 fold_convert (itype, fd->loops[i].step));
3968 if (POINTER_TYPE_P (vtype))
3969 t = fold_build_pointer_plus (fd->loops[i].n1, t);
3971 t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
3972 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3973 false, GSI_CONTINUE_LINKING);
3974 stmt = gimple_build_assign (fd->loops[i].v, t);
3975 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3978 t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
3979 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3980 false, GSI_CONTINUE_LINKING);
3981 stmt = gimple_build_assign (tem, t);
3982 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3989 /* Code to control the increment and predicate for the sequential
3990 loop goes in the CONT_BB. */
3991 gsi = gsi_last_bb (cont_bb);
3992 stmt = gsi_stmt (gsi);
3993 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
3994 vmain = gimple_omp_continue_control_use (stmt);
3995 vback = gimple_omp_continue_control_def (stmt);
3997 if (POINTER_TYPE_P (type))
3998 t = fold_build_pointer_plus (vmain, fd->loop.step);
4000 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
4001 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4002 true, GSI_SAME_STMT);
4003 stmt = gimple_build_assign (vback, t);
4004 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4006 t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
4007 stmt = gimple_build_cond_empty (t);
4008 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4010 /* Remove GIMPLE_OMP_CONTINUE. */
4011 gsi_remove (&gsi, true);
4013 if (fd->collapse > 1)
4015 basic_block last_bb, bb;
4018 for (i = fd->collapse - 1; i >= 0; i--)
4020 tree vtype = TREE_TYPE (fd->loops[i].v);
4022 bb = create_empty_bb (last_bb);
4023 gsi = gsi_start_bb (bb);
4025 if (i < fd->collapse - 1)
4027 e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
4028 e->probability = REG_BR_PROB_BASE / 8;
4030 t = fd->loops[i + 1].n1;
4031 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4032 false, GSI_CONTINUE_LINKING);
4033 stmt = gimple_build_assign (fd->loops[i + 1].v, t);
4034 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4039 set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
4041 if (POINTER_TYPE_P (vtype))
4042 t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
4044 t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
4046 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4047 false, GSI_CONTINUE_LINKING);
4048 stmt = gimple_build_assign (fd->loops[i].v, t);
4049 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4053 t = fd->loops[i].n2;
4054 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4055 false, GSI_CONTINUE_LINKING);
4056 t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
4058 stmt = gimple_build_cond_empty (t);
4059 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4060 e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
4061 e->probability = REG_BR_PROB_BASE * 7 / 8;
4064 make_edge (bb, l1_bb, EDGE_FALLTHRU);
4069 /* Emit code to get the next parallel iteration in L2_BB. */
4070 gsi = gsi_start_bb (l2_bb);
4072 t = build_call_expr (builtin_decl_explicit (next_fn), 2,
4073 build_fold_addr_expr (istart0),
4074 build_fold_addr_expr (iend0));
4075 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4076 false, GSI_CONTINUE_LINKING);
4077 if (TREE_TYPE (t) != boolean_type_node)
4078 t = fold_build2 (NE_EXPR, boolean_type_node,
4079 t, build_int_cst (TREE_TYPE (t), 0));
4080 stmt = gimple_build_cond_empty (t);
4081 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4084 /* Add the loop cleanup function. */
4085 gsi = gsi_last_bb (exit_bb);
4086 if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4087 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT);
4089 t = builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END);
4090 stmt = gimple_build_call (t, 0);
4091 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
4092 gsi_remove (&gsi, true);
4094 /* Connect the new blocks. */
4095 find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
4096 find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
4102 e = find_edge (cont_bb, l3_bb);
4103 ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
4105 phis = phi_nodes (l3_bb);
4106 for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
4108 gimple phi = gsi_stmt (gsi);
4109 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
4110 PHI_ARG_DEF_FROM_EDGE (phi, e));
4114 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
4115 if (fd->collapse > 1)
4117 e = find_edge (cont_bb, l1_bb);
4119 e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
4123 e = find_edge (cont_bb, l1_bb);
4124 e->flags = EDGE_TRUE_VALUE;
4126 e->probability = REG_BR_PROB_BASE * 7 / 8;
4127 find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
4128 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
4130 set_immediate_dominator (CDI_DOMINATORS, l2_bb,
4131 recompute_dominator (CDI_DOMINATORS, l2_bb));
4132 set_immediate_dominator (CDI_DOMINATORS, l3_bb,
4133 recompute_dominator (CDI_DOMINATORS, l3_bb));
4134 set_immediate_dominator (CDI_DOMINATORS, l0_bb,
4135 recompute_dominator (CDI_DOMINATORS, l0_bb));
4136 set_immediate_dominator (CDI_DOMINATORS, l1_bb,
4137 recompute_dominator (CDI_DOMINATORS, l1_bb));
4142 /* A subroutine of expand_omp_for. Generate code for a parallel
4143 loop with static schedule and no specified chunk size. Given
4146 for (V = N1; V cond N2; V += STEP) BODY;
4148 where COND is "<" or ">", we generate pseudocode
4154 if ((__typeof (V)) -1 > 0 && cond is >)
4155 n = -(adj + N2 - N1) / -STEP;
4157 n = (adj + N2 - N1) / STEP;
4160 if (threadid < tt) goto L3; else goto L4;
4165 s0 = q * threadid + tt;
4168 if (s0 >= e0) goto L2; else goto L0;
4174 if (V cond e) goto L1;
4179 expand_omp_for_static_nochunk (struct omp_region *region,
4180 struct omp_for_data *fd)
4182 tree n, q, s0, e0, e, t, tt, nthreads, threadid;
4183 tree type, itype, vmain, vback;
4184 basic_block entry_bb, second_bb, third_bb, exit_bb, seq_start_bb;
4185 basic_block body_bb, cont_bb;
4187 gimple_stmt_iterator gsi;
4191 itype = type = TREE_TYPE (fd->loop.v);
4192 if (POINTER_TYPE_P (type))
4193 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
4195 entry_bb = region->entry;
4196 cont_bb = region->cont;
4197 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
4198 gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
4199 seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
4200 body_bb = single_succ (seq_start_bb);
4201 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4202 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4203 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4204 exit_bb = region->exit;
4206 /* Iteration space partitioning goes in ENTRY_BB. */
4207 gsi = gsi_last_bb (entry_bb);
4208 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4210 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4211 t = fold_convert (itype, t);
4212 nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4213 true, GSI_SAME_STMT);
4215 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4216 t = fold_convert (itype, t);
4217 threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4218 true, GSI_SAME_STMT);
4221 = force_gimple_operand_gsi (&gsi, fold_convert (type, fd->loop.n1),
4222 true, NULL_TREE, true, GSI_SAME_STMT);
4224 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.n2),
4225 true, NULL_TREE, true, GSI_SAME_STMT);
4227 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.step),
4228 true, NULL_TREE, true, GSI_SAME_STMT);
4230 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4231 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4232 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4233 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4234 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4235 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4236 fold_build1 (NEGATE_EXPR, itype, t),
4237 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4239 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4240 t = fold_convert (itype, t);
4241 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4243 q = create_tmp_var (itype, "q");
4244 t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
4245 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4246 gsi_insert_before (&gsi, gimple_build_assign (q, t), GSI_SAME_STMT);
4248 tt = create_tmp_var (itype, "tt");
4249 t = fold_build2 (TRUNC_MOD_EXPR, itype, n, nthreads);
4250 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE, true, GSI_SAME_STMT);
4251 gsi_insert_before (&gsi, gimple_build_assign (tt, t), GSI_SAME_STMT);
4253 t = build2 (LT_EXPR, boolean_type_node, threadid, tt);
4254 stmt = gimple_build_cond_empty (t);
4255 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4257 second_bb = split_block (entry_bb, stmt)->dest;
4258 gsi = gsi_last_bb (second_bb);
4259 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4261 gsi_insert_before (&gsi, gimple_build_assign (tt, build_int_cst (itype, 0)),
4263 stmt = gimple_build_assign_with_ops (PLUS_EXPR, q, q,
4264 build_int_cst (itype, 1));
4265 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4267 third_bb = split_block (second_bb, stmt)->dest;
4268 gsi = gsi_last_bb (third_bb);
4269 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4271 t = build2 (MULT_EXPR, itype, q, threadid);
4272 t = build2 (PLUS_EXPR, itype, t, tt);
4273 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4275 t = fold_build2 (PLUS_EXPR, itype, s0, q);
4276 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4278 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
4279 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4281 /* Remove the GIMPLE_OMP_FOR statement. */
4282 gsi_remove (&gsi, true);
4284 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4285 gsi = gsi_start_bb (seq_start_bb);
4287 t = fold_convert (itype, s0);
4288 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4289 if (POINTER_TYPE_P (type))
4290 t = fold_build_pointer_plus (fd->loop.n1, t);
4292 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4293 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4294 false, GSI_CONTINUE_LINKING);
4295 stmt = gimple_build_assign (fd->loop.v, t);
4296 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4298 t = fold_convert (itype, e0);
4299 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4300 if (POINTER_TYPE_P (type))
4301 t = fold_build_pointer_plus (fd->loop.n1, t);
4303 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4304 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4305 false, GSI_CONTINUE_LINKING);
4307 /* The code controlling the sequential loop replaces the
4308 GIMPLE_OMP_CONTINUE. */
4309 gsi = gsi_last_bb (cont_bb);
4310 stmt = gsi_stmt (gsi);
4311 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4312 vmain = gimple_omp_continue_control_use (stmt);
4313 vback = gimple_omp_continue_control_def (stmt);
4315 if (POINTER_TYPE_P (type))
4316 t = fold_build_pointer_plus (vmain, fd->loop.step);
4318 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
4319 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4320 true, GSI_SAME_STMT);
4321 stmt = gimple_build_assign (vback, t);
4322 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4324 t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
4325 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4327 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4328 gsi_remove (&gsi, true);
4330 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4331 gsi = gsi_last_bb (exit_bb);
4332 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4333 force_gimple_operand_gsi (&gsi, build_omp_barrier (), false, NULL_TREE,
4334 false, GSI_SAME_STMT);
4335 gsi_remove (&gsi, true);
4337 /* Connect all the blocks. */
4338 ep = make_edge (entry_bb, third_bb, EDGE_FALSE_VALUE);
4339 ep->probability = REG_BR_PROB_BASE / 4 * 3;
4340 ep = find_edge (entry_bb, second_bb);
4341 ep->flags = EDGE_TRUE_VALUE;
4342 ep->probability = REG_BR_PROB_BASE / 4;
4343 find_edge (third_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
4344 find_edge (third_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
4346 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4347 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4349 set_immediate_dominator (CDI_DOMINATORS, second_bb, entry_bb);
4350 set_immediate_dominator (CDI_DOMINATORS, third_bb, entry_bb);
4351 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, third_bb);
4352 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4353 recompute_dominator (CDI_DOMINATORS, body_bb));
4354 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4355 recompute_dominator (CDI_DOMINATORS, fin_bb));
4359 /* A subroutine of expand_omp_for. Generate code for a parallel
4360 loop with static schedule and a specified chunk size. Given
4363 for (V = N1; V cond N2; V += STEP) BODY;
4365 where COND is "<" or ">", we generate pseudocode
4371 if ((__typeof (V)) -1 > 0 && cond is >)
4372 n = -(adj + N2 - N1) / -STEP;
4374 n = (adj + N2 - N1) / STEP;
4376 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4377 here so that V is defined
4378 if the loop is not entered
4380 s0 = (trip * nthreads + threadid) * CHUNK;
4381 e0 = min(s0 + CHUNK, n);
4382 if (s0 < n) goto L1; else goto L4;
4389 if (V cond e) goto L2; else goto L3;
4397 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
4399 tree n, s0, e0, e, t;
4400 tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
4401 tree type, itype, v_main, v_back, v_extra;
4402 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
4403 basic_block trip_update_bb, cont_bb, fin_bb;
4404 gimple_stmt_iterator si;
4408 itype = type = TREE_TYPE (fd->loop.v);
4409 if (POINTER_TYPE_P (type))
4410 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
4412 entry_bb = region->entry;
4413 se = split_block (entry_bb, last_stmt (entry_bb));
4415 iter_part_bb = se->dest;
4416 cont_bb = region->cont;
4417 gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
4418 gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
4419 == FALLTHRU_EDGE (cont_bb)->dest);
4420 seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
4421 body_bb = single_succ (seq_start_bb);
4422 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4423 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4424 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4425 trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
4426 exit_bb = region->exit;
4428 /* Trip and adjustment setup goes in ENTRY_BB. */
4429 si = gsi_last_bb (entry_bb);
4430 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
4432 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS), 0);
4433 t = fold_convert (itype, t);
4434 nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4435 true, GSI_SAME_STMT);
4437 t = build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM), 0);
4438 t = fold_convert (itype, t);
4439 threadid = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4440 true, GSI_SAME_STMT);
4443 = force_gimple_operand_gsi (&si, fold_convert (type, fd->loop.n1),
4444 true, NULL_TREE, true, GSI_SAME_STMT);
4446 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.n2),
4447 true, NULL_TREE, true, GSI_SAME_STMT);
4449 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.step),
4450 true, NULL_TREE, true, GSI_SAME_STMT);
4452 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->chunk_size),
4453 true, NULL_TREE, true, GSI_SAME_STMT);
4455 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4456 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4457 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4458 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4459 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4460 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4461 fold_build1 (NEGATE_EXPR, itype, t),
4462 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4464 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4465 t = fold_convert (itype, t);
4466 n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4467 true, GSI_SAME_STMT);
4469 trip_var = create_tmp_var (itype, ".trip");
4470 if (gimple_in_ssa_p (cfun))
4472 add_referenced_var (trip_var);
4473 trip_init = make_ssa_name (trip_var, NULL);
4474 trip_main = make_ssa_name (trip_var, NULL);
4475 trip_back = make_ssa_name (trip_var, NULL);
4479 trip_init = trip_var;
4480 trip_main = trip_var;
4481 trip_back = trip_var;
4484 stmt = gimple_build_assign (trip_init, build_int_cst (itype, 0));
4485 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4487 t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
4488 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4489 if (POINTER_TYPE_P (type))
4490 t = fold_build_pointer_plus (fd->loop.n1, t);
4492 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4493 v_extra = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4494 true, GSI_SAME_STMT);
4496 /* Remove the GIMPLE_OMP_FOR. */
4497 gsi_remove (&si, true);
4499 /* Iteration space partitioning goes in ITER_PART_BB. */
4500 si = gsi_last_bb (iter_part_bb);
4502 t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
4503 t = fold_build2 (PLUS_EXPR, itype, t, threadid);
4504 t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
4505 s0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4506 false, GSI_CONTINUE_LINKING);
4508 t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
4509 t = fold_build2 (MIN_EXPR, itype, t, n);
4510 e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4511 false, GSI_CONTINUE_LINKING);
4513 t = build2 (LT_EXPR, boolean_type_node, s0, n);
4514 gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
4516 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4517 si = gsi_start_bb (seq_start_bb);
4519 t = fold_convert (itype, s0);
4520 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4521 if (POINTER_TYPE_P (type))
4522 t = fold_build_pointer_plus (fd->loop.n1, t);
4524 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4525 t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
4526 false, GSI_CONTINUE_LINKING);
4527 stmt = gimple_build_assign (fd->loop.v, t);
4528 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4530 t = fold_convert (itype, e0);
4531 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4532 if (POINTER_TYPE_P (type))
4533 t = fold_build_pointer_plus (fd->loop.n1, t);
4535 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4536 e = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4537 false, GSI_CONTINUE_LINKING);
4539 /* The code controlling the sequential loop goes in CONT_BB,
4540 replacing the GIMPLE_OMP_CONTINUE. */
4541 si = gsi_last_bb (cont_bb);
4542 stmt = gsi_stmt (si);
4543 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4544 v_main = gimple_omp_continue_control_use (stmt);
4545 v_back = gimple_omp_continue_control_def (stmt);
4547 if (POINTER_TYPE_P (type))
4548 t = fold_build_pointer_plus (v_main, fd->loop.step);
4550 t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
4551 stmt = gimple_build_assign (v_back, t);
4552 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4554 t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
4555 gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
4557 /* Remove GIMPLE_OMP_CONTINUE. */
4558 gsi_remove (&si, true);
4560 /* Trip update code goes into TRIP_UPDATE_BB. */
4561 si = gsi_start_bb (trip_update_bb);
4563 t = build_int_cst (itype, 1);
4564 t = build2 (PLUS_EXPR, itype, trip_main, t);
4565 stmt = gimple_build_assign (trip_back, t);
4566 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4568 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4569 si = gsi_last_bb (exit_bb);
4570 if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
4571 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4572 false, GSI_SAME_STMT);
4573 gsi_remove (&si, true);
4575 /* Connect the new blocks. */
4576 find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
4577 find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4579 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4580 find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
4582 redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
4584 if (gimple_in_ssa_p (cfun))
4586 gimple_stmt_iterator psi;
4589 edge_var_map_vector head;
4593 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4594 remove arguments of the phi nodes in fin_bb. We need to create
4595 appropriate phi nodes in iter_part_bb instead. */
4596 se = single_pred_edge (fin_bb);
4597 re = single_succ_edge (trip_update_bb);
4598 head = redirect_edge_var_map_vector (re);
4599 ene = single_succ_edge (entry_bb);
4601 psi = gsi_start_phis (fin_bb);
4602 for (i = 0; !gsi_end_p (psi) && VEC_iterate (edge_var_map, head, i, vm);
4603 gsi_next (&psi), ++i)
4606 source_location locus;
4608 phi = gsi_stmt (psi);
4609 t = gimple_phi_result (phi);
4610 gcc_assert (t == redirect_edge_var_map_result (vm));
4611 nphi = create_phi_node (t, iter_part_bb);
4612 SSA_NAME_DEF_STMT (t) = nphi;
4614 t = PHI_ARG_DEF_FROM_EDGE (phi, se);
4615 locus = gimple_phi_arg_location_from_edge (phi, se);
4617 /* A special case -- fd->loop.v is not yet computed in
4618 iter_part_bb, we need to use v_extra instead. */
4619 if (t == fd->loop.v)
4621 add_phi_arg (nphi, t, ene, locus);
4622 locus = redirect_edge_var_map_location (vm);
4623 add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
4625 gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
4626 redirect_edge_var_map_clear (re);
4629 psi = gsi_start_phis (fin_bb);
4630 if (gsi_end_p (psi))
4632 remove_phi_node (&psi, false);
4635 /* Make phi node for trip. */
4636 phi = create_phi_node (trip_main, iter_part_bb);
4637 SSA_NAME_DEF_STMT (trip_main) = phi;
4638 add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
4640 add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
4644 set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
4645 set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
4646 recompute_dominator (CDI_DOMINATORS, iter_part_bb));
4647 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4648 recompute_dominator (CDI_DOMINATORS, fin_bb));
4649 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
4650 recompute_dominator (CDI_DOMINATORS, seq_start_bb));
4651 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4652 recompute_dominator (CDI_DOMINATORS, body_bb));
4656 /* Expand the OpenMP loop defined by REGION. */
4659 expand_omp_for (struct omp_region *region)
4661 struct omp_for_data fd;
4662 struct omp_for_data_loop *loops;
4665 = (struct omp_for_data_loop *)
4666 alloca (gimple_omp_for_collapse (last_stmt (region->entry))
4667 * sizeof (struct omp_for_data_loop));
4668 extract_omp_for_data (last_stmt (region->entry), &fd, loops);
4669 region->sched_kind = fd.sched_kind;
4671 gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
4672 BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4673 FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4676 gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
4677 BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4678 FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4681 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
4684 && region->cont != NULL)
4686 if (fd.chunk_size == NULL)
4687 expand_omp_for_static_nochunk (region, &fd);
4689 expand_omp_for_static_chunk (region, &fd);
4693 int fn_index, start_ix, next_ix;
4695 if (fd.chunk_size == NULL
4696 && fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
4697 fd.chunk_size = integer_zero_node;
4698 gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
4699 fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
4700 ? 3 : fd.sched_kind;
4701 fn_index += fd.have_ordered * 4;
4702 start_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_START) + fn_index;
4703 next_ix = ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT) + fn_index;
4704 if (fd.iter_type == long_long_unsigned_type_node)
4706 start_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4707 - (int)BUILT_IN_GOMP_LOOP_STATIC_START);
4708 next_ix += ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4709 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT);
4711 expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
4712 (enum built_in_function) next_ix);
4715 update_ssa (TODO_update_ssa_only_virtuals);
4719 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4721 v = GOMP_sections_start (n);
4738 v = GOMP_sections_next ();
4743 If this is a combined parallel sections, replace the call to
4744 GOMP_sections_start with call to GOMP_sections_next. */
4747 expand_omp_sections (struct omp_region *region)
4749 tree t, u, vin = NULL, vmain, vnext, l2;
4750 VEC (tree,heap) *label_vec;
4752 basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
4753 gimple_stmt_iterator si, switch_si;
4754 gimple sections_stmt, stmt, cont;
4757 struct omp_region *inner;
4759 bool exit_reachable = region->cont != NULL;
4761 gcc_assert (region->exit != NULL);
4762 entry_bb = region->entry;
4763 l0_bb = single_succ (entry_bb);
4764 l1_bb = region->cont;
4765 l2_bb = region->exit;
4766 if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
4767 l2 = gimple_block_label (l2_bb);
4770 /* This can happen if there are reductions. */
4771 len = EDGE_COUNT (l0_bb->succs);
4772 gcc_assert (len > 0);
4773 e = EDGE_SUCC (l0_bb, len - 1);
4774 si = gsi_last_bb (e->dest);
4777 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4778 l2 = gimple_block_label (e->dest);
4780 FOR_EACH_EDGE (e, ei, l0_bb->succs)
4782 si = gsi_last_bb (e->dest);
4784 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4786 l2 = gimple_block_label (e->dest);
4792 default_bb = create_empty_bb (l1_bb->prev_bb);
4794 default_bb = create_empty_bb (l0_bb);
4796 /* We will build a switch() with enough cases for all the
4797 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4798 and a default case to abort if something goes wrong. */
4799 len = EDGE_COUNT (l0_bb->succs);
4801 /* Use VEC_quick_push on label_vec throughout, since we know the size
4803 label_vec = VEC_alloc (tree, heap, len);
4805 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4806 GIMPLE_OMP_SECTIONS statement. */
4807 si = gsi_last_bb (entry_bb);
4808 sections_stmt = gsi_stmt (si);
4809 gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
4810 vin = gimple_omp_sections_control (sections_stmt);
4811 if (!is_combined_parallel (region))
4813 /* If we are not inside a combined parallel+sections region,
4814 call GOMP_sections_start. */
4815 t = build_int_cst (unsigned_type_node,
4816 exit_reachable ? len - 1 : len);
4817 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
4818 stmt = gimple_build_call (u, 1, t);
4822 /* Otherwise, call GOMP_sections_next. */
4823 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4824 stmt = gimple_build_call (u, 0);
4826 gimple_call_set_lhs (stmt, vin);
4827 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4828 gsi_remove (&si, true);
4830 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4832 switch_si = gsi_last_bb (l0_bb);
4833 gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
4836 cont = last_stmt (l1_bb);
4837 gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
4838 vmain = gimple_omp_continue_control_use (cont);
4839 vnext = gimple_omp_continue_control_def (cont);
4847 t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
4848 VEC_quick_push (tree, label_vec, t);
4851 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4852 for (inner = region->inner, casei = 1;
4854 inner = inner->next, i++, casei++)
4856 basic_block s_entry_bb, s_exit_bb;
4858 /* Skip optional reduction region. */
4859 if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
4866 s_entry_bb = inner->entry;
4867 s_exit_bb = inner->exit;
4869 t = gimple_block_label (s_entry_bb);
4870 u = build_int_cst (unsigned_type_node, casei);
4871 u = build_case_label (u, NULL, t);
4872 VEC_quick_push (tree, label_vec, u);
4874 si = gsi_last_bb (s_entry_bb);
4875 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
4876 gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
4877 gsi_remove (&si, true);
4878 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
4880 if (s_exit_bb == NULL)
4883 si = gsi_last_bb (s_exit_bb);
4884 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4885 gsi_remove (&si, true);
4887 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
4890 /* Error handling code goes in DEFAULT_BB. */
4891 t = gimple_block_label (default_bb);
4892 u = build_case_label (NULL, NULL, t);
4893 make_edge (l0_bb, default_bb, 0);
4895 stmt = gimple_build_switch_vec (vmain, u, label_vec);
4896 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4897 gsi_remove (&switch_si, true);
4898 VEC_free (tree, heap, label_vec);
4900 si = gsi_start_bb (default_bb);
4901 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
4902 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4908 /* Code to get the next section goes in L1_BB. */
4909 si = gsi_last_bb (l1_bb);
4910 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
4912 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4913 stmt = gimple_build_call (bfn_decl, 0);
4914 gimple_call_set_lhs (stmt, vnext);
4915 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4916 gsi_remove (&si, true);
4918 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
4921 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4922 si = gsi_last_bb (l2_bb);
4923 if (gimple_omp_return_nowait_p (gsi_stmt (si)))
4924 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
4926 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
4927 stmt = gimple_build_call (t, 0);
4928 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4929 gsi_remove (&si, true);
4931 set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
4935 /* Expand code for an OpenMP single directive. We've already expanded
4936 much of the code, here we simply place the GOMP_barrier call. */
4939 expand_omp_single (struct omp_region *region)
4941 basic_block entry_bb, exit_bb;
4942 gimple_stmt_iterator si;
4943 bool need_barrier = false;
4945 entry_bb = region->entry;
4946 exit_bb = region->exit;
4948 si = gsi_last_bb (entry_bb);
4949 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4950 be removed. We need to ensure that the thread that entered the single
4951 does not exit before the data is copied out by the other threads. */
4952 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
4953 OMP_CLAUSE_COPYPRIVATE))
4954 need_barrier = true;
4955 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
4956 gsi_remove (&si, true);
4957 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4959 si = gsi_last_bb (exit_bb);
4960 if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
4961 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4962 false, GSI_SAME_STMT);
4963 gsi_remove (&si, true);
4964 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4968 /* Generic expansion for OpenMP synchronization directives: master,
4969 ordered and critical. All we need to do here is remove the entry
4970 and exit markers for REGION. */
4973 expand_omp_synch (struct omp_region *region)
4975 basic_block entry_bb, exit_bb;
4976 gimple_stmt_iterator si;
4978 entry_bb = region->entry;
4979 exit_bb = region->exit;
4981 si = gsi_last_bb (entry_bb);
4982 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
4983 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
4984 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
4985 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
4986 gsi_remove (&si, true);
4987 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4991 si = gsi_last_bb (exit_bb);
4992 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4993 gsi_remove (&si, true);
4994 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4998 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
4999 operation as a normal volatile load. */
5002 expand_omp_atomic_load (basic_block load_bb, tree addr,
5003 tree loaded_val, int index)
5005 enum built_in_function tmpbase;
5006 gimple_stmt_iterator gsi;
5007 basic_block store_bb;
5010 tree decl, call, type, itype;
5012 gsi = gsi_last_bb (load_bb);
5013 stmt = gsi_stmt (gsi);
5014 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5015 loc = gimple_location (stmt);
5017 /* ??? If the target does not implement atomic_load_optab[mode], and mode
5018 is smaller than word size, then expand_atomic_load assumes that the load
5019 is atomic. We could avoid the builtin entirely in this case. */
5021 tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
5022 decl = builtin_decl_explicit (tmpbase);
5023 if (decl == NULL_TREE)
5026 type = TREE_TYPE (loaded_val);
5027 itype = TREE_TYPE (TREE_TYPE (decl));
5029 call = build_call_expr_loc (loc, decl, 2, addr,
5030 build_int_cst (NULL, MEMMODEL_RELAXED));
5031 if (!useless_type_conversion_p (type, itype))
5032 call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5033 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5035 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5036 gsi_remove (&gsi, true);
5038 store_bb = single_succ (load_bb);
5039 gsi = gsi_last_bb (store_bb);
5040 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5041 gsi_remove (&gsi, true);
5043 if (gimple_in_ssa_p (cfun))
5044 update_ssa (TODO_update_ssa_no_phi);
5049 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5050 operation as a normal volatile store. */
5053 expand_omp_atomic_store (basic_block load_bb, tree addr,
5054 tree loaded_val, tree stored_val, int index)
5056 enum built_in_function tmpbase;
5057 gimple_stmt_iterator gsi;
5058 basic_block store_bb = single_succ (load_bb);
5061 tree decl, call, type, itype;
5062 enum machine_mode imode;
5065 gsi = gsi_last_bb (load_bb);
5066 stmt = gsi_stmt (gsi);
5067 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5069 /* If the load value is needed, then this isn't a store but an exchange. */
5070 exchange = gimple_omp_atomic_need_value_p (stmt);
5072 gsi = gsi_last_bb (store_bb);
5073 stmt = gsi_stmt (gsi);
5074 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
5075 loc = gimple_location (stmt);
5077 /* ??? If the target does not implement atomic_store_optab[mode], and mode
5078 is smaller than word size, then expand_atomic_store assumes that the store
5079 is atomic. We could avoid the builtin entirely in this case. */
5081 tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
5082 tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
5083 decl = builtin_decl_explicit (tmpbase);
5084 if (decl == NULL_TREE)
5087 type = TREE_TYPE (stored_val);
5089 /* Dig out the type of the function's second argument. */
5090 itype = TREE_TYPE (decl);
5091 itype = TYPE_ARG_TYPES (itype);
5092 itype = TREE_CHAIN (itype);
5093 itype = TREE_VALUE (itype);
5094 imode = TYPE_MODE (itype);
5096 if (exchange && !can_atomic_exchange_p (imode, true))
5099 if (!useless_type_conversion_p (itype, type))
5100 stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
5101 call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
5102 build_int_cst (NULL, MEMMODEL_RELAXED));
5105 if (!useless_type_conversion_p (type, itype))
5106 call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5107 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5110 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5111 gsi_remove (&gsi, true);
5113 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
5114 gsi = gsi_last_bb (load_bb);
5115 gsi_remove (&gsi, true);
5117 if (gimple_in_ssa_p (cfun))
5118 update_ssa (TODO_update_ssa_no_phi);
5123 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5124 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
5125 size of the data type, and thus usable to find the index of the builtin
5126 decl. Returns false if the expression is not of the proper form. */
5129 expand_omp_atomic_fetch_op (basic_block load_bb,
5130 tree addr, tree loaded_val,
5131 tree stored_val, int index)
5133 enum built_in_function oldbase, newbase, tmpbase;
5134 tree decl, itype, call;
5136 basic_block store_bb = single_succ (load_bb);
5137 gimple_stmt_iterator gsi;
5140 enum tree_code code;
5141 bool need_old, need_new;
5142 enum machine_mode imode;
5144 /* We expect to find the following sequences:
5147 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5150 val = tmp OP something; (or: something OP tmp)
5151 GIMPLE_OMP_STORE (val)
5153 ???FIXME: Allow a more flexible sequence.
5154 Perhaps use data flow to pick the statements.
5158 gsi = gsi_after_labels (store_bb);
5159 stmt = gsi_stmt (gsi);
5160 loc = gimple_location (stmt);
5161 if (!is_gimple_assign (stmt))
5164 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
5166 need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
5167 need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
5168 gcc_checking_assert (!need_old || !need_new);
5170 if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
5173 /* Check for one of the supported fetch-op operations. */
5174 code = gimple_assign_rhs_code (stmt);
5178 case POINTER_PLUS_EXPR:
5179 oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
5180 newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
5183 oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
5184 newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
5187 oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
5188 newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
5191 oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
5192 newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
5195 oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
5196 newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
5202 /* Make sure the expression is of the proper form. */
5203 if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
5204 rhs = gimple_assign_rhs2 (stmt);
5205 else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
5206 && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
5207 rhs = gimple_assign_rhs1 (stmt);
5211 tmpbase = ((enum built_in_function)
5212 ((need_new ? newbase : oldbase) + index + 1));
5213 decl = builtin_decl_explicit (tmpbase);
5214 if (decl == NULL_TREE)
5216 itype = TREE_TYPE (TREE_TYPE (decl));
5217 imode = TYPE_MODE (itype);
5219 /* We could test all of the various optabs involved, but the fact of the
5220 matter is that (with the exception of i486 vs i586 and xadd) all targets
5221 that support any atomic operaton optab also implements compare-and-swap.
5222 Let optabs.c take care of expanding any compare-and-swap loop. */
5223 if (!can_compare_and_swap_p (imode, true))
5226 gsi = gsi_last_bb (load_bb);
5227 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
5229 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5230 It only requires that the operation happen atomically. Thus we can
5231 use the RELAXED memory model. */
5232 call = build_call_expr_loc (loc, decl, 3, addr,
5233 fold_convert_loc (loc, itype, rhs),
5234 build_int_cst (NULL, MEMMODEL_RELAXED));
5236 if (need_old || need_new)
5238 lhs = need_old ? loaded_val : stored_val;
5239 call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
5240 call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
5243 call = fold_convert_loc (loc, void_type_node, call);
5244 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5245 gsi_remove (&gsi, true);
5247 gsi = gsi_last_bb (store_bb);
5248 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5249 gsi_remove (&gsi, true);
5250 gsi = gsi_last_bb (store_bb);
5251 gsi_remove (&gsi, true);
5253 if (gimple_in_ssa_p (cfun))
5254 update_ssa (TODO_update_ssa_no_phi);
5259 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5263 newval = rhs; // with oldval replacing *addr in rhs
5264 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5265 if (oldval != newval)
5268 INDEX is log2 of the size of the data type, and thus usable to find the
5269 index of the builtin decl. */
5272 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
5273 tree addr, tree loaded_val, tree stored_val,
5276 tree loadedi, storedi, initial, new_storedi, old_vali;
5277 tree type, itype, cmpxchg, iaddr;
5278 gimple_stmt_iterator si;
5279 basic_block loop_header = single_succ (load_bb);
5282 enum built_in_function fncode;
5284 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5285 order to use the RELAXED memory model effectively. */
5286 fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5288 cmpxchg = builtin_decl_explicit (fncode);
5289 if (cmpxchg == NULL_TREE)
5291 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5292 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5294 if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
5297 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5298 si = gsi_last_bb (load_bb);
5299 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5301 /* For floating-point values, we'll need to view-convert them to integers
5302 so that we can perform the atomic compare and swap. Simplify the
5303 following code by always setting up the "i"ntegral variables. */
5304 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
5308 iaddr = create_tmp_var (build_pointer_type_for_mode (itype, ptr_mode,
5311 = force_gimple_operand_gsi (&si,
5312 fold_convert (TREE_TYPE (iaddr), addr),
5313 false, NULL_TREE, true, GSI_SAME_STMT);
5314 stmt = gimple_build_assign (iaddr, iaddr_val);
5315 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5316 loadedi = create_tmp_var (itype, NULL);
5317 if (gimple_in_ssa_p (cfun))
5319 add_referenced_var (iaddr);
5320 add_referenced_var (loadedi);
5321 loadedi = make_ssa_name (loadedi, NULL);
5327 loadedi = loaded_val;
5331 = force_gimple_operand_gsi (&si,
5332 build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
5334 build_int_cst (TREE_TYPE (iaddr), 0)),
5335 true, NULL_TREE, true, GSI_SAME_STMT);
5337 /* Move the value to the LOADEDI temporary. */
5338 if (gimple_in_ssa_p (cfun))
5340 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
5341 phi = create_phi_node (loadedi, loop_header);
5342 SSA_NAME_DEF_STMT (loadedi) = phi;
5343 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
5347 gsi_insert_before (&si,
5348 gimple_build_assign (loadedi, initial),
5350 if (loadedi != loaded_val)
5352 gimple_stmt_iterator gsi2;
5355 x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
5356 gsi2 = gsi_start_bb (loop_header);
5357 if (gimple_in_ssa_p (cfun))
5360 x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5361 true, GSI_SAME_STMT);
5362 stmt = gimple_build_assign (loaded_val, x);
5363 gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
5367 x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
5368 force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5369 true, GSI_SAME_STMT);
5372 gsi_remove (&si, true);
5374 si = gsi_last_bb (store_bb);
5375 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5378 storedi = stored_val;
5381 force_gimple_operand_gsi (&si,
5382 build1 (VIEW_CONVERT_EXPR, itype,
5383 stored_val), true, NULL_TREE, true,
5386 /* Build the compare&swap statement. */
5387 new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
5388 new_storedi = force_gimple_operand_gsi (&si,
5389 fold_convert (TREE_TYPE (loadedi),
5392 true, GSI_SAME_STMT);
5394 if (gimple_in_ssa_p (cfun))
5398 old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
5399 if (gimple_in_ssa_p (cfun))
5400 add_referenced_var (old_vali);
5401 stmt = gimple_build_assign (old_vali, loadedi);
5402 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5404 stmt = gimple_build_assign (loadedi, new_storedi);
5405 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5408 /* Note that we always perform the comparison as an integer, even for
5409 floating point. This allows the atomic operation to properly
5410 succeed even with NaNs and -0.0. */
5411 stmt = gimple_build_cond_empty
5412 (build2 (NE_EXPR, boolean_type_node,
5413 new_storedi, old_vali));
5414 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5417 e = single_succ_edge (store_bb);
5418 e->flags &= ~EDGE_FALLTHRU;
5419 e->flags |= EDGE_FALSE_VALUE;
5421 e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
5423 /* Copy the new value to loadedi (we already did that before the condition
5424 if we are not in SSA). */
5425 if (gimple_in_ssa_p (cfun))
5427 phi = gimple_seq_first_stmt (phi_nodes (loop_header));
5428 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
5431 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5432 gsi_remove (&si, true);
5434 if (gimple_in_ssa_p (cfun))
5435 update_ssa (TODO_update_ssa_no_phi);
5440 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5442 GOMP_atomic_start ();
5446 The result is not globally atomic, but works so long as all parallel
5447 references are within #pragma omp atomic directives. According to
5448 responses received from omp@openmp.org, appears to be within spec.
5449 Which makes sense, since that's how several other compilers handle
5450 this situation as well.
5451 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5452 expanding. STORED_VAL is the operand of the matching
5453 GIMPLE_OMP_ATOMIC_STORE.
5456 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5460 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
5465 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
5466 tree addr, tree loaded_val, tree stored_val)
5468 gimple_stmt_iterator si;
5472 si = gsi_last_bb (load_bb);
5473 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5475 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
5476 t = build_call_expr (t, 0);
5477 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5479 stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
5480 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5481 gsi_remove (&si, true);
5483 si = gsi_last_bb (store_bb);
5484 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5486 stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
5488 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5490 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
5491 t = build_call_expr (t, 0);
5492 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5493 gsi_remove (&si, true);
5495 if (gimple_in_ssa_p (cfun))
5496 update_ssa (TODO_update_ssa_no_phi);
5500 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5501 using expand_omp_atomic_fetch_op. If it failed, we try to
5502 call expand_omp_atomic_pipeline, and if it fails too, the
5503 ultimate fallback is wrapping the operation in a mutex
5504 (expand_omp_atomic_mutex). REGION is the atomic region built
5505 by build_omp_regions_1(). */
5508 expand_omp_atomic (struct omp_region *region)
5510 basic_block load_bb = region->entry, store_bb = region->exit;
5511 gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
5512 tree loaded_val = gimple_omp_atomic_load_lhs (load);
5513 tree addr = gimple_omp_atomic_load_rhs (load);
5514 tree stored_val = gimple_omp_atomic_store_val (store);
5515 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5516 HOST_WIDE_INT index;
5518 /* Make sure the type is one of the supported sizes. */
5519 index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5520 index = exact_log2 (index);
5521 if (index >= 0 && index <= 4)
5523 unsigned int align = TYPE_ALIGN_UNIT (type);
5525 /* __sync builtins require strict data alignment. */
5526 if (exact_log2 (align) >= index)
5529 if (loaded_val == stored_val
5530 && (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 && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
5537 if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5538 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5539 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5540 && store_bb == single_succ (load_bb)
5541 && first_stmt (store_bb) == store
5542 && expand_omp_atomic_store (load_bb, addr, loaded_val,
5546 /* When possible, use specialized atomic update functions. */
5547 if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5548 && store_bb == single_succ (load_bb)
5549 && expand_omp_atomic_fetch_op (load_bb, addr,
5550 loaded_val, stored_val, index))
5553 /* If we don't have specialized __sync builtins, try and implement
5554 as a compare and swap loop. */
5555 if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
5556 loaded_val, stored_val, index))
5561 /* The ultimate fallback is wrapping the operation in a mutex. */
5562 expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
5566 /* Expand the parallel region tree rooted at REGION. Expansion
5567 proceeds in depth-first order. Innermost regions are expanded
5568 first. This way, parallel regions that require a new function to
5569 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5570 internal dependencies in their body. */
5573 expand_omp (struct omp_region *region)
5577 location_t saved_location;
5579 /* First, determine whether this is a combined parallel+workshare
5581 if (region->type == GIMPLE_OMP_PARALLEL)
5582 determine_parallel_type (region);
5585 expand_omp (region->inner);
5587 saved_location = input_location;
5588 if (gimple_has_location (last_stmt (region->entry)))
5589 input_location = gimple_location (last_stmt (region->entry));
5591 switch (region->type)
5593 case GIMPLE_OMP_PARALLEL:
5594 case GIMPLE_OMP_TASK:
5595 expand_omp_taskreg (region);
5598 case GIMPLE_OMP_FOR:
5599 expand_omp_for (region);
5602 case GIMPLE_OMP_SECTIONS:
5603 expand_omp_sections (region);
5606 case GIMPLE_OMP_SECTION:
5607 /* Individual omp sections are handled together with their
5608 parent GIMPLE_OMP_SECTIONS region. */
5611 case GIMPLE_OMP_SINGLE:
5612 expand_omp_single (region);
5615 case GIMPLE_OMP_MASTER:
5616 case GIMPLE_OMP_ORDERED:
5617 case GIMPLE_OMP_CRITICAL:
5618 expand_omp_synch (region);
5621 case GIMPLE_OMP_ATOMIC_LOAD:
5622 expand_omp_atomic (region);
5629 input_location = saved_location;
5630 region = region->next;
5635 /* Helper for build_omp_regions. Scan the dominator tree starting at
5636 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5637 true, the function ends once a single tree is built (otherwise, whole
5638 forest of OMP constructs may be built). */
5641 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
5644 gimple_stmt_iterator gsi;
5648 gsi = gsi_last_bb (bb);
5649 if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
5651 struct omp_region *region;
5652 enum gimple_code code;
5654 stmt = gsi_stmt (gsi);
5655 code = gimple_code (stmt);
5656 if (code == GIMPLE_OMP_RETURN)
5658 /* STMT is the return point out of region PARENT. Mark it
5659 as the exit point and make PARENT the immediately
5660 enclosing region. */
5661 gcc_assert (parent);
5664 parent = parent->outer;
5666 else if (code == GIMPLE_OMP_ATOMIC_STORE)
5668 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5669 GIMPLE_OMP_RETURN, but matches with
5670 GIMPLE_OMP_ATOMIC_LOAD. */
5671 gcc_assert (parent);
5672 gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
5675 parent = parent->outer;
5678 else if (code == GIMPLE_OMP_CONTINUE)
5680 gcc_assert (parent);
5683 else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
5685 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5686 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5691 /* Otherwise, this directive becomes the parent for a new
5693 region = new_omp_region (bb, code, parent);
5698 if (single_tree && !parent)
5701 for (son = first_dom_son (CDI_DOMINATORS, bb);
5703 son = next_dom_son (CDI_DOMINATORS, son))
5704 build_omp_regions_1 (son, parent, single_tree);
5707 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5711 build_omp_regions_root (basic_block root)
5713 gcc_assert (root_omp_region == NULL);
5714 build_omp_regions_1 (root, NULL, true);
5715 gcc_assert (root_omp_region != NULL);
5718 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5721 omp_expand_local (basic_block head)
5723 build_omp_regions_root (head);
5724 if (dump_file && (dump_flags & TDF_DETAILS))
5726 fprintf (dump_file, "\nOMP region tree\n\n");
5727 dump_omp_region (dump_file, root_omp_region, 0);
5728 fprintf (dump_file, "\n");
5731 remove_exit_barriers (root_omp_region);
5732 expand_omp (root_omp_region);
5734 free_omp_regions ();
5737 /* Scan the CFG and build a tree of OMP regions. Return the root of
5738 the OMP region tree. */
5741 build_omp_regions (void)
5743 gcc_assert (root_omp_region == NULL);
5744 calculate_dominance_info (CDI_DOMINATORS);
5745 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
5748 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5751 execute_expand_omp (void)
5753 build_omp_regions ();
5755 if (!root_omp_region)
5760 fprintf (dump_file, "\nOMP region tree\n\n");
5761 dump_omp_region (dump_file, root_omp_region, 0);
5762 fprintf (dump_file, "\n");
5765 remove_exit_barriers (root_omp_region);
5767 expand_omp (root_omp_region);
5769 cleanup_tree_cfg ();
5771 free_omp_regions ();
5776 /* OMP expansion -- the default pass, run before creation of SSA form. */
5779 gate_expand_omp (void)
5781 return (flag_openmp != 0 && !seen_error ());
5784 struct gimple_opt_pass pass_expand_omp =
5788 "ompexp", /* name */
5789 gate_expand_omp, /* gate */
5790 execute_expand_omp, /* execute */
5793 0, /* static_pass_number */
5794 TV_NONE, /* tv_id */
5795 PROP_gimple_any, /* properties_required */
5796 0, /* properties_provided */
5797 0, /* properties_destroyed */
5798 0, /* todo_flags_start */
5799 0 /* todo_flags_finish */
5803 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5805 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5806 CTX is the enclosing OMP context for the current statement. */
5809 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5811 tree block, control;
5812 gimple_stmt_iterator tgsi;
5814 gimple stmt, new_stmt, bind, t;
5815 gimple_seq ilist, dlist, olist, new_body, body;
5816 struct gimplify_ctx gctx;
5818 stmt = gsi_stmt (*gsi_p);
5820 push_gimplify_context (&gctx);
5824 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5825 &ilist, &dlist, ctx);
5827 tgsi = gsi_start (gimple_omp_body (stmt));
5828 for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
5831 tgsi = gsi_start (gimple_omp_body (stmt));
5833 for (i = 0; i < len; i++, gsi_next (&tgsi))
5838 sec_start = gsi_stmt (tgsi);
5839 sctx = maybe_lookup_ctx (sec_start);
5842 gimple_seq_add_stmt (&body, sec_start);
5844 lower_omp (gimple_omp_body (sec_start), sctx);
5845 gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
5846 gimple_omp_set_body (sec_start, NULL);
5850 gimple_seq l = NULL;
5851 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5853 gimple_seq_add_seq (&body, l);
5854 gimple_omp_section_set_last (sec_start);
5857 gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
5860 block = make_node (BLOCK);
5861 bind = gimple_build_bind (NULL, body, block);
5864 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5866 block = make_node (BLOCK);
5867 new_stmt = gimple_build_bind (NULL, NULL, block);
5869 pop_gimplify_context (new_stmt);
5870 gimple_bind_append_vars (new_stmt, ctx->block_vars);
5871 BLOCK_VARS (block) = gimple_bind_vars (bind);
5872 if (BLOCK_VARS (block))
5873 TREE_USED (block) = 1;
5876 gimple_seq_add_seq (&new_body, ilist);
5877 gimple_seq_add_stmt (&new_body, stmt);
5878 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5879 gimple_seq_add_stmt (&new_body, bind);
5881 control = create_tmp_var (unsigned_type_node, ".section");
5882 t = gimple_build_omp_continue (control, control);
5883 gimple_omp_sections_set_control (stmt, control);
5884 gimple_seq_add_stmt (&new_body, t);
5886 gimple_seq_add_seq (&new_body, olist);
5887 gimple_seq_add_seq (&new_body, dlist);
5889 new_body = maybe_catch_exception (new_body);
5891 t = gimple_build_omp_return
5892 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5893 OMP_CLAUSE_NOWAIT));
5894 gimple_seq_add_stmt (&new_body, t);
5896 gimple_bind_set_body (new_stmt, new_body);
5897 gimple_omp_set_body (stmt, NULL);
5899 gsi_replace (gsi_p, new_stmt, true);
5903 /* A subroutine of lower_omp_single. Expand the simple form of
5904 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5906 if (GOMP_single_start ())
5908 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5910 FIXME. It may be better to delay expanding the logic of this until
5911 pass_expand_omp. The expanded logic may make the job more difficult
5912 to a synchronization analysis pass. */
5915 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5917 location_t loc = gimple_location (single_stmt);
5918 tree tlabel = create_artificial_label (loc);
5919 tree flabel = create_artificial_label (loc);
5923 decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
5924 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5925 call = gimple_build_call (decl, 0);
5926 gimple_call_set_lhs (call, lhs);
5927 gimple_seq_add_stmt (pre_p, call);
5929 cond = gimple_build_cond (EQ_EXPR, lhs,
5930 fold_convert_loc (loc, TREE_TYPE (lhs),
5933 gimple_seq_add_stmt (pre_p, cond);
5934 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5935 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5936 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5940 /* A subroutine of lower_omp_single. Expand the simple form of
5941 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5943 #pragma omp single copyprivate (a, b, c)
5945 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5948 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5954 GOMP_single_copy_end (©out);
5965 FIXME. It may be better to delay expanding the logic of this until
5966 pass_expand_omp. The expanded logic may make the job more difficult
5967 to a synchronization analysis pass. */
5970 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
5972 tree ptr_type, t, l0, l1, l2, bfn_decl;
5973 gimple_seq copyin_seq;
5974 location_t loc = gimple_location (single_stmt);
5976 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
5978 ptr_type = build_pointer_type (ctx->record_type);
5979 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
5981 l0 = create_artificial_label (loc);
5982 l1 = create_artificial_label (loc);
5983 l2 = create_artificial_label (loc);
5985 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
5986 t = build_call_expr_loc (loc, bfn_decl, 0);
5987 t = fold_convert_loc (loc, ptr_type, t);
5988 gimplify_assign (ctx->receiver_decl, t, pre_p);
5990 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
5991 build_int_cst (ptr_type, 0));
5992 t = build3 (COND_EXPR, void_type_node, t,
5993 build_and_jump (&l0), build_and_jump (&l1));
5994 gimplify_and_add (t, pre_p);
5996 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
5998 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
6001 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
6004 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6005 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
6006 t = build_call_expr_loc (loc, bfn_decl, 1, t);
6007 gimplify_and_add (t, pre_p);
6009 t = build_and_jump (&l2);
6010 gimplify_and_add (t, pre_p);
6012 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
6014 gimple_seq_add_seq (pre_p, copyin_seq);
6016 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
6020 /* Expand code for an OpenMP single directive. */
6023 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6026 gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
6027 gimple_seq bind_body, dlist;
6028 struct gimplify_ctx gctx;
6030 push_gimplify_context (&gctx);
6033 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
6034 &bind_body, &dlist, ctx);
6035 lower_omp (gimple_omp_body (single_stmt), ctx);
6037 gimple_seq_add_stmt (&bind_body, single_stmt);
6039 if (ctx->record_type)
6040 lower_omp_single_copy (single_stmt, &bind_body, ctx);
6042 lower_omp_single_simple (single_stmt, &bind_body);
6044 gimple_omp_set_body (single_stmt, NULL);
6046 gimple_seq_add_seq (&bind_body, dlist);
6048 bind_body = maybe_catch_exception (bind_body);
6050 t = gimple_build_omp_return
6051 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
6052 OMP_CLAUSE_NOWAIT));
6053 gimple_seq_add_stmt (&bind_body, t);
6055 block = make_node (BLOCK);
6056 bind = gimple_build_bind (NULL, bind_body, block);
6058 pop_gimplify_context (bind);
6060 gimple_bind_append_vars (bind, ctx->block_vars);
6061 BLOCK_VARS (block) = ctx->block_vars;
6062 gsi_replace (gsi_p, bind, true);
6063 if (BLOCK_VARS (block))
6064 TREE_USED (block) = 1;
6068 /* Expand code for an OpenMP master directive. */
6071 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6073 tree block, lab = NULL, x, bfn_decl;
6074 gimple stmt = gsi_stmt (*gsi_p), bind;
6075 location_t loc = gimple_location (stmt);
6077 struct gimplify_ctx gctx;
6079 push_gimplify_context (&gctx);
6081 block = make_node (BLOCK);
6082 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6085 bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6086 x = build_call_expr_loc (loc, bfn_decl, 0);
6087 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
6088 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
6090 gimplify_and_add (x, &tseq);
6091 gimple_bind_add_seq (bind, tseq);
6093 lower_omp (gimple_omp_body (stmt), ctx);
6094 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6095 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6096 gimple_omp_set_body (stmt, NULL);
6098 gimple_bind_add_stmt (bind, gimple_build_label (lab));
6100 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6102 pop_gimplify_context (bind);
6104 gimple_bind_append_vars (bind, ctx->block_vars);
6105 BLOCK_VARS (block) = ctx->block_vars;
6106 gsi_replace (gsi_p, bind, true);
6110 /* Expand code for an OpenMP ordered directive. */
6113 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6116 gimple stmt = gsi_stmt (*gsi_p), bind, x;
6117 struct gimplify_ctx gctx;
6119 push_gimplify_context (&gctx);
6121 block = make_node (BLOCK);
6122 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6125 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
6127 gimple_bind_add_stmt (bind, x);
6129 lower_omp (gimple_omp_body (stmt), ctx);
6130 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6131 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6132 gimple_omp_set_body (stmt, NULL);
6134 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
6135 gimple_bind_add_stmt (bind, x);
6137 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6139 pop_gimplify_context (bind);
6141 gimple_bind_append_vars (bind, ctx->block_vars);
6142 BLOCK_VARS (block) = gimple_bind_vars (bind);
6143 gsi_replace (gsi_p, bind, true);
6147 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
6148 substitution of a couple of function calls. But in the NAMED case,
6149 requires that languages coordinate a symbol name. It is therefore
6150 best put here in common code. */
6152 static GTY((param1_is (tree), param2_is (tree)))
6153 splay_tree critical_name_mutexes;
6156 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6159 tree name, lock, unlock;
6160 gimple stmt = gsi_stmt (*gsi_p), bind;
6161 location_t loc = gimple_location (stmt);
6163 struct gimplify_ctx gctx;
6165 name = gimple_omp_critical_name (stmt);
6171 if (!critical_name_mutexes)
6172 critical_name_mutexes
6173 = splay_tree_new_ggc (splay_tree_compare_pointers,
6174 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
6175 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
6177 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
6182 decl = create_tmp_var_raw (ptr_type_node, NULL);
6184 new_str = ACONCAT ((".gomp_critical_user_",
6185 IDENTIFIER_POINTER (name), NULL));
6186 DECL_NAME (decl) = get_identifier (new_str);
6187 TREE_PUBLIC (decl) = 1;
6188 TREE_STATIC (decl) = 1;
6189 DECL_COMMON (decl) = 1;
6190 DECL_ARTIFICIAL (decl) = 1;
6191 DECL_IGNORED_P (decl) = 1;
6192 varpool_finalize_decl (decl);
6194 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
6195 (splay_tree_value) decl);
6198 decl = (tree) n->value;
6200 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
6201 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
6203 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
6204 unlock = build_call_expr_loc (loc, unlock, 1,
6205 build_fold_addr_expr_loc (loc, decl));
6209 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
6210 lock = build_call_expr_loc (loc, lock, 0);
6212 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
6213 unlock = build_call_expr_loc (loc, unlock, 0);
6216 push_gimplify_context (&gctx);
6218 block = make_node (BLOCK);
6219 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
6221 tbody = gimple_bind_body (bind);
6222 gimplify_and_add (lock, &tbody);
6223 gimple_bind_set_body (bind, tbody);
6225 lower_omp (gimple_omp_body (stmt), ctx);
6226 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6227 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6228 gimple_omp_set_body (stmt, NULL);
6230 tbody = gimple_bind_body (bind);
6231 gimplify_and_add (unlock, &tbody);
6232 gimple_bind_set_body (bind, tbody);
6234 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6236 pop_gimplify_context (bind);
6237 gimple_bind_append_vars (bind, ctx->block_vars);
6238 BLOCK_VARS (block) = gimple_bind_vars (bind);
6239 gsi_replace (gsi_p, bind, true);
6243 /* A subroutine of lower_omp_for. Generate code to emit the predicate
6244 for a lastprivate clause. Given a loop control predicate of (V
6245 cond N2), we gate the clause on (!(V cond N2)). The lowered form
6246 is appended to *DLIST, iterator initialization is appended to
6250 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
6251 gimple_seq *dlist, struct omp_context *ctx)
6253 tree clauses, cond, vinit;
6254 enum tree_code cond_code;
6257 cond_code = fd->loop.cond_code;
6258 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
6260 /* When possible, use a strict equality expression. This can let VRP
6261 type optimizations deduce the value and remove a copy. */
6262 if (host_integerp (fd->loop.step, 0))
6264 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
6265 if (step == 1 || step == -1)
6266 cond_code = EQ_EXPR;
6269 cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
6271 clauses = gimple_omp_for_clauses (fd->for_stmt);
6273 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
6274 if (!gimple_seq_empty_p (stmts))
6276 gimple_seq_add_seq (&stmts, *dlist);
6279 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6280 vinit = fd->loop.n1;
6281 if (cond_code == EQ_EXPR
6282 && host_integerp (fd->loop.n2, 0)
6283 && ! integer_zerop (fd->loop.n2))
6284 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6286 /* Initialize the iterator variable, so that threads that don't execute
6287 any iterations don't execute the lastprivate clauses by accident. */
6288 gimplify_assign (fd->loop.v, vinit, body_p);
6293 /* Lower code for an OpenMP loop directive. */
6296 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6299 struct omp_for_data fd;
6300 gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6301 gimple_seq omp_for_body, body, dlist;
6303 struct gimplify_ctx gctx;
6305 push_gimplify_context (&gctx);
6307 lower_omp (gimple_omp_for_pre_body (stmt), ctx);
6308 lower_omp (gimple_omp_body (stmt), ctx);
6310 block = make_node (BLOCK);
6311 new_stmt = gimple_build_bind (NULL, NULL, block);
6313 /* Move declaration of temporaries in the loop body before we make
6315 omp_for_body = gimple_omp_body (stmt);
6316 if (!gimple_seq_empty_p (omp_for_body)
6317 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6319 tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6320 gimple_bind_append_vars (new_stmt, vars);
6323 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6326 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6327 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6329 /* Lower the header expressions. At this point, we can assume that
6330 the header is of the form:
6332 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6334 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6335 using the .omp_data_s mapping, if needed. */
6336 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6338 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6339 if (!is_gimple_min_invariant (*rhs_p))
6340 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6342 rhs_p = gimple_omp_for_final_ptr (stmt, i);
6343 if (!is_gimple_min_invariant (*rhs_p))
6344 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6346 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6347 if (!is_gimple_min_invariant (*rhs_p))
6348 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6351 /* Once lowered, extract the bounds and clauses. */
6352 extract_omp_for_data (stmt, &fd, NULL);
6354 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6356 gimple_seq_add_stmt (&body, stmt);
6357 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6359 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6362 /* After the loop, add exit clauses. */
6363 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6364 gimple_seq_add_seq (&body, dlist);
6366 body = maybe_catch_exception (body);
6368 /* Region exit marker goes at the end of the loop body. */
6369 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6371 pop_gimplify_context (new_stmt);
6373 gimple_bind_append_vars (new_stmt, ctx->block_vars);
6374 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6375 if (BLOCK_VARS (block))
6376 TREE_USED (block) = 1;
6378 gimple_bind_set_body (new_stmt, body);
6379 gimple_omp_set_body (stmt, NULL);
6380 gimple_omp_for_set_pre_body (stmt, NULL);
6381 gsi_replace (gsi_p, new_stmt, true);
6384 /* Callback for walk_stmts. Check if the current statement only contains
6385 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6388 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6389 bool *handled_ops_p,
6390 struct walk_stmt_info *wi)
6392 int *info = (int *) wi->info;
6393 gimple stmt = gsi_stmt (*gsi_p);
6395 *handled_ops_p = true;
6396 switch (gimple_code (stmt))
6400 case GIMPLE_OMP_FOR:
6401 case GIMPLE_OMP_SECTIONS:
6402 *info = *info == 0 ? 1 : -1;
6411 struct omp_taskcopy_context
6413 /* This field must be at the beginning, as we do "inheritance": Some
6414 callback functions for tree-inline.c (e.g., omp_copy_decl)
6415 receive a copy_body_data pointer that is up-casted to an
6416 omp_context pointer. */
6422 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6424 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6426 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6427 return create_tmp_var (TREE_TYPE (var), NULL);
6433 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6435 tree name, new_fields = NULL, type, f;
6437 type = lang_hooks.types.make_type (RECORD_TYPE);
6438 name = DECL_NAME (TYPE_NAME (orig_type));
6439 name = build_decl (gimple_location (tcctx->ctx->stmt),
6440 TYPE_DECL, name, type);
6441 TYPE_NAME (type) = name;
6443 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6445 tree new_f = copy_node (f);
6446 DECL_CONTEXT (new_f) = type;
6447 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6448 TREE_CHAIN (new_f) = new_fields;
6449 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6450 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6451 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6454 *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6456 TYPE_FIELDS (type) = nreverse (new_fields);
6461 /* Create task copyfn. */
6464 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6466 struct function *child_cfun;
6467 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6468 tree record_type, srecord_type, bind, list;
6469 bool record_needs_remap = false, srecord_needs_remap = false;
6471 struct omp_taskcopy_context tcctx;
6472 struct gimplify_ctx gctx;
6473 location_t loc = gimple_location (task_stmt);
6475 child_fn = gimple_omp_task_copy_fn (task_stmt);
6476 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6477 gcc_assert (child_cfun->cfg == NULL);
6478 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6480 /* Reset DECL_CONTEXT on function arguments. */
6481 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
6482 DECL_CONTEXT (t) = child_fn;
6484 /* Populate the function. */
6485 push_gimplify_context (&gctx);
6486 current_function_decl = child_fn;
6488 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6489 TREE_SIDE_EFFECTS (bind) = 1;
6491 DECL_SAVED_TREE (child_fn) = bind;
6492 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6494 /* Remap src and dst argument types if needed. */
6495 record_type = ctx->record_type;
6496 srecord_type = ctx->srecord_type;
6497 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6498 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6500 record_needs_remap = true;
6503 for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
6504 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6506 srecord_needs_remap = true;
6510 if (record_needs_remap || srecord_needs_remap)
6512 memset (&tcctx, '\0', sizeof (tcctx));
6513 tcctx.cb.src_fn = ctx->cb.src_fn;
6514 tcctx.cb.dst_fn = child_fn;
6515 tcctx.cb.src_node = cgraph_get_node (tcctx.cb.src_fn);
6516 gcc_checking_assert (tcctx.cb.src_node);
6517 tcctx.cb.dst_node = tcctx.cb.src_node;
6518 tcctx.cb.src_cfun = ctx->cb.src_cfun;
6519 tcctx.cb.copy_decl = task_copyfn_copy_decl;
6520 tcctx.cb.eh_lp_nr = 0;
6521 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6522 tcctx.cb.decl_map = pointer_map_create ();
6525 if (record_needs_remap)
6526 record_type = task_copyfn_remap_type (&tcctx, record_type);
6527 if (srecord_needs_remap)
6528 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6531 tcctx.cb.decl_map = NULL;
6533 push_cfun (child_cfun);
6535 arg = DECL_ARGUMENTS (child_fn);
6536 TREE_TYPE (arg) = build_pointer_type (record_type);
6537 sarg = DECL_CHAIN (arg);
6538 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6540 /* First pass: initialize temporaries used in record_type and srecord_type
6541 sizes and field offsets. */
6542 if (tcctx.cb.decl_map)
6543 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6544 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6548 decl = OMP_CLAUSE_DECL (c);
6549 p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6552 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6553 sf = (tree) n->value;
6554 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6555 src = build_simple_mem_ref_loc (loc, sarg);
6556 src = omp_build_component_ref (src, sf);
6557 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6558 append_to_statement_list (t, &list);
6561 /* Second pass: copy shared var pointers and copy construct non-VLA
6562 firstprivate vars. */
6563 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6564 switch (OMP_CLAUSE_CODE (c))
6566 case OMP_CLAUSE_SHARED:
6567 decl = OMP_CLAUSE_DECL (c);
6568 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6571 f = (tree) n->value;
6572 if (tcctx.cb.decl_map)
6573 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6574 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6575 sf = (tree) n->value;
6576 if (tcctx.cb.decl_map)
6577 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6578 src = build_simple_mem_ref_loc (loc, sarg);
6579 src = omp_build_component_ref (src, sf);
6580 dst = build_simple_mem_ref_loc (loc, arg);
6581 dst = omp_build_component_ref (dst, f);
6582 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6583 append_to_statement_list (t, &list);
6585 case OMP_CLAUSE_FIRSTPRIVATE:
6586 decl = OMP_CLAUSE_DECL (c);
6587 if (is_variable_sized (decl))
6589 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6592 f = (tree) n->value;
6593 if (tcctx.cb.decl_map)
6594 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6595 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6598 sf = (tree) n->value;
6599 if (tcctx.cb.decl_map)
6600 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6601 src = build_simple_mem_ref_loc (loc, sarg);
6602 src = omp_build_component_ref (src, sf);
6603 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6604 src = build_simple_mem_ref_loc (loc, src);
6608 dst = build_simple_mem_ref_loc (loc, arg);
6609 dst = omp_build_component_ref (dst, f);
6610 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6611 append_to_statement_list (t, &list);
6613 case OMP_CLAUSE_PRIVATE:
6614 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6616 decl = OMP_CLAUSE_DECL (c);
6617 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6618 f = (tree) n->value;
6619 if (tcctx.cb.decl_map)
6620 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6621 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6624 sf = (tree) n->value;
6625 if (tcctx.cb.decl_map)
6626 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6627 src = build_simple_mem_ref_loc (loc, sarg);
6628 src = omp_build_component_ref (src, sf);
6629 if (use_pointer_for_field (decl, NULL))
6630 src = build_simple_mem_ref_loc (loc, src);
6634 dst = build_simple_mem_ref_loc (loc, arg);
6635 dst = omp_build_component_ref (dst, f);
6636 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6637 append_to_statement_list (t, &list);
6643 /* Last pass: handle VLA firstprivates. */
6644 if (tcctx.cb.decl_map)
6645 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6646 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6650 decl = OMP_CLAUSE_DECL (c);
6651 if (!is_variable_sized (decl))
6653 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6656 f = (tree) n->value;
6657 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6658 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6659 ind = DECL_VALUE_EXPR (decl);
6660 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6661 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6662 n = splay_tree_lookup (ctx->sfield_map,
6663 (splay_tree_key) TREE_OPERAND (ind, 0));
6664 sf = (tree) n->value;
6665 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6666 src = build_simple_mem_ref_loc (loc, sarg);
6667 src = omp_build_component_ref (src, sf);
6668 src = build_simple_mem_ref_loc (loc, src);
6669 dst = build_simple_mem_ref_loc (loc, arg);
6670 dst = omp_build_component_ref (dst, f);
6671 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6672 append_to_statement_list (t, &list);
6673 n = splay_tree_lookup (ctx->field_map,
6674 (splay_tree_key) TREE_OPERAND (ind, 0));
6675 df = (tree) n->value;
6676 df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6677 ptr = build_simple_mem_ref_loc (loc, arg);
6678 ptr = omp_build_component_ref (ptr, df);
6679 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6680 build_fold_addr_expr_loc (loc, dst));
6681 append_to_statement_list (t, &list);
6684 t = build1 (RETURN_EXPR, void_type_node, NULL);
6685 append_to_statement_list (t, &list);
6687 if (tcctx.cb.decl_map)
6688 pointer_map_destroy (tcctx.cb.decl_map);
6689 pop_gimplify_context (NULL);
6690 BIND_EXPR_BODY (bind) = list;
6692 current_function_decl = ctx->cb.src_fn;
6695 /* Lower the OpenMP parallel or task directive in the current statement
6696 in GSI_P. CTX holds context information for the directive. */
6699 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6703 gimple stmt = gsi_stmt (*gsi_p);
6704 gimple par_bind, bind;
6705 gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6706 struct gimplify_ctx gctx;
6707 location_t loc = gimple_location (stmt);
6709 clauses = gimple_omp_taskreg_clauses (stmt);
6710 par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6711 par_body = gimple_bind_body (par_bind);
6712 child_fn = ctx->cb.dst_fn;
6713 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6714 && !gimple_omp_parallel_combined_p (stmt))
6716 struct walk_stmt_info wi;
6719 memset (&wi, 0, sizeof (wi));
6722 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6724 gimple_omp_parallel_set_combined_p (stmt, true);
6726 if (ctx->srecord_type)
6727 create_task_copyfn (stmt, ctx);
6729 push_gimplify_context (&gctx);
6733 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6734 lower_omp (par_body, ctx);
6735 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6736 lower_reduction_clauses (clauses, &par_olist, ctx);
6738 /* Declare all the variables created by mapping and the variables
6739 declared in the scope of the parallel body. */
6740 record_vars_into (ctx->block_vars, child_fn);
6741 record_vars_into (gimple_bind_vars (par_bind), child_fn);
6743 if (ctx->record_type)
6746 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6747 : ctx->record_type, ".omp_data_o");
6748 DECL_NAMELESS (ctx->sender_decl) = 1;
6749 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6750 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6755 lower_send_clauses (clauses, &ilist, &olist, ctx);
6756 lower_send_shared_vars (&ilist, &olist, ctx);
6758 /* Once all the expansions are done, sequence all the different
6759 fragments inside gimple_omp_body. */
6763 if (ctx->record_type)
6765 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6766 /* fixup_child_record_type might have changed receiver_decl's type. */
6767 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6768 gimple_seq_add_stmt (&new_body,
6769 gimple_build_assign (ctx->receiver_decl, t));
6772 gimple_seq_add_seq (&new_body, par_ilist);
6773 gimple_seq_add_seq (&new_body, par_body);
6774 gimple_seq_add_seq (&new_body, par_olist);
6775 new_body = maybe_catch_exception (new_body);
6776 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6777 gimple_omp_set_body (stmt, new_body);
6779 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6780 gimple_bind_add_stmt (bind, stmt);
6783 gimple_seq_add_stmt (&ilist, bind);
6784 gimple_seq_add_seq (&ilist, olist);
6785 bind = gimple_build_bind (NULL, ilist, NULL);
6788 gsi_replace (gsi_p, bind, true);
6790 pop_gimplify_context (NULL);
6793 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6794 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6795 of OpenMP context, but with task_shared_vars set. */
6798 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6803 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6804 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6807 if (task_shared_vars
6809 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6812 /* If a global variable has been privatized, TREE_CONSTANT on
6813 ADDR_EXPR might be wrong. */
6814 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6815 recompute_tree_invariant_for_addr_expr (t);
6817 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6822 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6824 gimple stmt = gsi_stmt (*gsi_p);
6825 struct walk_stmt_info wi;
6827 if (gimple_has_location (stmt))
6828 input_location = gimple_location (stmt);
6830 if (task_shared_vars)
6831 memset (&wi, '\0', sizeof (wi));
6833 /* If we have issued syntax errors, avoid doing any heavy lifting.
6834 Just replace the OpenMP directives with a NOP to avoid
6835 confusing RTL expansion. */
6836 if (seen_error () && is_gimple_omp (stmt))
6838 gsi_replace (gsi_p, gimple_build_nop (), true);
6842 switch (gimple_code (stmt))
6845 if ((ctx || task_shared_vars)
6846 && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6847 ctx ? NULL : &wi, NULL)
6848 || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6849 ctx ? NULL : &wi, NULL)))
6850 gimple_regimplify_operands (stmt, gsi_p);
6853 lower_omp (gimple_catch_handler (stmt), ctx);
6855 case GIMPLE_EH_FILTER:
6856 lower_omp (gimple_eh_filter_failure (stmt), ctx);
6859 lower_omp (gimple_try_eval (stmt), ctx);
6860 lower_omp (gimple_try_cleanup (stmt), ctx);
6862 case GIMPLE_TRANSACTION:
6863 lower_omp (gimple_transaction_body (stmt), ctx);
6866 lower_omp (gimple_bind_body (stmt), ctx);
6868 case GIMPLE_OMP_PARALLEL:
6869 case GIMPLE_OMP_TASK:
6870 ctx = maybe_lookup_ctx (stmt);
6871 lower_omp_taskreg (gsi_p, ctx);
6873 case GIMPLE_OMP_FOR:
6874 ctx = maybe_lookup_ctx (stmt);
6876 lower_omp_for (gsi_p, ctx);
6878 case GIMPLE_OMP_SECTIONS:
6879 ctx = maybe_lookup_ctx (stmt);
6881 lower_omp_sections (gsi_p, ctx);
6883 case GIMPLE_OMP_SINGLE:
6884 ctx = maybe_lookup_ctx (stmt);
6886 lower_omp_single (gsi_p, ctx);
6888 case GIMPLE_OMP_MASTER:
6889 ctx = maybe_lookup_ctx (stmt);
6891 lower_omp_master (gsi_p, ctx);
6893 case GIMPLE_OMP_ORDERED:
6894 ctx = maybe_lookup_ctx (stmt);
6896 lower_omp_ordered (gsi_p, ctx);
6898 case GIMPLE_OMP_CRITICAL:
6899 ctx = maybe_lookup_ctx (stmt);
6901 lower_omp_critical (gsi_p, ctx);
6903 case GIMPLE_OMP_ATOMIC_LOAD:
6904 if ((ctx || task_shared_vars)
6905 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6906 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6907 gimple_regimplify_operands (stmt, gsi_p);
6910 if ((ctx || task_shared_vars)
6911 && walk_gimple_op (stmt, lower_omp_regimplify_p,
6913 gimple_regimplify_operands (stmt, gsi_p);
6919 lower_omp (gimple_seq body, omp_context *ctx)
6921 location_t saved_location = input_location;
6922 gimple_stmt_iterator gsi = gsi_start (body);
6923 for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
6924 lower_omp_1 (&gsi, ctx);
6925 input_location = saved_location;
6928 /* Main entry point. */
6931 execute_lower_omp (void)
6935 /* This pass always runs, to provide PROP_gimple_lomp.
6936 But there is nothing to do unless -fopenmp is given. */
6937 if (flag_openmp == 0)
6940 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6941 delete_omp_context);
6943 body = gimple_body (current_function_decl);
6944 scan_omp (body, NULL);
6945 gcc_assert (taskreg_nesting_level == 0);
6947 if (all_contexts->root)
6949 struct gimplify_ctx gctx;
6951 if (task_shared_vars)
6952 push_gimplify_context (&gctx);
6953 lower_omp (body, NULL);
6954 if (task_shared_vars)
6955 pop_gimplify_context (NULL);
6960 splay_tree_delete (all_contexts);
6961 all_contexts = NULL;
6963 BITMAP_FREE (task_shared_vars);
6967 struct gimple_opt_pass pass_lower_omp =
6971 "omplower", /* name */
6973 execute_lower_omp, /* execute */
6976 0, /* static_pass_number */
6977 TV_NONE, /* tv_id */
6978 PROP_gimple_any, /* properties_required */
6979 PROP_gimple_lomp, /* properties_provided */
6980 0, /* properties_destroyed */
6981 0, /* todo_flags_start */
6982 0 /* todo_flags_finish */
6986 /* The following is a utility to diagnose OpenMP structured block violations.
6987 It is not part of the "omplower" pass, as that's invoked too late. It
6988 should be invoked by the respective front ends after gimplification. */
6990 static splay_tree all_labels;
6992 /* Check for mismatched contexts and generate an error if needed. Return
6993 true if an error is detected. */
6996 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
6997 gimple branch_ctx, gimple label_ctx)
6999 if (label_ctx == branch_ctx)
7004 Previously we kept track of the label's entire context in diagnose_sb_[12]
7005 so we could traverse it and issue a correct "exit" or "enter" error
7006 message upon a structured block violation.
7008 We built the context by building a list with tree_cons'ing, but there is
7009 no easy counterpart in gimple tuples. It seems like far too much work
7010 for issuing exit/enter error messages. If someone really misses the
7011 distinct error message... patches welcome.
7015 /* Try to avoid confusing the user by producing and error message
7016 with correct "exit" or "enter" verbiage. We prefer "exit"
7017 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
7018 if (branch_ctx == NULL)
7024 if (TREE_VALUE (label_ctx) == branch_ctx)
7029 label_ctx = TREE_CHAIN (label_ctx);
7034 error ("invalid exit from OpenMP structured block");
7036 error ("invalid entry to OpenMP structured block");
7039 /* If it's obvious we have an invalid entry, be specific about the error. */
7040 if (branch_ctx == NULL)
7041 error ("invalid entry to OpenMP structured block");
7043 /* Otherwise, be vague and lazy, but efficient. */
7044 error ("invalid branch to/from an OpenMP structured block");
7046 gsi_replace (gsi_p, gimple_build_nop (), false);
7050 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7051 where each label is found. */
7054 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7055 struct walk_stmt_info *wi)
7057 gimple context = (gimple) wi->info;
7058 gimple inner_context;
7059 gimple stmt = gsi_stmt (*gsi_p);
7061 *handled_ops_p = true;
7063 switch (gimple_code (stmt))
7067 case GIMPLE_OMP_PARALLEL:
7068 case GIMPLE_OMP_TASK:
7069 case GIMPLE_OMP_SECTIONS:
7070 case GIMPLE_OMP_SINGLE:
7071 case GIMPLE_OMP_SECTION:
7072 case GIMPLE_OMP_MASTER:
7073 case GIMPLE_OMP_ORDERED:
7074 case GIMPLE_OMP_CRITICAL:
7075 /* The minimal context here is just the current OMP construct. */
7076 inner_context = stmt;
7077 wi->info = inner_context;
7078 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7082 case GIMPLE_OMP_FOR:
7083 inner_context = stmt;
7084 wi->info = inner_context;
7085 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7087 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7088 diagnose_sb_1, NULL, wi);
7089 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7094 splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
7095 (splay_tree_value) context);
7105 /* Pass 2: Check each branch and see if its context differs from that of
7106 the destination label's context. */
7109 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7110 struct walk_stmt_info *wi)
7112 gimple context = (gimple) wi->info;
7114 gimple stmt = gsi_stmt (*gsi_p);
7116 *handled_ops_p = true;
7118 switch (gimple_code (stmt))
7122 case GIMPLE_OMP_PARALLEL:
7123 case GIMPLE_OMP_TASK:
7124 case GIMPLE_OMP_SECTIONS:
7125 case GIMPLE_OMP_SINGLE:
7126 case GIMPLE_OMP_SECTION:
7127 case GIMPLE_OMP_MASTER:
7128 case GIMPLE_OMP_ORDERED:
7129 case GIMPLE_OMP_CRITICAL:
7131 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7135 case GIMPLE_OMP_FOR:
7137 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7139 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7140 diagnose_sb_2, NULL, wi);
7141 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7147 tree lab = gimple_cond_true_label (stmt);
7150 n = splay_tree_lookup (all_labels,
7151 (splay_tree_key) lab);
7152 diagnose_sb_0 (gsi_p, context,
7153 n ? (gimple) n->value : NULL);
7155 lab = gimple_cond_false_label (stmt);
7158 n = splay_tree_lookup (all_labels,
7159 (splay_tree_key) lab);
7160 diagnose_sb_0 (gsi_p, context,
7161 n ? (gimple) n->value : NULL);
7168 tree lab = gimple_goto_dest (stmt);
7169 if (TREE_CODE (lab) != LABEL_DECL)
7172 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7173 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
7180 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
7182 tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
7183 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7184 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
7191 diagnose_sb_0 (gsi_p, context, NULL);
7202 diagnose_omp_structured_block_errors (void)
7204 struct walk_stmt_info wi;
7205 gimple_seq body = gimple_body (current_function_decl);
7207 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
7209 memset (&wi, 0, sizeof (wi));
7210 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
7212 memset (&wi, 0, sizeof (wi));
7213 wi.want_locations = true;
7214 walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
7216 splay_tree_delete (all_labels);
7223 gate_diagnose_omp_blocks (void)
7225 return flag_openmp != 0;
7228 struct gimple_opt_pass pass_diagnose_omp_blocks =
7232 "*diagnose_omp_blocks", /* name */
7233 gate_diagnose_omp_blocks, /* gate */
7234 diagnose_omp_structured_block_errors, /* execute */
7237 0, /* static_pass_number */
7238 TV_NONE, /* tv_id */
7239 PROP_gimple_any, /* properties_required */
7240 0, /* properties_provided */
7241 0, /* properties_destroyed */
7242 0, /* todo_flags_start */
7243 0, /* todo_flags_finish */
7247 #include "gt-omp-low.h"