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 Free Software Foundation, Inc.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
31 #include "tree-iterator.h"
32 #include "tree-inline.h"
33 #include "langhooks.h"
34 #include "diagnostic.h"
35 #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 /* The sub-statements for these should be walked. */ \
143 *handled_ops_p = false; \
146 /* Convenience function for calling scan_omp_1_op on tree operands. */
149 scan_omp_op (tree *tp, omp_context *ctx)
151 struct walk_stmt_info wi;
153 memset (&wi, 0, sizeof (wi));
155 wi.want_locations = true;
157 return walk_tree (tp, scan_omp_1_op, &wi, NULL);
160 static void lower_omp (gimple_seq, omp_context *);
161 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
162 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
164 /* Find an OpenMP clause of type KIND within CLAUSES. */
167 find_omp_clause (tree clauses, enum omp_clause_code kind)
169 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
170 if (OMP_CLAUSE_CODE (clauses) == kind)
176 /* Return true if CTX is for an omp parallel. */
179 is_parallel_ctx (omp_context *ctx)
181 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
185 /* Return true if CTX is for an omp task. */
188 is_task_ctx (omp_context *ctx)
190 return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
194 /* Return true if CTX is for an omp parallel or omp task. */
197 is_taskreg_ctx (omp_context *ctx)
199 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
200 || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
204 /* Return true if REGION is a combined parallel+workshare region. */
207 is_combined_parallel (struct omp_region *region)
209 return region->is_combined_parallel;
213 /* Extract the header elements of parallel loop FOR_STMT and store
217 extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
218 struct omp_for_data_loop *loops)
220 tree t, var, *collapse_iter, *collapse_count;
221 tree count = NULL_TREE, iter_type = long_integer_type_node;
222 struct omp_for_data_loop *loop;
224 struct omp_for_data_loop dummy_loop;
225 location_t loc = gimple_location (for_stmt);
227 fd->for_stmt = for_stmt;
229 fd->collapse = gimple_omp_for_collapse (for_stmt);
230 if (fd->collapse > 1)
233 fd->loops = &fd->loop;
235 fd->have_nowait = fd->have_ordered = false;
236 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
237 fd->chunk_size = NULL_TREE;
238 collapse_iter = NULL;
239 collapse_count = NULL;
241 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
242 switch (OMP_CLAUSE_CODE (t))
244 case OMP_CLAUSE_NOWAIT:
245 fd->have_nowait = true;
247 case OMP_CLAUSE_ORDERED:
248 fd->have_ordered = true;
250 case OMP_CLAUSE_SCHEDULE:
251 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
252 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
254 case OMP_CLAUSE_COLLAPSE:
255 if (fd->collapse > 1)
257 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
258 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
264 /* FIXME: for now map schedule(auto) to schedule(static).
265 There should be analysis to determine whether all iterations
266 are approximately the same amount of work (then schedule(static)
267 is best) or if it varies (then schedule(dynamic,N) is better). */
268 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
270 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
271 gcc_assert (fd->chunk_size == NULL);
273 gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
274 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
275 gcc_assert (fd->chunk_size == NULL);
276 else if (fd->chunk_size == NULL)
278 /* We only need to compute a default chunk size for ordered
279 static loops and dynamic loops. */
280 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
283 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
284 ? integer_zero_node : integer_one_node;
287 for (i = 0; i < fd->collapse; i++)
289 if (fd->collapse == 1)
291 else if (loops != NULL)
297 loop->v = gimple_omp_for_index (for_stmt, i);
298 gcc_assert (SSA_VAR_P (loop->v));
299 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
300 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
301 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
302 loop->n1 = gimple_omp_for_initial (for_stmt, i);
304 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
305 loop->n2 = gimple_omp_for_final (for_stmt, i);
306 switch (loop->cond_code)
312 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
313 loop->n2 = fold_build2_loc (loc,
314 POINTER_PLUS_EXPR, TREE_TYPE (loop->n2),
315 loop->n2, size_one_node);
317 loop->n2 = fold_build2_loc (loc,
318 PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
319 build_int_cst (TREE_TYPE (loop->n2), 1));
320 loop->cond_code = LT_EXPR;
323 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
324 loop->n2 = fold_build2_loc (loc,
325 POINTER_PLUS_EXPR, TREE_TYPE (loop->n2),
326 loop->n2, size_int (-1));
328 loop->n2 = fold_build2_loc (loc,
329 MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
330 build_int_cst (TREE_TYPE (loop->n2), 1));
331 loop->cond_code = GT_EXPR;
337 t = gimple_omp_for_incr (for_stmt, i);
338 gcc_assert (TREE_OPERAND (t, 0) == var);
339 switch (TREE_CODE (t))
342 case POINTER_PLUS_EXPR:
343 loop->step = TREE_OPERAND (t, 1);
346 loop->step = TREE_OPERAND (t, 1);
347 loop->step = fold_build1_loc (loc,
348 NEGATE_EXPR, TREE_TYPE (loop->step),
355 if (iter_type != long_long_unsigned_type_node)
357 if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
358 iter_type = long_long_unsigned_type_node;
359 else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
360 && TYPE_PRECISION (TREE_TYPE (loop->v))
361 >= TYPE_PRECISION (iter_type))
365 if (loop->cond_code == LT_EXPR)
366 n = fold_build2_loc (loc,
367 PLUS_EXPR, TREE_TYPE (loop->v),
368 loop->n2, loop->step);
371 if (TREE_CODE (n) != INTEGER_CST
372 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
373 iter_type = long_long_unsigned_type_node;
375 else if (TYPE_PRECISION (TREE_TYPE (loop->v))
376 > TYPE_PRECISION (iter_type))
380 if (loop->cond_code == LT_EXPR)
383 n2 = fold_build2_loc (loc,
384 PLUS_EXPR, TREE_TYPE (loop->v),
385 loop->n2, loop->step);
389 n1 = fold_build2_loc (loc,
390 MINUS_EXPR, TREE_TYPE (loop->v),
391 loop->n2, loop->step);
394 if (TREE_CODE (n1) != INTEGER_CST
395 || TREE_CODE (n2) != INTEGER_CST
396 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
397 || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
398 iter_type = long_long_unsigned_type_node;
402 if (collapse_count && *collapse_count == NULL)
404 if ((i == 0 || count != NULL_TREE)
405 && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
406 && TREE_CONSTANT (loop->n1)
407 && TREE_CONSTANT (loop->n2)
408 && TREE_CODE (loop->step) == INTEGER_CST)
410 tree itype = TREE_TYPE (loop->v);
412 if (POINTER_TYPE_P (itype))
414 = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
415 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
416 t = fold_build2_loc (loc,
418 fold_convert_loc (loc, itype, loop->step), t);
419 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
420 fold_convert_loc (loc, itype, loop->n2));
421 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
422 fold_convert_loc (loc, itype, loop->n1));
423 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
424 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
425 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
426 fold_build1_loc (loc, NEGATE_EXPR, itype,
427 fold_convert_loc (loc, itype,
430 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
431 fold_convert_loc (loc, itype, loop->step));
432 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
433 if (count != NULL_TREE)
434 count = fold_build2_loc (loc,
435 MULT_EXPR, long_long_unsigned_type_node,
439 if (TREE_CODE (count) != INTEGER_CST)
449 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
450 iter_type = long_long_unsigned_type_node;
452 iter_type = long_integer_type_node;
454 else if (collapse_iter && *collapse_iter != NULL)
455 iter_type = TREE_TYPE (*collapse_iter);
456 fd->iter_type = iter_type;
457 if (collapse_iter && *collapse_iter == NULL)
458 *collapse_iter = create_tmp_var (iter_type, ".iter");
459 if (collapse_count && *collapse_count == NULL)
462 *collapse_count = fold_convert_loc (loc, iter_type, count);
464 *collapse_count = create_tmp_var (iter_type, ".count");
467 if (fd->collapse > 1)
469 fd->loop.v = *collapse_iter;
470 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
471 fd->loop.n2 = *collapse_count;
472 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
473 fd->loop.cond_code = LT_EXPR;
478 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
479 is the immediate dominator of PAR_ENTRY_BB, return true if there
480 are no data dependencies that would prevent expanding the parallel
481 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
483 When expanding a combined parallel+workshare region, the call to
484 the child function may need additional arguments in the case of
485 GIMPLE_OMP_FOR regions. In some cases, these arguments are
486 computed out of variables passed in from the parent to the child
487 via 'struct .omp_data_s'. For instance:
489 #pragma omp parallel for schedule (guided, i * 4)
494 # BLOCK 2 (PAR_ENTRY_BB)
496 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
498 # BLOCK 3 (WS_ENTRY_BB)
499 .omp_data_i = &.omp_data_o;
500 D.1667 = .omp_data_i->i;
502 #pragma omp for schedule (guided, D.1598)
504 When we outline the parallel region, the call to the child function
505 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
506 that value is computed *after* the call site. So, in principle we
507 cannot do the transformation.
509 To see whether the code in WS_ENTRY_BB blocks the combined
510 parallel+workshare call, we collect all the variables used in the
511 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
512 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
515 FIXME. If we had the SSA form built at this point, we could merely
516 hoist the code in block 3 into block 2 and be done with it. But at
517 this point we don't have dataflow information and though we could
518 hack something up here, it is really not worth the aggravation. */
521 workshare_safe_to_combine_p (basic_block par_entry_bb, basic_block ws_entry_bb)
523 struct omp_for_data fd;
524 gimple par_stmt, ws_stmt;
526 par_stmt = last_stmt (par_entry_bb);
527 ws_stmt = last_stmt (ws_entry_bb);
529 if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
532 gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
534 extract_omp_for_data (ws_stmt, &fd, NULL);
536 if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
538 if (fd.iter_type != long_integer_type_node)
541 /* FIXME. We give up too easily here. If any of these arguments
542 are not constants, they will likely involve variables that have
543 been mapped into fields of .omp_data_s for sharing with the child
544 function. With appropriate data flow, it would be possible to
546 if (!is_gimple_min_invariant (fd.loop.n1)
547 || !is_gimple_min_invariant (fd.loop.n2)
548 || !is_gimple_min_invariant (fd.loop.step)
549 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
556 /* Collect additional arguments needed to emit a combined
557 parallel+workshare call. WS_STMT is the workshare directive being
561 get_ws_args_for (gimple ws_stmt)
564 location_t loc = gimple_location (ws_stmt);
566 if (gimple_code (ws_stmt) == GIMPLE_OMP_FOR)
568 struct omp_for_data fd;
571 extract_omp_for_data (ws_stmt, &fd, NULL);
576 t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
577 ws_args = tree_cons (NULL, t, ws_args);
580 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
581 ws_args = tree_cons (NULL, t, ws_args);
583 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n2);
584 ws_args = tree_cons (NULL, t, ws_args);
586 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.n1);
587 ws_args = tree_cons (NULL, t, ws_args);
591 else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
593 /* Number of sections is equal to the number of edges from the
594 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
595 the exit of the sections region. */
596 basic_block bb = single_succ (gimple_bb (ws_stmt));
597 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
598 t = tree_cons (NULL, t, NULL);
606 /* Discover whether REGION is a combined parallel+workshare region. */
609 determine_parallel_type (struct omp_region *region)
611 basic_block par_entry_bb, par_exit_bb;
612 basic_block ws_entry_bb, ws_exit_bb;
614 if (region == NULL || region->inner == NULL
615 || region->exit == NULL || region->inner->exit == NULL
616 || region->inner->cont == NULL)
619 /* We only support parallel+for and parallel+sections. */
620 if (region->type != GIMPLE_OMP_PARALLEL
621 || (region->inner->type != GIMPLE_OMP_FOR
622 && region->inner->type != GIMPLE_OMP_SECTIONS))
625 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
626 WS_EXIT_BB -> PAR_EXIT_BB. */
627 par_entry_bb = region->entry;
628 par_exit_bb = region->exit;
629 ws_entry_bb = region->inner->entry;
630 ws_exit_bb = region->inner->exit;
632 if (single_succ (par_entry_bb) == ws_entry_bb
633 && single_succ (ws_exit_bb) == par_exit_bb
634 && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb)
635 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
636 || (last_and_only_stmt (ws_entry_bb)
637 && last_and_only_stmt (par_exit_bb))))
639 gimple ws_stmt = last_stmt (ws_entry_bb);
641 if (region->inner->type == GIMPLE_OMP_FOR)
643 /* If this is a combined parallel loop, we need to determine
644 whether or not to use the combined library calls. There
645 are two cases where we do not apply the transformation:
646 static loops and any kind of ordered loop. In the first
647 case, we already open code the loop so there is no need
648 to do anything else. In the latter case, the combined
649 parallel loop call would still need extra synchronization
650 to implement ordered semantics, so there would not be any
651 gain in using the combined call. */
652 tree clauses = gimple_omp_for_clauses (ws_stmt);
653 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
655 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
656 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
658 region->is_combined_parallel = false;
659 region->inner->is_combined_parallel = false;
664 region->is_combined_parallel = true;
665 region->inner->is_combined_parallel = true;
666 region->ws_args = get_ws_args_for (ws_stmt);
671 /* Return true if EXPR is variable sized. */
674 is_variable_sized (const_tree expr)
676 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
679 /* Return true if DECL is a reference type. */
682 is_reference (tree decl)
684 return lang_hooks.decls.omp_privatize_by_reference (decl);
687 /* Lookup variables in the decl or field splay trees. The "maybe" form
688 allows for the variable form to not have been entered, otherwise we
689 assert that the variable must have been entered. */
692 lookup_decl (tree var, omp_context *ctx)
695 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
700 maybe_lookup_decl (const_tree var, omp_context *ctx)
703 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
704 return n ? *n : NULL_TREE;
708 lookup_field (tree var, omp_context *ctx)
711 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
712 return (tree) n->value;
716 lookup_sfield (tree var, omp_context *ctx)
719 n = splay_tree_lookup (ctx->sfield_map
720 ? ctx->sfield_map : ctx->field_map,
721 (splay_tree_key) var);
722 return (tree) n->value;
726 maybe_lookup_field (tree var, omp_context *ctx)
729 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
730 return n ? (tree) n->value : NULL_TREE;
733 /* Return true if DECL should be copied by pointer. SHARED_CTX is
734 the parallel context if DECL is to be shared. */
737 use_pointer_for_field (tree decl, omp_context *shared_ctx)
739 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
742 /* We can only use copy-in/copy-out semantics for shared variables
743 when we know the value is not accessible from an outer scope. */
746 /* ??? Trivially accessible from anywhere. But why would we even
747 be passing an address in this case? Should we simply assert
748 this to be false, or should we have a cleanup pass that removes
749 these from the list of mappings? */
750 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
753 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
754 without analyzing the expression whether or not its location
755 is accessible to anyone else. In the case of nested parallel
756 regions it certainly may be. */
757 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
760 /* Do not use copy-in/copy-out for variables that have their
762 if (TREE_ADDRESSABLE (decl))
765 /* Disallow copy-in/out in nested parallel if
766 decl is shared in outer parallel, otherwise
767 each thread could store the shared variable
768 in its own copy-in location, making the
769 variable no longer really shared. */
770 if (!TREE_READONLY (decl) && shared_ctx->is_nested)
774 for (up = shared_ctx->outer; up; up = up->outer)
775 if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
782 for (c = gimple_omp_taskreg_clauses (up->stmt);
783 c; c = OMP_CLAUSE_CHAIN (c))
784 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
785 && OMP_CLAUSE_DECL (c) == decl)
793 /* For tasks avoid using copy-in/out, unless they are readonly
794 (in which case just copy-in is used). As tasks can be
795 deferred or executed in different thread, when GOMP_task
796 returns, the task hasn't necessarily terminated. */
797 if (!TREE_READONLY (decl) && is_task_ctx (shared_ctx))
799 tree outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
800 if (is_gimple_reg (outer))
802 /* Taking address of OUTER in lower_send_shared_vars
803 might need regimplification of everything that uses the
805 if (!task_shared_vars)
806 task_shared_vars = BITMAP_ALLOC (NULL);
807 bitmap_set_bit (task_shared_vars, DECL_UID (outer));
808 TREE_ADDRESSABLE (outer) = 1;
817 /* Create a new VAR_DECL and copy information from VAR to it. */
820 copy_var_decl (tree var, tree name, tree type)
822 tree copy = build_decl (DECL_SOURCE_LOCATION (var), VAR_DECL, name, type);
824 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
825 TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (var);
826 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
827 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
828 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
829 DECL_CONTEXT (copy) = DECL_CONTEXT (var);
830 TREE_USED (copy) = 1;
831 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
836 /* Construct a new automatic decl similar to VAR. */
839 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
841 tree copy = copy_var_decl (var, name, type);
843 DECL_CONTEXT (copy) = current_function_decl;
844 TREE_CHAIN (copy) = ctx->block_vars;
845 ctx->block_vars = copy;
851 omp_copy_decl_1 (tree var, omp_context *ctx)
853 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
856 /* Build tree nodes to access the field for VAR on the receiver side. */
859 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
861 tree x, field = lookup_field (var, ctx);
863 /* If the receiver record type was remapped in the child function,
864 remap the field into the new record type. */
865 x = maybe_lookup_field (field, ctx);
869 x = build_fold_indirect_ref (ctx->receiver_decl);
870 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL);
872 x = build_fold_indirect_ref (x);
877 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
878 of a parallel, this is a component reference; for workshare constructs
879 this is some variable. */
882 build_outer_var_ref (tree var, omp_context *ctx)
886 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
888 else if (is_variable_sized (var))
890 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
891 x = build_outer_var_ref (x, ctx);
892 x = build_fold_indirect_ref (x);
894 else if (is_taskreg_ctx (ctx))
896 bool by_ref = use_pointer_for_field (var, NULL);
897 x = build_receiver_ref (var, by_ref, ctx);
900 x = lookup_decl (var, ctx->outer);
901 else if (is_reference (var))
902 /* This can happen with orphaned constructs. If var is reference, it is
903 possible it is shared and as such valid. */
908 if (is_reference (var))
909 x = build_fold_indirect_ref (x);
914 /* Build tree nodes to access the field for VAR on the sender side. */
917 build_sender_ref (tree var, omp_context *ctx)
919 tree field = lookup_sfield (var, ctx);
920 return build3 (COMPONENT_REF, TREE_TYPE (field),
921 ctx->sender_decl, field, NULL);
924 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
927 install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
929 tree field, type, sfield = NULL_TREE;
931 gcc_assert ((mask & 1) == 0
932 || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
933 gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
934 || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
936 type = TREE_TYPE (var);
938 type = build_pointer_type (type);
939 else if ((mask & 3) == 1 && is_reference (var))
940 type = TREE_TYPE (type);
942 field = build_decl (DECL_SOURCE_LOCATION (var),
943 FIELD_DECL, DECL_NAME (var), type);
945 /* Remember what variable this field was created for. This does have a
946 side effect of making dwarf2out ignore this member, so for helpful
947 debugging we clear it later in delete_omp_context. */
948 DECL_ABSTRACT_ORIGIN (field) = var;
949 if (type == TREE_TYPE (var))
951 DECL_ALIGN (field) = DECL_ALIGN (var);
952 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
953 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
956 DECL_ALIGN (field) = TYPE_ALIGN (type);
960 insert_field_into_struct (ctx->record_type, field);
961 if (ctx->srecord_type)
963 sfield = build_decl (DECL_SOURCE_LOCATION (var),
964 FIELD_DECL, DECL_NAME (var), type);
965 DECL_ABSTRACT_ORIGIN (sfield) = var;
966 DECL_ALIGN (sfield) = DECL_ALIGN (field);
967 DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
968 TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
969 insert_field_into_struct (ctx->srecord_type, sfield);
974 if (ctx->srecord_type == NULL_TREE)
978 ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
979 ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
980 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
982 sfield = build_decl (DECL_SOURCE_LOCATION (var),
983 FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
984 DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
985 insert_field_into_struct (ctx->srecord_type, sfield);
986 splay_tree_insert (ctx->sfield_map,
987 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
988 (splay_tree_value) sfield);
992 insert_field_into_struct ((mask & 1) ? ctx->record_type
993 : ctx->srecord_type, field);
997 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
998 (splay_tree_value) field);
999 if ((mask & 2) && ctx->sfield_map)
1000 splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1001 (splay_tree_value) sfield);
1005 install_var_local (tree var, omp_context *ctx)
1007 tree new_var = omp_copy_decl_1 (var, ctx);
1008 insert_decl_map (&ctx->cb, var, new_var);
1012 /* Adjust the replacement for DECL in CTX for the new context. This means
1013 copying the DECL_VALUE_EXPR, and fixing up the type. */
1016 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1018 tree new_decl, size;
1020 new_decl = lookup_decl (decl, ctx);
1022 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1024 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1025 && DECL_HAS_VALUE_EXPR_P (decl))
1027 tree ve = DECL_VALUE_EXPR (decl);
1028 walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1029 SET_DECL_VALUE_EXPR (new_decl, ve);
1030 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1033 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1035 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1036 if (size == error_mark_node)
1037 size = TYPE_SIZE (TREE_TYPE (new_decl));
1038 DECL_SIZE (new_decl) = size;
1040 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1041 if (size == error_mark_node)
1042 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1043 DECL_SIZE_UNIT (new_decl) = size;
1047 /* The callback for remap_decl. Search all containing contexts for a
1048 mapping of the variable; this avoids having to duplicate the splay
1049 tree ahead of time. We know a mapping doesn't already exist in the
1050 given context. Create new mappings to implement default semantics. */
1053 omp_copy_decl (tree var, copy_body_data *cb)
1055 omp_context *ctx = (omp_context *) cb;
1058 if (TREE_CODE (var) == LABEL_DECL)
1060 new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1061 DECL_CONTEXT (new_var) = current_function_decl;
1062 insert_decl_map (&ctx->cb, var, new_var);
1066 while (!is_taskreg_ctx (ctx))
1071 new_var = maybe_lookup_decl (var, ctx);
1076 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1079 return error_mark_node;
1083 /* Return the parallel region associated with STMT. */
1085 /* Debugging dumps for parallel regions. */
1086 void dump_omp_region (FILE *, struct omp_region *, int);
1087 void debug_omp_region (struct omp_region *);
1088 void debug_all_omp_regions (void);
1090 /* Dump the parallel region tree rooted at REGION. */
1093 dump_omp_region (FILE *file, struct omp_region *region, int indent)
1095 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1096 gimple_code_name[region->type]);
1099 dump_omp_region (file, region->inner, indent + 4);
1103 fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1104 region->cont->index);
1108 fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1109 region->exit->index);
1111 fprintf (file, "%*s[no exit marker]\n", indent, "");
1114 dump_omp_region (file, region->next, indent);
1118 debug_omp_region (struct omp_region *region)
1120 dump_omp_region (stderr, region, 0);
1124 debug_all_omp_regions (void)
1126 dump_omp_region (stderr, root_omp_region, 0);
1130 /* Create a new parallel region starting at STMT inside region PARENT. */
1133 new_omp_region (basic_block bb, enum gimple_code type,
1134 struct omp_region *parent)
1136 struct omp_region *region = XCNEW (struct omp_region);
1138 region->outer = parent;
1140 region->type = type;
1144 /* This is a nested region. Add it to the list of inner
1145 regions in PARENT. */
1146 region->next = parent->inner;
1147 parent->inner = region;
1151 /* This is a toplevel region. Add it to the list of toplevel
1152 regions in ROOT_OMP_REGION. */
1153 region->next = root_omp_region;
1154 root_omp_region = region;
1160 /* Release the memory associated with the region tree rooted at REGION. */
1163 free_omp_region_1 (struct omp_region *region)
1165 struct omp_region *i, *n;
1167 for (i = region->inner; i ; i = n)
1170 free_omp_region_1 (i);
1176 /* Release the memory for the entire omp region tree. */
1179 free_omp_regions (void)
1181 struct omp_region *r, *n;
1182 for (r = root_omp_region; r ; r = n)
1185 free_omp_region_1 (r);
1187 root_omp_region = NULL;
1191 /* Create a new context, with OUTER_CTX being the surrounding context. */
1193 static omp_context *
1194 new_omp_context (gimple stmt, omp_context *outer_ctx)
1196 omp_context *ctx = XCNEW (omp_context);
1198 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1199 (splay_tree_value) ctx);
1204 ctx->outer = outer_ctx;
1205 ctx->cb = outer_ctx->cb;
1206 ctx->cb.block = NULL;
1207 ctx->depth = outer_ctx->depth + 1;
1211 ctx->cb.src_fn = current_function_decl;
1212 ctx->cb.dst_fn = current_function_decl;
1213 ctx->cb.src_node = cgraph_node (current_function_decl);
1214 ctx->cb.dst_node = ctx->cb.src_node;
1215 ctx->cb.src_cfun = cfun;
1216 ctx->cb.copy_decl = omp_copy_decl;
1217 ctx->cb.eh_region = -1;
1218 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1222 ctx->cb.decl_map = pointer_map_create ();
1227 static gimple_seq maybe_catch_exception (gimple_seq);
1229 /* Finalize task copyfn. */
1232 finalize_task_copyfn (gimple task_stmt)
1234 struct function *child_cfun;
1235 tree child_fn, old_fn;
1236 gimple_seq seq, new_seq;
1239 child_fn = gimple_omp_task_copy_fn (task_stmt);
1240 if (child_fn == NULL_TREE)
1243 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1245 /* Inform the callgraph about the new function. */
1246 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
1247 = cfun->curr_properties;
1249 old_fn = current_function_decl;
1250 push_cfun (child_cfun);
1251 current_function_decl = child_fn;
1252 bind = gimplify_body (&DECL_SAVED_TREE (child_fn), child_fn, false);
1253 seq = gimple_seq_alloc ();
1254 gimple_seq_add_stmt (&seq, bind);
1255 new_seq = maybe_catch_exception (seq);
1258 bind = gimple_build_bind (NULL, new_seq, NULL);
1259 seq = gimple_seq_alloc ();
1260 gimple_seq_add_stmt (&seq, bind);
1262 gimple_set_body (child_fn, seq);
1264 current_function_decl = old_fn;
1266 cgraph_add_new_function (child_fn, false);
1269 /* Destroy a omp_context data structures. Called through the splay tree
1270 value delete callback. */
1273 delete_omp_context (splay_tree_value value)
1275 omp_context *ctx = (omp_context *) value;
1277 pointer_map_destroy (ctx->cb.decl_map);
1280 splay_tree_delete (ctx->field_map);
1281 if (ctx->sfield_map)
1282 splay_tree_delete (ctx->sfield_map);
1284 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1285 it produces corrupt debug information. */
1286 if (ctx->record_type)
1289 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
1290 DECL_ABSTRACT_ORIGIN (t) = NULL;
1292 if (ctx->srecord_type)
1295 for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = TREE_CHAIN (t))
1296 DECL_ABSTRACT_ORIGIN (t) = NULL;
1299 if (is_task_ctx (ctx))
1300 finalize_task_copyfn (ctx->stmt);
1305 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1309 fixup_child_record_type (omp_context *ctx)
1311 tree f, type = ctx->record_type;
1313 /* ??? It isn't sufficient to just call remap_type here, because
1314 variably_modified_type_p doesn't work the way we expect for
1315 record types. Testing each field for whether it needs remapping
1316 and creating a new record by hand works, however. */
1317 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
1318 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1322 tree name, new_fields = NULL;
1324 type = lang_hooks.types.make_type (RECORD_TYPE);
1325 name = DECL_NAME (TYPE_NAME (ctx->record_type));
1326 name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1327 TYPE_DECL, name, type);
1328 TYPE_NAME (type) = name;
1330 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
1332 tree new_f = copy_node (f);
1333 DECL_CONTEXT (new_f) = type;
1334 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
1335 TREE_CHAIN (new_f) = new_fields;
1336 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1337 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1339 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1343 /* Arrange to be able to look up the receiver field
1344 given the sender field. */
1345 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1346 (splay_tree_value) new_f);
1348 TYPE_FIELDS (type) = nreverse (new_fields);
1352 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
1355 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1356 specified by CLAUSES. */
1359 scan_sharing_clauses (tree clauses, omp_context *ctx)
1362 bool scan_array_reductions = false;
1364 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1368 switch (OMP_CLAUSE_CODE (c))
1370 case OMP_CLAUSE_PRIVATE:
1371 decl = OMP_CLAUSE_DECL (c);
1372 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1374 else if (!is_variable_sized (decl))
1375 install_var_local (decl, ctx);
1378 case OMP_CLAUSE_SHARED:
1379 gcc_assert (is_taskreg_ctx (ctx));
1380 decl = OMP_CLAUSE_DECL (c);
1381 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1382 || !is_variable_sized (decl));
1383 /* Global variables don't need to be copied,
1384 the receiver side will use them directly. */
1385 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1387 by_ref = use_pointer_for_field (decl, ctx);
1388 if (! TREE_READONLY (decl)
1389 || TREE_ADDRESSABLE (decl)
1391 || is_reference (decl))
1393 install_var_field (decl, by_ref, 3, ctx);
1394 install_var_local (decl, ctx);
1397 /* We don't need to copy const scalar vars back. */
1398 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1401 case OMP_CLAUSE_LASTPRIVATE:
1402 /* Let the corresponding firstprivate clause create
1404 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1408 case OMP_CLAUSE_FIRSTPRIVATE:
1409 case OMP_CLAUSE_REDUCTION:
1410 decl = OMP_CLAUSE_DECL (c);
1412 if (is_variable_sized (decl))
1414 if (is_task_ctx (ctx))
1415 install_var_field (decl, false, 1, ctx);
1418 else if (is_taskreg_ctx (ctx))
1421 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
1422 by_ref = use_pointer_for_field (decl, NULL);
1424 if (is_task_ctx (ctx)
1425 && (global || by_ref || is_reference (decl)))
1427 install_var_field (decl, false, 1, ctx);
1429 install_var_field (decl, by_ref, 2, ctx);
1432 install_var_field (decl, by_ref, 3, ctx);
1434 install_var_local (decl, ctx);
1437 case OMP_CLAUSE_COPYPRIVATE:
1439 scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
1442 case OMP_CLAUSE_COPYIN:
1443 decl = OMP_CLAUSE_DECL (c);
1444 by_ref = use_pointer_for_field (decl, NULL);
1445 install_var_field (decl, by_ref, 3, ctx);
1448 case OMP_CLAUSE_DEFAULT:
1449 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1453 case OMP_CLAUSE_NUM_THREADS:
1454 case OMP_CLAUSE_SCHEDULE:
1456 scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1459 case OMP_CLAUSE_NOWAIT:
1460 case OMP_CLAUSE_ORDERED:
1461 case OMP_CLAUSE_COLLAPSE:
1462 case OMP_CLAUSE_UNTIED:
1470 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1472 switch (OMP_CLAUSE_CODE (c))
1474 case OMP_CLAUSE_LASTPRIVATE:
1475 /* Let the corresponding firstprivate clause create
1477 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1478 scan_array_reductions = true;
1479 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1483 case OMP_CLAUSE_PRIVATE:
1484 case OMP_CLAUSE_FIRSTPRIVATE:
1485 case OMP_CLAUSE_REDUCTION:
1486 decl = OMP_CLAUSE_DECL (c);
1487 if (is_variable_sized (decl))
1488 install_var_local (decl, ctx);
1489 fixup_remapped_decl (decl, ctx,
1490 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1491 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1492 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1493 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1494 scan_array_reductions = true;
1497 case OMP_CLAUSE_SHARED:
1498 decl = OMP_CLAUSE_DECL (c);
1499 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1500 fixup_remapped_decl (decl, ctx, false);
1503 case OMP_CLAUSE_COPYPRIVATE:
1504 case OMP_CLAUSE_COPYIN:
1505 case OMP_CLAUSE_DEFAULT:
1507 case OMP_CLAUSE_NUM_THREADS:
1508 case OMP_CLAUSE_SCHEDULE:
1509 case OMP_CLAUSE_NOWAIT:
1510 case OMP_CLAUSE_ORDERED:
1511 case OMP_CLAUSE_COLLAPSE:
1512 case OMP_CLAUSE_UNTIED:
1520 if (scan_array_reductions)
1521 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1522 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1523 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1525 scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
1526 scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
1528 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
1529 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1530 scan_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
1533 /* Create a new name for omp child function. Returns an identifier. */
1535 static GTY(()) unsigned int tmp_ompfn_id_num;
1538 create_omp_child_function_name (bool task_copy)
1540 tree name = DECL_ASSEMBLER_NAME (current_function_decl);
1541 size_t len = IDENTIFIER_LENGTH (name);
1542 char *tmp_name, *prefix;
1545 suffix = task_copy ? "_omp_cpyfn" : "_omp_fn";
1546 prefix = XALLOCAVEC (char, len + strlen (suffix) + 1);
1547 memcpy (prefix, IDENTIFIER_POINTER (name), len);
1548 strcpy (prefix + len, suffix);
1549 #ifndef NO_DOT_IN_LABEL
1551 #elif !defined NO_DOLLAR_IN_LABEL
1554 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, tmp_ompfn_id_num++);
1555 return get_identifier (tmp_name);
1558 /* Build a decl for the omp child function. It'll not contain a body
1559 yet, just the bare decl. */
1562 create_omp_child_function (omp_context *ctx, bool task_copy)
1564 tree decl, type, name, t;
1566 name = create_omp_child_function_name (task_copy);
1568 type = build_function_type_list (void_type_node, ptr_type_node,
1569 ptr_type_node, NULL_TREE);
1571 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1573 decl = build_decl (gimple_location (ctx->stmt),
1574 FUNCTION_DECL, name, type);
1575 decl = lang_hooks.decls.pushdecl (decl);
1578 ctx->cb.dst_fn = decl;
1580 gimple_omp_task_set_copy_fn (ctx->stmt, decl);
1582 TREE_STATIC (decl) = 1;
1583 TREE_USED (decl) = 1;
1584 DECL_ARTIFICIAL (decl) = 1;
1585 DECL_IGNORED_P (decl) = 0;
1586 TREE_PUBLIC (decl) = 0;
1587 DECL_UNINLINABLE (decl) = 1;
1588 DECL_EXTERNAL (decl) = 0;
1589 DECL_CONTEXT (decl) = NULL_TREE;
1590 DECL_INITIAL (decl) = make_node (BLOCK);
1592 t = build_decl (DECL_SOURCE_LOCATION (decl),
1593 RESULT_DECL, NULL_TREE, void_type_node);
1594 DECL_ARTIFICIAL (t) = 1;
1595 DECL_IGNORED_P (t) = 1;
1596 DECL_CONTEXT (t) = decl;
1597 DECL_RESULT (decl) = t;
1599 t = build_decl (DECL_SOURCE_LOCATION (decl),
1600 PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1601 DECL_ARTIFICIAL (t) = 1;
1602 DECL_ARG_TYPE (t) = ptr_type_node;
1603 DECL_CONTEXT (t) = current_function_decl;
1605 DECL_ARGUMENTS (decl) = t;
1607 ctx->receiver_decl = t;
1610 t = build_decl (DECL_SOURCE_LOCATION (decl),
1611 PARM_DECL, get_identifier (".omp_data_o"),
1613 DECL_ARTIFICIAL (t) = 1;
1614 DECL_ARG_TYPE (t) = ptr_type_node;
1615 DECL_CONTEXT (t) = current_function_decl;
1617 TREE_ADDRESSABLE (t) = 1;
1618 TREE_CHAIN (t) = DECL_ARGUMENTS (decl);
1619 DECL_ARGUMENTS (decl) = t;
1622 /* Allocate memory for the function structure. The call to
1623 allocate_struct_function clobbers CFUN, so we need to restore
1625 push_struct_function (decl);
1626 cfun->function_end_locus = gimple_location (ctx->stmt);
1631 /* Scan an OpenMP parallel directive. */
1634 scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1638 gimple stmt = gsi_stmt (*gsi);
1640 /* Ignore parallel directives with empty bodies, unless there
1641 are copyin clauses. */
1643 && empty_body_p (gimple_omp_body (stmt))
1644 && find_omp_clause (gimple_omp_parallel_clauses (stmt),
1645 OMP_CLAUSE_COPYIN) == NULL)
1647 gsi_replace (gsi, gimple_build_nop (), false);
1651 ctx = new_omp_context (stmt, outer_ctx);
1652 if (taskreg_nesting_level > 1)
1653 ctx->is_nested = true;
1654 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1655 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1656 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1657 name = create_tmp_var_name (".omp_data_s");
1658 name = build_decl (gimple_location (stmt),
1659 TYPE_DECL, name, ctx->record_type);
1660 TYPE_NAME (ctx->record_type) = name;
1661 create_omp_child_function (ctx, false);
1662 gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
1664 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
1665 scan_omp (gimple_omp_body (stmt), ctx);
1667 if (TYPE_FIELDS (ctx->record_type) == NULL)
1668 ctx->record_type = ctx->receiver_decl = NULL;
1671 layout_type (ctx->record_type);
1672 fixup_child_record_type (ctx);
1676 /* Scan an OpenMP task directive. */
1679 scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
1683 gimple stmt = gsi_stmt (*gsi);
1684 location_t loc = gimple_location (stmt);
1686 /* Ignore task directives with empty bodies. */
1688 && empty_body_p (gimple_omp_body (stmt)))
1690 gsi_replace (gsi, gimple_build_nop (), false);
1694 ctx = new_omp_context (stmt, outer_ctx);
1695 if (taskreg_nesting_level > 1)
1696 ctx->is_nested = true;
1697 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1698 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1699 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1700 name = create_tmp_var_name (".omp_data_s");
1701 name = build_decl (gimple_location (stmt),
1702 TYPE_DECL, name, ctx->record_type);
1703 TYPE_NAME (ctx->record_type) = name;
1704 create_omp_child_function (ctx, false);
1705 gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
1707 scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
1709 if (ctx->srecord_type)
1711 name = create_tmp_var_name (".omp_data_a");
1712 name = build_decl (gimple_location (stmt),
1713 TYPE_DECL, name, ctx->srecord_type);
1714 TYPE_NAME (ctx->srecord_type) = name;
1715 create_omp_child_function (ctx, true);
1718 scan_omp (gimple_omp_body (stmt), ctx);
1720 if (TYPE_FIELDS (ctx->record_type) == NULL)
1722 ctx->record_type = ctx->receiver_decl = NULL;
1723 t = build_int_cst (long_integer_type_node, 0);
1724 gimple_omp_task_set_arg_size (stmt, t);
1725 t = build_int_cst (long_integer_type_node, 1);
1726 gimple_omp_task_set_arg_align (stmt, t);
1730 tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
1731 /* Move VLA fields to the end. */
1732 p = &TYPE_FIELDS (ctx->record_type);
1734 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
1735 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
1738 *p = TREE_CHAIN (*p);
1739 TREE_CHAIN (*q) = NULL_TREE;
1740 q = &TREE_CHAIN (*q);
1743 p = &TREE_CHAIN (*p);
1745 layout_type (ctx->record_type);
1746 fixup_child_record_type (ctx);
1747 if (ctx->srecord_type)
1748 layout_type (ctx->srecord_type);
1749 t = fold_convert_loc (loc, long_integer_type_node,
1750 TYPE_SIZE_UNIT (ctx->record_type));
1751 gimple_omp_task_set_arg_size (stmt, t);
1752 t = build_int_cst (long_integer_type_node,
1753 TYPE_ALIGN_UNIT (ctx->record_type));
1754 gimple_omp_task_set_arg_align (stmt, t);
1759 /* Scan an OpenMP loop directive. */
1762 scan_omp_for (gimple stmt, omp_context *outer_ctx)
1767 ctx = new_omp_context (stmt, outer_ctx);
1769 scan_sharing_clauses (gimple_omp_for_clauses (stmt), ctx);
1771 scan_omp (gimple_omp_for_pre_body (stmt), ctx);
1772 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
1774 scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
1775 scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
1776 scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
1777 scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
1779 scan_omp (gimple_omp_body (stmt), ctx);
1782 /* Scan an OpenMP sections directive. */
1785 scan_omp_sections (gimple stmt, omp_context *outer_ctx)
1789 ctx = new_omp_context (stmt, outer_ctx);
1790 scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
1791 scan_omp (gimple_omp_body (stmt), ctx);
1794 /* Scan an OpenMP single directive. */
1797 scan_omp_single (gimple stmt, omp_context *outer_ctx)
1802 ctx = new_omp_context (stmt, outer_ctx);
1803 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1804 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1805 name = create_tmp_var_name (".omp_copy_s");
1806 name = build_decl (gimple_location (stmt),
1807 TYPE_DECL, name, ctx->record_type);
1808 TYPE_NAME (ctx->record_type) = name;
1810 scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
1811 scan_omp (gimple_omp_body (stmt), ctx);
1813 if (TYPE_FIELDS (ctx->record_type) == NULL)
1814 ctx->record_type = NULL;
1816 layout_type (ctx->record_type);
1820 /* Check OpenMP nesting restrictions. */
1822 check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
1824 switch (gimple_code (stmt))
1826 case GIMPLE_OMP_FOR:
1827 case GIMPLE_OMP_SECTIONS:
1828 case GIMPLE_OMP_SINGLE:
1830 for (; ctx != NULL; ctx = ctx->outer)
1831 switch (gimple_code (ctx->stmt))
1833 case GIMPLE_OMP_FOR:
1834 case GIMPLE_OMP_SECTIONS:
1835 case GIMPLE_OMP_SINGLE:
1836 case GIMPLE_OMP_ORDERED:
1837 case GIMPLE_OMP_MASTER:
1838 case GIMPLE_OMP_TASK:
1839 if (is_gimple_call (stmt))
1841 warning (0, "barrier region may not be closely nested inside "
1842 "of work-sharing, critical, ordered, master or "
1843 "explicit task region");
1846 warning (0, "work-sharing region may not be closely nested inside "
1847 "of work-sharing, critical, ordered, master or explicit "
1850 case GIMPLE_OMP_PARALLEL:
1856 case GIMPLE_OMP_MASTER:
1857 for (; ctx != NULL; ctx = ctx->outer)
1858 switch (gimple_code (ctx->stmt))
1860 case GIMPLE_OMP_FOR:
1861 case GIMPLE_OMP_SECTIONS:
1862 case GIMPLE_OMP_SINGLE:
1863 case GIMPLE_OMP_TASK:
1864 warning (0, "master region may not be closely nested inside "
1865 "of work-sharing or explicit task region");
1867 case GIMPLE_OMP_PARALLEL:
1873 case GIMPLE_OMP_ORDERED:
1874 for (; ctx != NULL; ctx = ctx->outer)
1875 switch (gimple_code (ctx->stmt))
1877 case GIMPLE_OMP_CRITICAL:
1878 case GIMPLE_OMP_TASK:
1879 warning (0, "ordered region may not be closely nested inside "
1880 "of critical or explicit task region");
1882 case GIMPLE_OMP_FOR:
1883 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
1884 OMP_CLAUSE_ORDERED) == NULL)
1885 warning (0, "ordered region must be closely nested inside "
1886 "a loop region with an ordered clause");
1888 case GIMPLE_OMP_PARALLEL:
1894 case GIMPLE_OMP_CRITICAL:
1895 for (; ctx != NULL; ctx = ctx->outer)
1896 if (gimple_code (ctx->stmt) == GIMPLE_OMP_CRITICAL
1897 && (gimple_omp_critical_name (stmt)
1898 == gimple_omp_critical_name (ctx->stmt)))
1900 warning (0, "critical region may not be nested inside a critical "
1901 "region with the same name");
1911 /* Helper function scan_omp.
1913 Callback for walk_tree or operators in walk_gimple_stmt used to
1914 scan for OpenMP directives in TP. */
1917 scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
1919 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
1920 omp_context *ctx = (omp_context *) wi->info;
1923 switch (TREE_CODE (t))
1930 *tp = remap_decl (t, &ctx->cb);
1934 if (ctx && TYPE_P (t))
1935 *tp = remap_type (t, &ctx->cb);
1936 else if (!DECL_P (t))
1940 TREE_TYPE (t) = remap_type (TREE_TYPE (t), &ctx->cb);
1949 /* Helper function for scan_omp.
1951 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1952 the current statement in GSI. */
1955 scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
1956 struct walk_stmt_info *wi)
1958 gimple stmt = gsi_stmt (*gsi);
1959 omp_context *ctx = (omp_context *) wi->info;
1961 if (gimple_has_location (stmt))
1962 input_location = gimple_location (stmt);
1964 /* Check the OpenMP nesting restrictions. */
1967 if (is_gimple_omp (stmt))
1968 check_omp_nesting_restrictions (stmt, ctx);
1969 else if (is_gimple_call (stmt))
1971 tree fndecl = gimple_call_fndecl (stmt);
1972 if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
1973 && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_GOMP_BARRIER)
1974 check_omp_nesting_restrictions (stmt, ctx);
1978 *handled_ops_p = true;
1980 switch (gimple_code (stmt))
1982 case GIMPLE_OMP_PARALLEL:
1983 taskreg_nesting_level++;
1984 scan_omp_parallel (gsi, ctx);
1985 taskreg_nesting_level--;
1988 case GIMPLE_OMP_TASK:
1989 taskreg_nesting_level++;
1990 scan_omp_task (gsi, ctx);
1991 taskreg_nesting_level--;
1994 case GIMPLE_OMP_FOR:
1995 scan_omp_for (stmt, ctx);
1998 case GIMPLE_OMP_SECTIONS:
1999 scan_omp_sections (stmt, ctx);
2002 case GIMPLE_OMP_SINGLE:
2003 scan_omp_single (stmt, ctx);
2006 case GIMPLE_OMP_SECTION:
2007 case GIMPLE_OMP_MASTER:
2008 case GIMPLE_OMP_ORDERED:
2009 case GIMPLE_OMP_CRITICAL:
2010 ctx = new_omp_context (stmt, ctx);
2011 scan_omp (gimple_omp_body (stmt), ctx);
2018 *handled_ops_p = false;
2020 for (var = gimple_bind_vars (stmt); var ; var = TREE_CHAIN (var))
2021 insert_decl_map (&ctx->cb, var, var);
2025 *handled_ops_p = false;
2033 /* Scan all the statements starting at the current statement. CTX
2034 contains context information about the OpenMP directives and
2035 clauses found during the scan. */
2038 scan_omp (gimple_seq body, omp_context *ctx)
2040 location_t saved_location;
2041 struct walk_stmt_info wi;
2043 memset (&wi, 0, sizeof (wi));
2045 wi.want_locations = true;
2047 saved_location = input_location;
2048 walk_gimple_seq (body, scan_omp_1_stmt, scan_omp_1_op, &wi);
2049 input_location = saved_location;
2052 /* Re-gimplification and code generation routines. */
2054 /* Build a call to GOMP_barrier. */
2057 build_omp_barrier (void)
2059 return build_call_expr (built_in_decls[BUILT_IN_GOMP_BARRIER], 0);
2062 /* If a context was created for STMT when it was scanned, return it. */
2064 static omp_context *
2065 maybe_lookup_ctx (gimple stmt)
2068 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
2069 return n ? (omp_context *) n->value : NULL;
2073 /* Find the mapping for DECL in CTX or the immediately enclosing
2074 context that has a mapping for DECL.
2076 If CTX is a nested parallel directive, we may have to use the decl
2077 mappings created in CTX's parent context. Suppose that we have the
2078 following parallel nesting (variable UIDs showed for clarity):
2081 #omp parallel shared(iD.1562) -> outer parallel
2082 iD.1562 = iD.1562 + 1;
2084 #omp parallel shared (iD.1562) -> inner parallel
2085 iD.1562 = iD.1562 - 1;
2087 Each parallel structure will create a distinct .omp_data_s structure
2088 for copying iD.1562 in/out of the directive:
2090 outer parallel .omp_data_s.1.i -> iD.1562
2091 inner parallel .omp_data_s.2.i -> iD.1562
2093 A shared variable mapping will produce a copy-out operation before
2094 the parallel directive and a copy-in operation after it. So, in
2095 this case we would have:
2098 .omp_data_o.1.i = iD.1562;
2099 #omp parallel shared(iD.1562) -> outer parallel
2100 .omp_data_i.1 = &.omp_data_o.1
2101 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2103 .omp_data_o.2.i = iD.1562; -> **
2104 #omp parallel shared(iD.1562) -> inner parallel
2105 .omp_data_i.2 = &.omp_data_o.2
2106 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2109 ** This is a problem. The symbol iD.1562 cannot be referenced
2110 inside the body of the outer parallel region. But since we are
2111 emitting this copy operation while expanding the inner parallel
2112 directive, we need to access the CTX structure of the outer
2113 parallel directive to get the correct mapping:
2115 .omp_data_o.2.i = .omp_data_i.1->i
2117 Since there may be other workshare or parallel directives enclosing
2118 the parallel directive, it may be necessary to walk up the context
2119 parent chain. This is not a problem in general because nested
2120 parallelism happens only rarely. */
2123 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2128 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2129 t = maybe_lookup_decl (decl, up);
2131 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
2133 return t ? t : decl;
2137 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2138 in outer contexts. */
2141 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
2146 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
2147 t = maybe_lookup_decl (decl, up);
2149 return t ? t : decl;
2153 /* Construct the initialization value for reduction CLAUSE. */
2156 omp_reduction_init (tree clause, tree type)
2158 location_t loc = OMP_CLAUSE_LOCATION (clause);
2159 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
2166 case TRUTH_ORIF_EXPR:
2167 case TRUTH_XOR_EXPR:
2169 return fold_convert_loc (loc, type, integer_zero_node);
2172 case TRUTH_AND_EXPR:
2173 case TRUTH_ANDIF_EXPR:
2175 return fold_convert_loc (loc, type, integer_one_node);
2178 return fold_convert_loc (loc, type, integer_minus_one_node);
2181 if (SCALAR_FLOAT_TYPE_P (type))
2183 REAL_VALUE_TYPE max, min;
2184 if (HONOR_INFINITIES (TYPE_MODE (type)))
2187 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
2190 real_maxval (&min, 1, TYPE_MODE (type));
2191 return build_real (type, min);
2195 gcc_assert (INTEGRAL_TYPE_P (type));
2196 return TYPE_MIN_VALUE (type);
2200 if (SCALAR_FLOAT_TYPE_P (type))
2202 REAL_VALUE_TYPE max;
2203 if (HONOR_INFINITIES (TYPE_MODE (type)))
2206 real_maxval (&max, 0, TYPE_MODE (type));
2207 return build_real (type, max);
2211 gcc_assert (INTEGRAL_TYPE_P (type));
2212 return TYPE_MAX_VALUE (type);
2220 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2221 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2222 private variables. Initialization statements go in ILIST, while calls
2223 to destructors go in DLIST. */
2226 lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
2229 gimple_stmt_iterator diter;
2230 tree c, dtor, copyin_seq, x, ptr;
2231 bool copyin_by_ref = false;
2232 bool lastprivate_firstprivate = false;
2235 *dlist = gimple_seq_alloc ();
2236 diter = gsi_start (*dlist);
2239 /* Do all the fixed sized types in the first pass, and the variable sized
2240 types in the second pass. This makes sure that the scalar arguments to
2241 the variable sized types are processed before we use them in the
2242 variable sized operations. */
2243 for (pass = 0; pass < 2; ++pass)
2245 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2247 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
2250 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2254 case OMP_CLAUSE_PRIVATE:
2255 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
2258 case OMP_CLAUSE_SHARED:
2259 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
2261 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
2264 case OMP_CLAUSE_FIRSTPRIVATE:
2265 case OMP_CLAUSE_COPYIN:
2266 case OMP_CLAUSE_REDUCTION:
2268 case OMP_CLAUSE_LASTPRIVATE:
2269 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2271 lastprivate_firstprivate = true;
2280 new_var = var = OMP_CLAUSE_DECL (c);
2281 if (c_kind != OMP_CLAUSE_COPYIN)
2282 new_var = lookup_decl (var, ctx);
2284 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
2289 else if (is_variable_sized (var))
2291 /* For variable sized types, we need to allocate the
2292 actual storage here. Call alloca and store the
2293 result in the pointer decl that we created elsewhere. */
2297 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
2302 ptr = DECL_VALUE_EXPR (new_var);
2303 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
2304 ptr = TREE_OPERAND (ptr, 0);
2305 gcc_assert (DECL_P (ptr));
2306 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
2308 /* void *tmp = __builtin_alloca */
2310 = gimple_build_call (built_in_decls[BUILT_IN_ALLOCA], 1, x);
2311 tmp = create_tmp_var_raw (ptr_type_node, NULL);
2312 gimple_add_tmp_var (tmp);
2313 gimple_call_set_lhs (stmt, tmp);
2315 gimple_seq_add_stmt (ilist, stmt);
2317 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
2318 gimplify_assign (ptr, x, ilist);
2321 else if (is_reference (var))
2323 /* For references that are being privatized for Fortran,
2324 allocate new backing storage for the new pointer
2325 variable. This allows us to avoid changing all the
2326 code that expects a pointer to something that expects
2327 a direct variable. Note that this doesn't apply to
2328 C++, since reference types are disallowed in data
2329 sharing clauses there, except for NRV optimized
2334 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
2335 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
2337 x = build_receiver_ref (var, false, ctx);
2338 x = build_fold_addr_expr_loc (clause_loc, x);
2340 else if (TREE_CONSTANT (x))
2342 const char *name = NULL;
2343 if (DECL_NAME (var))
2344 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
2346 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
2348 gimple_add_tmp_var (x);
2349 TREE_ADDRESSABLE (x) = 1;
2350 x = build_fold_addr_expr_loc (clause_loc, x);
2354 x = build_call_expr_loc (clause_loc,
2355 built_in_decls[BUILT_IN_ALLOCA], 1, x);
2358 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
2359 gimplify_assign (new_var, x, ilist);
2361 new_var = build_fold_indirect_ref_loc (clause_loc, new_var);
2363 else if (c_kind == OMP_CLAUSE_REDUCTION
2364 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2372 switch (OMP_CLAUSE_CODE (c))
2374 case OMP_CLAUSE_SHARED:
2375 /* Shared global vars are just accessed directly. */
2376 if (is_global_var (new_var))
2378 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2379 needs to be delayed until after fixup_child_record_type so
2380 that we get the correct type during the dereference. */
2381 by_ref = use_pointer_for_field (var, ctx);
2382 x = build_receiver_ref (var, by_ref, ctx);
2383 SET_DECL_VALUE_EXPR (new_var, x);
2384 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2386 /* ??? If VAR is not passed by reference, and the variable
2387 hasn't been initialized yet, then we'll get a warning for
2388 the store into the omp_data_s structure. Ideally, we'd be
2389 able to notice this and not store anything at all, but
2390 we're generating code too early. Suppress the warning. */
2392 TREE_NO_WARNING (var) = 1;
2395 case OMP_CLAUSE_LASTPRIVATE:
2396 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2400 case OMP_CLAUSE_PRIVATE:
2401 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE)
2402 x = build_outer_var_ref (var, ctx);
2403 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2405 if (is_task_ctx (ctx))
2406 x = build_receiver_ref (var, false, ctx);
2408 x = build_outer_var_ref (var, ctx);
2412 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
2414 gimplify_and_add (x, ilist);
2418 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
2421 gimple_seq tseq = NULL;
2424 gimplify_stmt (&dtor, &tseq);
2425 gsi_insert_seq_before (&diter, tseq, GSI_SAME_STMT);
2429 case OMP_CLAUSE_FIRSTPRIVATE:
2430 if (is_task_ctx (ctx))
2432 if (is_reference (var) || is_variable_sized (var))
2434 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var,
2436 || use_pointer_for_field (var, NULL))
2438 x = build_receiver_ref (var, false, ctx);
2439 SET_DECL_VALUE_EXPR (new_var, x);
2440 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
2444 x = build_outer_var_ref (var, ctx);
2445 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
2446 gimplify_and_add (x, ilist);
2450 case OMP_CLAUSE_COPYIN:
2451 by_ref = use_pointer_for_field (var, NULL);
2452 x = build_receiver_ref (var, by_ref, ctx);
2453 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
2454 append_to_statement_list (x, ©in_seq);
2455 copyin_by_ref |= by_ref;
2458 case OMP_CLAUSE_REDUCTION:
2459 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2461 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2462 x = build_outer_var_ref (var, ctx);
2464 if (is_reference (var))
2465 x = build_fold_addr_expr_loc (clause_loc, x);
2466 SET_DECL_VALUE_EXPR (placeholder, x);
2467 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2468 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2469 gimple_seq_add_seq (ilist,
2470 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
2471 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
2472 DECL_HAS_VALUE_EXPR_P (placeholder) = 0;
2476 x = omp_reduction_init (c, TREE_TYPE (new_var));
2477 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
2478 gimplify_assign (new_var, x, ilist);
2488 /* The copyin sequence is not to be executed by the main thread, since
2489 that would result in self-copies. Perhaps not visible to scalars,
2490 but it certainly is to C++ operator=. */
2493 x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2494 x = build2 (NE_EXPR, boolean_type_node, x,
2495 build_int_cst (TREE_TYPE (x), 0));
2496 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
2497 gimplify_and_add (x, ilist);
2500 /* If any copyin variable is passed by reference, we must ensure the
2501 master thread doesn't modify it before it is copied over in all
2502 threads. Similarly for variables in both firstprivate and
2503 lastprivate clauses we need to ensure the lastprivate copying
2504 happens after firstprivate copying in all threads. */
2505 if (copyin_by_ref || lastprivate_firstprivate)
2506 gimplify_and_add (build_omp_barrier (), ilist);
2510 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2511 both parallel and workshare constructs. PREDICATE may be NULL if it's
2515 lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
2518 tree x, c, label = NULL;
2519 bool par_clauses = false;
2521 /* Early exit if there are no lastprivate clauses. */
2522 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
2523 if (clauses == NULL)
2525 /* If this was a workshare clause, see if it had been combined
2526 with its parallel. In that case, look for the clauses on the
2527 parallel statement itself. */
2528 if (is_parallel_ctx (ctx))
2532 if (ctx == NULL || !is_parallel_ctx (ctx))
2535 clauses = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2536 OMP_CLAUSE_LASTPRIVATE);
2537 if (clauses == NULL)
2545 tree label_true, arm1, arm2;
2547 label = create_artificial_label (UNKNOWN_LOCATION);
2548 label_true = create_artificial_label (UNKNOWN_LOCATION);
2549 arm1 = TREE_OPERAND (predicate, 0);
2550 arm2 = TREE_OPERAND (predicate, 1);
2551 gimplify_expr (&arm1, stmt_list, NULL, is_gimple_val, fb_rvalue);
2552 gimplify_expr (&arm2, stmt_list, NULL, is_gimple_val, fb_rvalue);
2553 stmt = gimple_build_cond (TREE_CODE (predicate), arm1, arm2,
2555 gimple_seq_add_stmt (stmt_list, stmt);
2556 gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
2559 for (c = clauses; c ;)
2562 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2564 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
2566 var = OMP_CLAUSE_DECL (c);
2567 new_var = lookup_decl (var, ctx);
2569 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2571 lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2572 gimple_seq_add_seq (stmt_list,
2573 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
2575 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
2577 x = build_outer_var_ref (var, ctx);
2578 if (is_reference (var))
2579 new_var = build_fold_indirect_ref_loc (clause_loc, new_var);
2580 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
2581 gimplify_and_add (x, stmt_list);
2583 c = OMP_CLAUSE_CHAIN (c);
2584 if (c == NULL && !par_clauses)
2586 /* If this was a workshare clause, see if it had been combined
2587 with its parallel. In that case, continue looking for the
2588 clauses also on the parallel statement itself. */
2589 if (is_parallel_ctx (ctx))
2593 if (ctx == NULL || !is_parallel_ctx (ctx))
2596 c = find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2597 OMP_CLAUSE_LASTPRIVATE);
2603 gimple_seq_add_stmt (stmt_list, gimple_build_label (label));
2607 /* Generate code to implement the REDUCTION clauses. */
2610 lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
2612 gimple_seq sub_seq = NULL;
2617 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2618 update in that case, otherwise use a lock. */
2619 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
2620 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
2622 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2624 /* Never use OMP_ATOMIC for array reductions. */
2634 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2636 tree var, ref, new_var;
2637 enum tree_code code;
2638 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2640 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
2643 var = OMP_CLAUSE_DECL (c);
2644 new_var = lookup_decl (var, ctx);
2645 if (is_reference (var))
2646 new_var = build_fold_indirect_ref_loc (clause_loc, new_var);
2647 ref = build_outer_var_ref (var, ctx);
2648 code = OMP_CLAUSE_REDUCTION_CODE (c);
2650 /* reduction(-:var) sums up the partial results, so it acts
2651 identically to reduction(+:var). */
2652 if (code == MINUS_EXPR)
2657 tree addr = build_fold_addr_expr_loc (clause_loc, ref);
2659 addr = save_expr (addr);
2660 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
2661 x = fold_build2_loc (clause_loc, code, TREE_TYPE (ref), ref, new_var);
2662 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
2663 gimplify_and_add (x, stmt_seqp);
2667 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2669 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
2671 if (is_reference (var))
2672 ref = build_fold_addr_expr_loc (clause_loc, ref);
2673 SET_DECL_VALUE_EXPR (placeholder, ref);
2674 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
2675 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2676 gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
2677 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
2678 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
2682 x = build2 (code, TREE_TYPE (ref), ref, new_var);
2683 ref = build_outer_var_ref (var, ctx);
2684 gimplify_assign (ref, x, &sub_seq);
2688 stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
2689 gimple_seq_add_stmt (stmt_seqp, stmt);
2691 gimple_seq_add_seq (stmt_seqp, sub_seq);
2693 stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
2694 gimple_seq_add_stmt (stmt_seqp, stmt);
2698 /* Generate code to implement the COPYPRIVATE clauses. */
2701 lower_copyprivate_clauses (tree clauses, gimple_seq *slist, gimple_seq *rlist,
2706 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2710 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2712 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
2715 var = OMP_CLAUSE_DECL (c);
2716 by_ref = use_pointer_for_field (var, NULL);
2718 ref = build_sender_ref (var, ctx);
2719 x = lookup_decl_in_outer_ctx (var, ctx);
2720 x = by_ref ? build_fold_addr_expr_loc (clause_loc, x) : x;
2721 gimplify_assign (ref, x, slist);
2723 ref = build_receiver_ref (var, by_ref, ctx);
2724 if (is_reference (var))
2726 ref = build_fold_indirect_ref_loc (clause_loc, ref);
2727 var = build_fold_indirect_ref_loc (clause_loc, var);
2729 x = lang_hooks.decls.omp_clause_assign_op (c, var, ref);
2730 gimplify_and_add (x, rlist);
2735 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2736 and REDUCTION from the sender (aka parent) side. */
2739 lower_send_clauses (tree clauses, gimple_seq *ilist, gimple_seq *olist,
2744 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2746 tree val, ref, x, var;
2747 bool by_ref, do_in = false, do_out = false;
2748 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
2750 switch (OMP_CLAUSE_CODE (c))
2752 case OMP_CLAUSE_PRIVATE:
2753 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
2756 case OMP_CLAUSE_FIRSTPRIVATE:
2757 case OMP_CLAUSE_COPYIN:
2758 case OMP_CLAUSE_LASTPRIVATE:
2759 case OMP_CLAUSE_REDUCTION:
2765 val = OMP_CLAUSE_DECL (c);
2766 var = lookup_decl_in_outer_ctx (val, ctx);
2768 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2769 && is_global_var (var))
2771 if (is_variable_sized (val))
2773 by_ref = use_pointer_for_field (val, NULL);
2775 switch (OMP_CLAUSE_CODE (c))
2777 case OMP_CLAUSE_PRIVATE:
2778 case OMP_CLAUSE_FIRSTPRIVATE:
2779 case OMP_CLAUSE_COPYIN:
2783 case OMP_CLAUSE_LASTPRIVATE:
2784 if (by_ref || is_reference (val))
2786 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2793 if (lang_hooks.decls.omp_private_outer_ref (val))
2798 case OMP_CLAUSE_REDUCTION:
2800 do_out = !(by_ref || is_reference (val));
2809 ref = build_sender_ref (val, ctx);
2810 x = by_ref ? build_fold_addr_expr_loc (clause_loc, var) : var;
2811 gimplify_assign (ref, x, ilist);
2812 if (is_task_ctx (ctx))
2813 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref, 1)) = NULL;
2818 ref = build_sender_ref (val, ctx);
2819 gimplify_assign (var, ref, olist);
2824 /* Generate code to implement SHARED from the sender (aka parent)
2825 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2826 list things that got automatically shared. */
2829 lower_send_shared_vars (gimple_seq *ilist, gimple_seq *olist, omp_context *ctx)
2831 tree var, ovar, nvar, f, x, record_type;
2833 if (ctx->record_type == NULL)
2836 record_type = ctx->srecord_type ? ctx->srecord_type : ctx->record_type;
2837 for (f = TYPE_FIELDS (record_type); f ; f = TREE_CHAIN (f))
2839 ovar = DECL_ABSTRACT_ORIGIN (f);
2840 nvar = maybe_lookup_decl (ovar, ctx);
2841 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2844 /* If CTX is a nested parallel directive. Find the immediately
2845 enclosing parallel or workshare construct that contains a
2846 mapping for OVAR. */
2847 var = lookup_decl_in_outer_ctx (ovar, ctx);
2849 if (use_pointer_for_field (ovar, ctx))
2851 x = build_sender_ref (ovar, ctx);
2852 var = build_fold_addr_expr (var);
2853 gimplify_assign (x, var, ilist);
2857 x = build_sender_ref (ovar, ctx);
2858 gimplify_assign (x, var, ilist);
2860 if (!TREE_READONLY (var)
2861 /* We don't need to receive a new reference to a result
2862 or parm decl. In fact we may not store to it as we will
2863 invalidate any pending RSO and generate wrong gimple
2865 && !((TREE_CODE (var) == RESULT_DECL
2866 || TREE_CODE (var) == PARM_DECL)
2867 && DECL_BY_REFERENCE (var)))
2869 x = build_sender_ref (ovar, ctx);
2870 gimplify_assign (var, x, olist);
2877 /* A convenience function to build an empty GIMPLE_COND with just the
2881 gimple_build_cond_empty (tree cond)
2883 enum tree_code pred_code;
2886 gimple_cond_get_ops_from_tree (cond, &pred_code, &lhs, &rhs);
2887 return gimple_build_cond (pred_code, lhs, rhs, NULL_TREE, NULL_TREE);
2891 /* Build the function calls to GOMP_parallel_start etc to actually
2892 generate the parallel operation. REGION is the parallel region
2893 being expanded. BB is the block where to insert the code. WS_ARGS
2894 will be set if this is a call to a combined parallel+workshare
2895 construct, it contains the list of additional arguments needed by
2896 the workshare construct. */
2899 expand_parallel_call (struct omp_region *region, basic_block bb,
2900 gimple entry_stmt, tree ws_args)
2902 tree t, t1, t2, val, cond, c, clauses;
2903 gimple_stmt_iterator gsi;
2906 location_t clause_loc;
2908 clauses = gimple_omp_parallel_clauses (entry_stmt);
2910 /* Determine what flavor of GOMP_parallel_start we will be
2912 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2913 if (is_combined_parallel (region))
2915 switch (region->inner->type)
2917 case GIMPLE_OMP_FOR:
2918 gcc_assert (region->inner->sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
2919 start_ix = BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2920 + (region->inner->sched_kind
2921 == OMP_CLAUSE_SCHEDULE_RUNTIME
2922 ? 3 : region->inner->sched_kind);
2924 case GIMPLE_OMP_SECTIONS:
2925 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2932 /* By default, the value of NUM_THREADS is zero (selected at run time)
2933 and there is no conditional. */
2935 val = build_int_cst (unsigned_type_node, 0);
2937 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2939 cond = OMP_CLAUSE_IF_EXPR (c);
2941 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2944 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2945 clause_loc = OMP_CLAUSE_LOCATION (c);
2948 clause_loc = gimple_location (entry_stmt);
2950 /* Ensure 'val' is of the correct type. */
2951 val = fold_convert_loc (clause_loc, unsigned_type_node, val);
2953 /* If we found the clause 'if (cond)', build either
2954 (cond != 0) or (cond ? val : 1u). */
2957 gimple_stmt_iterator gsi;
2959 cond = gimple_boolify (cond);
2961 if (integer_zerop (val))
2962 val = fold_build2_loc (clause_loc,
2963 EQ_EXPR, unsigned_type_node, cond,
2964 build_int_cst (TREE_TYPE (cond), 0));
2967 basic_block cond_bb, then_bb, else_bb;
2968 edge e, e_then, e_else;
2969 tree tmp_then, tmp_else, tmp_join, tmp_var;
2971 tmp_var = create_tmp_var (TREE_TYPE (val), NULL);
2972 if (gimple_in_ssa_p (cfun))
2974 tmp_then = make_ssa_name (tmp_var, NULL);
2975 tmp_else = make_ssa_name (tmp_var, NULL);
2976 tmp_join = make_ssa_name (tmp_var, NULL);
2985 e = split_block (bb, NULL);
2990 then_bb = create_empty_bb (cond_bb);
2991 else_bb = create_empty_bb (then_bb);
2992 set_immediate_dominator (CDI_DOMINATORS, then_bb, cond_bb);
2993 set_immediate_dominator (CDI_DOMINATORS, else_bb, cond_bb);
2995 stmt = gimple_build_cond_empty (cond);
2996 gsi = gsi_start_bb (cond_bb);
2997 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
2999 gsi = gsi_start_bb (then_bb);
3000 stmt = gimple_build_assign (tmp_then, val);
3001 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3003 gsi = gsi_start_bb (else_bb);
3004 stmt = gimple_build_assign
3005 (tmp_else, build_int_cst (unsigned_type_node, 1));
3006 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3008 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
3009 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
3010 e_then = make_edge (then_bb, bb, EDGE_FALLTHRU);
3011 e_else = make_edge (else_bb, bb, EDGE_FALLTHRU);
3013 if (gimple_in_ssa_p (cfun))
3015 gimple phi = create_phi_node (tmp_join, bb);
3016 SSA_NAME_DEF_STMT (tmp_join) = phi;
3017 add_phi_arg (phi, tmp_then, e_then);
3018 add_phi_arg (phi, tmp_else, e_else);
3024 gsi = gsi_start_bb (bb);
3025 val = force_gimple_operand_gsi (&gsi, val, true, NULL_TREE,
3026 false, GSI_CONTINUE_LINKING);
3029 gsi = gsi_last_bb (bb);
3030 t = gimple_omp_parallel_data_arg (entry_stmt);
3032 t1 = null_pointer_node;
3034 t1 = build_fold_addr_expr (t);
3035 t2 = build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt));
3039 tree args = tree_cons (NULL, t2,
3040 tree_cons (NULL, t1,
3041 tree_cons (NULL, val, ws_args)));
3042 t = build_function_call_expr (UNKNOWN_LOCATION,
3043 built_in_decls[start_ix], args);
3046 t = build_call_expr (built_in_decls[start_ix], 3, t2, t1, val);
3048 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3049 false, GSI_CONTINUE_LINKING);
3051 t = gimple_omp_parallel_data_arg (entry_stmt);
3053 t = null_pointer_node;
3055 t = build_fold_addr_expr (t);
3056 t = build_call_expr_loc (gimple_location (entry_stmt),
3057 gimple_omp_parallel_child_fn (entry_stmt), 1, t);
3058 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3059 false, GSI_CONTINUE_LINKING);
3061 t = build_call_expr_loc (gimple_location (entry_stmt),
3062 built_in_decls[BUILT_IN_GOMP_PARALLEL_END], 0);
3063 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3064 false, GSI_CONTINUE_LINKING);
3068 /* Build the function call to GOMP_task to actually
3069 generate the task operation. BB is the block where to insert the code. */
3072 expand_task_call (basic_block bb, gimple entry_stmt)
3074 tree t, t1, t2, t3, flags, cond, c, clauses;
3075 gimple_stmt_iterator gsi;
3076 location_t loc = gimple_location (entry_stmt);
3078 clauses = gimple_omp_task_clauses (entry_stmt);
3080 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
3082 cond = gimple_boolify (OMP_CLAUSE_IF_EXPR (c));
3084 cond = boolean_true_node;
3086 c = find_omp_clause (clauses, OMP_CLAUSE_UNTIED);
3087 flags = build_int_cst (unsigned_type_node, (c ? 1 : 0));
3089 gsi = gsi_last_bb (bb);
3090 t = gimple_omp_task_data_arg (entry_stmt);
3092 t2 = null_pointer_node;
3094 t2 = build_fold_addr_expr_loc (loc, t);
3095 t1 = build_fold_addr_expr_loc (loc, gimple_omp_task_child_fn (entry_stmt));
3096 t = gimple_omp_task_copy_fn (entry_stmt);
3098 t3 = null_pointer_node;
3100 t3 = build_fold_addr_expr_loc (loc, t);
3102 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_TASK], 7, t1, t2, t3,
3103 gimple_omp_task_arg_size (entry_stmt),
3104 gimple_omp_task_arg_align (entry_stmt), cond, flags);
3106 force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3107 false, GSI_CONTINUE_LINKING);
3111 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3112 catch handler and return it. This prevents programs from violating the
3113 structured block semantics with throws. */
3116 maybe_catch_exception (gimple_seq body)
3120 if (!flag_exceptions)
3123 if (lang_protect_cleanup_actions)
3124 t = lang_protect_cleanup_actions ();
3126 t = gimple_build_call (built_in_decls[BUILT_IN_TRAP], 0);
3128 f = gimple_build_eh_filter (NULL, gimple_seq_alloc_with_stmt (t));
3129 gimple_eh_filter_set_must_not_throw (f, true);
3131 t = gimple_build_try (body, gimple_seq_alloc_with_stmt (f),
3134 return gimple_seq_alloc_with_stmt (t);
3137 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3140 list2chain (tree list)
3144 for (t = list; t; t = TREE_CHAIN (t))
3146 tree var = TREE_VALUE (t);
3148 TREE_CHAIN (var) = TREE_VALUE (TREE_CHAIN (t));
3150 TREE_CHAIN (var) = NULL_TREE;
3153 return list ? TREE_VALUE (list) : NULL_TREE;
3157 /* Remove barriers in REGION->EXIT's block. Note that this is only
3158 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3159 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3160 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3164 remove_exit_barrier (struct omp_region *region)
3166 gimple_stmt_iterator gsi;
3167 basic_block exit_bb;
3171 int any_addressable_vars = -1;
3173 exit_bb = region->exit;
3175 /* If the parallel region doesn't return, we don't have REGION->EXIT
3180 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3181 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3182 statements that can appear in between are extremely limited -- no
3183 memory operations at all. Here, we allow nothing at all, so the
3184 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3185 gsi = gsi_last_bb (exit_bb);
3186 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3188 if (!gsi_end_p (gsi) && gimple_code (gsi_stmt (gsi)) != GIMPLE_LABEL)
3191 FOR_EACH_EDGE (e, ei, exit_bb->preds)
3193 gsi = gsi_last_bb (e->src);
3194 if (gsi_end_p (gsi))
3196 stmt = gsi_stmt (gsi);
3197 if (gimple_code (stmt) == GIMPLE_OMP_RETURN
3198 && !gimple_omp_return_nowait_p (stmt))
3200 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3201 in many cases. If there could be tasks queued, the barrier
3202 might be needed to let the tasks run before some local
3203 variable of the parallel that the task uses as shared
3204 runs out of scope. The task can be spawned either
3205 from within current function (this would be easy to check)
3206 or from some function it calls and gets passed an address
3207 of such a variable. */
3208 if (any_addressable_vars < 0)
3210 gimple parallel_stmt = last_stmt (region->entry);
3211 tree child_fun = gimple_omp_parallel_child_fn (parallel_stmt);
3212 tree local_decls = DECL_STRUCT_FUNCTION (child_fun)->local_decls;
3215 any_addressable_vars = 0;
3216 for (; local_decls; local_decls = TREE_CHAIN (local_decls))
3217 if (TREE_ADDRESSABLE (TREE_VALUE (local_decls)))
3219 any_addressable_vars = 1;
3222 for (block = gimple_block (stmt);
3223 !any_addressable_vars
3225 && TREE_CODE (block) == BLOCK;
3226 block = BLOCK_SUPERCONTEXT (block))
3228 for (local_decls = BLOCK_VARS (block);
3230 local_decls = TREE_CHAIN (local_decls))
3231 if (TREE_ADDRESSABLE (local_decls))
3233 any_addressable_vars = 1;
3236 if (block == gimple_block (parallel_stmt))
3240 if (!any_addressable_vars)
3241 gimple_omp_return_set_nowait (stmt);
3247 remove_exit_barriers (struct omp_region *region)
3249 if (region->type == GIMPLE_OMP_PARALLEL)
3250 remove_exit_barrier (region);
3254 region = region->inner;
3255 remove_exit_barriers (region);
3256 while (region->next)
3258 region = region->next;
3259 remove_exit_barriers (region);
3264 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3265 calls. These can't be declared as const functions, but
3266 within one parallel body they are constant, so they can be
3267 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3268 which are declared const. Similarly for task body, except
3269 that in untied task omp_get_thread_num () can change at any task
3270 scheduling point. */
3273 optimize_omp_library_calls (gimple entry_stmt)
3276 gimple_stmt_iterator gsi;
3278 = DECL_ASSEMBLER_NAME (built_in_decls [BUILT_IN_OMP_GET_THREAD_NUM]);
3280 = DECL_ASSEMBLER_NAME (built_in_decls [BUILT_IN_OMP_GET_NUM_THREADS]);
3281 bool untied_task = (gimple_code (entry_stmt) == GIMPLE_OMP_TASK
3282 && find_omp_clause (gimple_omp_task_clauses (entry_stmt),
3283 OMP_CLAUSE_UNTIED) != NULL);
3286 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
3288 gimple call = gsi_stmt (gsi);
3291 if (is_gimple_call (call)
3292 && (decl = gimple_call_fndecl (call))
3293 && DECL_EXTERNAL (decl)
3294 && TREE_PUBLIC (decl)
3295 && DECL_INITIAL (decl) == NULL)
3299 if (DECL_NAME (decl) == thr_num_id)
3301 /* In #pragma omp task untied omp_get_thread_num () can change
3302 during the execution of the task region. */
3305 built_in = built_in_decls [BUILT_IN_OMP_GET_THREAD_NUM];
3307 else if (DECL_NAME (decl) == num_thr_id)
3308 built_in = built_in_decls [BUILT_IN_OMP_GET_NUM_THREADS];
3312 if (DECL_ASSEMBLER_NAME (decl) != DECL_ASSEMBLER_NAME (built_in)
3313 || gimple_call_num_args (call) != 0)
3316 if (flag_exceptions && !TREE_NOTHROW (decl))
3319 if (TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE
3320 || TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (decl)))
3321 != TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (built_in))))
3324 gimple_call_set_fndecl (call, built_in);
3329 /* Expand the OpenMP parallel or task directive starting at REGION. */
3332 expand_omp_taskreg (struct omp_region *region)
3334 basic_block entry_bb, exit_bb, new_bb;
3335 struct function *child_cfun;
3336 tree child_fn, block, t, ws_args, *tp;
3338 gimple_stmt_iterator gsi;
3339 gimple entry_stmt, stmt;
3342 entry_stmt = last_stmt (region->entry);
3343 child_fn = gimple_omp_taskreg_child_fn (entry_stmt);
3344 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
3345 /* If this function has been already instrumented, make sure
3346 the child function isn't instrumented again. */
3347 child_cfun->after_tree_profile = cfun->after_tree_profile;
3349 entry_bb = region->entry;
3350 exit_bb = region->exit;
3352 if (is_combined_parallel (region))
3353 ws_args = region->ws_args;
3355 ws_args = NULL_TREE;
3357 if (child_cfun->cfg)
3359 /* Due to inlining, it may happen that we have already outlined
3360 the region, in which case all we need to do is make the
3361 sub-graph unreachable and emit the parallel call. */
3362 edge entry_succ_e, exit_succ_e;
3363 gimple_stmt_iterator gsi;
3365 entry_succ_e = single_succ_edge (entry_bb);
3367 gsi = gsi_last_bb (entry_bb);
3368 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_PARALLEL
3369 || gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_TASK);
3370 gsi_remove (&gsi, true);
3375 exit_succ_e = single_succ_edge (exit_bb);
3376 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
3378 remove_edge_and_dominated_blocks (entry_succ_e);
3382 /* If the parallel region needs data sent from the parent
3383 function, then the very first statement (except possible
3384 tree profile counter updates) of the parallel body
3385 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3386 &.OMP_DATA_O is passed as an argument to the child function,
3387 we need to replace it with the argument as seen by the child
3390 In most cases, this will end up being the identity assignment
3391 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3392 a function call that has been inlined, the original PARM_DECL
3393 .OMP_DATA_I may have been converted into a different local
3394 variable. In which case, we need to keep the assignment. */
3395 if (gimple_omp_taskreg_data_arg (entry_stmt))
3397 basic_block entry_succ_bb = single_succ (entry_bb);
3398 gimple_stmt_iterator gsi;
3400 gimple parcopy_stmt = NULL;
3402 for (gsi = gsi_start_bb (entry_succ_bb); ; gsi_next (&gsi))
3406 gcc_assert (!gsi_end_p (gsi));
3407 stmt = gsi_stmt (gsi);
3408 if (gimple_code (stmt) != GIMPLE_ASSIGN)
3411 if (gimple_num_ops (stmt) == 2)
3413 tree arg = gimple_assign_rhs1 (stmt);
3415 /* We're ignore the subcode because we're
3416 effectively doing a STRIP_NOPS. */
3418 if (TREE_CODE (arg) == ADDR_EXPR
3419 && TREE_OPERAND (arg, 0)
3420 == gimple_omp_taskreg_data_arg (entry_stmt))
3422 parcopy_stmt = stmt;
3428 gcc_assert (parcopy_stmt != NULL);
3429 arg = DECL_ARGUMENTS (child_fn);
3431 if (!gimple_in_ssa_p (cfun))
3433 if (gimple_assign_lhs (parcopy_stmt) == arg)
3434 gsi_remove (&gsi, true);
3437 /* ?? Is setting the subcode really necessary ?? */
3438 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (arg));
3439 gimple_assign_set_rhs1 (parcopy_stmt, arg);
3444 /* If we are in ssa form, we must load the value from the default
3445 definition of the argument. That should not be defined now,
3446 since the argument is not used uninitialized. */
3447 gcc_assert (gimple_default_def (cfun, arg) == NULL);
3448 narg = make_ssa_name (arg, gimple_build_nop ());
3449 set_default_def (arg, narg);
3450 /* ?? Is setting the subcode really necessary ?? */
3451 gimple_omp_set_subcode (parcopy_stmt, TREE_CODE (narg));
3452 gimple_assign_set_rhs1 (parcopy_stmt, narg);
3453 update_stmt (parcopy_stmt);
3457 /* Declare local variables needed in CHILD_CFUN. */
3458 block = DECL_INITIAL (child_fn);
3459 BLOCK_VARS (block) = list2chain (child_cfun->local_decls);
3460 /* The gimplifier could record temporaries in parallel/task block
3461 rather than in containing function's local_decls chain,
3462 which would mean cgraph missed finalizing them. Do it now. */
3463 for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
3464 if (TREE_CODE (t) == VAR_DECL
3466 && !DECL_EXTERNAL (t))
3467 varpool_finalize_decl (t);
3468 DECL_SAVED_TREE (child_fn) = NULL;
3469 gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
3470 TREE_USED (block) = 1;
3472 /* Reset DECL_CONTEXT on function arguments. */
3473 for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
3474 DECL_CONTEXT (t) = child_fn;
3476 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3477 so that it can be moved to the child function. */
3478 gsi = gsi_last_bb (entry_bb);
3479 stmt = gsi_stmt (gsi);
3480 gcc_assert (stmt && (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
3481 || gimple_code (stmt) == GIMPLE_OMP_TASK));
3482 gsi_remove (&gsi, true);
3483 e = split_block (entry_bb, stmt);
3485 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3487 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3490 gsi = gsi_last_bb (exit_bb);
3491 gcc_assert (!gsi_end_p (gsi)
3492 && gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_RETURN);
3493 stmt = gimple_build_return (NULL);
3494 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
3495 gsi_remove (&gsi, true);
3498 /* Move the parallel region into CHILD_CFUN. */
3500 if (gimple_in_ssa_p (cfun))
3502 push_cfun (child_cfun);
3503 init_tree_ssa (child_cfun);
3504 init_ssa_operands ();
3505 cfun->gimple_df->in_ssa_p = true;
3510 block = gimple_block (entry_stmt);
3512 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
3514 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
3516 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3517 for (tp = &child_cfun->local_decls; *tp; )
3518 if (DECL_CONTEXT (TREE_VALUE (*tp)) != cfun->decl)
3519 tp = &TREE_CHAIN (*tp);
3521 *tp = TREE_CHAIN (*tp);
3523 /* Inform the callgraph about the new function. */
3524 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
3525 = cfun->curr_properties;
3526 cgraph_add_new_function (child_fn, true);
3528 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3529 fixed in a following pass. */
3530 push_cfun (child_cfun);
3531 save_current = current_function_decl;
3532 current_function_decl = child_fn;
3534 optimize_omp_library_calls (entry_stmt);
3535 rebuild_cgraph_edges ();
3537 /* Some EH regions might become dead, see PR34608. If
3538 pass_cleanup_cfg isn't the first pass to happen with the
3539 new child, these dead EH edges might cause problems.
3540 Clean them up now. */
3541 if (flag_exceptions)
3544 bool changed = false;
3547 changed |= gimple_purge_dead_eh_edges (bb);
3549 cleanup_tree_cfg ();
3551 if (gimple_in_ssa_p (cfun))
3552 update_ssa (TODO_update_ssa);
3553 current_function_decl = save_current;
3557 /* Emit a library call to launch the children threads. */
3558 if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
3559 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
3561 expand_task_call (new_bb, entry_stmt);
3562 update_ssa (TODO_update_ssa_only_virtuals);
3566 /* A subroutine of expand_omp_for. Generate code for a parallel
3567 loop with any schedule. Given parameters:
3569 for (V = N1; V cond N2; V += STEP) BODY;
3571 where COND is "<" or ">", we generate pseudocode
3573 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3574 if (more) goto L0; else goto L3;
3581 if (V cond iend) goto L1; else goto L2;
3583 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3586 If this is a combined omp parallel loop, instead of the call to
3587 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3589 For collapsed loops, given parameters:
3591 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3592 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3593 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3596 we generate pseudocode
3602 count3 = (adj + N32 - N31) / STEP3;
3607 count2 = (adj + N22 - N21) / STEP2;
3612 count1 = (adj + N12 - N11) / STEP1;
3613 count = count1 * count2 * count3;
3614 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3615 if (more) goto L0; else goto L3;
3619 V3 = N31 + (T % count3) * STEP3;
3621 V2 = N21 + (T % count2) * STEP2;
3623 V1 = N11 + T * STEP1;
3628 if (V < iend) goto L10; else goto L2;
3631 if (V3 cond3 N32) goto L1; else goto L11;
3635 if (V2 cond2 N22) goto L1; else goto L12;
3641 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3647 expand_omp_for_generic (struct omp_region *region,
3648 struct omp_for_data *fd,
3649 enum built_in_function start_fn,
3650 enum built_in_function next_fn)
3652 tree type, istart0, iend0, iend;
3653 tree t, vmain, vback, bias = NULL_TREE;
3654 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, collapse_bb;
3655 basic_block l2_bb = NULL, l3_bb = NULL;
3656 gimple_stmt_iterator gsi;
3658 bool in_combined_parallel = is_combined_parallel (region);
3659 bool broken_loop = region->cont == NULL;
3661 tree *counts = NULL;
3664 gcc_assert (!broken_loop || !in_combined_parallel);
3665 gcc_assert (fd->iter_type == long_integer_type_node
3666 || !in_combined_parallel);
3668 type = TREE_TYPE (fd->loop.v);
3669 istart0 = create_tmp_var (fd->iter_type, ".istart0");
3670 iend0 = create_tmp_var (fd->iter_type, ".iend0");
3671 TREE_ADDRESSABLE (istart0) = 1;
3672 TREE_ADDRESSABLE (iend0) = 1;
3673 if (gimple_in_ssa_p (cfun))
3675 add_referenced_var (istart0);
3676 add_referenced_var (iend0);
3679 /* See if we need to bias by LLONG_MIN. */
3680 if (fd->iter_type == long_long_unsigned_type_node
3681 && TREE_CODE (type) == INTEGER_TYPE
3682 && !TYPE_UNSIGNED (type))
3686 if (fd->loop.cond_code == LT_EXPR)
3689 n2 = fold_build2 (PLUS_EXPR, type, fd->loop.n2, fd->loop.step);
3693 n1 = fold_build2 (MINUS_EXPR, type, fd->loop.n2, fd->loop.step);
3696 if (TREE_CODE (n1) != INTEGER_CST
3697 || TREE_CODE (n2) != INTEGER_CST
3698 || ((tree_int_cst_sgn (n1) < 0) ^ (tree_int_cst_sgn (n2) < 0)))
3699 bias = fold_convert (fd->iter_type, TYPE_MIN_VALUE (type));
3702 entry_bb = region->entry;
3703 cont_bb = region->cont;
3705 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
3706 gcc_assert (broken_loop
3707 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
3708 l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
3709 l1_bb = single_succ (l0_bb);
3712 l2_bb = create_empty_bb (cont_bb);
3713 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
3714 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
3718 l3_bb = BRANCH_EDGE (entry_bb)->dest;
3719 exit_bb = region->exit;
3721 gsi = gsi_last_bb (entry_bb);
3723 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
3724 if (fd->collapse > 1)
3726 /* collapsed loops need work for expansion in SSA form. */
3727 gcc_assert (!gimple_in_ssa_p (cfun));
3728 counts = (tree *) alloca (fd->collapse * sizeof (tree));
3729 for (i = 0; i < fd->collapse; i++)
3731 tree itype = TREE_TYPE (fd->loops[i].v);
3733 if (POINTER_TYPE_P (itype))
3734 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (itype), 0);
3735 t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
3737 t = fold_build2 (PLUS_EXPR, itype,
3738 fold_convert (itype, fd->loops[i].step), t);
3739 t = fold_build2 (PLUS_EXPR, itype, t,
3740 fold_convert (itype, fd->loops[i].n2));
3741 t = fold_build2 (MINUS_EXPR, itype, t,
3742 fold_convert (itype, fd->loops[i].n1));
3743 if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
3744 t = fold_build2 (TRUNC_DIV_EXPR, itype,
3745 fold_build1 (NEGATE_EXPR, itype, t),
3746 fold_build1 (NEGATE_EXPR, itype,
3747 fold_convert (itype,
3748 fd->loops[i].step)));
3750 t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
3751 fold_convert (itype, fd->loops[i].step));
3752 t = fold_convert (type, t);
3753 if (TREE_CODE (t) == INTEGER_CST)
3757 counts[i] = create_tmp_var (type, ".count");
3758 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3759 true, GSI_SAME_STMT);
3760 stmt = gimple_build_assign (counts[i], t);
3761 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3763 if (SSA_VAR_P (fd->loop.n2))
3769 t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
3770 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3771 true, GSI_SAME_STMT);
3773 stmt = gimple_build_assign (fd->loop.n2, t);
3774 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3778 if (in_combined_parallel)
3780 /* In a combined parallel loop, emit a call to
3781 GOMP_loop_foo_next. */
3782 t = build_call_expr (built_in_decls[next_fn], 2,
3783 build_fold_addr_expr (istart0),
3784 build_fold_addr_expr (iend0));
3788 tree t0, t1, t2, t3, t4;
3789 /* If this is not a combined parallel loop, emit a call to
3790 GOMP_loop_foo_start in ENTRY_BB. */
3791 t4 = build_fold_addr_expr (iend0);
3792 t3 = build_fold_addr_expr (istart0);
3793 t2 = fold_convert (fd->iter_type, fd->loop.step);
3794 if (POINTER_TYPE_P (type)
3795 && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
3797 /* Avoid casting pointers to integer of a different size. */
3799 = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
3800 t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
3801 t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
3805 t1 = fold_convert (fd->iter_type, fd->loop.n2);
3806 t0 = fold_convert (fd->iter_type, fd->loop.n1);
3810 t1 = fold_build2 (PLUS_EXPR, fd->iter_type, t1, bias);
3811 t0 = fold_build2 (PLUS_EXPR, fd->iter_type, t0, bias);
3813 if (fd->iter_type == long_integer_type_node)
3817 t = fold_convert (fd->iter_type, fd->chunk_size);
3818 t = build_call_expr (built_in_decls[start_fn], 6,
3819 t0, t1, t2, t, t3, t4);
3822 t = build_call_expr (built_in_decls[start_fn], 5,
3823 t0, t1, t2, t3, t4);
3830 /* The GOMP_loop_ull_*start functions have additional boolean
3831 argument, true for < loops and false for > loops.
3832 In Fortran, the C bool type can be different from
3833 boolean_type_node. */
3834 c_bool_type = TREE_TYPE (TREE_TYPE (built_in_decls[start_fn]));
3835 t5 = build_int_cst (c_bool_type,
3836 fd->loop.cond_code == LT_EXPR ? 1 : 0);
3839 t = fold_convert (fd->iter_type, fd->chunk_size);
3840 t = build_call_expr (built_in_decls[start_fn], 7,
3841 t5, t0, t1, t2, t, t3, t4);
3844 t = build_call_expr (built_in_decls[start_fn], 6,
3845 t5, t0, t1, t2, t3, t4);
3848 if (TREE_TYPE (t) != boolean_type_node)
3849 t = fold_build2 (NE_EXPR, boolean_type_node,
3850 t, build_int_cst (TREE_TYPE (t), 0));
3851 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3852 true, GSI_SAME_STMT);
3853 gsi_insert_after (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
3855 /* Remove the GIMPLE_OMP_FOR statement. */
3856 gsi_remove (&gsi, true);
3858 /* Iteration setup for sequential loop goes in L0_BB. */
3859 gsi = gsi_start_bb (l0_bb);
3862 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3863 if (POINTER_TYPE_P (type))
3864 t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
3866 t = fold_convert (type, t);
3867 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3868 false, GSI_CONTINUE_LINKING);
3869 stmt = gimple_build_assign (fd->loop.v, t);
3870 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3874 t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
3875 if (POINTER_TYPE_P (type))
3876 t = fold_convert (lang_hooks.types.type_for_size (TYPE_PRECISION (type),
3878 t = fold_convert (type, t);
3879 iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3880 false, GSI_CONTINUE_LINKING);
3881 if (fd->collapse > 1)
3883 tree tem = create_tmp_var (type, ".tem");
3885 stmt = gimple_build_assign (tem, fd->loop.v);
3886 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3887 for (i = fd->collapse - 1; i >= 0; i--)
3889 tree vtype = TREE_TYPE (fd->loops[i].v), itype;
3891 if (POINTER_TYPE_P (vtype))
3892 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (vtype), 0);
3893 t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
3894 t = fold_convert (itype, t);
3895 t = fold_build2 (MULT_EXPR, itype, t,
3896 fold_convert (itype, fd->loops[i].step));
3897 if (POINTER_TYPE_P (vtype))
3898 t = fold_build2 (POINTER_PLUS_EXPR, vtype,
3899 fd->loops[i].n1, fold_convert (sizetype, t));
3901 t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
3902 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3903 false, GSI_CONTINUE_LINKING);
3904 stmt = gimple_build_assign (fd->loops[i].v, t);
3905 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3908 t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
3909 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3910 false, GSI_CONTINUE_LINKING);
3911 stmt = gimple_build_assign (tem, t);
3912 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3919 /* Code to control the increment and predicate for the sequential
3920 loop goes in the CONT_BB. */
3921 gsi = gsi_last_bb (cont_bb);
3922 stmt = gsi_stmt (gsi);
3923 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
3924 vmain = gimple_omp_continue_control_use (stmt);
3925 vback = gimple_omp_continue_control_def (stmt);
3927 if (POINTER_TYPE_P (type))
3928 t = fold_build2 (POINTER_PLUS_EXPR, type, vmain,
3929 fold_convert (sizetype, fd->loop.step));
3931 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
3932 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3933 true, GSI_SAME_STMT);
3934 stmt = gimple_build_assign (vback, t);
3935 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3937 t = build2 (fd->loop.cond_code, boolean_type_node, vback, iend);
3938 stmt = gimple_build_cond_empty (t);
3939 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
3941 /* Remove GIMPLE_OMP_CONTINUE. */
3942 gsi_remove (&gsi, true);
3944 if (fd->collapse > 1)
3946 basic_block last_bb, bb;
3949 for (i = fd->collapse - 1; i >= 0; i--)
3951 tree vtype = TREE_TYPE (fd->loops[i].v);
3953 bb = create_empty_bb (last_bb);
3954 gsi = gsi_start_bb (bb);
3956 if (i < fd->collapse - 1)
3958 e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
3959 e->probability = REG_BR_PROB_BASE / 8;
3961 t = fd->loops[i + 1].n1;
3962 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3963 false, GSI_CONTINUE_LINKING);
3964 stmt = gimple_build_assign (fd->loops[i + 1].v, t);
3965 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3970 set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
3972 if (POINTER_TYPE_P (vtype))
3973 t = fold_build2 (POINTER_PLUS_EXPR, vtype,
3975 fold_convert (sizetype, fd->loops[i].step));
3977 t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
3979 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
3980 false, GSI_CONTINUE_LINKING);
3981 stmt = gimple_build_assign (fd->loops[i].v, t);
3982 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3986 t = fd->loops[i].n2;
3987 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
3988 false, GSI_CONTINUE_LINKING);
3989 t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
3991 stmt = gimple_build_cond_empty (t);
3992 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
3993 e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
3994 e->probability = REG_BR_PROB_BASE * 7 / 8;
3997 make_edge (bb, l1_bb, EDGE_FALLTHRU);
4002 /* Emit code to get the next parallel iteration in L2_BB. */
4003 gsi = gsi_start_bb (l2_bb);
4005 t = build_call_expr (built_in_decls[next_fn], 2,
4006 build_fold_addr_expr (istart0),
4007 build_fold_addr_expr (iend0));
4008 t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4009 false, GSI_CONTINUE_LINKING);
4010 if (TREE_TYPE (t) != boolean_type_node)
4011 t = fold_build2 (NE_EXPR, boolean_type_node,
4012 t, build_int_cst (TREE_TYPE (t), 0));
4013 stmt = gimple_build_cond_empty (t);
4014 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4017 /* Add the loop cleanup function. */
4018 gsi = gsi_last_bb (exit_bb);
4019 if (gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4020 t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
4022 t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
4023 stmt = gimple_build_call (t, 0);
4024 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
4025 gsi_remove (&gsi, true);
4027 /* Connect the new blocks. */
4028 find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
4029 find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
4035 e = find_edge (cont_bb, l3_bb);
4036 ne = make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
4038 phis = phi_nodes (l3_bb);
4039 for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
4041 gimple phi = gsi_stmt (gsi);
4042 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, ne),
4043 PHI_ARG_DEF_FROM_EDGE (phi, e));
4047 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
4048 if (fd->collapse > 1)
4050 e = find_edge (cont_bb, l1_bb);
4052 e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
4056 e = find_edge (cont_bb, l1_bb);
4057 e->flags = EDGE_TRUE_VALUE;
4059 e->probability = REG_BR_PROB_BASE * 7 / 8;
4060 find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
4061 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
4063 set_immediate_dominator (CDI_DOMINATORS, l2_bb,
4064 recompute_dominator (CDI_DOMINATORS, l2_bb));
4065 set_immediate_dominator (CDI_DOMINATORS, l3_bb,
4066 recompute_dominator (CDI_DOMINATORS, l3_bb));
4067 set_immediate_dominator (CDI_DOMINATORS, l0_bb,
4068 recompute_dominator (CDI_DOMINATORS, l0_bb));
4069 set_immediate_dominator (CDI_DOMINATORS, l1_bb,
4070 recompute_dominator (CDI_DOMINATORS, l1_bb));
4075 /* A subroutine of expand_omp_for. Generate code for a parallel
4076 loop with static schedule and no specified chunk size. Given
4079 for (V = N1; V cond N2; V += STEP) BODY;
4081 where COND is "<" or ">", we generate pseudocode
4087 if ((__typeof (V)) -1 > 0 && cond is >)
4088 n = -(adj + N2 - N1) / -STEP;
4090 n = (adj + N2 - N1) / STEP;
4092 q += (q * nthreads != n);
4094 e0 = min(s0 + q, n);
4096 if (s0 >= e0) goto L2; else goto L0;
4102 if (V cond e) goto L1;
4107 expand_omp_for_static_nochunk (struct omp_region *region,
4108 struct omp_for_data *fd)
4110 tree n, q, s0, e0, e, t, nthreads, threadid;
4111 tree type, itype, vmain, vback;
4112 basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
4114 gimple_stmt_iterator gsi;
4117 itype = type = TREE_TYPE (fd->loop.v);
4118 if (POINTER_TYPE_P (type))
4119 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
4121 entry_bb = region->entry;
4122 cont_bb = region->cont;
4123 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
4124 gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
4125 seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
4126 body_bb = single_succ (seq_start_bb);
4127 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4128 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4129 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4130 exit_bb = region->exit;
4132 /* Iteration space partitioning goes in ENTRY_BB. */
4133 gsi = gsi_last_bb (entry_bb);
4134 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
4136 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
4137 t = fold_convert (itype, t);
4138 nthreads = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4139 true, GSI_SAME_STMT);
4141 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
4142 t = fold_convert (itype, t);
4143 threadid = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4144 true, GSI_SAME_STMT);
4147 = force_gimple_operand_gsi (&gsi, fold_convert (type, fd->loop.n1),
4148 true, NULL_TREE, true, GSI_SAME_STMT);
4150 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.n2),
4151 true, NULL_TREE, true, GSI_SAME_STMT);
4153 = force_gimple_operand_gsi (&gsi, fold_convert (itype, fd->loop.step),
4154 true, NULL_TREE, true, GSI_SAME_STMT);
4156 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4157 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4158 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4159 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4160 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4161 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4162 fold_build1 (NEGATE_EXPR, itype, t),
4163 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4165 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4166 t = fold_convert (itype, t);
4167 n = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4169 t = fold_build2 (TRUNC_DIV_EXPR, itype, n, nthreads);
4170 q = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4172 t = fold_build2 (MULT_EXPR, itype, q, nthreads);
4173 t = fold_build2 (NE_EXPR, itype, t, n);
4174 t = fold_build2 (PLUS_EXPR, itype, q, t);
4175 q = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4177 t = build2 (MULT_EXPR, itype, q, threadid);
4178 s0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4180 t = fold_build2 (PLUS_EXPR, itype, s0, q);
4181 t = fold_build2 (MIN_EXPR, itype, t, n);
4182 e0 = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true, GSI_SAME_STMT);
4184 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
4185 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4187 /* Remove the GIMPLE_OMP_FOR statement. */
4188 gsi_remove (&gsi, true);
4190 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4191 gsi = gsi_start_bb (seq_start_bb);
4193 t = fold_convert (itype, s0);
4194 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4195 if (POINTER_TYPE_P (type))
4196 t = fold_build2 (POINTER_PLUS_EXPR, type, fd->loop.n1,
4197 fold_convert (sizetype, t));
4199 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4200 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4201 false, GSI_CONTINUE_LINKING);
4202 stmt = gimple_build_assign (fd->loop.v, t);
4203 gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
4205 t = fold_convert (itype, e0);
4206 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4207 if (POINTER_TYPE_P (type))
4208 t = fold_build2 (POINTER_PLUS_EXPR, type, fd->loop.n1,
4209 fold_convert (sizetype, t));
4211 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4212 e = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
4213 false, GSI_CONTINUE_LINKING);
4215 /* The code controlling the sequential loop replaces the
4216 GIMPLE_OMP_CONTINUE. */
4217 gsi = gsi_last_bb (cont_bb);
4218 stmt = gsi_stmt (gsi);
4219 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4220 vmain = gimple_omp_continue_control_use (stmt);
4221 vback = gimple_omp_continue_control_def (stmt);
4223 if (POINTER_TYPE_P (type))
4224 t = fold_build2 (POINTER_PLUS_EXPR, type, vmain,
4225 fold_convert (sizetype, fd->loop.step));
4227 t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
4228 t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
4229 true, GSI_SAME_STMT);
4230 stmt = gimple_build_assign (vback, t);
4231 gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
4233 t = build2 (fd->loop.cond_code, boolean_type_node, vback, e);
4234 gsi_insert_before (&gsi, gimple_build_cond_empty (t), GSI_SAME_STMT);
4236 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4237 gsi_remove (&gsi, true);
4239 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4240 gsi = gsi_last_bb (exit_bb);
4241 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi)))
4242 force_gimple_operand_gsi (&gsi, build_omp_barrier (), false, NULL_TREE,
4243 false, GSI_SAME_STMT);
4244 gsi_remove (&gsi, true);
4246 /* Connect all the blocks. */
4247 find_edge (entry_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
4248 find_edge (entry_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
4250 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4251 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4253 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb, entry_bb);
4254 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4255 recompute_dominator (CDI_DOMINATORS, body_bb));
4256 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4257 recompute_dominator (CDI_DOMINATORS, fin_bb));
4261 /* A subroutine of expand_omp_for. Generate code for a parallel
4262 loop with static schedule and a specified chunk size. Given
4265 for (V = N1; V cond N2; V += STEP) BODY;
4267 where COND is "<" or ">", we generate pseudocode
4273 if ((__typeof (V)) -1 > 0 && cond is >)
4274 n = -(adj + N2 - N1) / -STEP;
4276 n = (adj + N2 - N1) / STEP;
4278 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4279 here so that V is defined
4280 if the loop is not entered
4282 s0 = (trip * nthreads + threadid) * CHUNK;
4283 e0 = min(s0 + CHUNK, n);
4284 if (s0 < n) goto L1; else goto L4;
4291 if (V cond e) goto L2; else goto L3;
4299 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
4301 tree n, s0, e0, e, t;
4302 tree trip_var, trip_init, trip_main, trip_back, nthreads, threadid;
4303 tree type, itype, v_main, v_back, v_extra;
4304 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
4305 basic_block trip_update_bb, cont_bb, fin_bb;
4306 gimple_stmt_iterator si;
4310 itype = type = TREE_TYPE (fd->loop.v);
4311 if (POINTER_TYPE_P (type))
4312 itype = lang_hooks.types.type_for_size (TYPE_PRECISION (type), 0);
4314 entry_bb = region->entry;
4315 se = split_block (entry_bb, last_stmt (entry_bb));
4317 iter_part_bb = se->dest;
4318 cont_bb = region->cont;
4319 gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
4320 gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
4321 == FALLTHRU_EDGE (cont_bb)->dest);
4322 seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
4323 body_bb = single_succ (seq_start_bb);
4324 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
4325 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
4326 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
4327 trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
4328 exit_bb = region->exit;
4330 /* Trip and adjustment setup goes in ENTRY_BB. */
4331 si = gsi_last_bb (entry_bb);
4332 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_FOR);
4334 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
4335 t = fold_convert (itype, t);
4336 nthreads = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4337 true, GSI_SAME_STMT);
4339 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
4340 t = fold_convert (itype, t);
4341 threadid = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4342 true, GSI_SAME_STMT);
4345 = force_gimple_operand_gsi (&si, fold_convert (type, fd->loop.n1),
4346 true, NULL_TREE, true, GSI_SAME_STMT);
4348 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.n2),
4349 true, NULL_TREE, true, GSI_SAME_STMT);
4351 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->loop.step),
4352 true, NULL_TREE, true, GSI_SAME_STMT);
4354 = force_gimple_operand_gsi (&si, fold_convert (itype, fd->chunk_size),
4355 true, NULL_TREE, true, GSI_SAME_STMT);
4357 t = build_int_cst (itype, (fd->loop.cond_code == LT_EXPR ? -1 : 1));
4358 t = fold_build2 (PLUS_EXPR, itype, fd->loop.step, t);
4359 t = fold_build2 (PLUS_EXPR, itype, t, fd->loop.n2);
4360 t = fold_build2 (MINUS_EXPR, itype, t, fold_convert (itype, fd->loop.n1));
4361 if (TYPE_UNSIGNED (itype) && fd->loop.cond_code == GT_EXPR)
4362 t = fold_build2 (TRUNC_DIV_EXPR, itype,
4363 fold_build1 (NEGATE_EXPR, itype, t),
4364 fold_build1 (NEGATE_EXPR, itype, fd->loop.step));
4366 t = fold_build2 (TRUNC_DIV_EXPR, itype, t, fd->loop.step);
4367 t = fold_convert (itype, t);
4368 n = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4369 true, GSI_SAME_STMT);
4371 trip_var = create_tmp_var (itype, ".trip");
4372 if (gimple_in_ssa_p (cfun))
4374 add_referenced_var (trip_var);
4375 trip_init = make_ssa_name (trip_var, NULL);
4376 trip_main = make_ssa_name (trip_var, NULL);
4377 trip_back = make_ssa_name (trip_var, NULL);
4381 trip_init = trip_var;
4382 trip_main = trip_var;
4383 trip_back = trip_var;
4386 stmt = gimple_build_assign (trip_init, build_int_cst (itype, 0));
4387 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4389 t = fold_build2 (MULT_EXPR, itype, threadid, fd->chunk_size);
4390 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4391 if (POINTER_TYPE_P (type))
4392 t = fold_build2 (POINTER_PLUS_EXPR, type, fd->loop.n1,
4393 fold_convert (sizetype, t));
4395 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4396 v_extra = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4397 true, GSI_SAME_STMT);
4399 /* Remove the GIMPLE_OMP_FOR. */
4400 gsi_remove (&si, true);
4402 /* Iteration space partitioning goes in ITER_PART_BB. */
4403 si = gsi_last_bb (iter_part_bb);
4405 t = fold_build2 (MULT_EXPR, itype, trip_main, nthreads);
4406 t = fold_build2 (PLUS_EXPR, itype, t, threadid);
4407 t = fold_build2 (MULT_EXPR, itype, t, fd->chunk_size);
4408 s0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4409 false, GSI_CONTINUE_LINKING);
4411 t = fold_build2 (PLUS_EXPR, itype, s0, fd->chunk_size);
4412 t = fold_build2 (MIN_EXPR, itype, t, n);
4413 e0 = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4414 false, GSI_CONTINUE_LINKING);
4416 t = build2 (LT_EXPR, boolean_type_node, s0, n);
4417 gsi_insert_after (&si, gimple_build_cond_empty (t), GSI_CONTINUE_LINKING);
4419 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4420 si = gsi_start_bb (seq_start_bb);
4422 t = fold_convert (itype, s0);
4423 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4424 if (POINTER_TYPE_P (type))
4425 t = fold_build2 (POINTER_PLUS_EXPR, type, fd->loop.n1,
4426 fold_convert (sizetype, t));
4428 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4429 t = force_gimple_operand_gsi (&si, t, false, NULL_TREE,
4430 false, GSI_CONTINUE_LINKING);
4431 stmt = gimple_build_assign (fd->loop.v, t);
4432 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4434 t = fold_convert (itype, e0);
4435 t = fold_build2 (MULT_EXPR, itype, t, fd->loop.step);
4436 if (POINTER_TYPE_P (type))
4437 t = fold_build2 (POINTER_PLUS_EXPR, type, fd->loop.n1,
4438 fold_convert (sizetype, t));
4440 t = fold_build2 (PLUS_EXPR, type, t, fd->loop.n1);
4441 e = force_gimple_operand_gsi (&si, t, true, NULL_TREE,
4442 false, GSI_CONTINUE_LINKING);
4444 /* The code controlling the sequential loop goes in CONT_BB,
4445 replacing the GIMPLE_OMP_CONTINUE. */
4446 si = gsi_last_bb (cont_bb);
4447 stmt = gsi_stmt (si);
4448 gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
4449 v_main = gimple_omp_continue_control_use (stmt);
4450 v_back = gimple_omp_continue_control_def (stmt);
4452 if (POINTER_TYPE_P (type))
4453 t = fold_build2 (POINTER_PLUS_EXPR, type, v_main,
4454 fold_convert (sizetype, fd->loop.step));
4456 t = fold_build2 (PLUS_EXPR, type, v_main, fd->loop.step);
4457 stmt = gimple_build_assign (v_back, t);
4458 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
4460 t = build2 (fd->loop.cond_code, boolean_type_node, v_back, e);
4461 gsi_insert_before (&si, gimple_build_cond_empty (t), GSI_SAME_STMT);
4463 /* Remove GIMPLE_OMP_CONTINUE. */
4464 gsi_remove (&si, true);
4466 /* Trip update code goes into TRIP_UPDATE_BB. */
4467 si = gsi_start_bb (trip_update_bb);
4469 t = build_int_cst (itype, 1);
4470 t = build2 (PLUS_EXPR, itype, trip_main, t);
4471 stmt = gimple_build_assign (trip_back, t);
4472 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4474 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4475 si = gsi_last_bb (exit_bb);
4476 if (!gimple_omp_return_nowait_p (gsi_stmt (si)))
4477 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4478 false, GSI_SAME_STMT);
4479 gsi_remove (&si, true);
4481 /* Connect the new blocks. */
4482 find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
4483 find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
4485 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
4486 find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
4488 redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
4490 if (gimple_in_ssa_p (cfun))
4492 gimple_stmt_iterator psi;
4495 edge_var_map_vector head;
4499 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4500 remove arguments of the phi nodes in fin_bb. We need to create
4501 appropriate phi nodes in iter_part_bb instead. */
4502 se = single_pred_edge (fin_bb);
4503 re = single_succ_edge (trip_update_bb);
4504 head = redirect_edge_var_map_vector (re);
4505 ene = single_succ_edge (entry_bb);
4507 psi = gsi_start_phis (fin_bb);
4508 for (i = 0; !gsi_end_p (psi) && VEC_iterate (edge_var_map, head, i, vm);
4509 gsi_next (&psi), ++i)
4513 phi = gsi_stmt (psi);
4514 t = gimple_phi_result (phi);
4515 gcc_assert (t == redirect_edge_var_map_result (vm));
4516 nphi = create_phi_node (t, iter_part_bb);
4517 SSA_NAME_DEF_STMT (t) = nphi;
4519 t = PHI_ARG_DEF_FROM_EDGE (phi, se);
4520 /* A special case -- fd->loop.v is not yet computed in
4521 iter_part_bb, we need to use v_extra instead. */
4522 if (t == fd->loop.v)
4524 add_phi_arg (nphi, t, ene);
4525 add_phi_arg (nphi, redirect_edge_var_map_def (vm), re);
4527 gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
4528 redirect_edge_var_map_clear (re);
4531 psi = gsi_start_phis (fin_bb);
4532 if (gsi_end_p (psi))
4534 remove_phi_node (&psi, false);
4537 /* Make phi node for trip. */
4538 phi = create_phi_node (trip_main, iter_part_bb);
4539 SSA_NAME_DEF_STMT (trip_main) = phi;
4540 add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb));
4541 add_phi_arg (phi, trip_init, single_succ_edge (entry_bb));
4544 set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
4545 set_immediate_dominator (CDI_DOMINATORS, iter_part_bb,
4546 recompute_dominator (CDI_DOMINATORS, iter_part_bb));
4547 set_immediate_dominator (CDI_DOMINATORS, fin_bb,
4548 recompute_dominator (CDI_DOMINATORS, fin_bb));
4549 set_immediate_dominator (CDI_DOMINATORS, seq_start_bb,
4550 recompute_dominator (CDI_DOMINATORS, seq_start_bb));
4551 set_immediate_dominator (CDI_DOMINATORS, body_bb,
4552 recompute_dominator (CDI_DOMINATORS, body_bb));
4556 /* Expand the OpenMP loop defined by REGION. */
4559 expand_omp_for (struct omp_region *region)
4561 struct omp_for_data fd;
4562 struct omp_for_data_loop *loops;
4565 = (struct omp_for_data_loop *)
4566 alloca (gimple_omp_for_collapse (last_stmt (region->entry))
4567 * sizeof (struct omp_for_data_loop));
4568 extract_omp_for_data (last_stmt (region->entry), &fd, loops);
4569 region->sched_kind = fd.sched_kind;
4571 gcc_assert (EDGE_COUNT (region->entry->succs) == 2);
4572 BRANCH_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4573 FALLTHRU_EDGE (region->entry)->flags &= ~EDGE_ABNORMAL;
4576 gcc_assert (EDGE_COUNT (region->cont->succs) == 2);
4577 BRANCH_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4578 FALLTHRU_EDGE (region->cont)->flags &= ~EDGE_ABNORMAL;
4581 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
4584 && region->cont != NULL)
4586 if (fd.chunk_size == NULL)
4587 expand_omp_for_static_nochunk (region, &fd);
4589 expand_omp_for_static_chunk (region, &fd);
4593 int fn_index, start_ix, next_ix;
4595 gcc_assert (fd.sched_kind != OMP_CLAUSE_SCHEDULE_AUTO);
4596 fn_index = (fd.sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
4597 ? 3 : fd.sched_kind;
4598 fn_index += fd.have_ordered * 4;
4599 start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index;
4600 next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index;
4601 if (fd.iter_type == long_long_unsigned_type_node)
4603 start_ix += BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4604 - BUILT_IN_GOMP_LOOP_STATIC_START;
4605 next_ix += BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4606 - BUILT_IN_GOMP_LOOP_STATIC_NEXT;
4608 expand_omp_for_generic (region, &fd, (enum built_in_function) start_ix,
4609 (enum built_in_function) next_ix);
4612 update_ssa (TODO_update_ssa_only_virtuals);
4616 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4618 v = GOMP_sections_start (n);
4635 v = GOMP_sections_next ();
4640 If this is a combined parallel sections, replace the call to
4641 GOMP_sections_start with call to GOMP_sections_next. */
4644 expand_omp_sections (struct omp_region *region)
4646 tree t, u, vin = NULL, vmain, vnext, l1, l2;
4647 VEC (tree,heap) *label_vec;
4649 basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
4650 gimple_stmt_iterator si, switch_si;
4651 gimple sections_stmt, stmt, cont;
4654 struct omp_region *inner;
4656 bool exit_reachable = region->cont != NULL;
4658 gcc_assert (exit_reachable == (region->exit != NULL));
4659 entry_bb = region->entry;
4660 l0_bb = single_succ (entry_bb);
4661 l1_bb = region->cont;
4662 l2_bb = region->exit;
4665 if (single_pred (l2_bb) == l0_bb)
4666 l2 = gimple_block_label (l2_bb);
4669 /* This can happen if there are reductions. */
4670 len = EDGE_COUNT (l0_bb->succs);
4671 gcc_assert (len > 0);
4672 e = EDGE_SUCC (l0_bb, len - 1);
4673 si = gsi_last_bb (e->dest);
4676 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4677 l2 = gimple_block_label (e->dest);
4679 FOR_EACH_EDGE (e, ei, l0_bb->succs)
4681 si = gsi_last_bb (e->dest);
4683 || gimple_code (gsi_stmt (si)) != GIMPLE_OMP_SECTION)
4685 l2 = gimple_block_label (e->dest);
4690 default_bb = create_empty_bb (l1_bb->prev_bb);
4691 l1 = gimple_block_label (l1_bb);
4695 default_bb = create_empty_bb (l0_bb);
4697 l2 = gimple_block_label (default_bb);
4700 /* We will build a switch() with enough cases for all the
4701 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4702 and a default case to abort if something goes wrong. */
4703 len = EDGE_COUNT (l0_bb->succs);
4705 /* Use VEC_quick_push on label_vec throughout, since we know the size
4707 label_vec = VEC_alloc (tree, heap, len);
4709 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4710 GIMPLE_OMP_SECTIONS statement. */
4711 si = gsi_last_bb (entry_bb);
4712 sections_stmt = gsi_stmt (si);
4713 gcc_assert (gimple_code (sections_stmt) == GIMPLE_OMP_SECTIONS);
4714 vin = gimple_omp_sections_control (sections_stmt);
4715 if (!is_combined_parallel (region))
4717 /* If we are not inside a combined parallel+sections region,
4718 call GOMP_sections_start. */
4719 t = build_int_cst (unsigned_type_node,
4720 exit_reachable ? len - 1 : len);
4721 u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
4722 stmt = gimple_build_call (u, 1, t);
4726 /* Otherwise, call GOMP_sections_next. */
4727 u = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
4728 stmt = gimple_build_call (u, 0);
4730 gimple_call_set_lhs (stmt, vin);
4731 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4732 gsi_remove (&si, true);
4734 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4736 switch_si = gsi_last_bb (l0_bb);
4737 gcc_assert (gimple_code (gsi_stmt (switch_si)) == GIMPLE_OMP_SECTIONS_SWITCH);
4740 cont = last_stmt (l1_bb);
4741 gcc_assert (gimple_code (cont) == GIMPLE_OMP_CONTINUE);
4742 vmain = gimple_omp_continue_control_use (cont);
4743 vnext = gimple_omp_continue_control_def (cont);
4754 t = build3 (CASE_LABEL_EXPR, void_type_node,
4755 build_int_cst (unsigned_type_node, 0), NULL, l2);
4756 VEC_quick_push (tree, label_vec, t);
4760 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4761 for (inner = region->inner, casei = 1;
4763 inner = inner->next, i++, casei++)
4765 basic_block s_entry_bb, s_exit_bb;
4767 /* Skip optional reduction region. */
4768 if (inner->type == GIMPLE_OMP_ATOMIC_LOAD)
4775 s_entry_bb = inner->entry;
4776 s_exit_bb = inner->exit;
4778 t = gimple_block_label (s_entry_bb);
4779 u = build_int_cst (unsigned_type_node, casei);
4780 u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
4781 VEC_quick_push (tree, label_vec, u);
4783 si = gsi_last_bb (s_entry_bb);
4784 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SECTION);
4785 gcc_assert (i < len || gimple_omp_section_last_p (gsi_stmt (si)));
4786 gsi_remove (&si, true);
4787 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
4789 if (s_exit_bb == NULL)
4792 si = gsi_last_bb (s_exit_bb);
4793 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4794 gsi_remove (&si, true);
4796 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
4799 /* Error handling code goes in DEFAULT_BB. */
4800 t = gimple_block_label (default_bb);
4801 u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
4802 make_edge (l0_bb, default_bb, 0);
4804 stmt = gimple_build_switch_vec (vmain, u, label_vec);
4805 gsi_insert_after (&switch_si, stmt, GSI_SAME_STMT);
4806 gsi_remove (&switch_si, true);
4807 VEC_free (tree, heap, label_vec);
4809 si = gsi_start_bb (default_bb);
4810 stmt = gimple_build_call (built_in_decls[BUILT_IN_TRAP], 0);
4811 gsi_insert_after (&si, stmt, GSI_CONTINUE_LINKING);
4815 /* Code to get the next section goes in L1_BB. */
4816 si = gsi_last_bb (l1_bb);
4817 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CONTINUE);
4819 stmt = gimple_build_call (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
4820 gimple_call_set_lhs (stmt, vnext);
4821 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4822 gsi_remove (&si, true);
4824 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
4826 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4827 si = gsi_last_bb (l2_bb);
4828 if (gimple_omp_return_nowait_p (gsi_stmt (si)))
4829 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
4831 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
4832 stmt = gimple_build_call (t, 0);
4833 gsi_insert_after (&si, stmt, GSI_SAME_STMT);
4834 gsi_remove (&si, true);
4837 set_immediate_dominator (CDI_DOMINATORS, default_bb, l0_bb);
4841 /* Expand code for an OpenMP single directive. We've already expanded
4842 much of the code, here we simply place the GOMP_barrier call. */
4845 expand_omp_single (struct omp_region *region)
4847 basic_block entry_bb, exit_bb;
4848 gimple_stmt_iterator si;
4849 bool need_barrier = false;
4851 entry_bb = region->entry;
4852 exit_bb = region->exit;
4854 si = gsi_last_bb (entry_bb);
4855 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4856 be removed. We need to ensure that the thread that entered the single
4857 does not exit before the data is copied out by the other threads. */
4858 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si)),
4859 OMP_CLAUSE_COPYPRIVATE))
4860 need_barrier = true;
4861 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE);
4862 gsi_remove (&si, true);
4863 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4865 si = gsi_last_bb (exit_bb);
4866 if (!gimple_omp_return_nowait_p (gsi_stmt (si)) || need_barrier)
4867 force_gimple_operand_gsi (&si, build_omp_barrier (), false, NULL_TREE,
4868 false, GSI_SAME_STMT);
4869 gsi_remove (&si, true);
4870 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4874 /* Generic expansion for OpenMP synchronization directives: master,
4875 ordered and critical. All we need to do here is remove the entry
4876 and exit markers for REGION. */
4879 expand_omp_synch (struct omp_region *region)
4881 basic_block entry_bb, exit_bb;
4882 gimple_stmt_iterator si;
4884 entry_bb = region->entry;
4885 exit_bb = region->exit;
4887 si = gsi_last_bb (entry_bb);
4888 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_SINGLE
4889 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_MASTER
4890 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ORDERED
4891 || gimple_code (gsi_stmt (si)) == GIMPLE_OMP_CRITICAL);
4892 gsi_remove (&si, true);
4893 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
4897 si = gsi_last_bb (exit_bb);
4898 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_RETURN);
4899 gsi_remove (&si, true);
4900 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
4904 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
4905 operation as a __sync_fetch_and_op builtin. INDEX is log2 of the
4906 size of the data type, and thus usable to find the index of the builtin
4907 decl. Returns false if the expression is not of the proper form. */
4910 expand_omp_atomic_fetch_op (basic_block load_bb,
4911 tree addr, tree loaded_val,
4912 tree stored_val, int index)
4914 enum built_in_function base;
4915 tree decl, itype, call;
4916 enum insn_code *optab;
4918 basic_block store_bb = single_succ (load_bb);
4919 gimple_stmt_iterator gsi;
4923 /* We expect to find the following sequences:
4926 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
4929 val = tmp OP something; (or: something OP tmp)
4930 GIMPLE_OMP_STORE (val)
4932 ???FIXME: Allow a more flexible sequence.
4933 Perhaps use data flow to pick the statements.
4937 gsi = gsi_after_labels (store_bb);
4938 stmt = gsi_stmt (gsi);
4939 loc = gimple_location (stmt);
4940 if (!is_gimple_assign (stmt))
4943 if (gimple_code (gsi_stmt (gsi)) != GIMPLE_OMP_ATOMIC_STORE)
4946 if (!operand_equal_p (gimple_assign_lhs (stmt), stored_val, 0))
4949 /* Check for one of the supported fetch-op operations. */
4950 switch (gimple_assign_rhs_code (stmt))
4953 case POINTER_PLUS_EXPR:
4954 base = BUILT_IN_FETCH_AND_ADD_N;
4955 optab = sync_add_optab;
4958 base = BUILT_IN_FETCH_AND_SUB_N;
4959 optab = sync_add_optab;
4962 base = BUILT_IN_FETCH_AND_AND_N;
4963 optab = sync_and_optab;
4966 base = BUILT_IN_FETCH_AND_OR_N;
4967 optab = sync_ior_optab;
4970 base = BUILT_IN_FETCH_AND_XOR_N;
4971 optab = sync_xor_optab;
4976 /* Make sure the expression is of the proper form. */
4977 if (operand_equal_p (gimple_assign_rhs1 (stmt), loaded_val, 0))
4978 rhs = gimple_assign_rhs2 (stmt);
4979 else if (commutative_tree_code (gimple_assign_rhs_code (stmt))
4980 && operand_equal_p (gimple_assign_rhs2 (stmt), loaded_val, 0))
4981 rhs = gimple_assign_rhs1 (stmt);
4985 decl = built_in_decls[base + index + 1];
4986 itype = TREE_TYPE (TREE_TYPE (decl));
4988 if (optab[TYPE_MODE (itype)] == CODE_FOR_nothing)
4991 gsi = gsi_last_bb (load_bb);
4992 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_LOAD);
4993 call = build_call_expr_loc (loc,
4995 fold_convert_loc (loc, itype, rhs));
4996 call = fold_convert_loc (loc, void_type_node, call);
4997 force_gimple_operand_gsi (&gsi, call, true, NULL_TREE, true, GSI_SAME_STMT);
4998 gsi_remove (&gsi, true);
5000 gsi = gsi_last_bb (store_bb);
5001 gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_ATOMIC_STORE);
5002 gsi_remove (&gsi, true);
5003 gsi = gsi_last_bb (store_bb);
5004 gsi_remove (&gsi, true);
5006 if (gimple_in_ssa_p (cfun))
5007 update_ssa (TODO_update_ssa_no_phi);
5012 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5016 newval = rhs; // with oldval replacing *addr in rhs
5017 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5018 if (oldval != newval)
5021 INDEX is log2 of the size of the data type, and thus usable to find the
5022 index of the builtin decl. */
5025 expand_omp_atomic_pipeline (basic_block load_bb, basic_block store_bb,
5026 tree addr, tree loaded_val, tree stored_val,
5029 tree loadedi, storedi, initial, new_storedi, old_vali;
5030 tree type, itype, cmpxchg, iaddr;
5031 gimple_stmt_iterator si;
5032 basic_block loop_header = single_succ (load_bb);
5036 cmpxchg = built_in_decls[BUILT_IN_VAL_COMPARE_AND_SWAP_N + index + 1];
5037 type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5038 itype = TREE_TYPE (TREE_TYPE (cmpxchg));
5040 if (sync_compare_and_swap[TYPE_MODE (itype)] == CODE_FOR_nothing)
5043 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5044 si = gsi_last_bb (load_bb);
5045 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5047 /* For floating-point values, we'll need to view-convert them to integers
5048 so that we can perform the atomic compare and swap. Simplify the
5049 following code by always setting up the "i"ntegral variables. */
5050 if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
5054 iaddr = create_tmp_var (build_pointer_type_for_mode (itype, ptr_mode,
5057 = force_gimple_operand_gsi (&si,
5058 fold_convert (TREE_TYPE (iaddr), addr),
5059 false, NULL_TREE, true, GSI_SAME_STMT);
5060 stmt = gimple_build_assign (iaddr, iaddr_val);
5061 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5062 loadedi = create_tmp_var (itype, NULL);
5063 if (gimple_in_ssa_p (cfun))
5065 add_referenced_var (iaddr);
5066 add_referenced_var (loadedi);
5067 loadedi = make_ssa_name (loadedi, NULL);
5073 loadedi = loaded_val;
5076 initial = force_gimple_operand_gsi (&si, build_fold_indirect_ref (iaddr),
5077 true, NULL_TREE, true, GSI_SAME_STMT);
5079 /* Move the value to the LOADEDI temporary. */
5080 if (gimple_in_ssa_p (cfun))
5082 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header)));
5083 phi = create_phi_node (loadedi, loop_header);
5084 SSA_NAME_DEF_STMT (loadedi) = phi;
5085 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (load_bb)),
5089 gsi_insert_before (&si,
5090 gimple_build_assign (loadedi, initial),
5092 if (loadedi != loaded_val)
5094 gimple_stmt_iterator gsi2;
5097 x = build1 (VIEW_CONVERT_EXPR, type, loadedi);
5098 gsi2 = gsi_start_bb (loop_header);
5099 if (gimple_in_ssa_p (cfun))
5102 x = force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5103 true, GSI_SAME_STMT);
5104 stmt = gimple_build_assign (loaded_val, x);
5105 gsi_insert_before (&gsi2, stmt, GSI_SAME_STMT);
5109 x = build2 (MODIFY_EXPR, TREE_TYPE (loaded_val), loaded_val, x);
5110 force_gimple_operand_gsi (&gsi2, x, true, NULL_TREE,
5111 true, GSI_SAME_STMT);
5114 gsi_remove (&si, true);
5116 si = gsi_last_bb (store_bb);
5117 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5120 storedi = stored_val;
5123 force_gimple_operand_gsi (&si,
5124 build1 (VIEW_CONVERT_EXPR, itype,
5125 stored_val), true, NULL_TREE, true,
5128 /* Build the compare&swap statement. */
5129 new_storedi = build_call_expr (cmpxchg, 3, iaddr, loadedi, storedi);
5130 new_storedi = force_gimple_operand_gsi (&si,
5131 fold_convert (TREE_TYPE (loadedi),
5134 true, GSI_SAME_STMT);
5136 if (gimple_in_ssa_p (cfun))
5140 old_vali = create_tmp_var (TREE_TYPE (loadedi), NULL);
5141 if (gimple_in_ssa_p (cfun))
5142 add_referenced_var (old_vali);
5143 stmt = gimple_build_assign (old_vali, loadedi);
5144 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5146 stmt = gimple_build_assign (loadedi, new_storedi);
5147 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5150 /* Note that we always perform the comparison as an integer, even for
5151 floating point. This allows the atomic operation to properly
5152 succeed even with NaNs and -0.0. */
5153 stmt = gimple_build_cond_empty
5154 (build2 (NE_EXPR, boolean_type_node,
5155 new_storedi, old_vali));
5156 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5159 e = single_succ_edge (store_bb);
5160 e->flags &= ~EDGE_FALLTHRU;
5161 e->flags |= EDGE_FALSE_VALUE;
5163 e = make_edge (store_bb, loop_header, EDGE_TRUE_VALUE);
5165 /* Copy the new value to loadedi (we already did that before the condition
5166 if we are not in SSA). */
5167 if (gimple_in_ssa_p (cfun))
5169 phi = gimple_seq_first_stmt (phi_nodes (loop_header));
5170 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), new_storedi);
5173 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5174 gsi_remove (&si, true);
5176 if (gimple_in_ssa_p (cfun))
5177 update_ssa (TODO_update_ssa_no_phi);
5182 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5184 GOMP_atomic_start ();
5188 The result is not globally atomic, but works so long as all parallel
5189 references are within #pragma omp atomic directives. According to
5190 responses received from omp@openmp.org, appears to be within spec.
5191 Which makes sense, since that's how several other compilers handle
5192 this situation as well.
5193 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5194 expanding. STORED_VAL is the operand of the matching
5195 GIMPLE_OMP_ATOMIC_STORE.
5198 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5202 GIMPLE_OMP_ATOMIC_ATORE (stored_val) with
5207 expand_omp_atomic_mutex (basic_block load_bb, basic_block store_bb,
5208 tree addr, tree loaded_val, tree stored_val)
5210 gimple_stmt_iterator si;
5214 si = gsi_last_bb (load_bb);
5215 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_LOAD);
5217 t = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
5218 t = build_function_call_expr (UNKNOWN_LOCATION, t, 0);
5219 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5221 stmt = gimple_build_assign (loaded_val, build_fold_indirect_ref (addr));
5222 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5223 gsi_remove (&si, true);
5225 si = gsi_last_bb (store_bb);
5226 gcc_assert (gimple_code (gsi_stmt (si)) == GIMPLE_OMP_ATOMIC_STORE);
5228 stmt = gimple_build_assign (build_fold_indirect_ref (unshare_expr (addr)),
5230 gsi_insert_before (&si, stmt, GSI_SAME_STMT);
5232 t = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
5233 t = build_function_call_expr (UNKNOWN_LOCATION, t, 0);
5234 force_gimple_operand_gsi (&si, t, true, NULL_TREE, true, GSI_SAME_STMT);
5235 gsi_remove (&si, true);
5237 if (gimple_in_ssa_p (cfun))
5238 update_ssa (TODO_update_ssa_no_phi);
5242 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5243 using expand_omp_atomic_fetch_op. If it failed, we try to
5244 call expand_omp_atomic_pipeline, and if it fails too, the
5245 ultimate fallback is wrapping the operation in a mutex
5246 (expand_omp_atomic_mutex). REGION is the atomic region built
5247 by build_omp_regions_1(). */
5250 expand_omp_atomic (struct omp_region *region)
5252 basic_block load_bb = region->entry, store_bb = region->exit;
5253 gimple load = last_stmt (load_bb), store = last_stmt (store_bb);
5254 tree loaded_val = gimple_omp_atomic_load_lhs (load);
5255 tree addr = gimple_omp_atomic_load_rhs (load);
5256 tree stored_val = gimple_omp_atomic_store_val (store);
5257 tree type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr)));
5258 HOST_WIDE_INT index;
5260 /* Make sure the type is one of the supported sizes. */
5261 index = tree_low_cst (TYPE_SIZE_UNIT (type), 1);
5262 index = exact_log2 (index);
5263 if (index >= 0 && index <= 4)
5265 unsigned int align = TYPE_ALIGN_UNIT (type);
5267 /* __sync builtins require strict data alignment. */
5268 if (exact_log2 (align) >= index)
5270 /* When possible, use specialized atomic update functions. */
5271 if ((INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
5272 && store_bb == single_succ (load_bb))
5274 if (expand_omp_atomic_fetch_op (load_bb, addr,
5275 loaded_val, stored_val, index))
5279 /* If we don't have specialized __sync builtins, try and implement
5280 as a compare and swap loop. */
5281 if (expand_omp_atomic_pipeline (load_bb, store_bb, addr,
5282 loaded_val, stored_val, index))
5287 /* The ultimate fallback is wrapping the operation in a mutex. */
5288 expand_omp_atomic_mutex (load_bb, store_bb, addr, loaded_val, stored_val);
5292 /* Expand the parallel region tree rooted at REGION. Expansion
5293 proceeds in depth-first order. Innermost regions are expanded
5294 first. This way, parallel regions that require a new function to
5295 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5296 internal dependencies in their body. */
5299 expand_omp (struct omp_region *region)
5303 location_t saved_location;
5305 /* First, determine whether this is a combined parallel+workshare
5307 if (region->type == GIMPLE_OMP_PARALLEL)
5308 determine_parallel_type (region);
5311 expand_omp (region->inner);
5313 saved_location = input_location;
5314 if (gimple_has_location (last_stmt (region->entry)))
5315 input_location = gimple_location (last_stmt (region->entry));
5317 switch (region->type)
5319 case GIMPLE_OMP_PARALLEL:
5320 case GIMPLE_OMP_TASK:
5321 expand_omp_taskreg (region);
5324 case GIMPLE_OMP_FOR:
5325 expand_omp_for (region);
5328 case GIMPLE_OMP_SECTIONS:
5329 expand_omp_sections (region);
5332 case GIMPLE_OMP_SECTION:
5333 /* Individual omp sections are handled together with their
5334 parent GIMPLE_OMP_SECTIONS region. */
5337 case GIMPLE_OMP_SINGLE:
5338 expand_omp_single (region);
5341 case GIMPLE_OMP_MASTER:
5342 case GIMPLE_OMP_ORDERED:
5343 case GIMPLE_OMP_CRITICAL:
5344 expand_omp_synch (region);
5347 case GIMPLE_OMP_ATOMIC_LOAD:
5348 expand_omp_atomic (region);
5355 input_location = saved_location;
5356 region = region->next;
5361 /* Helper for build_omp_regions. Scan the dominator tree starting at
5362 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5363 true, the function ends once a single tree is built (otherwise, whole
5364 forest of OMP constructs may be built). */
5367 build_omp_regions_1 (basic_block bb, struct omp_region *parent,
5370 gimple_stmt_iterator gsi;
5374 gsi = gsi_last_bb (bb);
5375 if (!gsi_end_p (gsi) && is_gimple_omp (gsi_stmt (gsi)))
5377 struct omp_region *region;
5378 enum gimple_code code;
5380 stmt = gsi_stmt (gsi);
5381 code = gimple_code (stmt);
5382 if (code == GIMPLE_OMP_RETURN)
5384 /* STMT is the return point out of region PARENT. Mark it
5385 as the exit point and make PARENT the immediately
5386 enclosing region. */
5387 gcc_assert (parent);
5390 parent = parent->outer;
5392 else if (code == GIMPLE_OMP_ATOMIC_STORE)
5394 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5395 GIMPLE_OMP_RETURN, but matches with
5396 GIMPLE_OMP_ATOMIC_LOAD. */
5397 gcc_assert (parent);
5398 gcc_assert (parent->type == GIMPLE_OMP_ATOMIC_LOAD);
5401 parent = parent->outer;
5404 else if (code == GIMPLE_OMP_CONTINUE)
5406 gcc_assert (parent);
5409 else if (code == GIMPLE_OMP_SECTIONS_SWITCH)
5411 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5412 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5417 /* Otherwise, this directive becomes the parent for a new
5419 region = new_omp_region (bb, code, parent);
5424 if (single_tree && !parent)
5427 for (son = first_dom_son (CDI_DOMINATORS, bb);
5429 son = next_dom_son (CDI_DOMINATORS, son))
5430 build_omp_regions_1 (son, parent, single_tree);
5433 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5437 build_omp_regions_root (basic_block root)
5439 gcc_assert (root_omp_region == NULL);
5440 build_omp_regions_1 (root, NULL, true);
5441 gcc_assert (root_omp_region != NULL);
5444 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5447 omp_expand_local (basic_block head)
5449 build_omp_regions_root (head);
5450 if (dump_file && (dump_flags & TDF_DETAILS))
5452 fprintf (dump_file, "\nOMP region tree\n\n");
5453 dump_omp_region (dump_file, root_omp_region, 0);
5454 fprintf (dump_file, "\n");
5457 remove_exit_barriers (root_omp_region);
5458 expand_omp (root_omp_region);
5460 free_omp_regions ();
5463 /* Scan the CFG and build a tree of OMP regions. Return the root of
5464 the OMP region tree. */
5467 build_omp_regions (void)
5469 gcc_assert (root_omp_region == NULL);
5470 calculate_dominance_info (CDI_DOMINATORS);
5471 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL, false);
5474 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5477 execute_expand_omp (void)
5479 build_omp_regions ();
5481 if (!root_omp_region)
5486 fprintf (dump_file, "\nOMP region tree\n\n");
5487 dump_omp_region (dump_file, root_omp_region, 0);
5488 fprintf (dump_file, "\n");
5491 remove_exit_barriers (root_omp_region);
5493 expand_omp (root_omp_region);
5495 cleanup_tree_cfg ();
5497 free_omp_regions ();
5502 /* OMP expansion -- the default pass, run before creation of SSA form. */
5505 gate_expand_omp (void)
5507 return (flag_openmp != 0 && errorcount == 0);
5510 struct gimple_opt_pass pass_expand_omp =
5514 "ompexp", /* name */
5515 gate_expand_omp, /* gate */
5516 execute_expand_omp, /* execute */
5519 0, /* static_pass_number */
5520 TV_NONE, /* tv_id */
5521 PROP_gimple_any, /* properties_required */
5522 0, /* properties_provided */
5523 0, /* properties_destroyed */
5524 0, /* todo_flags_start */
5525 TODO_dump_func /* todo_flags_finish */
5529 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5531 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5532 CTX is the enclosing OMP context for the current statement. */
5535 lower_omp_sections (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5537 tree block, control;
5538 gimple_stmt_iterator tgsi;
5540 gimple stmt, new_stmt, bind, t;
5541 gimple_seq ilist, dlist, olist, new_body, body;
5542 struct gimplify_ctx gctx;
5544 stmt = gsi_stmt (*gsi_p);
5546 push_gimplify_context (&gctx);
5550 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
5551 &ilist, &dlist, ctx);
5553 tgsi = gsi_start (gimple_omp_body (stmt));
5554 for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
5557 tgsi = gsi_start (gimple_omp_body (stmt));
5559 for (i = 0; i < len; i++, gsi_next (&tgsi))
5564 sec_start = gsi_stmt (tgsi);
5565 sctx = maybe_lookup_ctx (sec_start);
5568 gimple_seq_add_stmt (&body, sec_start);
5570 lower_omp (gimple_omp_body (sec_start), sctx);
5571 gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
5572 gimple_omp_set_body (sec_start, NULL);
5576 gimple_seq l = NULL;
5577 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
5579 gimple_seq_add_seq (&body, l);
5580 gimple_omp_section_set_last (sec_start);
5583 gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
5586 block = make_node (BLOCK);
5587 bind = gimple_build_bind (NULL, body, block);
5590 lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
5592 block = make_node (BLOCK);
5593 new_stmt = gimple_build_bind (NULL, NULL, block);
5595 pop_gimplify_context (new_stmt);
5596 gimple_bind_append_vars (new_stmt, ctx->block_vars);
5597 BLOCK_VARS (block) = gimple_bind_vars (bind);
5598 if (BLOCK_VARS (block))
5599 TREE_USED (block) = 1;
5602 gimple_seq_add_seq (&new_body, ilist);
5603 gimple_seq_add_stmt (&new_body, stmt);
5604 gimple_seq_add_stmt (&new_body, gimple_build_omp_sections_switch ());
5605 gimple_seq_add_stmt (&new_body, bind);
5607 control = create_tmp_var (unsigned_type_node, ".section");
5608 t = gimple_build_omp_continue (control, control);
5609 gimple_omp_sections_set_control (stmt, control);
5610 gimple_seq_add_stmt (&new_body, t);
5612 gimple_seq_add_seq (&new_body, olist);
5613 gimple_seq_add_seq (&new_body, dlist);
5615 new_body = maybe_catch_exception (new_body);
5617 t = gimple_build_omp_return
5618 (!!find_omp_clause (gimple_omp_sections_clauses (stmt),
5619 OMP_CLAUSE_NOWAIT));
5620 gimple_seq_add_stmt (&new_body, t);
5622 gimple_bind_set_body (new_stmt, new_body);
5623 gimple_omp_set_body (stmt, NULL);
5625 gsi_replace (gsi_p, new_stmt, true);
5629 /* A subroutine of lower_omp_single. Expand the simple form of
5630 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5632 if (GOMP_single_start ())
5634 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5636 FIXME. It may be better to delay expanding the logic of this until
5637 pass_expand_omp. The expanded logic may make the job more difficult
5638 to a synchronization analysis pass. */
5641 lower_omp_single_simple (gimple single_stmt, gimple_seq *pre_p)
5643 location_t loc = gimple_location (single_stmt);
5644 tree tlabel = create_artificial_label (loc);
5645 tree flabel = create_artificial_label (loc);
5649 decl = built_in_decls[BUILT_IN_GOMP_SINGLE_START];
5650 lhs = create_tmp_var (TREE_TYPE (TREE_TYPE (decl)), NULL);
5651 call = gimple_build_call (decl, 0);
5652 gimple_call_set_lhs (call, lhs);
5653 gimple_seq_add_stmt (pre_p, call);
5655 cond = gimple_build_cond (EQ_EXPR, lhs,
5656 fold_convert_loc (loc, TREE_TYPE (lhs),
5659 gimple_seq_add_stmt (pre_p, cond);
5660 gimple_seq_add_stmt (pre_p, gimple_build_label (tlabel));
5661 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5662 gimple_seq_add_stmt (pre_p, gimple_build_label (flabel));
5666 /* A subroutine of lower_omp_single. Expand the simple form of
5667 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5669 #pragma omp single copyprivate (a, b, c)
5671 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5674 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5680 GOMP_single_copy_end (©out);
5691 FIXME. It may be better to delay expanding the logic of this until
5692 pass_expand_omp. The expanded logic may make the job more difficult
5693 to a synchronization analysis pass. */
5696 lower_omp_single_copy (gimple single_stmt, gimple_seq *pre_p, omp_context *ctx)
5698 tree ptr_type, t, l0, l1, l2;
5699 gimple_seq copyin_seq;
5700 location_t loc = gimple_location (single_stmt);
5702 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
5704 ptr_type = build_pointer_type (ctx->record_type);
5705 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
5707 l0 = create_artificial_label (loc);
5708 l1 = create_artificial_label (loc);
5709 l2 = create_artificial_label (loc);
5711 t = build_call_expr_loc (loc, built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
5712 t = fold_convert_loc (loc, ptr_type, t);
5713 gimplify_assign (ctx->receiver_decl, t, pre_p);
5715 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
5716 build_int_cst (ptr_type, 0));
5717 t = build3 (COND_EXPR, void_type_node, t,
5718 build_and_jump (&l0), build_and_jump (&l1));
5719 gimplify_and_add (t, pre_p);
5721 gimple_seq_add_stmt (pre_p, gimple_build_label (l0));
5723 gimple_seq_add_seq (pre_p, gimple_omp_body (single_stmt));
5726 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt), pre_p,
5729 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
5730 t = build_call_expr_loc (loc, built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END],
5732 gimplify_and_add (t, pre_p);
5734 t = build_and_jump (&l2);
5735 gimplify_and_add (t, pre_p);
5737 gimple_seq_add_stmt (pre_p, gimple_build_label (l1));
5739 gimple_seq_add_seq (pre_p, copyin_seq);
5741 gimple_seq_add_stmt (pre_p, gimple_build_label (l2));
5745 /* Expand code for an OpenMP single directive. */
5748 lower_omp_single (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5751 gimple t, bind, single_stmt = gsi_stmt (*gsi_p);
5752 gimple_seq bind_body, dlist;
5753 struct gimplify_ctx gctx;
5755 push_gimplify_context (&gctx);
5758 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
5759 &bind_body, &dlist, ctx);
5760 lower_omp (gimple_omp_body (single_stmt), ctx);
5762 gimple_seq_add_stmt (&bind_body, single_stmt);
5764 if (ctx->record_type)
5765 lower_omp_single_copy (single_stmt, &bind_body, ctx);
5767 lower_omp_single_simple (single_stmt, &bind_body);
5769 gimple_omp_set_body (single_stmt, NULL);
5771 gimple_seq_add_seq (&bind_body, dlist);
5773 bind_body = maybe_catch_exception (bind_body);
5775 t = gimple_build_omp_return
5776 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
5777 OMP_CLAUSE_NOWAIT));
5778 gimple_seq_add_stmt (&bind_body, t);
5780 block = make_node (BLOCK);
5781 bind = gimple_build_bind (NULL, bind_body, block);
5783 pop_gimplify_context (bind);
5785 gimple_bind_append_vars (bind, ctx->block_vars);
5786 BLOCK_VARS (block) = ctx->block_vars;
5787 gsi_replace (gsi_p, bind, true);
5788 if (BLOCK_VARS (block))
5789 TREE_USED (block) = 1;
5793 /* Expand code for an OpenMP master directive. */
5796 lower_omp_master (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5798 tree block, lab = NULL, x;
5799 gimple stmt = gsi_stmt (*gsi_p), bind;
5800 location_t loc = gimple_location (stmt);
5802 struct gimplify_ctx gctx;
5804 push_gimplify_context (&gctx);
5806 block = make_node (BLOCK);
5807 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
5810 x = build_call_expr_loc (loc, built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
5811 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
5812 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
5814 gimplify_and_add (x, &tseq);
5815 gimple_bind_add_seq (bind, tseq);
5817 lower_omp (gimple_omp_body (stmt), ctx);
5818 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
5819 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
5820 gimple_omp_set_body (stmt, NULL);
5822 gimple_bind_add_stmt (bind, gimple_build_label (lab));
5824 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
5826 pop_gimplify_context (bind);
5828 gimple_bind_append_vars (bind, ctx->block_vars);
5829 BLOCK_VARS (block) = ctx->block_vars;
5830 gsi_replace (gsi_p, bind, true);
5834 /* Expand code for an OpenMP ordered directive. */
5837 lower_omp_ordered (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5840 gimple stmt = gsi_stmt (*gsi_p), bind, x;
5841 struct gimplify_ctx gctx;
5843 push_gimplify_context (&gctx);
5845 block = make_node (BLOCK);
5846 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
5849 x = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
5850 gimple_bind_add_stmt (bind, x);
5852 lower_omp (gimple_omp_body (stmt), ctx);
5853 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
5854 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
5855 gimple_omp_set_body (stmt, NULL);
5857 x = gimple_build_call (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
5858 gimple_bind_add_stmt (bind, x);
5860 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
5862 pop_gimplify_context (bind);
5864 gimple_bind_append_vars (bind, ctx->block_vars);
5865 BLOCK_VARS (block) = gimple_bind_vars (bind);
5866 gsi_replace (gsi_p, bind, true);
5870 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
5871 substitution of a couple of function calls. But in the NAMED case,
5872 requires that languages coordinate a symbol name. It is therefore
5873 best put here in common code. */
5875 static GTY((param1_is (tree), param2_is (tree)))
5876 splay_tree critical_name_mutexes;
5879 lower_omp_critical (gimple_stmt_iterator *gsi_p, omp_context *ctx)
5882 tree name, lock, unlock;
5883 gimple stmt = gsi_stmt (*gsi_p), bind;
5884 location_t loc = gimple_location (stmt);
5886 struct gimplify_ctx gctx;
5888 name = gimple_omp_critical_name (stmt);
5894 if (!critical_name_mutexes)
5895 critical_name_mutexes
5896 = splay_tree_new_ggc (splay_tree_compare_pointers);
5898 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
5903 decl = create_tmp_var_raw (ptr_type_node, NULL);
5905 new_str = ACONCAT ((".gomp_critical_user_",
5906 IDENTIFIER_POINTER (name), NULL));
5907 DECL_NAME (decl) = get_identifier (new_str);
5908 TREE_PUBLIC (decl) = 1;
5909 TREE_STATIC (decl) = 1;
5910 DECL_COMMON (decl) = 1;
5911 DECL_ARTIFICIAL (decl) = 1;
5912 DECL_IGNORED_P (decl) = 1;
5913 varpool_finalize_decl (decl);
5915 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
5916 (splay_tree_value) decl);
5919 decl = (tree) n->value;
5921 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
5922 lock = build_call_expr_loc (loc, lock, 1, build_fold_addr_expr_loc (loc, decl));
5924 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
5925 unlock = build_call_expr_loc (loc, unlock, 1,
5926 build_fold_addr_expr_loc (loc, decl));
5930 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
5931 lock = build_call_expr_loc (loc, lock, 0);
5933 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
5934 unlock = build_call_expr_loc (loc, unlock, 0);
5937 push_gimplify_context (&gctx);
5939 block = make_node (BLOCK);
5940 bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
5942 tbody = gimple_bind_body (bind);
5943 gimplify_and_add (lock, &tbody);
5944 gimple_bind_set_body (bind, tbody);
5946 lower_omp (gimple_omp_body (stmt), ctx);
5947 gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
5948 gimple_bind_add_seq (bind, gimple_omp_body (stmt));
5949 gimple_omp_set_body (stmt, NULL);
5951 tbody = gimple_bind_body (bind);
5952 gimplify_and_add (unlock, &tbody);
5953 gimple_bind_set_body (bind, tbody);
5955 gimple_bind_add_stmt (bind, gimple_build_omp_return (true));
5957 pop_gimplify_context (bind);
5958 gimple_bind_append_vars (bind, ctx->block_vars);
5959 BLOCK_VARS (block) = gimple_bind_vars (bind);
5960 gsi_replace (gsi_p, bind, true);
5964 /* A subroutine of lower_omp_for. Generate code to emit the predicate
5965 for a lastprivate clause. Given a loop control predicate of (V
5966 cond N2), we gate the clause on (!(V cond N2)). The lowered form
5967 is appended to *DLIST, iterator initialization is appended to
5971 lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
5972 gimple_seq *dlist, struct omp_context *ctx)
5974 tree clauses, cond, vinit;
5975 enum tree_code cond_code;
5978 cond_code = fd->loop.cond_code;
5979 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
5981 /* When possible, use a strict equality expression. This can let VRP
5982 type optimizations deduce the value and remove a copy. */
5983 if (host_integerp (fd->loop.step, 0))
5985 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->loop.step);
5986 if (step == 1 || step == -1)
5987 cond_code = EQ_EXPR;
5990 cond = build2 (cond_code, boolean_type_node, fd->loop.v, fd->loop.n2);
5992 clauses = gimple_omp_for_clauses (fd->for_stmt);
5994 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
5995 if (!gimple_seq_empty_p (stmts))
5997 gimple_seq_add_seq (&stmts, *dlist);
6000 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6001 vinit = fd->loop.n1;
6002 if (cond_code == EQ_EXPR
6003 && host_integerp (fd->loop.n2, 0)
6004 && ! integer_zerop (fd->loop.n2))
6005 vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
6007 /* Initialize the iterator variable, so that threads that don't execute
6008 any iterations don't execute the lastprivate clauses by accident. */
6009 gimplify_assign (fd->loop.v, vinit, body_p);
6014 /* Lower code for an OpenMP loop directive. */
6017 lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6020 struct omp_for_data fd;
6021 gimple stmt = gsi_stmt (*gsi_p), new_stmt;
6022 gimple_seq omp_for_body, body, dlist, ilist;
6024 struct gimplify_ctx gctx;
6026 push_gimplify_context (&gctx);
6028 lower_omp (gimple_omp_for_pre_body (stmt), ctx);
6029 lower_omp (gimple_omp_body (stmt), ctx);
6031 block = make_node (BLOCK);
6032 new_stmt = gimple_build_bind (NULL, NULL, block);
6034 /* Move declaration of temporaries in the loop body before we make
6036 omp_for_body = gimple_omp_body (stmt);
6037 if (!gimple_seq_empty_p (omp_for_body)
6038 && gimple_code (gimple_seq_first_stmt (omp_for_body)) == GIMPLE_BIND)
6040 tree vars = gimple_bind_vars (gimple_seq_first_stmt (omp_for_body));
6041 gimple_bind_append_vars (new_stmt, vars);
6044 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6048 lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
6049 gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
6051 /* Lower the header expressions. At this point, we can assume that
6052 the header is of the form:
6054 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6056 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6057 using the .omp_data_s mapping, if needed. */
6058 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
6060 rhs_p = gimple_omp_for_initial_ptr (stmt, i);
6061 if (!is_gimple_min_invariant (*rhs_p))
6062 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6064 rhs_p = gimple_omp_for_final_ptr (stmt, i);
6065 if (!is_gimple_min_invariant (*rhs_p))
6066 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6068 rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
6069 if (!is_gimple_min_invariant (*rhs_p))
6070 *rhs_p = get_formal_tmp_var (*rhs_p, &body);
6073 /* Once lowered, extract the bounds and clauses. */
6074 extract_omp_for_data (stmt, &fd, NULL);
6076 lower_omp_for_lastprivate (&fd, &body, &dlist, ctx);
6078 gimple_seq_add_stmt (&body, stmt);
6079 gimple_seq_add_seq (&body, gimple_omp_body (stmt));
6081 gimple_seq_add_stmt (&body, gimple_build_omp_continue (fd.loop.v,
6084 /* After the loop, add exit clauses. */
6085 lower_reduction_clauses (gimple_omp_for_clauses (stmt), &body, ctx);
6086 gimple_seq_add_seq (&body, dlist);
6088 body = maybe_catch_exception (body);
6090 /* Region exit marker goes at the end of the loop body. */
6091 gimple_seq_add_stmt (&body, gimple_build_omp_return (fd.have_nowait));
6093 pop_gimplify_context (new_stmt);
6095 gimple_bind_append_vars (new_stmt, ctx->block_vars);
6096 BLOCK_VARS (block) = gimple_bind_vars (new_stmt);
6097 if (BLOCK_VARS (block))
6098 TREE_USED (block) = 1;
6100 gimple_bind_set_body (new_stmt, body);
6101 gimple_omp_set_body (stmt, NULL);
6102 gimple_omp_for_set_pre_body (stmt, NULL);
6103 gsi_replace (gsi_p, new_stmt, true);
6106 /* Callback for walk_stmts. Check if the current statement only contains
6107 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6110 check_combined_parallel (gimple_stmt_iterator *gsi_p,
6111 bool *handled_ops_p,
6112 struct walk_stmt_info *wi)
6114 int *info = (int *) wi->info;
6115 gimple stmt = gsi_stmt (*gsi_p);
6117 *handled_ops_p = true;
6118 switch (gimple_code (stmt))
6122 case GIMPLE_OMP_FOR:
6123 case GIMPLE_OMP_SECTIONS:
6124 *info = *info == 0 ? 1 : -1;
6133 struct omp_taskcopy_context
6135 /* This field must be at the beginning, as we do "inheritance": Some
6136 callback functions for tree-inline.c (e.g., omp_copy_decl)
6137 receive a copy_body_data pointer that is up-casted to an
6138 omp_context pointer. */
6144 task_copyfn_copy_decl (tree var, copy_body_data *cb)
6146 struct omp_taskcopy_context *tcctx = (struct omp_taskcopy_context *) cb;
6148 if (splay_tree_lookup (tcctx->ctx->sfield_map, (splay_tree_key) var))
6149 return create_tmp_var (TREE_TYPE (var), NULL);
6155 task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
6157 tree name, new_fields = NULL, type, f;
6159 type = lang_hooks.types.make_type (RECORD_TYPE);
6160 name = DECL_NAME (TYPE_NAME (orig_type));
6161 name = build_decl (gimple_location (tcctx->ctx->stmt),
6162 TYPE_DECL, name, type);
6163 TYPE_NAME (type) = name;
6165 for (f = TYPE_FIELDS (orig_type); f ; f = TREE_CHAIN (f))
6167 tree new_f = copy_node (f);
6168 DECL_CONTEXT (new_f) = type;
6169 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &tcctx->cb);
6170 TREE_CHAIN (new_f) = new_fields;
6171 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6172 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r, &tcctx->cb, NULL);
6173 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
6176 *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
6178 TYPE_FIELDS (type) = nreverse (new_fields);
6183 /* Create task copyfn. */
6186 create_task_copyfn (gimple task_stmt, omp_context *ctx)
6188 struct function *child_cfun;
6189 tree child_fn, t, c, src, dst, f, sf, arg, sarg, decl;
6190 tree record_type, srecord_type, bind, list;
6191 bool record_needs_remap = false, srecord_needs_remap = false;
6193 struct omp_taskcopy_context tcctx;
6194 struct gimplify_ctx gctx;
6195 location_t loc = gimple_location (task_stmt);
6197 child_fn = gimple_omp_task_copy_fn (task_stmt);
6198 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
6199 gcc_assert (child_cfun->cfg == NULL);
6200 child_cfun->dont_save_pending_sizes_p = 1;
6201 DECL_SAVED_TREE (child_fn) = alloc_stmt_list ();
6203 /* Reset DECL_CONTEXT on function arguments. */
6204 for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
6205 DECL_CONTEXT (t) = child_fn;
6207 /* Populate the function. */
6208 push_gimplify_context (&gctx);
6209 current_function_decl = child_fn;
6211 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
6212 TREE_SIDE_EFFECTS (bind) = 1;
6214 DECL_SAVED_TREE (child_fn) = bind;
6215 DECL_SOURCE_LOCATION (child_fn) = gimple_location (task_stmt);
6217 /* Remap src and dst argument types if needed. */
6218 record_type = ctx->record_type;
6219 srecord_type = ctx->srecord_type;
6220 for (f = TYPE_FIELDS (record_type); f ; f = TREE_CHAIN (f))
6221 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6223 record_needs_remap = true;
6226 for (f = TYPE_FIELDS (srecord_type); f ; f = TREE_CHAIN (f))
6227 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
6229 srecord_needs_remap = true;
6233 if (record_needs_remap || srecord_needs_remap)
6235 memset (&tcctx, '\0', sizeof (tcctx));
6236 tcctx.cb.src_fn = ctx->cb.src_fn;
6237 tcctx.cb.dst_fn = child_fn;
6238 tcctx.cb.src_node = cgraph_node (tcctx.cb.src_fn);
6239 tcctx.cb.dst_node = tcctx.cb.src_node;
6240 tcctx.cb.src_cfun = ctx->cb.src_cfun;
6241 tcctx.cb.copy_decl = task_copyfn_copy_decl;
6242 tcctx.cb.eh_region = -1;
6243 tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
6244 tcctx.cb.decl_map = pointer_map_create ();
6247 if (record_needs_remap)
6248 record_type = task_copyfn_remap_type (&tcctx, record_type);
6249 if (srecord_needs_remap)
6250 srecord_type = task_copyfn_remap_type (&tcctx, srecord_type);
6253 tcctx.cb.decl_map = NULL;
6255 push_cfun (child_cfun);
6257 arg = DECL_ARGUMENTS (child_fn);
6258 TREE_TYPE (arg) = build_pointer_type (record_type);
6259 sarg = TREE_CHAIN (arg);
6260 TREE_TYPE (sarg) = build_pointer_type (srecord_type);
6262 /* First pass: initialize temporaries used in record_type and srecord_type
6263 sizes and field offsets. */
6264 if (tcctx.cb.decl_map)
6265 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6266 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6270 decl = OMP_CLAUSE_DECL (c);
6271 p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
6274 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6275 sf = (tree) n->value;
6276 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6277 src = build_fold_indirect_ref_loc (loc, sarg);
6278 src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6279 t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
6280 append_to_statement_list (t, &list);
6283 /* Second pass: copy shared var pointers and copy construct non-VLA
6284 firstprivate vars. */
6285 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6286 switch (OMP_CLAUSE_CODE (c))
6288 case OMP_CLAUSE_SHARED:
6289 decl = OMP_CLAUSE_DECL (c);
6290 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6293 f = (tree) n->value;
6294 if (tcctx.cb.decl_map)
6295 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6296 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6297 sf = (tree) n->value;
6298 if (tcctx.cb.decl_map)
6299 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6300 src = build_fold_indirect_ref_loc (loc, sarg);
6301 src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6302 dst = build_fold_indirect_ref_loc (loc, arg);
6303 dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
6304 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6305 append_to_statement_list (t, &list);
6307 case OMP_CLAUSE_FIRSTPRIVATE:
6308 decl = OMP_CLAUSE_DECL (c);
6309 if (is_variable_sized (decl))
6311 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6314 f = (tree) n->value;
6315 if (tcctx.cb.decl_map)
6316 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6317 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6320 sf = (tree) n->value;
6321 if (tcctx.cb.decl_map)
6322 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6323 src = build_fold_indirect_ref_loc (loc, sarg);
6324 src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6325 if (use_pointer_for_field (decl, NULL) || is_reference (decl))
6326 src = build_fold_indirect_ref_loc (loc, src);
6330 dst = build_fold_indirect_ref_loc (loc, arg);
6331 dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
6332 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6333 append_to_statement_list (t, &list);
6335 case OMP_CLAUSE_PRIVATE:
6336 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c))
6338 decl = OMP_CLAUSE_DECL (c);
6339 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6340 f = (tree) n->value;
6341 if (tcctx.cb.decl_map)
6342 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6343 n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
6346 sf = (tree) n->value;
6347 if (tcctx.cb.decl_map)
6348 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6349 src = build_fold_indirect_ref_loc (loc, sarg);
6350 src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6351 if (use_pointer_for_field (decl, NULL))
6352 src = build_fold_indirect_ref_loc (loc, src);
6356 dst = build_fold_indirect_ref_loc (loc, arg);
6357 dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
6358 t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
6359 append_to_statement_list (t, &list);
6365 /* Last pass: handle VLA firstprivates. */
6366 if (tcctx.cb.decl_map)
6367 for (c = gimple_omp_task_clauses (task_stmt); c; c = OMP_CLAUSE_CHAIN (c))
6368 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
6372 decl = OMP_CLAUSE_DECL (c);
6373 if (!is_variable_sized (decl))
6375 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
6378 f = (tree) n->value;
6379 f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
6380 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
6381 ind = DECL_VALUE_EXPR (decl);
6382 gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
6383 gcc_assert (DECL_P (TREE_OPERAND (ind, 0)));
6384 n = splay_tree_lookup (ctx->sfield_map,
6385 (splay_tree_key) TREE_OPERAND (ind, 0));
6386 sf = (tree) n->value;
6387 sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
6388 src = build_fold_indirect_ref_loc (loc, sarg);
6389 src = build3 (COMPONENT_REF, TREE_TYPE (sf), src, sf, NULL);
6390 src = build_fold_indirect_ref_loc (loc, src);
6391 dst = build_fold_indirect_ref_loc (loc, arg);
6392 dst = build3 (COMPONENT_REF, TREE_TYPE (f), dst, f, NULL);
6393 t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
6394 append_to_statement_list (t, &list);
6395 n = splay_tree_lookup (ctx->field_map,
6396 (splay_tree_key) TREE_OPERAND (ind, 0));
6397 df = (tree) n->value;
6398 df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
6399 ptr = build_fold_indirect_ref_loc (loc, arg);
6400 ptr = build3 (COMPONENT_REF, TREE_TYPE (df), ptr, df, NULL);
6401 t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
6402 build_fold_addr_expr_loc (loc, dst));
6403 append_to_statement_list (t, &list);
6406 t = build1 (RETURN_EXPR, void_type_node, NULL);
6407 append_to_statement_list (t, &list);
6409 if (tcctx.cb.decl_map)
6410 pointer_map_destroy (tcctx.cb.decl_map);
6411 pop_gimplify_context (NULL);
6412 BIND_EXPR_BODY (bind) = list;
6414 current_function_decl = ctx->cb.src_fn;
6417 /* Lower the OpenMP parallel or task directive in the current statement
6418 in GSI_P. CTX holds context information for the directive. */
6421 lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6425 gimple stmt = gsi_stmt (*gsi_p);
6426 gimple par_bind, bind;
6427 gimple_seq par_body, olist, ilist, par_olist, par_ilist, new_body;
6428 struct gimplify_ctx gctx;
6429 location_t loc = gimple_location (stmt);
6431 clauses = gimple_omp_taskreg_clauses (stmt);
6432 par_bind = gimple_seq_first_stmt (gimple_omp_body (stmt));
6433 par_body = gimple_bind_body (par_bind);
6434 child_fn = ctx->cb.dst_fn;
6435 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL
6436 && !gimple_omp_parallel_combined_p (stmt))
6438 struct walk_stmt_info wi;
6441 memset (&wi, 0, sizeof (wi));
6444 walk_gimple_seq (par_body, check_combined_parallel, NULL, &wi);
6446 gimple_omp_parallel_set_combined_p (stmt, true);
6448 if (ctx->srecord_type)
6449 create_task_copyfn (stmt, ctx);
6451 push_gimplify_context (&gctx);
6455 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
6456 lower_omp (par_body, ctx);
6457 if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
6458 lower_reduction_clauses (clauses, &par_olist, ctx);
6460 /* Declare all the variables created by mapping and the variables
6461 declared in the scope of the parallel body. */
6462 record_vars_into (ctx->block_vars, child_fn);
6463 record_vars_into (gimple_bind_vars (par_bind), child_fn);
6465 if (ctx->record_type)
6468 = create_tmp_var (ctx->srecord_type ? ctx->srecord_type
6469 : ctx->record_type, ".omp_data_o");
6470 TREE_ADDRESSABLE (ctx->sender_decl) = 1;
6471 gimple_omp_taskreg_set_data_arg (stmt, ctx->sender_decl);
6476 lower_send_clauses (clauses, &ilist, &olist, ctx);
6477 lower_send_shared_vars (&ilist, &olist, ctx);
6479 /* Once all the expansions are done, sequence all the different
6480 fragments inside gimple_omp_body. */
6484 if (ctx->record_type)
6486 t = build_fold_addr_expr_loc (loc, ctx->sender_decl);
6487 /* fixup_child_record_type might have changed receiver_decl's type. */
6488 t = fold_convert_loc (loc, TREE_TYPE (ctx->receiver_decl), t);
6489 gimple_seq_add_stmt (&new_body,
6490 gimple_build_assign (ctx->receiver_decl, t));
6493 gimple_seq_add_seq (&new_body, par_ilist);
6494 gimple_seq_add_seq (&new_body, par_body);
6495 gimple_seq_add_seq (&new_body, par_olist);
6496 new_body = maybe_catch_exception (new_body);
6497 gimple_seq_add_stmt (&new_body, gimple_build_omp_return (false));
6498 gimple_omp_set_body (stmt, new_body);
6500 bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
6501 gimple_bind_add_stmt (bind, stmt);
6504 gimple_seq_add_stmt (&ilist, bind);
6505 gimple_seq_add_seq (&ilist, olist);
6506 bind = gimple_build_bind (NULL, ilist, NULL);
6509 gsi_replace (gsi_p, bind, true);
6511 pop_gimplify_context (NULL);
6514 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6515 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6516 of OpenMP context, but with task_shared_vars set. */
6519 lower_omp_regimplify_p (tree *tp, int *walk_subtrees,
6524 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6525 if (TREE_CODE (t) == VAR_DECL && data == NULL && DECL_HAS_VALUE_EXPR_P (t))
6528 if (task_shared_vars
6530 && bitmap_bit_p (task_shared_vars, DECL_UID (t)))
6533 /* If a global variable has been privatized, TREE_CONSTANT on
6534 ADDR_EXPR might be wrong. */
6535 if (data == NULL && TREE_CODE (t) == ADDR_EXPR)
6536 recompute_tree_invariant_for_addr_expr (t);
6538 *walk_subtrees = !TYPE_P (t) && !DECL_P (t);
6543 lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx)
6545 gimple stmt = gsi_stmt (*gsi_p);
6546 struct walk_stmt_info wi;
6548 if (gimple_has_location (stmt))
6549 input_location = gimple_location (stmt);
6551 if (task_shared_vars)
6552 memset (&wi, '\0', sizeof (wi));
6554 /* If we have issued syntax errors, avoid doing any heavy lifting.
6555 Just replace the OpenMP directives with a NOP to avoid
6556 confusing RTL expansion. */
6557 if (errorcount && is_gimple_omp (stmt))
6559 gsi_replace (gsi_p, gimple_build_nop (), true);
6563 switch (gimple_code (stmt))
6566 if ((ctx || task_shared_vars)
6567 && (walk_tree (gimple_cond_lhs_ptr (stmt), lower_omp_regimplify_p,
6568 ctx ? NULL : &wi, NULL)
6569 || walk_tree (gimple_cond_rhs_ptr (stmt), lower_omp_regimplify_p,
6570 ctx ? NULL : &wi, NULL)))
6571 gimple_regimplify_operands (stmt, gsi_p);
6574 lower_omp (gimple_catch_handler (stmt), ctx);
6576 case GIMPLE_EH_FILTER:
6577 lower_omp (gimple_eh_filter_failure (stmt), ctx);
6580 lower_omp (gimple_try_eval (stmt), ctx);
6581 lower_omp (gimple_try_cleanup (stmt), ctx);
6584 lower_omp (gimple_bind_body (stmt), ctx);
6586 case GIMPLE_OMP_PARALLEL:
6587 case GIMPLE_OMP_TASK:
6588 ctx = maybe_lookup_ctx (stmt);
6589 lower_omp_taskreg (gsi_p, ctx);
6591 case GIMPLE_OMP_FOR:
6592 ctx = maybe_lookup_ctx (stmt);
6594 lower_omp_for (gsi_p, ctx);
6596 case GIMPLE_OMP_SECTIONS:
6597 ctx = maybe_lookup_ctx (stmt);
6599 lower_omp_sections (gsi_p, ctx);
6601 case GIMPLE_OMP_SINGLE:
6602 ctx = maybe_lookup_ctx (stmt);
6604 lower_omp_single (gsi_p, ctx);
6606 case GIMPLE_OMP_MASTER:
6607 ctx = maybe_lookup_ctx (stmt);
6609 lower_omp_master (gsi_p, ctx);
6611 case GIMPLE_OMP_ORDERED:
6612 ctx = maybe_lookup_ctx (stmt);
6614 lower_omp_ordered (gsi_p, ctx);
6616 case GIMPLE_OMP_CRITICAL:
6617 ctx = maybe_lookup_ctx (stmt);
6619 lower_omp_critical (gsi_p, ctx);
6621 case GIMPLE_OMP_ATOMIC_LOAD:
6622 if ((ctx || task_shared_vars)
6623 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt),
6624 lower_omp_regimplify_p, ctx ? NULL : &wi, NULL))
6625 gimple_regimplify_operands (stmt, gsi_p);
6628 if ((ctx || task_shared_vars)
6629 && walk_gimple_op (stmt, lower_omp_regimplify_p,
6631 gimple_regimplify_operands (stmt, gsi_p);
6637 lower_omp (gimple_seq body, omp_context *ctx)
6639 location_t saved_location = input_location;
6640 gimple_stmt_iterator gsi = gsi_start (body);
6641 for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
6642 lower_omp_1 (&gsi, ctx);
6643 input_location = saved_location;
6646 /* Main entry point. */
6649 execute_lower_omp (void)
6653 /* This pass always runs, to provide PROP_gimple_lomp.
6654 But there is nothing to do unless -fopenmp is given. */
6655 if (flag_openmp == 0)
6658 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
6659 delete_omp_context);
6661 body = gimple_body (current_function_decl);
6662 scan_omp (body, NULL);
6663 gcc_assert (taskreg_nesting_level == 0);
6665 if (all_contexts->root)
6667 struct gimplify_ctx gctx;
6669 if (task_shared_vars)
6670 push_gimplify_context (&gctx);
6671 lower_omp (body, NULL);
6672 if (task_shared_vars)
6673 pop_gimplify_context (NULL);
6678 splay_tree_delete (all_contexts);
6679 all_contexts = NULL;
6681 BITMAP_FREE (task_shared_vars);
6685 struct gimple_opt_pass pass_lower_omp =
6689 "omplower", /* name */
6691 execute_lower_omp, /* execute */
6694 0, /* static_pass_number */
6695 TV_NONE, /* tv_id */
6696 PROP_gimple_any, /* properties_required */
6697 PROP_gimple_lomp, /* properties_provided */
6698 0, /* properties_destroyed */
6699 0, /* todo_flags_start */
6700 TODO_dump_func /* todo_flags_finish */
6704 /* The following is a utility to diagnose OpenMP structured block violations.
6705 It is not part of the "omplower" pass, as that's invoked too late. It
6706 should be invoked by the respective front ends after gimplification. */
6708 static splay_tree all_labels;
6710 /* Check for mismatched contexts and generate an error if needed. Return
6711 true if an error is detected. */
6714 diagnose_sb_0 (gimple_stmt_iterator *gsi_p,
6715 gimple branch_ctx, gimple label_ctx)
6717 if (label_ctx == branch_ctx)
6722 Previously we kept track of the label's entire context in diagnose_sb_[12]
6723 so we could traverse it and issue a correct "exit" or "enter" error
6724 message upon a structured block violation.
6726 We built the context by building a list with tree_cons'ing, but there is
6727 no easy counterpart in gimple tuples. It seems like far too much work
6728 for issuing exit/enter error messages. If someone really misses the
6729 distinct error message... patches welcome.
6733 /* Try to avoid confusing the user by producing and error message
6734 with correct "exit" or "enter" verbiage. We prefer "exit"
6735 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
6736 if (branch_ctx == NULL)
6742 if (TREE_VALUE (label_ctx) == branch_ctx)
6747 label_ctx = TREE_CHAIN (label_ctx);
6752 error ("invalid exit from OpenMP structured block");
6754 error ("invalid entry to OpenMP structured block");
6757 /* If it's obvious we have an invalid entry, be specific about the error. */
6758 if (branch_ctx == NULL)
6759 error ("invalid entry to OpenMP structured block");
6761 /* Otherwise, be vague and lazy, but efficient. */
6762 error ("invalid branch to/from an OpenMP structured block");
6764 gsi_replace (gsi_p, gimple_build_nop (), false);
6768 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
6769 where each label is found. */
6772 diagnose_sb_1 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
6773 struct walk_stmt_info *wi)
6775 gimple context = (gimple) wi->info;
6776 gimple inner_context;
6777 gimple stmt = gsi_stmt (*gsi_p);
6779 *handled_ops_p = true;
6781 switch (gimple_code (stmt))
6785 case GIMPLE_OMP_PARALLEL:
6786 case GIMPLE_OMP_TASK:
6787 case GIMPLE_OMP_SECTIONS:
6788 case GIMPLE_OMP_SINGLE:
6789 case GIMPLE_OMP_SECTION:
6790 case GIMPLE_OMP_MASTER:
6791 case GIMPLE_OMP_ORDERED:
6792 case GIMPLE_OMP_CRITICAL:
6793 /* The minimal context here is just the current OMP construct. */
6794 inner_context = stmt;
6795 wi->info = inner_context;
6796 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
6800 case GIMPLE_OMP_FOR:
6801 inner_context = stmt;
6802 wi->info = inner_context;
6803 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
6805 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
6806 diagnose_sb_1, NULL, wi);
6807 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_1, NULL, wi);
6812 splay_tree_insert (all_labels, (splay_tree_key) gimple_label_label (stmt),
6813 (splay_tree_value) context);
6823 /* Pass 2: Check each branch and see if its context differs from that of
6824 the destination label's context. */
6827 diagnose_sb_2 (gimple_stmt_iterator *gsi_p, bool *handled_ops_p,
6828 struct walk_stmt_info *wi)
6830 gimple context = (gimple) wi->info;
6832 gimple stmt = gsi_stmt (*gsi_p);
6834 *handled_ops_p = true;
6836 switch (gimple_code (stmt))
6840 case GIMPLE_OMP_PARALLEL:
6841 case GIMPLE_OMP_TASK:
6842 case GIMPLE_OMP_SECTIONS:
6843 case GIMPLE_OMP_SINGLE:
6844 case GIMPLE_OMP_SECTION:
6845 case GIMPLE_OMP_MASTER:
6846 case GIMPLE_OMP_ORDERED:
6847 case GIMPLE_OMP_CRITICAL:
6849 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
6853 case GIMPLE_OMP_FOR:
6855 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
6857 walk_gimple_seq (gimple_omp_for_pre_body (stmt),
6858 diagnose_sb_2, NULL, wi);
6859 walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
6865 tree lab = gimple_goto_dest (stmt);
6866 if (TREE_CODE (lab) != LABEL_DECL)
6869 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
6870 diagnose_sb_0 (gsi_p, context, n ? (gimple) n->value : NULL);
6877 for (i = 0; i < gimple_switch_num_labels (stmt); ++i)
6879 tree lab = CASE_LABEL (gimple_switch_label (stmt, i));
6880 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
6881 if (n && diagnose_sb_0 (gsi_p, context, (gimple) n->value))
6888 diagnose_sb_0 (gsi_p, context, NULL);
6899 diagnose_omp_structured_block_errors (tree fndecl)
6901 tree save_current = current_function_decl;
6902 struct walk_stmt_info wi;
6903 struct function *old_cfun = cfun;
6904 gimple_seq body = gimple_body (fndecl);
6906 current_function_decl = fndecl;
6907 set_cfun (DECL_STRUCT_FUNCTION (fndecl));
6909 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
6911 memset (&wi, 0, sizeof (wi));
6912 walk_gimple_seq (body, diagnose_sb_1, NULL, &wi);
6914 memset (&wi, 0, sizeof (wi));
6915 wi.want_locations = true;
6916 walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
6918 splay_tree_delete (all_labels);
6921 set_cfun (old_cfun);
6922 current_function_decl = save_current;
6925 #include "gt-omp-low.h"