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 (exit_reachable == (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;
4768 if (single_pred_p (l2_bb) && single_pred (l2_bb) == l0_bb)
4769 l2 = gimple_block_label (l2_bb);
4772 /* This can happen if there are reductions. */
4773 len = EDGE_COUNT (l0_bb->succs);
4774 gcc_assert (len > 0);
4775 e = EDGE_SUCC (l0_bb, len - 1);
4776 si = gsi_last_bb (e->dest);
4779 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4780 l2 = gimple_block_label (e->dest);
4782 FOR_EACH_EDGE (e, ei, l0_bb->succs)
4784 si = gsi_last_bb (e->dest);
4786 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4788 l2 = gimple_block_label (e->dest);
4793 default_bb = create_empty_bb (l1_bb->prev_bb);
4797 default_bb = create_empty_bb (l0_bb);
4798 l2 = gimple_block_label (default_bb);
4801 /* We will build a switch() with enough cases for all the
4802 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4803 and a default case to abort if something goes wrong. */
4804 len = EDGE_COUNT (l0_bb->succs);
4806 /* Use VEC_quick_push on label_vec throughout, since we know the size
4808 label_vec = VEC_alloc (tree, heap, len);
4810 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4811 GIMPLE_OMP_SECTIONS statement. */
4812 si = gsi_last_bb (entry_bb);
4813 sections_stmt = gsi_stmt (si);
4814 gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
4815 vin = gimple_omp_sections_control (sections_stmt);
4816 if (!is_combined_parallel (region))
4818 /* If we are not inside a combined parallel+sections region,
4819 call GOMP_sections_start. */
4820 t = build_int_cst (unsigned_type_node,
4821 exit_reachable ? len - 1 : len);
4822 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START);
4823 stmt = gimple_build_call (u, 1, t);
4827 /* Otherwise, call GOMP_sections_next. */
4828 u = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4829 stmt = gimple_build_call (u, 0);
4831 gimple_call_set_lhs (stmt, vin);
4832 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4833 gsi_remove (&si, true);
4835 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4837 switch_si = gsi_last_bb (l0_bb);
4838 gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
4841 cont = last_stmt (l1_bb);
4842 gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
4843 vmain = gimple_omp_continue_control_use (cont);
4844 vnext = gimple_omp_continue_control_def (cont);
4855 t = build_case_label (build_int_cst (unsigned_type_node, 0), NULL, l2);
4856 VEC_quick_push (tree, label_vec, t);
4860 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4861 for (inner = region->inner, casei = 1;
4863 inner = inner->next, i++, casei++)
4865 basic_block s_entry_bb, s_exit_bb;
4867 /* Skip optional reduction region. */
4868 if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
4875 s_entry_bb = inner->entry;
4876 s_exit_bb = inner->exit;
4878 t = gimple_block_label (s_entry_bb);
4879 u = build_int_cst (unsigned_type_node, casei);
4880 u = build_case_label (u, NULL, t);
4881 VEC_quick_push (tree, label_vec, u);
4883 si = gsi_last_bb (s_entry_bb);
4884 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
4885 gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
4886 gsi_remove (&si, true);
4887 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
4889 if (s_exit_bb == NULL)
4892 si = gsi_last_bb (s_exit_bb);
4893 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4894 gsi_remove (&si, true);
4896 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
4899 /* Error handling code goes in DEFAULT_BB. */
4900 t = gimple_block_label (default_bb);
4901 u = build_case_label (NULL, NULL, t);
4902 make_edge (l0_bb, default_bb, 0);
4904 stmt = gimple_build_switch_vec (vmain, u, label_vec);
4905 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4906 gsi_remove (&switch_si, true);
4907 VEC_free (tree, heap, label_vec);
4909 si = gsi_start_bb (default_bb);
4910 stmt = gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP), 0);
4911 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4917 /* Code to get the next section goes in L1_BB. */
4918 si = gsi_last_bb (l1_bb);
4919 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
4921 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT);
4922 stmt = gimple_build_call (bfn_decl, 0);
4923 gimple_call_set_lhs (stmt, vnext);
4924 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4925 gsi_remove (&si, true);
4927 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
4929 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4930 si = gsi_last_bb (l2_bb);
4931 if (gimple_omp_return_nowait_p (gsi_stmt (si)))
4932 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT);
4934 t = builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END);
4935 stmt = gimple_build_call (t, 0);
4936 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4937 gsi_remove (&si, true);
4940 set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
4944 /* Expand code for an OpenMP single directive. We've already expanded
4945 much of the code, here we simply place the GOMP_barrier call. */
4948 expand_omp_single (struct omp_region *region)
4950 basic_block entry_bb, exit_bb;
4951 gimple_stmt_iterator si;
4952 bool need_barrier = false;
4954 entry_bb = region->entry;
4955 exit_bb = region->exit;
4957 si = gsi_last_bb (entry_bb);
4958 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4959 be removed. We need to ensure that the thread that entered the single
4960 does not exit before the data is copied out by the other threads. */
4961 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
4962 OMP_CLAUSE_COPYPRIVATE))
4963 need_barrier = true;
4964 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
4965 gsi_remove (&si, true);
4966 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4968 si = gsi_last_bb (exit_bb);
4969 if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
4970 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4971 false, GSI_SAME_STMT);
4972 gsi_remove (&si, true);
4973 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4977 /* Generic expansion for OpenMP synchronization directives: master,
4978 ordered and critical. All we need to do here is remove the entry
4979 and exit markers for REGION. */
4982 expand_omp_synch (struct omp_region *region)
4984 basic_block entry_bb, exit_bb;
4985 gimple_stmt_iterator si;
4987 entry_bb = region->entry;
4988 exit_bb = region->exit;
4990 si = gsi_last_bb (entry_bb);
4991 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
4992 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
4993 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
4994 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
4995 gsi_remove (&si, true);
4996 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
5000 si = gsi_last_bb (exit_bb);
5001 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
5002 gsi_remove (&si, true);
5003 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
5007 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5008 operation as a normal volatile load. */
5011 expand_omp_atomic_load (basic_block load_bb, tree addr,
5012 tree loaded_val, int index)
5014 enum built_in_function tmpbase;
5015 gimple_stmt_iterator gsi;
5016 basic_block store_bb;
5019 tree decl, call, type, itype;
5021 gsi = gsi_last_bb (load_bb);
5022 stmt = gsi_stmt (gsi);
5023 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5024 loc = gimple_location (stmt);
5026 /* ??? If the target does not implement atomic_load_optab[mode], and mode
5027 is smaller than word size, then expand_atomic_load assumes that the load
5028 is atomic. We could avoid the builtin entirely in this case. */
5030 tmpbase = (enum built_in_function) (BUILT_IN_ATOMIC_LOAD_N + index + 1);
5031 decl = builtin_decl_explicit (tmpbase);
5032 if (decl == NULL_TREE)
5035 type = TREE_TYPE (loaded_val);
5036 itype = TREE_TYPE (TREE_TYPE (decl));
5038 call = build_call_expr_loc (loc, decl, 2, addr,
5039 build_int_cst (NULL, MEMMODEL_RELAXED));
5040 if (!useless_type_conversion_p (type, itype))
5041 call = fold_build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5042 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5044 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5045 gsi_remove (&gsi, true);
5047 store_bb = single_succ (load_bb);
5048 gsi = gsi_last_bb (store_bb);
5049 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5050 gsi_remove (&gsi, true);
5052 if (gimple_in_ssa_p (cfun))
5053 update_ssa (TODO_update_ssa_no_phi);
5058 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5059 operation as a normal volatile store. */
5062 expand_omp_atomic_store (basic_block load_bb, tree addr,
5063 tree loaded_val, tree stored_val, int index)
5065 enum built_in_function tmpbase;
5066 gimple_stmt_iterator gsi;
5067 basic_block store_bb = single_succ (load_bb);
5070 tree decl, call, type, itype;
5071 enum machine_mode imode;
5074 gsi = gsi_last_bb (load_bb);
5075 stmt = gsi_stmt (gsi);
5076 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_LOAD);
5078 /* If the load value is needed, then this isn't a store but an exchange. */
5079 exchange = gimple_omp_atomic_need_value_p (stmt);
5081 gsi = gsi_last_bb (store_bb);
5082 stmt = gsi_stmt (gsi);
5083 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_ATOMIC_STORE);
5084 loc = gimple_location (stmt);
5086 /* ??? If the target does not implement atomic_store_optab[mode], and mode
5087 is smaller than word size, then expand_atomic_store assumes that the store
5088 is atomic. We could avoid the builtin entirely in this case. */
5090 tmpbase = (exchange ? BUILT_IN_ATOMIC_EXCHANGE_N : BUILT_IN_ATOMIC_STORE_N);
5091 tmpbase = (enum built_in_function) ((int) tmpbase + index + 1);
5092 decl = builtin_decl_explicit (tmpbase);
5093 if (decl == NULL_TREE)
5096 type = TREE_TYPE (stored_val);
5098 /* Dig out the type of the function's second argument. */
5099 itype = TREE_TYPE (decl);
5100 itype = TYPE_ARG_TYPES (itype);
5101 itype = TREE_CHAIN (itype);
5102 itype = TREE_VALUE (itype);
5103 imode = TYPE_MODE (itype);
5105 if (exchange && !can_atomic_exchange_p (imode, true))
5108 if (!useless_type_conversion_p (itype, type))
5109 stored_val = fold_build1_loc (loc, VIEW_CONVERT_EXPR, itype, stored_val);
5110 call = build_call_expr_loc (loc, decl, 3, addr, stored_val,
5111 build_int_cst (NULL, MEMMODEL_RELAXED));
5114 if (!useless_type_conversion_p (type, itype))
5115 call = build1_loc (loc, VIEW_CONVERT_EXPR, type, call);
5116 call = build2_loc (loc, MODIFY_EXPR, void_type_node, loaded_val, call);
5119 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5120 gsi_remove (&gsi, true);
5122 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
5123 gsi = gsi_last_bb (load_bb);
5124 gsi_remove (&gsi, true);
5126 if (gimple_in_ssa_p (cfun))
5127 update_ssa (TODO_update_ssa_no_phi);
5132 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5133 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
5134 size of the data type, and thus usable to find the index of the builtin
5135 decl. Returns false if the expression is not of the proper form. */
5138 expand_omp_atomic_fetch_op (basic_block load_bb,
5139 tree addr, tree loaded_val,
5140 tree stored_val, int index)
5142 enum built_in_function oldbase, newbase, tmpbase;
5143 tree decl, itype, call;
5145 basic_block store_bb = single_succ (load_bb);
5146 gimple_stmt_iterator gsi;
5149 enum tree_code code;
5150 bool need_old, need_new;
5151 enum machine_mode imode;
5153 /* We expect to find the following sequences:
5156 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5159 val = tmp OP something; (or: something OP tmp)
5160 GIMPLE_OMP_STORE (val)
5162 ???FIXME: Allow a more flexible sequence.
5163 Perhaps use data flow to pick the statements.
5167 gsi = gsi_after_labels (store_bb);
5168 stmt = gsi_stmt (gsi);
5169 loc = gimple_location (stmt);
5170 if (!is_gimple_assign (stmt))
5173 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
5175 need_new = gimple_omp_atomic_need_value_p (gsi_stmt (gsi));
5176 need_old = gimple_omp_atomic_need_value_p (last_stmt (load_bb));
5177 gcc_checking_assert (!need_old || !need_new);
5179 if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
5182 /* Check for one of the supported fetch-op operations. */
5183 code = gimple_assign_rhs_code (stmt);
5187 case POINTER_PLUS_EXPR:
5188 oldbase = BUILT_IN_ATOMIC_FETCH_ADD_N;
5189 newbase = BUILT_IN_ATOMIC_ADD_FETCH_N;
5192 oldbase = BUILT_IN_ATOMIC_FETCH_SUB_N;
5193 newbase = BUILT_IN_ATOMIC_SUB_FETCH_N;
5196 oldbase = BUILT_IN_ATOMIC_FETCH_AND_N;
5197 newbase = BUILT_IN_ATOMIC_AND_FETCH_N;
5200 oldbase = BUILT_IN_ATOMIC_FETCH_OR_N;
5201 newbase = BUILT_IN_ATOMIC_OR_FETCH_N;
5204 oldbase = BUILT_IN_ATOMIC_FETCH_XOR_N;
5205 newbase = BUILT_IN_ATOMIC_XOR_FETCH_N;
5211 /* Make sure the expression is of the proper form. */
5212 if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
5213 rhs = gimple_assign_rhs2 (stmt);
5214 else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
5215 && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
5216 rhs = gimple_assign_rhs1 (stmt);
5220 tmpbase = ((enum built_in_function)
5221 ((need_new ? newbase : oldbase) + index + 1));
5222 decl = builtin_decl_explicit (tmpbase);
5223 if (decl == NULL_TREE)
5225 itype = TREE_TYPE (TREE_TYPE (decl));
5226 imode = TYPE_MODE (itype);
5228 /* We could test all of the various optabs involved, but the fact of the
5229 matter is that (with the exception of i486 vs i586 and xadd) all targets
5230 that support any atomic operaton optab also implements compare-and-swap.
5231 Let optabs.c take care of expanding any compare-and-swap loop. */
5232 if (!can_compare_and_swap_p (imode, true))
5235 gsi = gsi_last_bb (load_bb);
5236 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
5238 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5239 It only requires that the operation happen atomically. Thus we can
5240 use the RELAXED memory model. */
5241 call = build_call_expr_loc (loc, decl, 3, addr,
5242 fold_convert_loc (loc, itype, rhs),
5243 build_int_cst (NULL, MEMMODEL_RELAXED));
5245 if (need_old || need_new)
5247 lhs = need_old ? loaded_val : stored_val;
5248 call = fold_convert_loc (loc, TREE_TYPE (lhs), call);
5249 call = build2_loc (loc, MODIFY_EXPR, void_type_node, lhs, call);
5252 call = fold_convert_loc (loc, void_type_node, call);
5253 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
5254 gsi_remove (&gsi, true);
5256 gsi = gsi_last_bb (store_bb);
5257 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5258 gsi_remove (&gsi, true);
5259 gsi = gsi_last_bb (store_bb);
5260 gsi_remove (&gsi, true);
5262 if (gimple_in_ssa_p (cfun))
5263 update_ssa (TODO_update_ssa_no_phi);
5268 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5272 newval = rhs; // with oldval replacing *addr in rhs
5273 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5274 if (oldval != newval)
5277 INDEX is log2 of the size of the data type, and thus usable to find the
5278 index of the builtin decl. */
5281 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
5282 tree addr, tree loaded_val, tree stored_val,
5285 tree loadedi, storedi, initial, new_storedi, old_vali;
5286 tree type, itype, cmpxchg, iaddr;
5287 gimple_stmt_iterator si;
5288 basic_block loop_header = single_succ (load_bb);
5291 enum built_in_function fncode;
5293 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5294 order to use the RELAXED memory model effectively. */
5295 fncode = (enum built_in_function)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5297 cmpxchg = builtin_decl_explicit (fncode);
5298 if (cmpxchg == NULL_TREE)
5300 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5301 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5303 if (!can_compare_and_swap_p (TYPE_MODE (itype), true))
5306 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5307 si = gsi_last_bb (load_bb);
5308 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5310 /* For floating-point values, we'll need to view-convert them to integers
5311 so that we can perform the atomic compare and swap. Simplify the
5312 following code by always setting up the "i"ntegral variables. */
5313 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
5317 iaddr = create_tmp_var (build_pointer_type_for_mode (itype, ptr_mode,
5320 = force_gimple_operand_gsi (&si,
5321 fold_convert (TREE_TYPE (iaddr), addr),
5322 false, NULL_TREE, true, GSI_SAME_STMT);
5323 stmt = gimple_build_assign (iaddr, iaddr_val);
5324 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5325 loadedi = create_tmp_var (itype, NULL);
5326 if (gimple_in_ssa_p (cfun))
5328 add_referenced_var (iaddr);
5329 add_referenced_var (loadedi);
5330 loadedi = make_ssa_name (loadedi, NULL);
5336 loadedi = loaded_val;
5340 = force_gimple_operand_gsi (&si,
5341 build2 (MEM_REF, TREE_TYPE (TREE_TYPE (iaddr)),
5343 build_int_cst (TREE_TYPE (iaddr), 0)),
5344 true, NULL_TREE, true, GSI_SAME_STMT);
5346 /* Move the value to the LOADEDI temporary. */
5347 if (gimple_in_ssa_p (cfun))
5349 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
5350 phi = create_phi_node (loadedi, loop_header);
5351 SSA_NAME_DEF_STMT (loadedi) = phi;
5352 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
5356 gsi_insert_before (&si,
5357 gimple_build_assign (loadedi, initial),
5359 if (loadedi != loaded_val)
5361 gimple_stmt_iterator gsi2;
5364 x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
5365 gsi2 = gsi_start_bb (loop_header);
5366 if (gimple_in_ssa_p (cfun))
5369 x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5370 true, GSI_SAME_STMT);
5371 stmt = gimple_build_assign (loaded_val, x);
5372 gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
5376 x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
5377 force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5378 true, GSI_SAME_STMT);
5381 gsi_remove (&si, true);
5383 si = gsi_last_bb (store_bb);
5384 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5387 storedi = stored_val;
5390 force_gimple_operand_gsi (&si,
5391 build1 (VIEW_CONVERT_EXPR, itype,
5392 stored_val), true, NULL_TREE, true,
5395 /* Build the compare&swap statement. */
5396 new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
5397 new_storedi = force_gimple_operand_gsi (&si,
5398 fold_convert (TREE_TYPE (loadedi),
5401 true, GSI_SAME_STMT);
5403 if (gimple_in_ssa_p (cfun))
5407 old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
5408 if (gimple_in_ssa_p (cfun))
5409 add_referenced_var (old_vali);
5410 stmt = gimple_build_assign (old_vali, loadedi);
5411 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5413 stmt = gimple_build_assign (loadedi, new_storedi);
5414 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5417 /* Note that we always perform the comparison as an integer, even for
5418 floating point. This allows the atomic operation to properly
5419 succeed even with NaNs and -0.0. */
5420 stmt = gimple_build_cond_empty
5421 (build2 (NE_EXPR, boolean_type_node,
5422 new_storedi, old_vali));
5423 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5426 e = single_succ_edge (store_bb);
5427 e->flags &= ~EDGE_FALLTHRU;
5428 e->flags |= EDGE_FALSE_VALUE;
5430 e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
5432 /* Copy the new value to loadedi (we already did that before the condition
5433 if we are not in SSA). */
5434 if (gimple_in_ssa_p (cfun))
5436 phi = gimple_seq_first_stmt (phi_nodes (loop_header));
5437 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
5440 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5441 gsi_remove (&si, true);
5443 if (gimple_in_ssa_p (cfun))
5444 update_ssa (TODO_update_ssa_no_phi);
5449 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5451 GOMP_atomic_start ();
5455 The result is not globally atomic, but works so long as all parallel
5456 references are within #pragma omp atomic directives. According to
5457 responses received from omp@openmp.org, appears to be within spec.
5458 Which makes sense, since that's how several other compilers handle
5459 this situation as well.
5460 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5461 expanding. STORED_VAL is the operand of the matching
5462 GIMPLE_OMP_ATOMIC_STORE.
5465 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5469 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
5474 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
5475 tree addr, tree loaded_val, tree stored_val)
5477 gimple_stmt_iterator si;
5481 si = gsi_last_bb (load_bb);
5482 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5484 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START);
5485 t = build_call_expr (t, 0);
5486 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5488 stmt = gimple_build_assign (loaded_val, build_simple_mem_ref (addr));
5489 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5490 gsi_remove (&si, true);
5492 si = gsi_last_bb (store_bb);
5493 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5495 stmt = gimple_build_assign (build_simple_mem_ref (unshare_expr (addr)),
5497 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5499 t = builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END);
5500 t = build_call_expr (t, 0);
5501 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5502 gsi_remove (&si, true);
5504 if (gimple_in_ssa_p (cfun))
5505 update_ssa (TODO_update_ssa_no_phi);
5509 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5510 using expand_omp_atomic_fetch_op. If it failed, we try to
5511 call expand_omp_atomic_pipeline, and if it fails too, the
5512 ultimate fallback is wrapping the operation in a mutex
5513 (expand_omp_atomic_mutex). REGION is the atomic region built
5514 by build_omp_regions_1(). */
5517 expand_omp_atomic (struct omp_region *region)
5519 basic_block load_bb = region->entry, store_bb = region->exit;
5520 gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
5521 tree loaded_val = gimple_omp_atomic_load_lhs (load);
5522 tree addr = gimple_omp_atomic_load_rhs (load);
5523 tree stored_val = gimple_omp_atomic_store_val (store);
5524 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5525 HOST_WIDE_INT index;
5527 /* Make sure the type is one of the supported sizes. */
5528 index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5529 index = exact_log2 (index);
5530 if (index >= 0 && index <= 4)
5532 unsigned int align = TYPE_ALIGN_UNIT (type);
5534 /* __sync builtins require strict data alignment. */
5535 if (exact_log2 (align) >= index)
5538 if (loaded_val == stored_val
5539 && (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5540 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5541 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5542 && expand_omp_atomic_load (load_bb, addr, loaded_val, index))
5546 if ((GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT
5547 || GET_MODE_CLASS (TYPE_MODE (type)) == MODE_FLOAT)
5548 && GET_MODE_BITSIZE (TYPE_MODE (type)) <= BITS_PER_WORD
5549 && store_bb == single_succ (load_bb)
5550 && first_stmt (store_bb) == store
5551 && expand_omp_atomic_store (load_bb, addr, loaded_val,
5555 /* When possible, use specialized atomic update functions. */
5556 if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5557 && store_bb == single_succ (load_bb)
5558 && expand_omp_atomic_fetch_op (load_bb, addr,
5559 loaded_val, stored_val, index))
5562 /* If we don't have specialized __sync builtins, try and implement
5563 as a compare and swap loop. */
5564 if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
5565 loaded_val, stored_val, index))
5570 /* The ultimate fallback is wrapping the operation in a mutex. */
5571 expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
5575 /* Expand the parallel region tree rooted at REGION. Expansion
5576 proceeds in depth-first order. Innermost regions are expanded
5577 first. This way, parallel regions that require a new function to
5578 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5579 internal dependencies in their body. */
5582 expand_omp (struct omp_region *region)
5586 location_t saved_location;
5588 /* First, determine whether this is a combined parallel+workshare
5590 if (region->type == GIMPLE_OMP_PARALLEL)
5591 determine_parallel_type (region);
5594 expand_omp (region->inner);
5596 saved_location = input_location;
5597 if (gimple_has_location (last_stmt (region->entry)))
5598 input_location = gimple_location (last_stmt (region->entry));
5600 switch (region->type)
5602 case GIMPLE_OMP_PARALLEL:
5603 case GIMPLE_OMP_TASK:
5604 expand_omp_taskreg (region);
5607 case GIMPLE_OMP_FOR:
5608 expand_omp_for (region);
5611 case GIMPLE_OMP_SECTIONS:
5612 expand_omp_sections (region);
5615 case GIMPLE_OMP_SECTION:
5616 /* Individual omp sections are handled together with their
5617 parent GIMPLE_OMP_SECTIONS region. */
5620 case GIMPLE_OMP_SINGLE:
5621 expand_omp_single (region);
5624 case GIMPLE_OMP_MASTER:
5625 case GIMPLE_OMP_ORDERED:
5626 case GIMPLE_OMP_CRITICAL:
5627 expand_omp_synch (region);
5630 case GIMPLE_OMP_ATOMIC_LOAD:
5631 expand_omp_atomic (region);
5638 input_location = saved_location;
5639 region = region->next;
5644 /* Helper for build_omp_regions. Scan the dominator tree starting at
5645 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5646 true, the function ends once a single tree is built (otherwise, whole
5647 forest of OMP constructs may be built). */
5650 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
5653 gimple_stmt_iterator gsi;
5657 gsi = gsi_last_bb (bb);
5658 if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
5660 struct omp_region *region;
5661 enum gimple_code code;
5663 stmt = gsi_stmt (gsi);
5664 code = gimple_code (stmt);
5665 if (code == GIMPLE_OMP_RETURN)
5667 /* STMT is the return point out of region PARENT. Mark it
5668 as the exit point and make PARENT the immediately
5669 enclosing region. */
5670 gcc_assert (parent);
5673 parent = parent->outer;
5675 else if (code == GIMPLE_OMP_ATOMIC_STORE)
5677 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5678 GIMPLE_OMP_RETURN, but matches with
5679 GIMPLE_OMP_ATOMIC_LOAD. */
5680 gcc_assert (parent);
5681 gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
5684 parent = parent->outer;
5687 else if (code == GIMPLE_OMP_CONTINUE)
5689 gcc_assert (parent);
5692 else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
5694 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5695 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5700 /* Otherwise, this directive becomes the parent for a new
5702 region = new_omp_region (bb, code, parent);
5707 if (single_tree && !parent)
5710 for (son = first_dom_son (CDI_DOMINATORS, bb);
5712 son = next_dom_son (CDI_DOMINATORS, son))
5713 build_omp_regions_1 (son, parent, single_tree);
5716 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5720 build_omp_regions_root (basic_block root)
5722 gcc_assert (root_omp_region == NULL);
5723 build_omp_regions_1 (root, NULL, true);
5724 gcc_assert (root_omp_region != NULL);
5727 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5730 omp_expand_local (basic_block head)
5732 build_omp_regions_root (head);
5733 if (dump_file && (dump_flags & TDF_DETAILS))
5735 fprintf (dump_file, "\nOMP region tree\n\n");
5736 dump_omp_region (dump_file, root_omp_region, 0);
5737 fprintf (dump_file, "\n");
5740 remove_exit_barriers (root_omp_region);
5741 expand_omp (root_omp_region);
5743 free_omp_regions ();
5746 /* Scan the CFG and build a tree of OMP regions. Return the root of
5747 the OMP region tree. */
5750 build_omp_regions (void)
5752 gcc_assert (root_omp_region == NULL);
5753 calculate_dominance_info (CDI_DOMINATORS);
5754 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
5757 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5760 execute_expand_omp (void)
5762 build_omp_regions ();
5764 if (!root_omp_region)
5769 fprintf (dump_file, "\nOMP region tree\n\n");
5770 dump_omp_region (dump_file, root_omp_region, 0);
5771 fprintf (dump_file, "\n");
5774 remove_exit_barriers (root_omp_region);
5776 expand_omp (root_omp_region);
5778 cleanup_tree_cfg ();
5780 free_omp_regions ();
5785 /* OMP expansion -- the default pass, run before creation of SSA form. */
5788 gate_expand_omp (void)
5790 return (flag_openmp != 0 && !seen_error ());
5793 struct gimple_opt_pass pass_expand_omp =
5797 "ompexp", /* name */
5798 gate_expand_omp, /* gate */
5799 execute_expand_omp, /* execute */
5802 0, /* static_pass_number */
5803 TV_NONE, /* tv_id */
5804 PROP_gimple_any, /* properties_required */
5805 0, /* properties_provided */
5806 0, /* properties_destroyed */
5807 0, /* todo_flags_start */
5808 0 /* todo_flags_finish */
5812 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5814 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5815 CTX is the enclosing OMP context for the current statement. */
5818 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5820 tree block, control;
5821 gimple_stmt_iterator tgsi;
5823 gimple stmt, new_stmt, bind, t;
5824 gimple_seq ilist, dlist, olist, new_body, body;
5825 struct gimplify_ctx gctx;
5827 stmt = gsi_stmt (*gsi_p);
5829 push_gimplify_context (&gctx);
5833 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5834 &ilist, &dlist, ctx);
5836 tgsi = gsi_start (gimple_omp_body (stmt));
5837 for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
5840 tgsi = gsi_start (gimple_omp_body (stmt));
5842 for (i = 0; i < len; i++, gsi_next (&tgsi))
5847 sec_start = gsi_stmt (tgsi);
5848 sctx = maybe_lookup_ctx (sec_start);
5851 gimple_seq_add_stmt (&body, sec_start);
5853 lower_omp (gimple_omp_body (sec_start), sctx);
5854 gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
5855 gimple_omp_set_body (sec_start, NULL);
5859 gimple_seq l = NULL;
5860 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5862 gimple_seq_add_seq (&body, l);
5863 gimple_omp_section_set_last (sec_start);
5866 gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
5869 block = make_node (BLOCK);
5870 bind = gimple_build_bind (NULL, body, block);
5873 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5875 block = make_node (BLOCK);
5876 new_stmt = gimple_build_bind (NULL, NULL, block);
5878 pop_gimplify_context (new_stmt);
5879 gimple_bind_append_vars (new_stmt, ctx->block_vars);
5880 BLOCK_VARS (block) = gimple_bind_vars (bind);
5881 if (BLOCK_VARS (block))
5882 TREE_USED (block) = 1;
5885 gimple_seq_add_seq (&new_body, ilist);
5886 gimple_seq_add_stmt (&new_body, stmt);
5887 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5888 gimple_seq_add_stmt (&new_body, bind);
5890 control = create_tmp_var (unsigned_type_node, ".section");
5891 t = gimple_build_omp_continue (control, control);
5892 gimple_omp_sections_set_control (stmt, control);
5893 gimple_seq_add_stmt (&new_body, t);
5895 gimple_seq_add_seq (&new_body, olist);
5896 gimple_seq_add_seq (&new_body, dlist);
5898 new_body = maybe_catch_exception (new_body);
5900 t = gimple_build_omp_return
5901 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5902 OMP_CLAUSE_NOWAIT));
5903 gimple_seq_add_stmt (&new_body, t);
5905 gimple_bind_set_body (new_stmt, new_body);
5906 gimple_omp_set_body (stmt, NULL);
5908 gsi_replace (gsi_p, new_stmt, true);
5912 /* A subroutine of lower_omp_single. Expand the simple form of
5913 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5915 if (GOMP_single_start ())
5917 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5919 FIXME. It may be better to delay expanding the logic of this until
5920 pass_expand_omp. The expanded logic may make the job more difficult
5921 to a synchronization analysis pass. */
5924 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5926 location_t loc = gimple_location (single_stmt);
5927 tree tlabel = create_artificial_label (loc);
5928 tree flabel = create_artificial_label (loc);
5932 decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START);
5933 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5934 call = gimple_build_call (decl, 0);
5935 gimple_call_set_lhs (call, lhs);
5936 gimple_seq_add_stmt (pre_p, call);
5938 cond = gimple_build_cond (EQ_EXPR, lhs,
5939 fold_convert_loc (loc, TREE_TYPE (lhs),
5942 gimple_seq_add_stmt (pre_p, cond);
5943 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5944 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5945 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5949 /* A subroutine of lower_omp_single. Expand the simple form of
5950 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5952 #pragma omp single copyprivate (a, b, c)
5954 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5957 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5963 GOMP_single_copy_end (©out);
5974 FIXME. It may be better to delay expanding the logic of this until
5975 pass_expand_omp. The expanded logic may make the job more difficult
5976 to a synchronization analysis pass. */
5979 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
5981 tree ptr_type, t, l0, l1, l2, bfn_decl;
5982 gimple_seq copyin_seq;
5983 location_t loc = gimple_location (single_stmt);
5985 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
5987 ptr_type = build_pointer_type (ctx->record_type);
5988 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
5990 l0 = create_artificial_label (loc);
5991 l1 = create_artificial_label (loc);
5992 l2 = create_artificial_label (loc);
5994 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START);
5995 t = build_call_expr_loc (loc, bfn_decl, 0);
5996 t = fold_convert_loc (loc, ptr_type, t);
5997 gimplify_assign (ctx->receiver_decl, t, pre_p);
5999 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
6000 build_int_cst (ptr_type, 0));
6001 t = build3 (COND_EXPR, void_type_node, t,
6002 build_and_jump (&l0), build_and_jump (&l1));
6003 gimplify_and_add (t, pre_p);
6005 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
6007 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
6010 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
6013 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6014 bfn_decl = builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END);
6015 t = build_call_expr_loc (loc, bfn_decl, 1, t);
6016 gimplify_and_add (t, pre_p);
6018 t = build_and_jump (&l2);
6019 gimplify_and_add (t, pre_p);
6021 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
6023 gimple_seq_add_seq (pre_p, copyin_seq);
6025 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
6029 /* Expand code for an OpenMP single directive. */
6032 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6035 gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
6036 gimple_seq bind_body, dlist;
6037 struct gimplify_ctx gctx;
6039 push_gimplify_context (&gctx);
6042 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
6043 &bind_body, &dlist, ctx);
6044 lower_omp (gimple_omp_body (single_stmt), ctx);
6046 gimple_seq_add_stmt (&bind_body, single_stmt);
6048 if (ctx->record_type)
6049 lower_omp_single_copy (single_stmt, &bind_body, ctx);
6051 lower_omp_single_simple (single_stmt, &bind_body);
6053 gimple_omp_set_body (single_stmt, NULL);
6055 gimple_seq_add_seq (&bind_body, dlist);
6057 bind_body = maybe_catch_exception (bind_body);
6059 t = gimple_build_omp_return
6060 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
6061 OMP_CLAUSE_NOWAIT));
6062 gimple_seq_add_stmt (&bind_body, t);
6064 block = make_node (BLOCK);
6065 bind = gimple_build_bind (NULL, bind_body, block);
6067 pop_gimplify_context (bind);
6069 gimple_bind_append_vars (bind, ctx->block_vars);
6070 BLOCK_VARS (block) = ctx->block_vars;
6071 gsi_replace (gsi_p, bind, true);
6072 if (BLOCK_VARS (block))
6073 TREE_USED (block) = 1;
6077 /* Expand code for an OpenMP master directive. */
6080 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6082 tree block, lab = NULL, x, bfn_decl;
6083 gimple stmt = gsi_stmt (*gsi_p), bind;
6084 location_t loc = gimple_location (stmt);
6086 struct gimplify_ctx gctx;
6088 push_gimplify_context (&gctx);
6090 block = make_node (BLOCK);
6091 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6094 bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
6095 x = build_call_expr_loc (loc, bfn_decl, 0);
6096 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
6097 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
6099 gimplify_and_add (x, &tseq);
6100 gimple_bind_add_seq (bind, tseq);
6102 lower_omp (gimple_omp_body (stmt), ctx);
6103 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6104 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6105 gimple_omp_set_body (stmt, NULL);
6107 gimple_bind_add_stmt (bind, gimple_build_label (lab));
6109 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6111 pop_gimplify_context (bind);
6113 gimple_bind_append_vars (bind, ctx->block_vars);
6114 BLOCK_VARS (block) = ctx->block_vars;
6115 gsi_replace (gsi_p, bind, true);
6119 /* Expand code for an OpenMP ordered directive. */
6122 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6125 gimple stmt = gsi_stmt (*gsi_p), bind, x;
6126 struct gimplify_ctx gctx;
6128 push_gimplify_context (&gctx);
6130 block = make_node (BLOCK);
6131 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
6134 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
6136 gimple_bind_add_stmt (bind, x);
6138 lower_omp (gimple_omp_body (stmt), ctx);
6139 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6140 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6141 gimple_omp_set_body (stmt, NULL);
6143 x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END), 0);
6144 gimple_bind_add_stmt (bind, x);
6146 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6148 pop_gimplify_context (bind);
6150 gimple_bind_append_vars (bind, ctx->block_vars);
6151 BLOCK_VARS (block) = gimple_bind_vars (bind);
6152 gsi_replace (gsi_p, bind, true);
6156 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
6157 substitution of a couple of function calls. But in the NAMED case,
6158 requires that languages coordinate a symbol name. It is therefore
6159 best put here in common code. */
6161 static GTY((param1_is (tree), param2_is (tree)))
6162 splay_tree critical_name_mutexes;
6165 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6168 tree name, lock, unlock;
6169 gimple stmt = gsi_stmt (*gsi_p), bind;
6170 location_t loc = gimple_location (stmt);
6172 struct gimplify_ctx gctx;
6174 name = gimple_omp_critical_name (stmt);
6180 if (!critical_name_mutexes)
6181 critical_name_mutexes
6182 = splay_tree_new_ggc (splay_tree_compare_pointers,
6183 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s,
6184 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s);
6186 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
6191 decl = create_tmp_var_raw (ptr_type_node, NULL);
6193 new_str = ACONCAT ((".gomp_critical_user_",
6194 IDENTIFIER_POINTER (name), NULL));
6195 DECL_NAME (decl) = get_identifier (new_str);
6196 TREE_PUBLIC (decl) = 1;
6197 TREE_STATIC (decl) = 1;
6198 DECL_COMMON (decl) = 1;
6199 DECL_ARTIFICIAL (decl) = 1;
6200 DECL_IGNORED_P (decl) = 1;
6201 varpool_finalize_decl (decl);
6203 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
6204 (splay_tree_value) decl);
6207 decl = (tree) n->value;
6209 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START);
6210 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
6212 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END);
6213 unlock = build_call_expr_loc (loc, unlock, 1,
6214 build_fold_addr_expr_loc (loc, decl));
6218 lock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START);
6219 lock = build_call_expr_loc (loc, lock, 0);
6221 unlock = builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END);
6222 unlock = build_call_expr_loc (loc, unlock, 0);
6225 push_gimplify_context (&gctx);
6227 block = make_node (BLOCK);
6228 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
6230 tbody = gimple_bind_body (bind);
6231 gimplify_and_add (lock, &tbody);
6232 gimple_bind_set_body (bind, tbody);
6234 lower_omp (gimple_omp_body (stmt), ctx);
6235 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
6236 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
6237 gimple_omp_set_body (stmt, NULL);
6239 tbody = gimple_bind_body (bind);
6240 gimplify_and_add (unlock, &tbody);
6241 gimple_bind_set_body (bind, tbody);
6243 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
6245 pop_gimplify_context (bind);
6246 gimple_bind_append_vars (bind, ctx->block_vars);
6247 BLOCK_VARS (block) = gimple_bind_vars (bind);
6248 gsi_replace (gsi_p, bind, true);
6252 /* A subroutine of lower_omp_for. Generate code to emit the predicate
6253 for a lastprivate clause. Given a loop control predicate of (V
6254 cond N2), we gate the clause on (!(V cond N2)). The lowered form
6255 is appended to *DLIST, iterator initialization is appended to
6259 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
6260 gimple_seq *dlist, struct omp_context *ctx)
6262 tree clauses, cond, vinit;
6263 enum tree_code cond_code;
6266 cond_code = fd->loop.cond_code;
6267 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
6269 /* When possible, use a strict equality expression. This can let VRP
6270 type optimizations deduce the value and remove a copy. */
6271 if (host_integerp (fd->loop.step, 0))
6273 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
6274 if (step == 1 || step == -1)
6275 cond_code = EQ_EXPR;
6278 cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
6280 clauses = gimple_omp_for_clauses (fd->for_stmt);
6282 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
6283 if (!gimple_seq_empty_p (stmts))
6285 gimple_seq_add_seq (&stmts, *dlist);
6288 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6289 vinit = fd->loop.n1;
6290 if (cond_code == EQ_EXPR
6291 && host_integerp (fd->loop.n2, 0)
6292 && ! integer_zerop (fd->loop.n2))
6293 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6295 /* Initialize the iterator variable, so that threads that don't execute
6296 any iterations don't execute the lastprivate clauses by accident. */
6297 gimplify_assign (fd->loop.v, vinit, body_p);
6302 /* Lower code for an OpenMP loop directive. */
6305 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6308 struct omp_for_data fd;
6309 gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6310 gimple_seq omp_for_body, body, dlist;
6312 struct gimplify_ctx gctx;
6314 push_gimplify_context (&gctx);
6316 lower_omp (gimple_omp_for_pre_body (stmt), ctx);
6317 lower_omp (gimple_omp_body (stmt), ctx);
6319 block = make_node (BLOCK);
6320 new_stmt = gimple_build_bind (NULL, NULL, block);
6322 /* Move declaration of temporaries in the loop body before we make
6324 omp_for_body = gimple_omp_body (stmt);
6325 if (!gimple_seq_empty_p (omp_for_body)
6326 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6328 tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6329 gimple_bind_append_vars (new_stmt, vars);
6332 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6335 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6336 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6338 /* Lower the header expressions. At this point, we can assume that
6339 the header is of the form:
6341 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6343 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6344 using the .omp_data_s mapping, if needed. */
6345 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6347 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6348 if (!is_gimple_min_invariant (*rhs_p))
6349 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6351 rhs_p = gimple_omp_for_final_ptr (stmt, i);
6352 if (!is_gimple_min_invariant (*rhs_p))
6353 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6355 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6356 if (!is_gimple_min_invariant (*rhs_p))
6357 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6360 /* Once lowered, extract the bounds and clauses. */
6361 extract_omp_for_data (stmt, &fd, NULL);
6363 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6365 gimple_seq_add_stmt (&body, stmt);
6366 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6368 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6371 /* After the loop, add exit clauses. */
6372 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6373 gimple_seq_add_seq (&body, dlist);
6375 body = maybe_catch_exception (body);
6377 /* Region exit marker goes at the end of the loop body. */
6378 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6380 pop_gimplify_context (new_stmt);
6382 gimple_bind_append_vars (new_stmt, ctx->block_vars);
6383 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6384 if (BLOCK_VARS (block))
6385 TREE_USED (block) = 1;
6387 gimple_bind_set_body (new_stmt, body);
6388 gimple_omp_set_body (stmt, NULL);
6389 gimple_omp_for_set_pre_body (stmt, NULL);
6390 gsi_replace (gsi_p, new_stmt, true);
6393 /* Callback for walk_stmts. Check if the current statement only contains
6394 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6397 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6398 bool *handled_ops_p,
6399 struct walk_stmt_info *wi)
6401 int *info = (int *) wi->info;
6402 gimple stmt = gsi_stmt (*gsi_p);
6404 *handled_ops_p = true;
6405 switch (gimple_code (stmt))
6409 case GIMPLE_OMP_FOR:
6410 case GIMPLE_OMP_SECTIONS:
6411 *info = *info == 0 ? 1 : -1;
6420 struct omp_taskcopy_context
6422 /* This field must be at the beginning, as we do "inheritance": Some
6423 callback functions for tree-inline.c (e.g., omp_copy_decl)
6424 receive a copy_body_data pointer that is up-casted to an
6425 omp_context pointer. */
6431 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6433 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6435 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6436 return create_tmp_var (TREE_TYPE (var), NULL);
6442 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6444 tree name, new_fields = NULL, type, f;
6446 type = lang_hooks.types.make_type (RECORD_TYPE);
6447 name = DECL_NAME (TYPE_NAME (orig_type));
6448 name = build_decl (gimple_location (tcctx->ctx->stmt),
6449 TYPE_DECL, name, type);
6450 TYPE_NAME (type) = name;
6452 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6454 tree new_f = copy_node (f);
6455 DECL_CONTEXT (new_f) = type;
6456 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6457 TREE_CHAIN (new_f) = new_fields;
6458 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6459 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6460 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6463 *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6465 TYPE_FIELDS (type) = nreverse (new_fields);
6470 /* Create task copyfn. */
6473 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6475 struct function *child_cfun;
6476 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6477 tree record_type, srecord_type, bind, list;
6478 bool record_needs_remap = false, srecord_needs_remap = false;
6480 struct omp_taskcopy_context tcctx;
6481 struct gimplify_ctx gctx;
6482 location_t loc = gimple_location (task_stmt);
6484 child_fn = gimple_omp_task_copy_fn (task_stmt);
6485 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6486 gcc_assert (child_cfun->cfg == NULL);
6487 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6489 /* Reset DECL_CONTEXT on function arguments. */
6490 for (t = DECL_ARGUMENTS (child_fn); t; t = DECL_CHAIN (t))
6491 DECL_CONTEXT (t) = child_fn;
6493 /* Populate the function. */
6494 push_gimplify_context (&gctx);
6495 current_function_decl = child_fn;
6497 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6498 TREE_SIDE_EFFECTS (bind) = 1;
6500 DECL_SAVED_TREE (child_fn) = bind;
6501 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6503 /* Remap src and dst argument types if needed. */
6504 record_type = ctx->record_type;
6505 srecord_type = ctx->srecord_type;
6506 for (f = TYPE_FIELDS (record_type); f ; f = DECL_CHAIN (f))
6507 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6509 record_needs_remap = true;
6512 for (f = TYPE_FIELDS (srecord_type); f ; f = DECL_CHAIN (f))
6513 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6515 srecord_needs_remap = true;
6519 if (record_needs_remap || srecord_needs_remap)
6521 memset (&tcctx, '\0', sizeof (tcctx));
6522 tcctx.cb.src_fn = ctx->cb.src_fn;
6523 tcctx.cb.dst_fn = child_fn;
6524 tcctx.cb.src_node = cgraph_get_node (tcctx.cb.src_fn);
6525 gcc_checking_assert (tcctx.cb.src_node);
6526 tcctx.cb.dst_node = tcctx.cb.src_node;
6527 tcctx.cb.src_cfun = ctx->cb.src_cfun;
6528 tcctx.cb.copy_decl = task_copyfn_copy_decl;
6529 tcctx.cb.eh_lp_nr = 0;
6530 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6531 tcctx.cb.decl_map = pointer_map_create ();
6534 if (record_needs_remap)
6535 record_type = task_copyfn_remap_type (&tcctx, record_type);
6536 if (srecord_needs_remap)
6537 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6540 tcctx.cb.decl_map = NULL;
6542 push_cfun (child_cfun);
6544 arg = DECL_ARGUMENTS (child_fn);
6545 TREE_TYPE (arg) = build_pointer_type (record_type);
6546 sarg = DECL_CHAIN (arg);
6547 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6549 /* First pass: initialize temporaries used in record_type and srecord_type
6550 sizes and field offsets. */
6551 if (tcctx.cb.decl_map)
6552 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6553 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6557 decl = OMP_CLAUSE_DECL (c);
6558 p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6561 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6562 sf = (tree) n->value;
6563 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6564 src = build_simple_mem_ref_loc (loc, sarg);
6565 src = omp_build_component_ref (src, sf);
6566 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6567 append_to_statement_list (t, &list);
6570 /* Second pass: copy shared var pointers and copy construct non-VLA
6571 firstprivate vars. */
6572 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6573 switch (OMP_CLAUSE_CODE (c))
6575 case OMP_CLAUSE_SHARED:
6576 decl = OMP_CLAUSE_DECL (c);
6577 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6580 f = (tree) n->value;
6581 if (tcctx.cb.decl_map)
6582 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6583 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6584 sf = (tree) n->value;
6585 if (tcctx.cb.decl_map)
6586 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6587 src = build_simple_mem_ref_loc (loc, sarg);
6588 src = omp_build_component_ref (src, sf);
6589 dst = build_simple_mem_ref_loc (loc, arg);
6590 dst = omp_build_component_ref (dst, f);
6591 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6592 append_to_statement_list (t, &list);
6594 case OMP_CLAUSE_FIRSTPRIVATE:
6595 decl = OMP_CLAUSE_DECL (c);
6596 if (is_variable_sized (decl))
6598 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6601 f = (tree) n->value;
6602 if (tcctx.cb.decl_map)
6603 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6604 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6607 sf = (tree) n->value;
6608 if (tcctx.cb.decl_map)
6609 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6610 src = build_simple_mem_ref_loc (loc, sarg);
6611 src = omp_build_component_ref (src, sf);
6612 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6613 src = build_simple_mem_ref_loc (loc, src);
6617 dst = build_simple_mem_ref_loc (loc, arg);
6618 dst = omp_build_component_ref (dst, f);
6619 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6620 append_to_statement_list (t, &list);
6622 case OMP_CLAUSE_PRIVATE:
6623 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6625 decl = OMP_CLAUSE_DECL (c);
6626 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6627 f = (tree) n->value;
6628 if (tcctx.cb.decl_map)
6629 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6630 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6633 sf = (tree) n->value;
6634 if (tcctx.cb.decl_map)
6635 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6636 src = build_simple_mem_ref_loc (loc, sarg);
6637 src = omp_build_component_ref (src, sf);
6638 if (use_pointer_for_field (decl, NULL))
6639 src = build_simple_mem_ref_loc (loc, src);
6643 dst = build_simple_mem_ref_loc (loc, arg);
6644 dst = omp_build_component_ref (dst, f);
6645 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6646 append_to_statement_list (t, &list);
6652 /* Last pass: handle VLA firstprivates. */
6653 if (tcctx.cb.decl_map)
6654 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6655 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6659 decl = OMP_CLAUSE_DECL (c);
6660 if (!is_variable_sized (decl))
6662 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6665 f = (tree) n->value;
6666 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6667 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6668 ind = DECL_VALUE_EXPR (decl);
6669 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6670 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6671 n = splay_tree_lookup (ctx->sfield_map,
6672 (splay_tree_key) TREE_OPERAND (ind, 0));
6673 sf = (tree) n->value;
6674 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6675 src = build_simple_mem_ref_loc (loc, sarg);
6676 src = omp_build_component_ref (src, sf);
6677 src = build_simple_mem_ref_loc (loc, src);
6678 dst = build_simple_mem_ref_loc (loc, arg);
6679 dst = omp_build_component_ref (dst, f);
6680 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6681 append_to_statement_list (t, &list);
6682 n = splay_tree_lookup (ctx->field_map,
6683 (splay_tree_key) TREE_OPERAND (ind, 0));
6684 df = (tree) n->value;
6685 df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6686 ptr = build_simple_mem_ref_loc (loc, arg);
6687 ptr = omp_build_component_ref (ptr, df);
6688 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6689 build_fold_addr_expr_loc (loc, dst));
6690 append_to_statement_list (t, &list);
6693 t = build1 (RETURN_EXPR, void_type_node, NULL);
6694 append_to_statement_list (t, &list);
6696 if (tcctx.cb.decl_map)
6697 pointer_map_destroy (tcctx.cb.decl_map);
6698 pop_gimplify_context (NULL);
6699 BIND_EXPR_BODY (bind) = list;
6701 current_function_decl = ctx->cb.src_fn;
6704 /* Lower the OpenMP parallel or task directive in the current statement
6705 in GSI_P. CTX holds context information for the directive. */
6708 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6712 gimple stmt = gsi_stmt (*gsi_p);
6713 gimple par_bind, bind;
6714 gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6715 struct gimplify_ctx gctx;
6716 location_t loc = gimple_location (stmt);
6718 clauses = gimple_omp_taskreg_clauses (stmt);
6719 par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6720 par_body = gimple_bind_body (par_bind);
6721 child_fn = ctx->cb.dst_fn;
6722 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6723 && !gimple_omp_parallel_combined_p (stmt))
6725 struct walk_stmt_info wi;
6728 memset (&wi, 0, sizeof (wi));
6731 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6733 gimple_omp_parallel_set_combined_p (stmt, true);
6735 if (ctx->srecord_type)
6736 create_task_copyfn (stmt, ctx);
6738 push_gimplify_context (&gctx);
6742 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6743 lower_omp (par_body, ctx);
6744 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6745 lower_reduction_clauses (clauses, &par_olist, ctx);
6747 /* Declare all the variables created by mapping and the variables
6748 declared in the scope of the parallel body. */
6749 record_vars_into (ctx->block_vars, child_fn);
6750 record_vars_into (gimple_bind_vars (par_bind), child_fn);
6752 if (ctx->record_type)
6755 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6756 : ctx->record_type, ".omp_data_o");
6757 DECL_NAMELESS (ctx->sender_decl) = 1;
6758 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6759 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6764 lower_send_clauses (clauses, &ilist, &olist, ctx);
6765 lower_send_shared_vars (&ilist, &olist, ctx);
6767 /* Once all the expansions are done, sequence all the different
6768 fragments inside gimple_omp_body. */
6772 if (ctx->record_type)
6774 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6775 /* fixup_child_record_type might have changed receiver_decl's type. */
6776 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6777 gimple_seq_add_stmt (&new_body,
6778 gimple_build_assign (ctx->receiver_decl, t));
6781 gimple_seq_add_seq (&new_body, par_ilist);
6782 gimple_seq_add_seq (&new_body, par_body);
6783 gimple_seq_add_seq (&new_body, par_olist);
6784 new_body = maybe_catch_exception (new_body);
6785 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6786 gimple_omp_set_body (stmt, new_body);
6788 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6789 gimple_bind_add_stmt (bind, stmt);
6792 gimple_seq_add_stmt (&ilist, bind);
6793 gimple_seq_add_seq (&ilist, olist);
6794 bind = gimple_build_bind (NULL, ilist, NULL);
6797 gsi_replace (gsi_p, bind, true);
6799 pop_gimplify_context (NULL);
6802 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6803 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6804 of OpenMP context, but with task_shared_vars set. */
6807 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6812 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6813 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6816 if (task_shared_vars
6818 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6821 /* If a global variable has been privatized, TREE_CONSTANT on
6822 ADDR_EXPR might be wrong. */
6823 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6824 recompute_tree_invariant_for_addr_expr (t);
6826 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6831 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6833 gimple stmt = gsi_stmt (*gsi_p);
6834 struct walk_stmt_info wi;
6836 if (gimple_has_location (stmt))
6837 input_location = gimple_location (stmt);
6839 if (task_shared_vars)
6840 memset (&wi, '\0', sizeof (wi));
6842 /* If we have issued syntax errors, avoid doing any heavy lifting.
6843 Just replace the OpenMP directives with a NOP to avoid
6844 confusing RTL expansion. */
6845 if (seen_error () && is_gimple_omp (stmt))
6847 gsi_replace (gsi_p, gimple_build_nop (), true);
6851 switch (gimple_code (stmt))
6854 if ((ctx || task_shared_vars)
6855 && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6856 ctx ? NULL : &wi, NULL)
6857 || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6858 ctx ? NULL : &wi, NULL)))
6859 gimple_regimplify_operands (stmt, gsi_p);
6862 lower_omp (gimple_catch_handler (stmt), ctx);
6864 case GIMPLE_EH_FILTER:
6865 lower_omp (gimple_eh_filter_failure (stmt), ctx);
6868 lower_omp (gimple_try_eval (stmt), ctx);
6869 lower_omp (gimple_try_cleanup (stmt), ctx);
6872 lower_omp (gimple_bind_body (stmt), ctx);
6874 case GIMPLE_OMP_PARALLEL:
6875 case GIMPLE_OMP_TASK:
6876 ctx = maybe_lookup_ctx (stmt);
6877 lower_omp_taskreg (gsi_p, ctx);
6879 case GIMPLE_OMP_FOR:
6880 ctx = maybe_lookup_ctx (stmt);
6882 lower_omp_for (gsi_p, ctx);
6884 case GIMPLE_OMP_SECTIONS:
6885 ctx = maybe_lookup_ctx (stmt);
6887 lower_omp_sections (gsi_p, ctx);
6889 case GIMPLE_OMP_SINGLE:
6890 ctx = maybe_lookup_ctx (stmt);
6892 lower_omp_single (gsi_p, ctx);
6894 case GIMPLE_OMP_MASTER:
6895 ctx = maybe_lookup_ctx (stmt);
6897 lower_omp_master (gsi_p, ctx);
6899 case GIMPLE_OMP_ORDERED:
6900 ctx = maybe_lookup_ctx (stmt);
6902 lower_omp_ordered (gsi_p, ctx);
6904 case GIMPLE_OMP_CRITICAL:
6905 ctx = maybe_lookup_ctx (stmt);
6907 lower_omp_critical (gsi_p, ctx);
6909 case GIMPLE_OMP_ATOMIC_LOAD:
6910 if ((ctx || task_shared_vars)
6911 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6912 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6913 gimple_regimplify_operands (stmt, gsi_p);
6916 if ((ctx || task_shared_vars)
6917 && walk_gimple_op (stmt, lower_omp_regimplify_p,
6919 gimple_regimplify_operands (stmt, gsi_p);
6925 lower_omp (gimple_seq body, omp_context *ctx)
6927 location_t saved_location = input_location;
6928 gimple_stmt_iterator gsi = gsi_start (body);
6929 for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
6930 lower_omp_1 (&gsi, ctx);
6931 input_location = saved_location;
6934 /* Main entry point. */
6937 execute_lower_omp (void)
6941 /* This pass always runs, to provide PROP_gimple_lomp.
6942 But there is nothing to do unless -fopenmp is given. */
6943 if (flag_openmp == 0)
6946 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6947 delete_omp_context);
6949 body = gimple_body (current_function_decl);
6950 scan_omp (body, NULL);
6951 gcc_assert (taskreg_nesting_level == 0);
6953 if (all_contexts->root)
6955 struct gimplify_ctx gctx;
6957 if (task_shared_vars)
6958 push_gimplify_context (&gctx);
6959 lower_omp (body, NULL);
6960 if (task_shared_vars)
6961 pop_gimplify_context (NULL);
6966 splay_tree_delete (all_contexts);
6967 all_contexts = NULL;
6969 BITMAP_FREE (task_shared_vars);
6973 struct gimple_opt_pass pass_lower_omp =
6977 "omplower", /* name */
6979 execute_lower_omp, /* execute */
6982 0, /* static_pass_number */
6983 TV_NONE, /* tv_id */
6984 PROP_gimple_any, /* properties_required */
6985 PROP_gimple_lomp, /* properties_provided */
6986 0, /* properties_destroyed */
6987 0, /* todo_flags_start */
6988 0 /* todo_flags_finish */
6992 /* The following is a utility to diagnose OpenMP structured block violations.
6993 It is not part of the "omplower" pass, as that's invoked too late. It
6994 should be invoked by the respective front ends after gimplification. */
6996 static splay_tree all_labels;
6998 /* Check for mismatched contexts and generate an error if needed. Return
6999 true if an error is detected. */
7002 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
7003 gimple branch_ctx, gimple label_ctx)
7005 if (label_ctx == branch_ctx)
7010 Previously we kept track of the label's entire context in diagnose_sb_[12]
7011 so we could traverse it and issue a correct "exit" or "enter" error
7012 message upon a structured block violation.
7014 We built the context by building a list with tree_cons'ing, but there is
7015 no easy counterpart in gimple tuples. It seems like far too much work
7016 for issuing exit/enter error messages. If someone really misses the
7017 distinct error message... patches welcome.
7021 /* Try to avoid confusing the user by producing and error message
7022 with correct "exit" or "enter" verbiage. We prefer "exit"
7023 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
7024 if (branch_ctx == NULL)
7030 if (TREE_VALUE (label_ctx) == branch_ctx)
7035 label_ctx = TREE_CHAIN (label_ctx);
7040 error ("invalid exit from OpenMP structured block");
7042 error ("invalid entry to OpenMP structured block");
7045 /* If it's obvious we have an invalid entry, be specific about the error. */
7046 if (branch_ctx == NULL)
7047 error ("invalid entry to OpenMP structured block");
7049 /* Otherwise, be vague and lazy, but efficient. */
7050 error ("invalid branch to/from an OpenMP structured block");
7052 gsi_replace (gsi_p, gimple_build_nop (), false);
7056 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7057 where each label is found. */
7060 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7061 struct walk_stmt_info *wi)
7063 gimple context = (gimple) wi->info;
7064 gimple inner_context;
7065 gimple stmt = gsi_stmt (*gsi_p);
7067 *handled_ops_p = true;
7069 switch (gimple_code (stmt))
7073 case GIMPLE_OMP_PARALLEL:
7074 case GIMPLE_OMP_TASK:
7075 case GIMPLE_OMP_SECTIONS:
7076 case GIMPLE_OMP_SINGLE:
7077 case GIMPLE_OMP_SECTION:
7078 case GIMPLE_OMP_MASTER:
7079 case GIMPLE_OMP_ORDERED:
7080 case GIMPLE_OMP_CRITICAL:
7081 /* The minimal context here is just the current OMP construct. */
7082 inner_context = stmt;
7083 wi->info = inner_context;
7084 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7088 case GIMPLE_OMP_FOR:
7089 inner_context = stmt;
7090 wi->info = inner_context;
7091 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7093 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7094 diagnose_sb_1, NULL, wi);
7095 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
7100 splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
7101 (splay_tree_value) context);
7111 /* Pass 2: Check each branch and see if its context differs from that of
7112 the destination label's context. */
7115 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
7116 struct walk_stmt_info *wi)
7118 gimple context = (gimple) wi->info;
7120 gimple stmt = gsi_stmt (*gsi_p);
7122 *handled_ops_p = true;
7124 switch (gimple_code (stmt))
7128 case GIMPLE_OMP_PARALLEL:
7129 case GIMPLE_OMP_TASK:
7130 case GIMPLE_OMP_SECTIONS:
7131 case GIMPLE_OMP_SINGLE:
7132 case GIMPLE_OMP_SECTION:
7133 case GIMPLE_OMP_MASTER:
7134 case GIMPLE_OMP_ORDERED:
7135 case GIMPLE_OMP_CRITICAL:
7137 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7141 case GIMPLE_OMP_FOR:
7143 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7145 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
7146 diagnose_sb_2, NULL, wi);
7147 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
7153 tree lab = gimple_cond_true_label (stmt);
7156 n = splay_tree_lookup (all_labels,
7157 (splay_tree_key) lab);
7158 diagnose_sb_0 (gsi_p, context,
7159 n ? (gimple) n->value : NULL);
7161 lab = gimple_cond_false_label (stmt);
7164 n = splay_tree_lookup (all_labels,
7165 (splay_tree_key) lab);
7166 diagnose_sb_0 (gsi_p, context,
7167 n ? (gimple) n->value : NULL);
7174 tree lab = gimple_goto_dest (stmt);
7175 if (TREE_CODE (lab) != LABEL_DECL)
7178 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7179 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
7186 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
7188 tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
7189 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
7190 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
7197 diagnose_sb_0 (gsi_p, context, NULL);
7208 diagnose_omp_structured_block_errors (void)
7210 struct walk_stmt_info wi;
7211 gimple_seq body = gimple_body (current_function_decl);
7213 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
7215 memset (&wi, 0, sizeof (wi));
7216 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
7218 memset (&wi, 0, sizeof (wi));
7219 wi.want_locations = true;
7220 walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
7222 splay_tree_delete (all_labels);
7229 gate_diagnose_omp_blocks (void)
7231 return flag_openmp != 0;
7234 struct gimple_opt_pass pass_diagnose_omp_blocks =
7238 "*diagnose_omp_blocks", /* name */
7239 gate_diagnose_omp_blocks, /* gate */
7240 diagnose_omp_structured_block_errors, /* execute */
7243 0, /* static_pass_number */
7244 TV_NONE, /* tv_id */
7245 PROP_gimple_any, /* properties_required */
7246 0, /* properties_provided */
7247 0, /* properties_destroyed */
7248 0, /* todo_flags_start */
7249 0, /* todo_flags_finish */
7253 #include "gt-omp-low.h"