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 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 2, 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 COPYING. If not, write to the Free
22 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
27 #include "coretypes.h"
31 #include "tree-gimple.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"
47 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
48 phases. The first phase scans the function looking for OMP statements
49 and then for variables that must be replaced to satisfy data sharing
50 clauses. The second phase expands code for the constructs, as well as
51 re-gimplifying things when variables have been replaced with complex
54 Final code generation is done by pass_expand_omp. The flowgraph is
55 scanned for parallel regions which are then moved to a new
56 function, to be invoked by the thread library. */
58 /* Context structure. Used to store information about each parallel
59 directive in the code. */
61 typedef struct omp_context
63 /* This field must be at the beginning, as we do "inheritance": Some
64 callback functions for tree-inline.c (e.g., omp_copy_decl)
65 receive a copy_body_data pointer that is up-casted to an
66 omp_context pointer. */
69 /* The tree of contexts corresponding to the encountered constructs. */
70 struct omp_context *outer;
73 /* Map variables to fields in a structure that allows communication
74 between sending and receiving threads. */
80 /* A chain of variables to add to the top-level block surrounding the
81 construct. In the case of a parallel, this is in the child function. */
84 /* What to do with variables with implicitly determined sharing
86 enum omp_clause_default_kind default_kind;
88 /* Nesting depth of this context. Used to beautify error messages re
89 invalid gotos. The outermost ctx is depth 1, with depth 0 being
90 reserved for the main body of the function. */
93 /* True if this parallel directive is nested within another. */
98 /* A structure describing the main elements of a parallel loop. */
102 tree v, n1, n2, step, chunk_size, for_stmt;
103 enum tree_code cond_code;
105 bool have_nowait, have_ordered;
106 enum omp_clause_schedule_kind sched_kind;
110 static splay_tree all_contexts;
111 static int parallel_nesting_level;
112 struct omp_region *root_omp_region;
114 static void scan_omp (tree *, omp_context *);
115 static void lower_omp (tree *, omp_context *);
116 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
117 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
119 /* Find an OpenMP clause of type KIND within CLAUSES. */
122 find_omp_clause (tree clauses, enum tree_code kind)
124 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
125 if (OMP_CLAUSE_CODE (clauses) == kind)
131 /* Return true if CTX is for an omp parallel. */
134 is_parallel_ctx (omp_context *ctx)
136 return TREE_CODE (ctx->stmt) == OMP_PARALLEL;
140 /* Return true if REGION is a combined parallel+workshare region. */
143 is_combined_parallel (struct omp_region *region)
145 return region->is_combined_parallel;
149 /* Extract the header elements of parallel loop FOR_STMT and store
153 extract_omp_for_data (tree for_stmt, struct omp_for_data *fd)
157 fd->for_stmt = for_stmt;
160 t = OMP_FOR_INIT (for_stmt);
161 gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
162 fd->v = GIMPLE_STMT_OPERAND (t, 0);
163 gcc_assert (DECL_P (fd->v));
164 gcc_assert (TREE_CODE (TREE_TYPE (fd->v)) == INTEGER_TYPE);
165 fd->n1 = GIMPLE_STMT_OPERAND (t, 1);
167 t = OMP_FOR_COND (for_stmt);
168 fd->cond_code = TREE_CODE (t);
169 gcc_assert (TREE_OPERAND (t, 0) == fd->v);
170 fd->n2 = TREE_OPERAND (t, 1);
171 switch (fd->cond_code)
177 fd->n2 = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->n2), fd->n2,
178 build_int_cst (TREE_TYPE (fd->n2), 1));
179 fd->cond_code = LT_EXPR;
182 fd->n2 = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->n2), fd->n2,
183 build_int_cst (TREE_TYPE (fd->n2), 1));
184 fd->cond_code = GT_EXPR;
190 t = OMP_FOR_INCR (fd->for_stmt);
191 gcc_assert (TREE_CODE (t) == GIMPLE_MODIFY_STMT);
192 gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == fd->v);
193 t = GIMPLE_STMT_OPERAND (t, 1);
194 gcc_assert (TREE_OPERAND (t, 0) == fd->v);
195 switch (TREE_CODE (t))
198 fd->step = TREE_OPERAND (t, 1);
201 fd->step = TREE_OPERAND (t, 1);
202 fd->step = fold_build1 (NEGATE_EXPR, TREE_TYPE (fd->step), fd->step);
208 fd->have_nowait = fd->have_ordered = false;
209 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
210 fd->chunk_size = NULL_TREE;
212 for (t = OMP_FOR_CLAUSES (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
213 switch (OMP_CLAUSE_CODE (t))
215 case OMP_CLAUSE_NOWAIT:
216 fd->have_nowait = true;
218 case OMP_CLAUSE_ORDERED:
219 fd->have_ordered = true;
221 case OMP_CLAUSE_SCHEDULE:
222 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
223 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
229 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
230 gcc_assert (fd->chunk_size == NULL);
231 else if (fd->chunk_size == NULL)
233 /* We only need to compute a default chunk size for ordered
234 static loops and dynamic loops. */
235 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC || fd->have_ordered)
236 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
237 ? integer_zero_node : integer_one_node;
242 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
243 is the immediate dominator of PAR_ENTRY_BB, return true if there
244 are no data dependencies that would prevent expanding the parallel
245 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
247 When expanding a combined parallel+workshare region, the call to
248 the child function may need additional arguments in the case of
249 OMP_FOR regions. In some cases, these arguments are computed out
250 of variables passed in from the parent to the child via 'struct
251 .omp_data_s'. For instance:
253 #pragma omp parallel for schedule (guided, i * 4)
258 # BLOCK 2 (PAR_ENTRY_BB)
260 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
262 # BLOCK 3 (WS_ENTRY_BB)
263 .omp_data_i = &.omp_data_o;
264 D.1667 = .omp_data_i->i;
266 #pragma omp for schedule (guided, D.1598)
268 When we outline the parallel region, the call to the child function
269 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
270 that value is computed *after* the call site. So, in principle we
271 cannot do the transformation.
273 To see whether the code in WS_ENTRY_BB blocks the combined
274 parallel+workshare call, we collect all the variables used in the
275 OMP_FOR header check whether they appear on the LHS of any
276 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
279 FIXME. If we had the SSA form built at this point, we could merely
280 hoist the code in block 3 into block 2 and be done with it. But at
281 this point we don't have dataflow information and though we could
282 hack something up here, it is really not worth the aggravation. */
285 workshare_safe_to_combine_p (basic_block par_entry_bb, basic_block ws_entry_bb)
287 struct omp_for_data fd;
288 tree par_stmt, ws_stmt;
290 par_stmt = last_stmt (par_entry_bb);
291 ws_stmt = last_stmt (ws_entry_bb);
293 if (TREE_CODE (ws_stmt) == OMP_SECTIONS)
296 gcc_assert (TREE_CODE (ws_stmt) == OMP_FOR);
298 extract_omp_for_data (ws_stmt, &fd);
300 /* FIXME. We give up too easily here. If any of these arguments
301 are not constants, they will likely involve variables that have
302 been mapped into fields of .omp_data_s for sharing with the child
303 function. With appropriate data flow, it would be possible to
305 if (!is_gimple_min_invariant (fd.n1)
306 || !is_gimple_min_invariant (fd.n2)
307 || !is_gimple_min_invariant (fd.step)
308 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
315 /* Collect additional arguments needed to emit a combined
316 parallel+workshare call. WS_STMT is the workshare directive being
320 get_ws_args_for (tree ws_stmt)
324 if (TREE_CODE (ws_stmt) == OMP_FOR)
326 struct omp_for_data fd;
329 extract_omp_for_data (ws_stmt, &fd);
334 t = fold_convert (long_integer_type_node, fd.chunk_size);
335 ws_args = tree_cons (NULL, t, ws_args);
338 t = fold_convert (long_integer_type_node, fd.step);
339 ws_args = tree_cons (NULL, t, ws_args);
341 t = fold_convert (long_integer_type_node, fd.n2);
342 ws_args = tree_cons (NULL, t, ws_args);
344 t = fold_convert (long_integer_type_node, fd.n1);
345 ws_args = tree_cons (NULL, t, ws_args);
349 else if (TREE_CODE (ws_stmt) == OMP_SECTIONS)
351 basic_block bb = bb_for_stmt (ws_stmt);
352 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs));
353 t = tree_cons (NULL, t, NULL);
361 /* Discover whether REGION is a combined parallel+workshare region. */
364 determine_parallel_type (struct omp_region *region)
366 basic_block par_entry_bb, par_exit_bb;
367 basic_block ws_entry_bb, ws_exit_bb;
369 if (region == NULL || region->inner == NULL
370 || region->exit == NULL || region->inner->exit == NULL)
373 /* We only support parallel+for and parallel+sections. */
374 if (region->type != OMP_PARALLEL
375 || (region->inner->type != OMP_FOR
376 && region->inner->type != OMP_SECTIONS))
379 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
380 WS_EXIT_BB -> PAR_EXIT_BB. */
381 par_entry_bb = region->entry;
382 par_exit_bb = region->exit;
383 ws_entry_bb = region->inner->entry;
384 ws_exit_bb = region->inner->exit;
386 if (single_succ (par_entry_bb) == ws_entry_bb
387 && single_succ (ws_exit_bb) == par_exit_bb
388 && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb))
390 tree ws_stmt = last_stmt (region->inner->entry);
392 if (region->inner->type == OMP_FOR)
394 /* If this is a combined parallel loop, we need to determine
395 whether or not to use the combined library calls. There
396 are two cases where we do not apply the transformation:
397 static loops and any kind of ordered loop. In the first
398 case, we already open code the loop so there is no need
399 to do anything else. In the latter case, the combined
400 parallel loop call would still need extra synchronization
401 to implement ordered semantics, so there would not be any
402 gain in using the combined call. */
403 tree clauses = OMP_FOR_CLAUSES (ws_stmt);
404 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
406 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
407 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
409 region->is_combined_parallel = false;
410 region->inner->is_combined_parallel = false;
415 region->is_combined_parallel = true;
416 region->inner->is_combined_parallel = true;
417 region->ws_args = get_ws_args_for (ws_stmt);
422 /* Return true if EXPR is variable sized. */
425 is_variable_sized (tree expr)
427 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
430 /* Return true if DECL is a reference type. */
433 is_reference (tree decl)
435 return lang_hooks.decls.omp_privatize_by_reference (decl);
438 /* Lookup variables in the decl or field splay trees. The "maybe" form
439 allows for the variable form to not have been entered, otherwise we
440 assert that the variable must have been entered. */
443 lookup_decl (tree var, omp_context *ctx)
446 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
451 maybe_lookup_decl (tree var, omp_context *ctx)
454 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
455 return n ? *n : NULL_TREE;
459 lookup_field (tree var, omp_context *ctx)
462 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
463 return (tree) n->value;
467 maybe_lookup_field (tree var, omp_context *ctx)
470 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
471 return n ? (tree) n->value : NULL_TREE;
474 /* Return true if DECL should be copied by pointer. SHARED_P is true
475 if DECL is to be shared. */
478 use_pointer_for_field (tree decl, bool shared_p)
480 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
483 /* We can only use copy-in/copy-out semantics for shared variables
484 when we know the value is not accessible from an outer scope. */
487 /* ??? Trivially accessible from anywhere. But why would we even
488 be passing an address in this case? Should we simply assert
489 this to be false, or should we have a cleanup pass that removes
490 these from the list of mappings? */
491 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
494 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
495 without analyzing the expression whether or not its location
496 is accessible to anyone else. In the case of nested parallel
497 regions it certainly may be. */
498 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
501 /* Do not use copy-in/copy-out for variables that have their
503 if (TREE_ADDRESSABLE (decl))
510 /* Construct a new automatic decl similar to VAR. */
513 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
515 tree copy = build_decl (VAR_DECL, name, type);
517 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
518 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
519 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
520 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
521 TREE_USED (copy) = 1;
522 DECL_CONTEXT (copy) = current_function_decl;
523 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
525 TREE_CHAIN (copy) = ctx->block_vars;
526 ctx->block_vars = copy;
532 omp_copy_decl_1 (tree var, omp_context *ctx)
534 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
537 /* Build tree nodes to access the field for VAR on the receiver side. */
540 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
542 tree x, field = lookup_field (var, ctx);
544 /* If the receiver record type was remapped in the child function,
545 remap the field into the new record type. */
546 x = maybe_lookup_field (field, ctx);
550 x = build_fold_indirect_ref (ctx->receiver_decl);
551 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL);
553 x = build_fold_indirect_ref (x);
558 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
559 of a parallel, this is a component reference; for workshare constructs
560 this is some variable. */
563 build_outer_var_ref (tree var, omp_context *ctx)
567 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
569 else if (is_variable_sized (var))
571 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
572 x = build_outer_var_ref (x, ctx);
573 x = build_fold_indirect_ref (x);
575 else if (is_parallel_ctx (ctx))
577 bool by_ref = use_pointer_for_field (var, false);
578 x = build_receiver_ref (var, by_ref, ctx);
581 x = lookup_decl (var, ctx->outer);
582 else if (is_reference (var))
583 /* This can happen with orphaned constructs. If var is reference, it is
584 possible it is shared and as such valid. */
589 if (is_reference (var))
590 x = build_fold_indirect_ref (x);
595 /* Build tree nodes to access the field for VAR on the sender side. */
598 build_sender_ref (tree var, omp_context *ctx)
600 tree field = lookup_field (var, ctx);
601 return build3 (COMPONENT_REF, TREE_TYPE (field),
602 ctx->sender_decl, field, NULL);
605 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
608 install_var_field (tree var, bool by_ref, omp_context *ctx)
612 gcc_assert (!splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
614 type = TREE_TYPE (var);
616 type = build_pointer_type (type);
618 field = build_decl (FIELD_DECL, DECL_NAME (var), type);
620 /* Remember what variable this field was created for. This does have a
621 side effect of making dwarf2out ignore this member, so for helpful
622 debugging we clear it later in delete_omp_context. */
623 DECL_ABSTRACT_ORIGIN (field) = var;
625 insert_field_into_struct (ctx->record_type, field);
627 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
628 (splay_tree_value) field);
632 install_var_local (tree var, omp_context *ctx)
634 tree new_var = omp_copy_decl_1 (var, ctx);
635 insert_decl_map (&ctx->cb, var, new_var);
639 /* Adjust the replacement for DECL in CTX for the new context. This means
640 copying the DECL_VALUE_EXPR, and fixing up the type. */
643 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
647 new_decl = lookup_decl (decl, ctx);
649 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
651 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
652 && DECL_HAS_VALUE_EXPR_P (decl))
654 tree ve = DECL_VALUE_EXPR (decl);
655 walk_tree (&ve, copy_body_r, &ctx->cb, NULL);
656 SET_DECL_VALUE_EXPR (new_decl, ve);
657 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
660 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
662 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
663 if (size == error_mark_node)
664 size = TYPE_SIZE (TREE_TYPE (new_decl));
665 DECL_SIZE (new_decl) = size;
667 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
668 if (size == error_mark_node)
669 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
670 DECL_SIZE_UNIT (new_decl) = size;
674 /* The callback for remap_decl. Search all containing contexts for a
675 mapping of the variable; this avoids having to duplicate the splay
676 tree ahead of time. We know a mapping doesn't already exist in the
677 given context. Create new mappings to implement default semantics. */
680 omp_copy_decl (tree var, copy_body_data *cb)
682 omp_context *ctx = (omp_context *) cb;
685 if (TREE_CODE (var) == LABEL_DECL)
687 new_var = create_artificial_label ();
688 DECL_CONTEXT (new_var) = current_function_decl;
689 insert_decl_map (&ctx->cb, var, new_var);
693 while (!is_parallel_ctx (ctx))
698 new_var = maybe_lookup_decl (var, ctx);
703 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
706 return error_mark_node;
710 /* Return the parallel region associated with STMT. */
712 /* Debugging dumps for parallel regions. */
713 void dump_omp_region (FILE *, struct omp_region *, int);
714 void debug_omp_region (struct omp_region *);
715 void debug_all_omp_regions (void);
717 /* Dump the parallel region tree rooted at REGION. */
720 dump_omp_region (FILE *file, struct omp_region *region, int indent)
722 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
723 tree_code_name[region->type]);
726 dump_omp_region (file, region->inner, indent + 4);
730 fprintf (file, "%*sbb %d: OMP_CONTINUE\n", indent, "",
731 region->cont->index);
735 fprintf (file, "%*sbb %d: OMP_RETURN\n", indent, "",
736 region->exit->index);
738 fprintf (file, "%*s[no exit marker]\n", indent, "");
741 dump_omp_region (file, region->next, indent);
745 debug_omp_region (struct omp_region *region)
747 dump_omp_region (stderr, region, 0);
751 debug_all_omp_regions (void)
753 dump_omp_region (stderr, root_omp_region, 0);
757 /* Create a new parallel region starting at STMT inside region PARENT. */
760 new_omp_region (basic_block bb, enum tree_code type, struct omp_region *parent)
762 struct omp_region *region = xcalloc (1, sizeof (*region));
764 region->outer = parent;
770 /* This is a nested region. Add it to the list of inner
771 regions in PARENT. */
772 region->next = parent->inner;
773 parent->inner = region;
777 /* This is a toplevel region. Add it to the list of toplevel
778 regions in ROOT_OMP_REGION. */
779 region->next = root_omp_region;
780 root_omp_region = region;
786 /* Release the memory associated with the region tree rooted at REGION. */
789 free_omp_region_1 (struct omp_region *region)
791 struct omp_region *i, *n;
793 for (i = region->inner; i ; i = n)
796 free_omp_region_1 (i);
802 /* Release the memory for the entire omp region tree. */
805 free_omp_regions (void)
807 struct omp_region *r, *n;
808 for (r = root_omp_region; r ; r = n)
811 free_omp_region_1 (r);
813 root_omp_region = NULL;
817 /* Create a new context, with OUTER_CTX being the surrounding context. */
820 new_omp_context (tree stmt, omp_context *outer_ctx)
822 omp_context *ctx = XCNEW (omp_context);
824 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
825 (splay_tree_value) ctx);
830 ctx->outer = outer_ctx;
831 ctx->cb = outer_ctx->cb;
832 ctx->cb.block = NULL;
833 ctx->depth = outer_ctx->depth + 1;
837 ctx->cb.src_fn = current_function_decl;
838 ctx->cb.dst_fn = current_function_decl;
839 ctx->cb.src_node = cgraph_node (current_function_decl);
840 ctx->cb.dst_node = ctx->cb.src_node;
841 ctx->cb.src_cfun = cfun;
842 ctx->cb.copy_decl = omp_copy_decl;
843 ctx->cb.eh_region = -1;
844 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
848 ctx->cb.decl_map = pointer_map_create ();
853 /* Destroy a omp_context data structures. Called through the splay tree
854 value delete callback. */
857 delete_omp_context (splay_tree_value value)
859 omp_context *ctx = (omp_context *) value;
861 pointer_map_destroy (ctx->cb.decl_map);
864 splay_tree_delete (ctx->field_map);
866 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
867 it produces corrupt debug information. */
868 if (ctx->record_type)
871 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
872 DECL_ABSTRACT_ORIGIN (t) = NULL;
878 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
882 fixup_child_record_type (omp_context *ctx)
884 tree f, type = ctx->record_type;
886 /* ??? It isn't sufficient to just call remap_type here, because
887 variably_modified_type_p doesn't work the way we expect for
888 record types. Testing each field for whether it needs remapping
889 and creating a new record by hand works, however. */
890 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
891 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
895 tree name, new_fields = NULL;
897 type = lang_hooks.types.make_type (RECORD_TYPE);
898 name = DECL_NAME (TYPE_NAME (ctx->record_type));
899 name = build_decl (TYPE_DECL, name, type);
900 TYPE_NAME (type) = name;
902 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
904 tree new_f = copy_node (f);
905 DECL_CONTEXT (new_f) = type;
906 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
907 TREE_CHAIN (new_f) = new_fields;
910 /* Arrange to be able to look up the receiver field
911 given the sender field. */
912 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
913 (splay_tree_value) new_f);
915 TYPE_FIELDS (type) = nreverse (new_fields);
919 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
922 /* Instantiate decls as necessary in CTX to satisfy the data sharing
923 specified by CLAUSES. */
926 scan_sharing_clauses (tree clauses, omp_context *ctx)
929 bool scan_array_reductions = false;
931 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
935 switch (OMP_CLAUSE_CODE (c))
937 case OMP_CLAUSE_PRIVATE:
938 decl = OMP_CLAUSE_DECL (c);
939 if (!is_variable_sized (decl))
940 install_var_local (decl, ctx);
943 case OMP_CLAUSE_SHARED:
944 gcc_assert (is_parallel_ctx (ctx));
945 decl = OMP_CLAUSE_DECL (c);
946 gcc_assert (!is_variable_sized (decl));
947 by_ref = use_pointer_for_field (decl, true);
948 /* Global variables don't need to be copied,
949 the receiver side will use them directly. */
950 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
952 if (! TREE_READONLY (decl)
953 || TREE_ADDRESSABLE (decl)
955 || is_reference (decl))
957 install_var_field (decl, by_ref, ctx);
958 install_var_local (decl, ctx);
961 /* We don't need to copy const scalar vars back. */
962 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
965 case OMP_CLAUSE_LASTPRIVATE:
966 /* Let the corresponding firstprivate clause create
968 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
972 case OMP_CLAUSE_FIRSTPRIVATE:
973 case OMP_CLAUSE_REDUCTION:
974 decl = OMP_CLAUSE_DECL (c);
976 if (is_variable_sized (decl))
978 else if (is_parallel_ctx (ctx)
979 && ! is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
982 by_ref = use_pointer_for_field (decl, false);
983 install_var_field (decl, by_ref, ctx);
985 install_var_local (decl, ctx);
988 case OMP_CLAUSE_COPYPRIVATE:
990 scan_omp (&OMP_CLAUSE_DECL (c), ctx->outer);
993 case OMP_CLAUSE_COPYIN:
994 decl = OMP_CLAUSE_DECL (c);
995 by_ref = use_pointer_for_field (decl, false);
996 install_var_field (decl, by_ref, ctx);
999 case OMP_CLAUSE_DEFAULT:
1000 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1004 case OMP_CLAUSE_NUM_THREADS:
1005 case OMP_CLAUSE_SCHEDULE:
1007 scan_omp (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1010 case OMP_CLAUSE_NOWAIT:
1011 case OMP_CLAUSE_ORDERED:
1019 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1021 switch (OMP_CLAUSE_CODE (c))
1023 case OMP_CLAUSE_LASTPRIVATE:
1024 /* Let the corresponding firstprivate clause create
1026 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1030 case OMP_CLAUSE_PRIVATE:
1031 case OMP_CLAUSE_FIRSTPRIVATE:
1032 case OMP_CLAUSE_REDUCTION:
1033 decl = OMP_CLAUSE_DECL (c);
1034 if (is_variable_sized (decl))
1035 install_var_local (decl, ctx);
1036 fixup_remapped_decl (decl, ctx,
1037 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1038 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1039 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1040 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1041 scan_array_reductions = true;
1044 case OMP_CLAUSE_SHARED:
1045 decl = OMP_CLAUSE_DECL (c);
1046 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1047 fixup_remapped_decl (decl, ctx, false);
1050 case OMP_CLAUSE_COPYPRIVATE:
1051 case OMP_CLAUSE_COPYIN:
1052 case OMP_CLAUSE_DEFAULT:
1054 case OMP_CLAUSE_NUM_THREADS:
1055 case OMP_CLAUSE_SCHEDULE:
1056 case OMP_CLAUSE_NOWAIT:
1057 case OMP_CLAUSE_ORDERED:
1065 if (scan_array_reductions)
1066 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1067 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1068 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1070 scan_omp (&OMP_CLAUSE_REDUCTION_INIT (c), ctx);
1071 scan_omp (&OMP_CLAUSE_REDUCTION_MERGE (c), ctx);
1075 /* Create a new name for omp child function. Returns an identifier. */
1077 static GTY(()) unsigned int tmp_ompfn_id_num;
1080 create_omp_child_function_name (void)
1082 tree name = DECL_ASSEMBLER_NAME (current_function_decl);
1083 size_t len = IDENTIFIER_LENGTH (name);
1084 char *tmp_name, *prefix;
1086 prefix = alloca (len + sizeof ("_omp_fn"));
1087 memcpy (prefix, IDENTIFIER_POINTER (name), len);
1088 strcpy (prefix + len, "_omp_fn");
1089 #ifndef NO_DOT_IN_LABEL
1091 #elif !defined NO_DOLLAR_IN_LABEL
1094 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, tmp_ompfn_id_num++);
1095 return get_identifier (tmp_name);
1098 /* Build a decl for the omp child function. It'll not contain a body
1099 yet, just the bare decl. */
1102 create_omp_child_function (omp_context *ctx)
1104 tree decl, type, name, t;
1106 name = create_omp_child_function_name ();
1107 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1109 decl = build_decl (FUNCTION_DECL, name, type);
1110 decl = lang_hooks.decls.pushdecl (decl);
1112 ctx->cb.dst_fn = decl;
1114 TREE_STATIC (decl) = 1;
1115 TREE_USED (decl) = 1;
1116 DECL_ARTIFICIAL (decl) = 1;
1117 DECL_IGNORED_P (decl) = 0;
1118 TREE_PUBLIC (decl) = 0;
1119 DECL_UNINLINABLE (decl) = 1;
1120 DECL_EXTERNAL (decl) = 0;
1121 DECL_CONTEXT (decl) = NULL_TREE;
1122 DECL_INITIAL (decl) = make_node (BLOCK);
1124 t = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1125 DECL_ARTIFICIAL (t) = 1;
1126 DECL_IGNORED_P (t) = 1;
1127 DECL_RESULT (decl) = t;
1129 t = build_decl (PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1130 DECL_ARTIFICIAL (t) = 1;
1131 DECL_ARG_TYPE (t) = ptr_type_node;
1132 DECL_CONTEXT (t) = current_function_decl;
1134 DECL_ARGUMENTS (decl) = t;
1135 ctx->receiver_decl = t;
1137 /* Allocate memory for the function structure. The call to
1138 allocate_struct_function clobbers CFUN, so we need to restore
1140 allocate_struct_function (decl);
1141 DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (ctx->stmt);
1142 cfun->function_end_locus = EXPR_LOCATION (ctx->stmt);
1143 cfun = ctx->cb.src_cfun;
1147 /* Scan an OpenMP parallel directive. */
1150 scan_omp_parallel (tree *stmt_p, omp_context *outer_ctx)
1155 /* Ignore parallel directives with empty bodies, unless there
1156 are copyin clauses. */
1158 && empty_body_p (OMP_PARALLEL_BODY (*stmt_p))
1159 && find_omp_clause (OMP_CLAUSES (*stmt_p), OMP_CLAUSE_COPYIN) == NULL)
1161 *stmt_p = build_empty_stmt ();
1165 ctx = new_omp_context (*stmt_p, outer_ctx);
1166 if (parallel_nesting_level > 1)
1167 ctx->is_nested = true;
1168 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1169 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1170 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1171 name = create_tmp_var_name (".omp_data_s");
1172 name = build_decl (TYPE_DECL, name, ctx->record_type);
1173 TYPE_NAME (ctx->record_type) = name;
1174 create_omp_child_function (ctx);
1175 OMP_PARALLEL_FN (*stmt_p) = ctx->cb.dst_fn;
1177 scan_sharing_clauses (OMP_PARALLEL_CLAUSES (*stmt_p), ctx);
1178 scan_omp (&OMP_PARALLEL_BODY (*stmt_p), ctx);
1180 if (TYPE_FIELDS (ctx->record_type) == NULL)
1181 ctx->record_type = ctx->receiver_decl = NULL;
1184 layout_type (ctx->record_type);
1185 fixup_child_record_type (ctx);
1190 /* Scan an OpenMP loop directive. */
1193 scan_omp_for (tree *stmt_p, omp_context *outer_ctx)
1199 ctx = new_omp_context (stmt, outer_ctx);
1201 scan_sharing_clauses (OMP_FOR_CLAUSES (stmt), ctx);
1203 scan_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
1204 scan_omp (&OMP_FOR_INIT (stmt), ctx);
1205 scan_omp (&OMP_FOR_COND (stmt), ctx);
1206 scan_omp (&OMP_FOR_INCR (stmt), ctx);
1207 scan_omp (&OMP_FOR_BODY (stmt), ctx);
1210 /* Scan an OpenMP sections directive. */
1213 scan_omp_sections (tree *stmt_p, omp_context *outer_ctx)
1219 ctx = new_omp_context (stmt, outer_ctx);
1220 scan_sharing_clauses (OMP_SECTIONS_CLAUSES (stmt), ctx);
1221 scan_omp (&OMP_SECTIONS_BODY (stmt), ctx);
1224 /* Scan an OpenMP single directive. */
1227 scan_omp_single (tree *stmt_p, omp_context *outer_ctx)
1229 tree stmt = *stmt_p;
1233 ctx = new_omp_context (stmt, outer_ctx);
1234 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1235 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1236 name = create_tmp_var_name (".omp_copy_s");
1237 name = build_decl (TYPE_DECL, name, ctx->record_type);
1238 TYPE_NAME (ctx->record_type) = name;
1240 scan_sharing_clauses (OMP_SINGLE_CLAUSES (stmt), ctx);
1241 scan_omp (&OMP_SINGLE_BODY (stmt), ctx);
1243 if (TYPE_FIELDS (ctx->record_type) == NULL)
1244 ctx->record_type = NULL;
1246 layout_type (ctx->record_type);
1250 /* Check OpenMP nesting restrictions. */
1252 check_omp_nesting_restrictions (tree t, omp_context *ctx)
1254 switch (TREE_CODE (t))
1259 for (; ctx != NULL; ctx = ctx->outer)
1260 switch (TREE_CODE (ctx->stmt))
1267 warning (0, "work-sharing region may not be closely nested inside "
1268 "of work-sharing, critical, ordered or master region");
1277 for (; ctx != NULL; ctx = ctx->outer)
1278 switch (TREE_CODE (ctx->stmt))
1283 warning (0, "master region may not be closely nested inside "
1284 "of work-sharing region");
1293 for (; ctx != NULL; ctx = ctx->outer)
1294 switch (TREE_CODE (ctx->stmt))
1297 warning (0, "ordered region may not be closely nested inside "
1298 "of critical region");
1301 if (find_omp_clause (OMP_CLAUSES (ctx->stmt),
1302 OMP_CLAUSE_ORDERED) == NULL)
1303 warning (0, "ordered region must be closely nested inside "
1304 "a loop region with an ordered clause");
1313 for (; ctx != NULL; ctx = ctx->outer)
1314 if (TREE_CODE (ctx->stmt) == OMP_CRITICAL
1315 && OMP_CRITICAL_NAME (t) == OMP_CRITICAL_NAME (ctx->stmt))
1317 warning (0, "critical region may not be nested inside a critical "
1318 "region with the same name");
1328 /* Callback for walk_stmts used to scan for OpenMP directives at TP. */
1331 scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
1333 struct walk_stmt_info *wi = data;
1334 omp_context *ctx = wi->info;
1337 if (EXPR_HAS_LOCATION (t))
1338 input_location = EXPR_LOCATION (t);
1340 /* Check the OpenMP nesting restrictions. */
1341 if (OMP_DIRECTIVE_P (t) && ctx != NULL)
1342 check_omp_nesting_restrictions (t, ctx);
1345 switch (TREE_CODE (t))
1348 parallel_nesting_level++;
1349 scan_omp_parallel (tp, ctx);
1350 parallel_nesting_level--;
1354 scan_omp_for (tp, ctx);
1358 scan_omp_sections (tp, ctx);
1362 scan_omp_single (tp, ctx);
1369 ctx = new_omp_context (*tp, ctx);
1370 scan_omp (&OMP_BODY (*tp), ctx);
1378 for (var = BIND_EXPR_VARS (t); var ; var = TREE_CHAIN (var))
1379 insert_decl_map (&ctx->cb, var, var);
1388 *tp = remap_decl (t, &ctx->cb);
1392 if (ctx && TYPE_P (t))
1393 *tp = remap_type (t, &ctx->cb);
1394 else if (!DECL_P (t))
1403 /* Scan all the statements starting at STMT_P. CTX contains context
1404 information about the OpenMP directives and clauses found during
1408 scan_omp (tree *stmt_p, omp_context *ctx)
1410 location_t saved_location;
1411 struct walk_stmt_info wi;
1413 memset (&wi, 0, sizeof (wi));
1414 wi.callback = scan_omp_1;
1416 wi.want_bind_expr = (ctx != NULL);
1417 wi.want_locations = true;
1419 saved_location = input_location;
1420 walk_stmts (&wi, stmt_p);
1421 input_location = saved_location;
1424 /* Re-gimplification and code generation routines. */
1426 /* Build a call to GOMP_barrier. */
1429 build_omp_barrier (tree *stmt_list)
1431 tree t = build_call_expr (built_in_decls[BUILT_IN_GOMP_BARRIER], 0);
1432 gimplify_and_add (t, stmt_list);
1435 /* If a context was created for STMT when it was scanned, return it. */
1437 static omp_context *
1438 maybe_lookup_ctx (tree stmt)
1441 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
1442 return n ? (omp_context *) n->value : NULL;
1446 /* Find the mapping for DECL in CTX or the immediately enclosing
1447 context that has a mapping for DECL.
1449 If CTX is a nested parallel directive, we may have to use the decl
1450 mappings created in CTX's parent context. Suppose that we have the
1451 following parallel nesting (variable UIDs showed for clarity):
1454 #omp parallel shared(iD.1562) -> outer parallel
1455 iD.1562 = iD.1562 + 1;
1457 #omp parallel shared (iD.1562) -> inner parallel
1458 iD.1562 = iD.1562 - 1;
1460 Each parallel structure will create a distinct .omp_data_s structure
1461 for copying iD.1562 in/out of the directive:
1463 outer parallel .omp_data_s.1.i -> iD.1562
1464 inner parallel .omp_data_s.2.i -> iD.1562
1466 A shared variable mapping will produce a copy-out operation before
1467 the parallel directive and a copy-in operation after it. So, in
1468 this case we would have:
1471 .omp_data_o.1.i = iD.1562;
1472 #omp parallel shared(iD.1562) -> outer parallel
1473 .omp_data_i.1 = &.omp_data_o.1
1474 .omp_data_i.1->i = .omp_data_i.1->i + 1;
1476 .omp_data_o.2.i = iD.1562; -> **
1477 #omp parallel shared(iD.1562) -> inner parallel
1478 .omp_data_i.2 = &.omp_data_o.2
1479 .omp_data_i.2->i = .omp_data_i.2->i - 1;
1482 ** This is a problem. The symbol iD.1562 cannot be referenced
1483 inside the body of the outer parallel region. But since we are
1484 emitting this copy operation while expanding the inner parallel
1485 directive, we need to access the CTX structure of the outer
1486 parallel directive to get the correct mapping:
1488 .omp_data_o.2.i = .omp_data_i.1->i
1490 Since there may be other workshare or parallel directives enclosing
1491 the parallel directive, it may be necessary to walk up the context
1492 parent chain. This is not a problem in general because nested
1493 parallelism happens only rarely. */
1496 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1501 gcc_assert (ctx->is_nested);
1503 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1504 t = maybe_lookup_decl (decl, up);
1512 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
1513 in outer contexts. */
1516 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1522 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1523 t = maybe_lookup_decl (decl, up);
1525 return t ? t : decl;
1529 /* Construct the initialization value for reduction CLAUSE. */
1532 omp_reduction_init (tree clause, tree type)
1534 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
1541 case TRUTH_ORIF_EXPR:
1542 case TRUTH_XOR_EXPR:
1544 return fold_convert (type, integer_zero_node);
1547 case TRUTH_AND_EXPR:
1548 case TRUTH_ANDIF_EXPR:
1550 return fold_convert (type, integer_one_node);
1553 return fold_convert (type, integer_minus_one_node);
1556 if (SCALAR_FLOAT_TYPE_P (type))
1558 REAL_VALUE_TYPE max, min;
1559 if (HONOR_INFINITIES (TYPE_MODE (type)))
1562 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
1565 real_maxval (&min, 1, TYPE_MODE (type));
1566 return build_real (type, min);
1570 gcc_assert (INTEGRAL_TYPE_P (type));
1571 return TYPE_MIN_VALUE (type);
1575 if (SCALAR_FLOAT_TYPE_P (type))
1577 REAL_VALUE_TYPE max;
1578 if (HONOR_INFINITIES (TYPE_MODE (type)))
1581 real_maxval (&max, 0, TYPE_MODE (type));
1582 return build_real (type, max);
1586 gcc_assert (INTEGRAL_TYPE_P (type));
1587 return TYPE_MAX_VALUE (type);
1595 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
1596 from the receiver (aka child) side and initializers for REFERENCE_TYPE
1597 private variables. Initialization statements go in ILIST, while calls
1598 to destructors go in DLIST. */
1601 lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
1604 tree_stmt_iterator diter;
1605 tree c, dtor, copyin_seq, x, ptr;
1606 bool copyin_by_ref = false;
1607 bool lastprivate_firstprivate = false;
1610 *dlist = alloc_stmt_list ();
1611 diter = tsi_start (*dlist);
1614 /* Do all the fixed sized types in the first pass, and the variable sized
1615 types in the second pass. This makes sure that the scalar arguments to
1616 the variable sized types are processed before we use them in the
1617 variable sized operations. */
1618 for (pass = 0; pass < 2; ++pass)
1620 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1622 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
1628 case OMP_CLAUSE_PRIVATE:
1629 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
1632 case OMP_CLAUSE_SHARED:
1633 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
1635 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
1638 case OMP_CLAUSE_FIRSTPRIVATE:
1639 case OMP_CLAUSE_COPYIN:
1640 case OMP_CLAUSE_REDUCTION:
1642 case OMP_CLAUSE_LASTPRIVATE:
1643 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1645 lastprivate_firstprivate = true;
1654 new_var = var = OMP_CLAUSE_DECL (c);
1655 if (c_kind != OMP_CLAUSE_COPYIN)
1656 new_var = lookup_decl (var, ctx);
1658 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
1663 else if (is_variable_sized (var))
1665 /* For variable sized types, we need to allocate the
1666 actual storage here. Call alloca and store the
1667 result in the pointer decl that we created elsewhere. */
1671 ptr = DECL_VALUE_EXPR (new_var);
1672 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
1673 ptr = TREE_OPERAND (ptr, 0);
1674 gcc_assert (DECL_P (ptr));
1676 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
1677 x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
1678 x = fold_convert (TREE_TYPE (ptr), x);
1679 x = build_gimple_modify_stmt (ptr, x);
1680 gimplify_and_add (x, ilist);
1682 else if (is_reference (var))
1684 /* For references that are being privatized for Fortran,
1685 allocate new backing storage for the new pointer
1686 variable. This allows us to avoid changing all the
1687 code that expects a pointer to something that expects
1688 a direct variable. Note that this doesn't apply to
1689 C++, since reference types are disallowed in data
1690 sharing clauses there, except for NRV optimized
1695 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
1696 if (TREE_CONSTANT (x))
1698 const char *name = NULL;
1699 if (DECL_NAME (var))
1700 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
1702 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
1704 gimple_add_tmp_var (x);
1705 x = build_fold_addr_expr_with_type (x, TREE_TYPE (new_var));
1709 x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
1710 x = fold_convert (TREE_TYPE (new_var), x);
1713 x = build_gimple_modify_stmt (new_var, x);
1714 gimplify_and_add (x, ilist);
1716 new_var = build_fold_indirect_ref (new_var);
1718 else if (c_kind == OMP_CLAUSE_REDUCTION
1719 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1727 switch (OMP_CLAUSE_CODE (c))
1729 case OMP_CLAUSE_SHARED:
1730 /* Shared global vars are just accessed directly. */
1731 if (is_global_var (new_var))
1733 /* Set up the DECL_VALUE_EXPR for shared variables now. This
1734 needs to be delayed until after fixup_child_record_type so
1735 that we get the correct type during the dereference. */
1736 by_ref = use_pointer_for_field (var, true);
1737 x = build_receiver_ref (var, by_ref, ctx);
1738 SET_DECL_VALUE_EXPR (new_var, x);
1739 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
1741 /* ??? If VAR is not passed by reference, and the variable
1742 hasn't been initialized yet, then we'll get a warning for
1743 the store into the omp_data_s structure. Ideally, we'd be
1744 able to notice this and not store anything at all, but
1745 we're generating code too early. Suppress the warning. */
1747 TREE_NO_WARNING (var) = 1;
1750 case OMP_CLAUSE_LASTPRIVATE:
1751 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1755 case OMP_CLAUSE_PRIVATE:
1756 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var);
1758 gimplify_and_add (x, ilist);
1762 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
1766 gimplify_stmt (&dtor);
1767 tsi_link_before (&diter, dtor, TSI_SAME_STMT);
1771 case OMP_CLAUSE_FIRSTPRIVATE:
1772 x = build_outer_var_ref (var, ctx);
1773 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
1774 gimplify_and_add (x, ilist);
1778 case OMP_CLAUSE_COPYIN:
1779 by_ref = use_pointer_for_field (var, false);
1780 x = build_receiver_ref (var, by_ref, ctx);
1781 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
1782 append_to_statement_list (x, ©in_seq);
1783 copyin_by_ref |= by_ref;
1786 case OMP_CLAUSE_REDUCTION:
1787 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1789 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), ilist);
1790 OMP_CLAUSE_REDUCTION_INIT (c) = NULL;
1794 x = omp_reduction_init (c, TREE_TYPE (new_var));
1795 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
1796 x = build_gimple_modify_stmt (new_var, x);
1797 gimplify_and_add (x, ilist);
1807 /* The copyin sequence is not to be executed by the main thread, since
1808 that would result in self-copies. Perhaps not visible to scalars,
1809 but it certainly is to C++ operator=. */
1812 x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
1813 x = build2 (NE_EXPR, boolean_type_node, x,
1814 build_int_cst (TREE_TYPE (x), 0));
1815 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
1816 gimplify_and_add (x, ilist);
1819 /* If any copyin variable is passed by reference, we must ensure the
1820 master thread doesn't modify it before it is copied over in all
1821 threads. Similarly for variables in both firstprivate and
1822 lastprivate clauses we need to ensure the lastprivate copying
1823 happens after firstprivate copying in all threads. */
1824 if (copyin_by_ref || lastprivate_firstprivate)
1825 build_omp_barrier (ilist);
1829 /* Generate code to implement the LASTPRIVATE clauses. This is used for
1830 both parallel and workshare constructs. PREDICATE may be NULL if it's
1834 lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
1837 tree sub_list, x, c;
1839 /* Early exit if there are no lastprivate clauses. */
1840 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
1841 if (clauses == NULL)
1843 /* If this was a workshare clause, see if it had been combined
1844 with its parallel. In that case, look for the clauses on the
1845 parallel statement itself. */
1846 if (is_parallel_ctx (ctx))
1850 if (ctx == NULL || !is_parallel_ctx (ctx))
1853 clauses = find_omp_clause (OMP_PARALLEL_CLAUSES (ctx->stmt),
1854 OMP_CLAUSE_LASTPRIVATE);
1855 if (clauses == NULL)
1859 sub_list = alloc_stmt_list ();
1861 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1865 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE)
1868 var = OMP_CLAUSE_DECL (c);
1869 new_var = lookup_decl (var, ctx);
1871 x = build_outer_var_ref (var, ctx);
1872 if (is_reference (var))
1873 new_var = build_fold_indirect_ref (new_var);
1874 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
1875 append_to_statement_list (x, &sub_list);
1879 x = build3 (COND_EXPR, void_type_node, predicate, sub_list, NULL);
1883 gimplify_and_add (x, stmt_list);
1887 /* Generate code to implement the REDUCTION clauses. */
1890 lower_reduction_clauses (tree clauses, tree *stmt_list, omp_context *ctx)
1892 tree sub_list = NULL, x, c;
1895 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
1896 update in that case, otherwise use a lock. */
1897 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
1898 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
1900 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1902 /* Never use OMP_ATOMIC for array reductions. */
1912 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1914 tree var, ref, new_var;
1915 enum tree_code code;
1917 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
1920 var = OMP_CLAUSE_DECL (c);
1921 new_var = lookup_decl (var, ctx);
1922 if (is_reference (var))
1923 new_var = build_fold_indirect_ref (new_var);
1924 ref = build_outer_var_ref (var, ctx);
1925 code = OMP_CLAUSE_REDUCTION_CODE (c);
1927 /* reduction(-:var) sums up the partial results, so it acts
1928 identically to reduction(+:var). */
1929 if (code == MINUS_EXPR)
1934 tree addr = build_fold_addr_expr (ref);
1936 addr = save_expr (addr);
1937 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
1938 x = fold_build2 (code, TREE_TYPE (ref), ref, new_var);
1939 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
1940 gimplify_and_add (x, stmt_list);
1944 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1946 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
1948 if (is_reference (var))
1949 ref = build_fold_addr_expr (ref);
1950 SET_DECL_VALUE_EXPR (placeholder, ref);
1951 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
1952 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), &sub_list);
1953 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL;
1954 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
1958 x = build2 (code, TREE_TYPE (ref), ref, new_var);
1959 ref = build_outer_var_ref (var, ctx);
1960 x = build_gimple_modify_stmt (ref, x);
1961 append_to_statement_list (x, &sub_list);
1965 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
1966 gimplify_and_add (x, stmt_list);
1968 gimplify_and_add (sub_list, stmt_list);
1970 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
1971 gimplify_and_add (x, stmt_list);
1975 /* Generate code to implement the COPYPRIVATE clauses. */
1978 lower_copyprivate_clauses (tree clauses, tree *slist, tree *rlist,
1983 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1988 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
1991 var = OMP_CLAUSE_DECL (c);
1992 by_ref = use_pointer_for_field (var, false);
1994 ref = build_sender_ref (var, ctx);
1995 x = (ctx->is_nested) ? lookup_decl_in_outer_ctx (var, ctx) : var;
1996 x = by_ref ? build_fold_addr_expr (x) : x;
1997 x = build_gimple_modify_stmt (ref, x);
1998 gimplify_and_add (x, slist);
2000 ref = build_receiver_ref (var, by_ref, ctx);
2001 if (is_reference (var))
2003 ref = build_fold_indirect_ref (ref);
2004 var = build_fold_indirect_ref (var);
2006 x = lang_hooks.decls.omp_clause_assign_op (c, var, ref);
2007 gimplify_and_add (x, rlist);
2012 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2013 and REDUCTION from the sender (aka parent) side. */
2016 lower_send_clauses (tree clauses, tree *ilist, tree *olist, omp_context *ctx)
2020 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2022 tree val, ref, x, var;
2023 bool by_ref, do_in = false, do_out = false;
2025 switch (OMP_CLAUSE_CODE (c))
2027 case OMP_CLAUSE_FIRSTPRIVATE:
2028 case OMP_CLAUSE_COPYIN:
2029 case OMP_CLAUSE_LASTPRIVATE:
2030 case OMP_CLAUSE_REDUCTION:
2036 var = val = OMP_CLAUSE_DECL (c);
2038 var = lookup_decl_in_outer_ctx (val, ctx);
2040 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2041 && is_global_var (var))
2043 if (is_variable_sized (val))
2045 by_ref = use_pointer_for_field (val, false);
2047 switch (OMP_CLAUSE_CODE (c))
2049 case OMP_CLAUSE_FIRSTPRIVATE:
2050 case OMP_CLAUSE_COPYIN:
2054 case OMP_CLAUSE_LASTPRIVATE:
2055 if (by_ref || is_reference (val))
2057 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2065 case OMP_CLAUSE_REDUCTION:
2067 do_out = !(by_ref || is_reference (val));
2076 ref = build_sender_ref (val, ctx);
2077 x = by_ref ? build_fold_addr_expr (var) : var;
2078 x = build_gimple_modify_stmt (ref, x);
2079 gimplify_and_add (x, ilist);
2084 ref = build_sender_ref (val, ctx);
2085 x = build_gimple_modify_stmt (var, ref);
2086 gimplify_and_add (x, olist);
2091 /* Generate code to implement SHARED from the sender (aka parent) side.
2092 This is trickier, since OMP_PARALLEL_CLAUSES doesn't list things that
2093 got automatically shared. */
2096 lower_send_shared_vars (tree *ilist, tree *olist, omp_context *ctx)
2098 tree var, ovar, nvar, f, x;
2100 if (ctx->record_type == NULL)
2103 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
2105 ovar = DECL_ABSTRACT_ORIGIN (f);
2106 nvar = maybe_lookup_decl (ovar, ctx);
2107 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2112 /* If CTX is a nested parallel directive. Find the immediately
2113 enclosing parallel or workshare construct that contains a
2114 mapping for OVAR. */
2116 var = lookup_decl_in_outer_ctx (ovar, ctx);
2118 if (use_pointer_for_field (ovar, true))
2120 x = build_sender_ref (ovar, ctx);
2121 var = build_fold_addr_expr (var);
2122 x = build_gimple_modify_stmt (x, var);
2123 gimplify_and_add (x, ilist);
2127 x = build_sender_ref (ovar, ctx);
2128 x = build_gimple_modify_stmt (x, var);
2129 gimplify_and_add (x, ilist);
2131 x = build_sender_ref (ovar, ctx);
2132 x = build_gimple_modify_stmt (var, x);
2133 gimplify_and_add (x, olist);
2138 /* Build the function calls to GOMP_parallel_start etc to actually
2139 generate the parallel operation. REGION is the parallel region
2140 being expanded. BB is the block where to insert the code. WS_ARGS
2141 will be set if this is a call to a combined parallel+workshare
2142 construct, it contains the list of additional arguments needed by
2143 the workshare construct. */
2146 expand_parallel_call (struct omp_region *region, basic_block bb,
2147 tree entry_stmt, tree ws_args)
2149 tree t, t1, t2, val, cond, c, list, clauses;
2150 block_stmt_iterator si;
2153 clauses = OMP_PARALLEL_CLAUSES (entry_stmt);
2154 push_gimplify_context ();
2156 /* Determine what flavor of GOMP_parallel_start we will be
2158 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2159 if (is_combined_parallel (region))
2161 switch (region->inner->type)
2164 start_ix = BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2165 + region->inner->sched_kind;
2168 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2175 /* By default, the value of NUM_THREADS is zero (selected at run time)
2176 and there is no conditional. */
2178 val = build_int_cst (unsigned_type_node, 0);
2180 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2182 cond = OMP_CLAUSE_IF_EXPR (c);
2184 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2186 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2188 /* Ensure 'val' is of the correct type. */
2189 val = fold_convert (unsigned_type_node, val);
2191 /* If we found the clause 'if (cond)', build either
2192 (cond != 0) or (cond ? val : 1u). */
2195 block_stmt_iterator si;
2197 cond = gimple_boolify (cond);
2199 if (integer_zerop (val))
2200 val = build2 (EQ_EXPR, unsigned_type_node, cond,
2201 build_int_cst (TREE_TYPE (cond), 0));
2204 basic_block cond_bb, then_bb, else_bb;
2206 tree t, then_lab, else_lab, tmp;
2208 tmp = create_tmp_var (TREE_TYPE (val), NULL);
2209 e = split_block (bb, NULL);
2214 then_bb = create_empty_bb (cond_bb);
2215 else_bb = create_empty_bb (then_bb);
2216 then_lab = create_artificial_label ();
2217 else_lab = create_artificial_label ();
2219 t = build3 (COND_EXPR, void_type_node,
2221 build_and_jump (&then_lab),
2222 build_and_jump (&else_lab));
2224 si = bsi_start (cond_bb);
2225 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2227 si = bsi_start (then_bb);
2228 t = build1 (LABEL_EXPR, void_type_node, then_lab);
2229 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2230 t = build_gimple_modify_stmt (tmp, val);
2231 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2233 si = bsi_start (else_bb);
2234 t = build1 (LABEL_EXPR, void_type_node, else_lab);
2235 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2236 t = build_gimple_modify_stmt (tmp,
2237 build_int_cst (unsigned_type_node, 1));
2238 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2240 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
2241 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
2242 make_edge (then_bb, bb, EDGE_FALLTHRU);
2243 make_edge (else_bb, bb, EDGE_FALLTHRU);
2249 val = get_formal_tmp_var (val, &list);
2250 si = bsi_start (bb);
2251 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2255 t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2257 t1 = null_pointer_node;
2259 t1 = build_fold_addr_expr (t);
2260 t2 = build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt));
2264 tree args = tree_cons (NULL, t2,
2265 tree_cons (NULL, t1,
2266 tree_cons (NULL, val, ws_args)));
2267 t = build_function_call_expr (built_in_decls[start_ix], args);
2270 t = build_call_expr (built_in_decls[start_ix], 3, t2, t1, val);
2272 gimplify_and_add (t, &list);
2274 t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2276 t = null_pointer_node;
2278 t = build_fold_addr_expr (t);
2279 t = build_call_expr (OMP_PARALLEL_FN (entry_stmt), 1, t);
2280 gimplify_and_add (t, &list);
2282 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_PARALLEL_END], 0);
2283 gimplify_and_add (t, &list);
2286 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2288 pop_gimplify_context (NULL_TREE);
2292 /* If exceptions are enabled, wrap *STMT_P in a MUST_NOT_THROW catch
2293 handler. This prevents programs from violating the structured
2294 block semantics with throws. */
2297 maybe_catch_exception (tree *stmt_p)
2301 if (!flag_exceptions)
2304 if (lang_protect_cleanup_actions)
2305 t = lang_protect_cleanup_actions ();
2307 t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
2308 f = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
2309 EH_FILTER_MUST_NOT_THROW (f) = 1;
2310 gimplify_and_add (t, &EH_FILTER_FAILURE (f));
2312 t = build2 (TRY_CATCH_EXPR, void_type_node, *stmt_p, NULL);
2313 append_to_statement_list (f, &TREE_OPERAND (t, 1));
2316 append_to_statement_list (t, stmt_p);
2319 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
2322 list2chain (tree list)
2326 for (t = list; t; t = TREE_CHAIN (t))
2328 tree var = TREE_VALUE (t);
2330 TREE_CHAIN (var) = TREE_VALUE (TREE_CHAIN (t));
2332 TREE_CHAIN (var) = NULL_TREE;
2335 return list ? TREE_VALUE (list) : NULL_TREE;
2339 /* Remove barriers in REGION->EXIT's block. Note that this is only
2340 valid for OMP_PARALLEL regions. Since the end of a parallel region
2341 is an implicit barrier, any workshare inside the OMP_PARALLEL that
2342 left a barrier at the end of the OMP_PARALLEL region can now be
2346 remove_exit_barrier (struct omp_region *region)
2348 block_stmt_iterator si;
2349 basic_block exit_bb;
2354 exit_bb = region->exit;
2356 /* If the parallel region doesn't return, we don't have REGION->EXIT
2361 /* The last insn in the block will be the parallel's OMP_RETURN. The
2362 workshare's OMP_RETURN will be in a preceding block. The kinds of
2363 statements that can appear in between are extremely limited -- no
2364 memory operations at all. Here, we allow nothing at all, so the
2365 only thing we allow to precede this OMP_RETURN is a label. */
2366 si = bsi_last (exit_bb);
2367 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2369 if (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) != LABEL_EXPR)
2372 FOR_EACH_EDGE (e, ei, exit_bb->preds)
2374 si = bsi_last (e->src);
2378 if (TREE_CODE (t) == OMP_RETURN)
2379 OMP_RETURN_NOWAIT (t) = 1;
2384 remove_exit_barriers (struct omp_region *region)
2386 if (region->type == OMP_PARALLEL)
2387 remove_exit_barrier (region);
2391 region = region->inner;
2392 remove_exit_barriers (region);
2393 while (region->next)
2395 region = region->next;
2396 remove_exit_barriers (region);
2401 /* Expand the OpenMP parallel directive starting at REGION. */
2404 expand_omp_parallel (struct omp_region *region)
2406 basic_block entry_bb, exit_bb, new_bb;
2407 struct function *child_cfun, *saved_cfun;
2408 tree child_fn, block, t, ws_args;
2409 block_stmt_iterator si;
2412 bool do_cleanup_cfg = false;
2414 entry_stmt = last_stmt (region->entry);
2415 child_fn = OMP_PARALLEL_FN (entry_stmt);
2416 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
2419 entry_bb = region->entry;
2420 exit_bb = region->exit;
2422 if (is_combined_parallel (region))
2423 ws_args = region->ws_args;
2425 ws_args = NULL_TREE;
2427 if (child_cfun->cfg)
2429 /* Due to inlining, it may happen that we have already outlined
2430 the region, in which case all we need to do is make the
2431 sub-graph unreachable and emit the parallel call. */
2432 edge entry_succ_e, exit_succ_e;
2433 block_stmt_iterator si;
2435 entry_succ_e = single_succ_edge (entry_bb);
2437 si = bsi_last (entry_bb);
2438 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_PARALLEL);
2439 bsi_remove (&si, true);
2442 remove_edge (entry_succ_e);
2445 exit_succ_e = single_succ_edge (exit_bb);
2446 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
2448 do_cleanup_cfg = true;
2452 /* If the parallel region needs data sent from the parent
2453 function, then the very first statement (except possible
2454 tree profile counter updates) of the parallel body
2455 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
2456 &.OMP_DATA_O is passed as an argument to the child function,
2457 we need to replace it with the argument as seen by the child
2460 In most cases, this will end up being the identity assignment
2461 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
2462 a function call that has been inlined, the original PARM_DECL
2463 .OMP_DATA_I may have been converted into a different local
2464 variable. In which case, we need to keep the assignment. */
2465 if (OMP_PARALLEL_DATA_ARG (entry_stmt))
2467 basic_block entry_succ_bb = single_succ (entry_bb);
2468 block_stmt_iterator si;
2470 for (si = bsi_start (entry_succ_bb); ; bsi_next (&si))
2474 gcc_assert (!bsi_end_p (si));
2475 stmt = bsi_stmt (si);
2476 if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
2479 arg = GIMPLE_STMT_OPERAND (stmt, 1);
2481 if (TREE_CODE (arg) == ADDR_EXPR
2482 && TREE_OPERAND (arg, 0)
2483 == OMP_PARALLEL_DATA_ARG (entry_stmt))
2485 if (GIMPLE_STMT_OPERAND (stmt, 0)
2486 == DECL_ARGUMENTS (child_fn))
2487 bsi_remove (&si, true);
2489 GIMPLE_STMT_OPERAND (stmt, 1) = DECL_ARGUMENTS (child_fn);
2495 /* Declare local variables needed in CHILD_CFUN. */
2496 block = DECL_INITIAL (child_fn);
2497 BLOCK_VARS (block) = list2chain (child_cfun->unexpanded_var_list);
2498 DECL_SAVED_TREE (child_fn) = single_succ (entry_bb)->stmt_list;
2500 /* Reset DECL_CONTEXT on locals and function arguments. */
2501 for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
2502 DECL_CONTEXT (t) = child_fn;
2504 for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
2505 DECL_CONTEXT (t) = child_fn;
2507 /* Split ENTRY_BB at OMP_PARALLEL so that it can be moved to the
2509 si = bsi_last (entry_bb);
2511 gcc_assert (t && TREE_CODE (t) == OMP_PARALLEL);
2512 bsi_remove (&si, true);
2513 e = split_block (entry_bb, t);
2515 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
2517 /* Move the parallel region into CHILD_CFUN. We need to reset
2518 dominance information because the expansion of the inner
2519 regions has invalidated it. */
2520 free_dominance_info (CDI_DOMINATORS);
2521 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
2523 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
2524 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
2525 = cfun->curr_properties;
2526 cgraph_add_new_function (child_fn, true);
2528 /* Convert OMP_RETURN into a RETURN_EXPR. */
2531 si = bsi_last (exit_bb);
2532 gcc_assert (!bsi_end_p (si)
2533 && TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2534 t = build1 (RETURN_EXPR, void_type_node, NULL);
2535 bsi_insert_after (&si, t, BSI_SAME_STMT);
2536 bsi_remove (&si, true);
2540 /* Emit a library call to launch the children threads. */
2541 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
2545 /* Clean up the unreachable sub-graph we created above. */
2546 free_dominance_info (CDI_DOMINATORS);
2547 free_dominance_info (CDI_POST_DOMINATORS);
2548 cleanup_tree_cfg ();
2553 /* A subroutine of expand_omp_for. Generate code for a parallel
2554 loop with any schedule. Given parameters:
2556 for (V = N1; V cond N2; V += STEP) BODY;
2558 where COND is "<" or ">", we generate pseudocode
2560 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
2561 if (more) goto L0; else goto L3;
2568 if (V cond iend) goto L1; else goto L2;
2570 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
2573 If this is a combined omp parallel loop, instead of the call to
2574 GOMP_loop_foo_start, we emit 'goto L3'. */
2577 expand_omp_for_generic (struct omp_region *region,
2578 struct omp_for_data *fd,
2579 enum built_in_function start_fn,
2580 enum built_in_function next_fn)
2582 tree l0, l1, l2 = NULL, l3 = NULL;
2583 tree type, istart0, iend0, iend;
2585 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
2586 basic_block l2_bb = NULL, l3_bb = NULL;
2587 block_stmt_iterator si;
2588 bool in_combined_parallel = is_combined_parallel (region);
2590 type = TREE_TYPE (fd->v);
2592 istart0 = create_tmp_var (long_integer_type_node, ".istart0");
2593 iend0 = create_tmp_var (long_integer_type_node, ".iend0");
2594 iend = create_tmp_var (type, NULL);
2595 TREE_ADDRESSABLE (istart0) = 1;
2596 TREE_ADDRESSABLE (iend0) = 1;
2598 gcc_assert ((region->cont != NULL) ^ (region->exit == NULL));
2600 entry_bb = region->entry;
2601 l0_bb = create_empty_bb (entry_bb);
2602 l1_bb = single_succ (entry_bb);
2604 l0 = tree_block_label (l0_bb);
2605 l1 = tree_block_label (l1_bb);
2607 cont_bb = region->cont;
2608 exit_bb = region->exit;
2611 l2_bb = create_empty_bb (cont_bb);
2612 l3_bb = single_succ (cont_bb);
2614 l2 = tree_block_label (l2_bb);
2615 l3 = tree_block_label (l3_bb);
2618 si = bsi_last (entry_bb);
2619 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2620 if (!in_combined_parallel)
2622 tree t0, t1, t2, t3, t4;
2623 /* If this is not a combined parallel loop, emit a call to
2624 GOMP_loop_foo_start in ENTRY_BB. */
2625 list = alloc_stmt_list ();
2626 t4 = build_fold_addr_expr (iend0);
2627 t3 = build_fold_addr_expr (istart0);
2628 t2 = fold_convert (long_integer_type_node, fd->step);
2629 t1 = fold_convert (long_integer_type_node, fd->n2);
2630 t0 = fold_convert (long_integer_type_node, fd->n1);
2633 t = fold_convert (long_integer_type_node, fd->chunk_size);
2634 t = build_call_expr (built_in_decls[start_fn], 6,
2635 t0, t1, t2, t, t3, t4);
2638 t = build_call_expr (built_in_decls[start_fn], 5,
2639 t0, t1, t2, t3, t4);
2640 t = get_formal_tmp_var (t, &list);
2643 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
2644 build_and_jump (&l3));
2645 append_to_statement_list (t, &list);
2647 bsi_insert_after (&si, list, BSI_SAME_STMT);
2649 bsi_remove (&si, true);
2651 /* Iteration setup for sequential loop goes in L0_BB. */
2652 list = alloc_stmt_list ();
2653 t = fold_convert (type, istart0);
2654 t = build_gimple_modify_stmt (fd->v, t);
2655 gimplify_and_add (t, &list);
2657 t = fold_convert (type, iend0);
2658 t = build_gimple_modify_stmt (iend, t);
2659 gimplify_and_add (t, &list);
2661 si = bsi_start (l0_bb);
2662 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2664 /* Handle the rare case where BODY doesn't ever return. */
2665 if (cont_bb == NULL)
2667 remove_edge (single_succ_edge (entry_bb));
2668 make_edge (entry_bb, l0_bb, EDGE_FALLTHRU);
2669 make_edge (l0_bb, l1_bb, EDGE_FALLTHRU);
2673 /* Code to control the increment and predicate for the sequential
2674 loop goes in the first half of EXIT_BB (we split EXIT_BB so
2675 that we can inherit all the edges going out of the loop
2677 list = alloc_stmt_list ();
2679 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
2680 t = build_gimple_modify_stmt (fd->v, t);
2681 gimplify_and_add (t, &list);
2683 t = build2 (fd->cond_code, boolean_type_node, fd->v, iend);
2684 t = get_formal_tmp_var (t, &list);
2685 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1),
2686 build_and_jump (&l2));
2687 append_to_statement_list (t, &list);
2689 si = bsi_last (cont_bb);
2690 bsi_insert_after (&si, list, BSI_SAME_STMT);
2691 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
2692 bsi_remove (&si, true);
2694 /* Emit code to get the next parallel iteration in L2_BB. */
2695 list = alloc_stmt_list ();
2697 t = build_call_expr (built_in_decls[next_fn], 2,
2698 build_fold_addr_expr (istart0),
2699 build_fold_addr_expr (iend0));
2700 t = get_formal_tmp_var (t, &list);
2701 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
2702 build_and_jump (&l3));
2703 append_to_statement_list (t, &list);
2705 si = bsi_start (l2_bb);
2706 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2708 /* Add the loop cleanup function. */
2709 si = bsi_last (exit_bb);
2710 if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
2711 t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
2713 t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
2714 t = build_call_expr (t, 0);
2715 bsi_insert_after (&si, t, BSI_SAME_STMT);
2716 bsi_remove (&si, true);
2718 /* Connect the new blocks. */
2719 remove_edge (single_succ_edge (entry_bb));
2720 if (in_combined_parallel)
2721 make_edge (entry_bb, l2_bb, EDGE_FALLTHRU);
2724 make_edge (entry_bb, l0_bb, EDGE_TRUE_VALUE);
2725 make_edge (entry_bb, l3_bb, EDGE_FALSE_VALUE);
2728 make_edge (l0_bb, l1_bb, EDGE_FALLTHRU);
2730 remove_edge (single_succ_edge (cont_bb));
2731 make_edge (cont_bb, l1_bb, EDGE_TRUE_VALUE);
2732 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
2734 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
2735 make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
2739 /* A subroutine of expand_omp_for. Generate code for a parallel
2740 loop with static schedule and no specified chunk size. Given
2743 for (V = N1; V cond N2; V += STEP) BODY;
2745 where COND is "<" or ">", we generate pseudocode
2751 n = (adj + N2 - N1) / STEP;
2753 q += (q * nthreads != n);
2755 e0 = min(s0 + q, n);
2756 if (s0 >= e0) goto L2; else goto L0;
2763 if (V cond e) goto L1;
2768 expand_omp_for_static_nochunk (struct omp_region *region,
2769 struct omp_for_data *fd)
2771 tree l0, l1, l2, n, q, s0, e0, e, t, nthreads, threadid;
2773 basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
2775 block_stmt_iterator si;
2777 type = TREE_TYPE (fd->v);
2779 entry_bb = region->entry;
2780 seq_start_bb = create_empty_bb (entry_bb);
2781 body_bb = single_succ (entry_bb);
2782 cont_bb = region->cont;
2783 fin_bb = single_succ (cont_bb);
2784 exit_bb = region->exit;
2786 l0 = tree_block_label (seq_start_bb);
2787 l1 = tree_block_label (body_bb);
2788 l2 = tree_block_label (fin_bb);
2790 /* Iteration space partitioning goes in ENTRY_BB. */
2791 list = alloc_stmt_list ();
2793 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
2794 t = fold_convert (type, t);
2795 nthreads = get_formal_tmp_var (t, &list);
2797 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2798 t = fold_convert (type, t);
2799 threadid = get_formal_tmp_var (t, &list);
2801 fd->n1 = fold_convert (type, fd->n1);
2802 if (!is_gimple_val (fd->n1))
2803 fd->n1 = get_formal_tmp_var (fd->n1, &list);
2805 fd->n2 = fold_convert (type, fd->n2);
2806 if (!is_gimple_val (fd->n2))
2807 fd->n2 = get_formal_tmp_var (fd->n2, &list);
2809 fd->step = fold_convert (type, fd->step);
2810 if (!is_gimple_val (fd->step))
2811 fd->step = get_formal_tmp_var (fd->step, &list);
2813 t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2814 t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2815 t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2816 t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2817 t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2818 t = fold_convert (type, t);
2819 if (is_gimple_val (t))
2822 n = get_formal_tmp_var (t, &list);
2824 t = build2 (TRUNC_DIV_EXPR, type, n, nthreads);
2825 q = get_formal_tmp_var (t, &list);
2827 t = build2 (MULT_EXPR, type, q, nthreads);
2828 t = build2 (NE_EXPR, type, t, n);
2829 t = build2 (PLUS_EXPR, type, q, t);
2830 q = get_formal_tmp_var (t, &list);
2832 t = build2 (MULT_EXPR, type, q, threadid);
2833 s0 = get_formal_tmp_var (t, &list);
2835 t = build2 (PLUS_EXPR, type, s0, q);
2836 t = build2 (MIN_EXPR, type, t, n);
2837 e0 = get_formal_tmp_var (t, &list);
2839 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
2840 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l2),
2841 build_and_jump (&l0));
2842 append_to_statement_list (t, &list);
2844 si = bsi_last (entry_bb);
2845 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2846 bsi_insert_after (&si, list, BSI_SAME_STMT);
2847 bsi_remove (&si, true);
2849 /* Setup code for sequential iteration goes in SEQ_START_BB. */
2850 list = alloc_stmt_list ();
2852 t = fold_convert (type, s0);
2853 t = build2 (MULT_EXPR, type, t, fd->step);
2854 t = build2 (PLUS_EXPR, type, t, fd->n1);
2855 t = build_gimple_modify_stmt (fd->v, t);
2856 gimplify_and_add (t, &list);
2858 t = fold_convert (type, e0);
2859 t = build2 (MULT_EXPR, type, t, fd->step);
2860 t = build2 (PLUS_EXPR, type, t, fd->n1);
2861 e = get_formal_tmp_var (t, &list);
2863 si = bsi_start (seq_start_bb);
2864 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2866 /* The code controlling the sequential loop replaces the OMP_CONTINUE. */
2867 list = alloc_stmt_list ();
2869 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
2870 t = build_gimple_modify_stmt (fd->v, t);
2871 gimplify_and_add (t, &list);
2873 t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
2874 t = get_formal_tmp_var (t, &list);
2875 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1),
2876 build_and_jump (&l2));
2877 append_to_statement_list (t, &list);
2879 si = bsi_last (cont_bb);
2880 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
2881 bsi_insert_after (&si, list, BSI_SAME_STMT);
2882 bsi_remove (&si, true);
2884 /* Replace the OMP_RETURN with a barrier, or nothing. */
2885 si = bsi_last (exit_bb);
2886 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
2888 list = alloc_stmt_list ();
2889 build_omp_barrier (&list);
2890 bsi_insert_after (&si, list, BSI_SAME_STMT);
2892 bsi_remove (&si, true);
2894 /* Connect all the blocks. */
2895 make_edge (seq_start_bb, body_bb, EDGE_FALLTHRU);
2897 remove_edge (single_succ_edge (entry_bb));
2898 make_edge (entry_bb, fin_bb, EDGE_TRUE_VALUE);
2899 make_edge (entry_bb, seq_start_bb, EDGE_FALSE_VALUE);
2901 make_edge (cont_bb, body_bb, EDGE_TRUE_VALUE);
2902 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
2906 /* A subroutine of expand_omp_for. Generate code for a parallel
2907 loop with static schedule and a specified chunk size. Given
2910 for (V = N1; V cond N2; V += STEP) BODY;
2912 where COND is "<" or ">", we generate pseudocode
2918 n = (adj + N2 - N1) / STEP;
2921 s0 = (trip * nthreads + threadid) * CHUNK;
2922 e0 = min(s0 + CHUNK, n);
2923 if (s0 < n) goto L1; else goto L4;
2930 if (V cond e) goto L2; else goto L3;
2938 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
2940 tree l0, l1, l2, l3, l4, n, s0, e0, e, t;
2941 tree trip, nthreads, threadid;
2943 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
2944 basic_block trip_update_bb, cont_bb, fin_bb;
2946 block_stmt_iterator si;
2948 type = TREE_TYPE (fd->v);
2950 entry_bb = region->entry;
2951 iter_part_bb = create_empty_bb (entry_bb);
2952 seq_start_bb = create_empty_bb (iter_part_bb);
2953 body_bb = single_succ (entry_bb);
2954 cont_bb = region->cont;
2955 trip_update_bb = create_empty_bb (cont_bb);
2956 fin_bb = single_succ (cont_bb);
2957 exit_bb = region->exit;
2959 l0 = tree_block_label (iter_part_bb);
2960 l1 = tree_block_label (seq_start_bb);
2961 l2 = tree_block_label (body_bb);
2962 l3 = tree_block_label (trip_update_bb);
2963 l4 = tree_block_label (fin_bb);
2965 /* Trip and adjustment setup goes in ENTRY_BB. */
2966 list = alloc_stmt_list ();
2968 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
2969 t = fold_convert (type, t);
2970 nthreads = get_formal_tmp_var (t, &list);
2972 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2973 t = fold_convert (type, t);
2974 threadid = get_formal_tmp_var (t, &list);
2976 fd->n1 = fold_convert (type, fd->n1);
2977 if (!is_gimple_val (fd->n1))
2978 fd->n1 = get_formal_tmp_var (fd->n1, &list);
2980 fd->n2 = fold_convert (type, fd->n2);
2981 if (!is_gimple_val (fd->n2))
2982 fd->n2 = get_formal_tmp_var (fd->n2, &list);
2984 fd->step = fold_convert (type, fd->step);
2985 if (!is_gimple_val (fd->step))
2986 fd->step = get_formal_tmp_var (fd->step, &list);
2988 fd->chunk_size = fold_convert (type, fd->chunk_size);
2989 if (!is_gimple_val (fd->chunk_size))
2990 fd->chunk_size = get_formal_tmp_var (fd->chunk_size, &list);
2992 t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2993 t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2994 t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2995 t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2996 t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2997 t = fold_convert (type, t);
2998 if (is_gimple_val (t))
3001 n = get_formal_tmp_var (t, &list);
3003 t = build_int_cst (type, 0);
3004 trip = get_initialized_tmp_var (t, &list, NULL);
3006 si = bsi_last (entry_bb);
3007 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
3008 bsi_insert_after (&si, list, BSI_SAME_STMT);
3009 bsi_remove (&si, true);
3011 /* Iteration space partitioning goes in ITER_PART_BB. */
3012 list = alloc_stmt_list ();
3014 t = build2 (MULT_EXPR, type, trip, nthreads);
3015 t = build2 (PLUS_EXPR, type, t, threadid);
3016 t = build2 (MULT_EXPR, type, t, fd->chunk_size);
3017 s0 = get_formal_tmp_var (t, &list);
3019 t = build2 (PLUS_EXPR, type, s0, fd->chunk_size);
3020 t = build2 (MIN_EXPR, type, t, n);
3021 e0 = get_formal_tmp_var (t, &list);
3023 t = build2 (LT_EXPR, boolean_type_node, s0, n);
3024 t = build3 (COND_EXPR, void_type_node, t,
3025 build_and_jump (&l1), build_and_jump (&l4));
3026 append_to_statement_list (t, &list);
3028 si = bsi_start (iter_part_bb);
3029 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3031 /* Setup code for sequential iteration goes in SEQ_START_BB. */
3032 list = alloc_stmt_list ();
3034 t = fold_convert (type, s0);
3035 t = build2 (MULT_EXPR, type, t, fd->step);
3036 t = build2 (PLUS_EXPR, type, t, fd->n1);
3037 t = build_gimple_modify_stmt (fd->v, t);
3038 gimplify_and_add (t, &list);
3040 t = fold_convert (type, e0);
3041 t = build2 (MULT_EXPR, type, t, fd->step);
3042 t = build2 (PLUS_EXPR, type, t, fd->n1);
3043 e = get_formal_tmp_var (t, &list);
3045 si = bsi_start (seq_start_bb);
3046 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3048 /* The code controlling the sequential loop goes in CONT_BB,
3049 replacing the OMP_CONTINUE. */
3050 list = alloc_stmt_list ();
3052 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
3053 t = build_gimple_modify_stmt (fd->v, t);
3054 gimplify_and_add (t, &list);
3056 t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
3057 t = get_formal_tmp_var (t, &list);
3058 t = build3 (COND_EXPR, void_type_node, t,
3059 build_and_jump (&l2), build_and_jump (&l3));
3060 append_to_statement_list (t, &list);
3062 si = bsi_last (cont_bb);
3063 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3064 bsi_insert_after (&si, list, BSI_SAME_STMT);
3065 bsi_remove (&si, true);
3067 /* Trip update code goes into TRIP_UPDATE_BB. */
3068 list = alloc_stmt_list ();
3070 t = build_int_cst (type, 1);
3071 t = build2 (PLUS_EXPR, type, trip, t);
3072 t = build_gimple_modify_stmt (trip, t);
3073 gimplify_and_add (t, &list);
3075 si = bsi_start (trip_update_bb);
3076 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3078 /* Replace the OMP_RETURN with a barrier, or nothing. */
3079 si = bsi_last (exit_bb);
3080 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
3082 list = alloc_stmt_list ();
3083 build_omp_barrier (&list);
3084 bsi_insert_after (&si, list, BSI_SAME_STMT);
3086 bsi_remove (&si, true);
3088 /* Connect the new blocks. */
3089 remove_edge (single_succ_edge (entry_bb));
3090 make_edge (entry_bb, iter_part_bb, EDGE_FALLTHRU);
3092 make_edge (iter_part_bb, seq_start_bb, EDGE_TRUE_VALUE);
3093 make_edge (iter_part_bb, fin_bb, EDGE_FALSE_VALUE);
3095 make_edge (seq_start_bb, body_bb, EDGE_FALLTHRU);
3097 remove_edge (single_succ_edge (cont_bb));
3098 make_edge (cont_bb, body_bb, EDGE_TRUE_VALUE);
3099 make_edge (cont_bb, trip_update_bb, EDGE_FALSE_VALUE);
3101 make_edge (trip_update_bb, iter_part_bb, EDGE_FALLTHRU);
3105 /* Expand the OpenMP loop defined by REGION. */
3108 expand_omp_for (struct omp_region *region)
3110 struct omp_for_data fd;
3112 push_gimplify_context ();
3114 extract_omp_for_data (last_stmt (region->entry), &fd);
3115 region->sched_kind = fd.sched_kind;
3117 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
3122 if (fd.chunk_size == NULL)
3123 expand_omp_for_static_nochunk (region, &fd);
3125 expand_omp_for_static_chunk (region, &fd);
3129 int fn_index = fd.sched_kind + fd.have_ordered * 4;
3130 int start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index;
3131 int next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index;
3132 expand_omp_for_generic (region, &fd, start_ix, next_ix);
3135 pop_gimplify_context (NULL);
3139 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
3141 v = GOMP_sections_start (n);
3158 v = GOMP_sections_next ();
3163 If this is a combined parallel sections, replace the call to
3164 GOMP_sections_start with 'goto L1'. */
3167 expand_omp_sections (struct omp_region *region)
3169 tree label_vec, l0, l1, l2, t, u, v, sections_stmt;
3171 basic_block entry_bb, exit_bb, l0_bb, l1_bb, l2_bb, default_bb;
3172 block_stmt_iterator si;
3173 struct omp_region *inner;
3176 entry_bb = region->entry;
3177 l0_bb = create_empty_bb (entry_bb);
3178 l0 = tree_block_label (l0_bb);
3180 gcc_assert ((region->cont != NULL) ^ (region->exit == NULL));
3181 l1_bb = region->cont;
3184 l2_bb = single_succ (l1_bb);
3185 default_bb = create_empty_bb (l1_bb->prev_bb);
3187 l1 = tree_block_label (l1_bb);
3191 l2_bb = create_empty_bb (l0_bb);
3196 l2 = tree_block_label (l2_bb);
3198 exit_bb = region->exit;
3200 v = create_tmp_var (unsigned_type_node, ".section");
3202 /* We will build a switch() with enough cases for all the
3203 OMP_SECTION regions, a '0' case to handle the end of more work
3204 and a default case to abort if something goes wrong. */
3205 len = EDGE_COUNT (entry_bb->succs);
3206 label_vec = make_tree_vec (len + 2);
3208 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
3209 OMP_SECTIONS statement. */
3210 si = bsi_last (entry_bb);
3211 sections_stmt = bsi_stmt (si);
3212 gcc_assert (TREE_CODE (sections_stmt) == OMP_SECTIONS);
3213 if (!is_combined_parallel (region))
3215 /* If we are not inside a combined parallel+sections region,
3216 call GOMP_sections_start. */
3217 t = build_int_cst (unsigned_type_node, len);
3218 u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
3219 t = build_call_expr (u, 1, t);
3220 t = build_gimple_modify_stmt (v, t);
3221 bsi_insert_after (&si, t, BSI_SAME_STMT);
3223 bsi_remove (&si, true);
3225 /* The switch() statement replacing OMP_SECTIONS goes in L0_BB. */
3226 si = bsi_start (l0_bb);
3228 t = build3 (SWITCH_EXPR, void_type_node, v, NULL, label_vec);
3229 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3231 t = build3 (CASE_LABEL_EXPR, void_type_node,
3232 build_int_cst (unsigned_type_node, 0), NULL, l2);
3233 TREE_VEC_ELT (label_vec, 0) = t;
3234 make_edge (l0_bb, l2_bb, 0);
3236 /* Convert each OMP_SECTION into a CASE_LABEL_EXPR. */
3237 for (inner = region->inner, i = 1; inner; inner = inner->next, ++i)
3239 basic_block s_entry_bb, s_exit_bb;
3241 s_entry_bb = inner->entry;
3242 s_exit_bb = inner->exit;
3244 t = tree_block_label (s_entry_bb);
3245 u = build_int_cst (unsigned_type_node, i);
3246 u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
3247 TREE_VEC_ELT (label_vec, i) = u;
3249 si = bsi_last (s_entry_bb);
3250 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTION);
3251 gcc_assert (i < len || OMP_SECTION_LAST (bsi_stmt (si)));
3252 bsi_remove (&si, true);
3254 e = single_pred_edge (s_entry_bb);
3256 redirect_edge_pred (e, l0_bb);
3258 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
3260 if (s_exit_bb == NULL)
3263 si = bsi_last (s_exit_bb);
3264 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3265 bsi_remove (&si, true);
3267 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
3270 /* Error handling code goes in DEFAULT_BB. */
3271 t = tree_block_label (default_bb);
3272 u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
3273 TREE_VEC_ELT (label_vec, len + 1) = u;
3274 make_edge (l0_bb, default_bb, 0);
3276 si = bsi_start (default_bb);
3277 t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
3278 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3280 /* Code to get the next section goes in L1_BB. */
3283 si = bsi_last (l1_bb);
3284 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3286 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
3287 t = build_gimple_modify_stmt (v, t);
3288 bsi_insert_after (&si, t, BSI_SAME_STMT);
3289 bsi_remove (&si, true);
3292 /* Cleanup function replaces OMP_RETURN in EXIT_BB. */
3295 si = bsi_last (exit_bb);
3296 if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
3297 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
3299 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
3300 t = build_call_expr (t, 0);
3301 bsi_insert_after (&si, t, BSI_SAME_STMT);
3302 bsi_remove (&si, true);
3305 /* Connect the new blocks. */
3306 if (is_combined_parallel (region))
3308 /* If this was a combined parallel+sections region, we did not
3309 emit a GOMP_sections_start in the entry block, so we just
3310 need to jump to L1_BB to get the next section. */
3311 make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
3314 make_edge (entry_bb, l0_bb, EDGE_FALLTHRU);
3318 e = single_succ_edge (l1_bb);
3319 redirect_edge_succ (e, l0_bb);
3320 e->flags = EDGE_FALLTHRU;
3325 /* Expand code for an OpenMP single directive. We've already expanded
3326 much of the code, here we simply place the GOMP_barrier call. */
3329 expand_omp_single (struct omp_region *region)
3331 basic_block entry_bb, exit_bb;
3332 block_stmt_iterator si;
3333 bool need_barrier = false;
3335 entry_bb = region->entry;
3336 exit_bb = region->exit;
3338 si = bsi_last (entry_bb);
3339 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
3340 be removed. We need to ensure that the thread that entered the single
3341 does not exit before the data is copied out by the other threads. */
3342 if (find_omp_clause (OMP_SINGLE_CLAUSES (bsi_stmt (si)),
3343 OMP_CLAUSE_COPYPRIVATE))
3344 need_barrier = true;
3345 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE);
3346 bsi_remove (&si, true);
3347 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3349 si = bsi_last (exit_bb);
3350 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)) || need_barrier)
3352 tree t = alloc_stmt_list ();
3353 build_omp_barrier (&t);
3354 bsi_insert_after (&si, t, BSI_SAME_STMT);
3356 bsi_remove (&si, true);
3357 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3361 /* Generic expansion for OpenMP synchronization directives: master,
3362 ordered and critical. All we need to do here is remove the entry
3363 and exit markers for REGION. */
3366 expand_omp_synch (struct omp_region *region)
3368 basic_block entry_bb, exit_bb;
3369 block_stmt_iterator si;
3371 entry_bb = region->entry;
3372 exit_bb = region->exit;
3374 si = bsi_last (entry_bb);
3375 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE
3376 || TREE_CODE (bsi_stmt (si)) == OMP_MASTER
3377 || TREE_CODE (bsi_stmt (si)) == OMP_ORDERED
3378 || TREE_CODE (bsi_stmt (si)) == OMP_CRITICAL);
3379 bsi_remove (&si, true);
3380 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3384 si = bsi_last (exit_bb);
3385 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3386 bsi_remove (&si, true);
3387 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3392 /* Expand the parallel region tree rooted at REGION. Expansion
3393 proceeds in depth-first order. Innermost regions are expanded
3394 first. This way, parallel regions that require a new function to
3395 be created (e.g., OMP_PARALLEL) can be expanded without having any
3396 internal dependencies in their body. */
3399 expand_omp (struct omp_region *region)
3404 expand_omp (region->inner);
3406 switch (region->type)
3409 expand_omp_parallel (region);
3413 expand_omp_for (region);
3417 expand_omp_sections (region);
3421 /* Individual omp sections are handled together with their
3422 parent OMP_SECTIONS region. */
3426 expand_omp_single (region);
3432 expand_omp_synch (region);
3439 region = region->next;
3444 /* Helper for build_omp_regions. Scan the dominator tree starting at
3445 block BB. PARENT is the region that contains BB. */
3448 build_omp_regions_1 (basic_block bb, struct omp_region *parent)
3450 block_stmt_iterator si;
3455 if (!bsi_end_p (si) && OMP_DIRECTIVE_P (bsi_stmt (si)))
3457 struct omp_region *region;
3458 enum tree_code code;
3460 stmt = bsi_stmt (si);
3461 code = TREE_CODE (stmt);
3463 if (code == OMP_RETURN)
3465 /* STMT is the return point out of region PARENT. Mark it
3466 as the exit point and make PARENT the immediately
3467 enclosing region. */
3468 gcc_assert (parent);
3471 parent = parent->outer;
3473 /* If REGION is a parallel region, determine whether it is
3474 a combined parallel+workshare region. */
3475 if (region->type == OMP_PARALLEL)
3476 determine_parallel_type (region);
3478 else if (code == OMP_CONTINUE)
3480 gcc_assert (parent);
3485 /* Otherwise, this directive becomes the parent for a new
3487 region = new_omp_region (bb, code, parent);
3492 for (son = first_dom_son (CDI_DOMINATORS, bb);
3494 son = next_dom_son (CDI_DOMINATORS, son))
3495 build_omp_regions_1 (son, parent);
3499 /* Scan the CFG and build a tree of OMP regions. Return the root of
3500 the OMP region tree. */
3503 build_omp_regions (void)
3505 gcc_assert (root_omp_region == NULL);
3506 calculate_dominance_info (CDI_DOMINATORS);
3507 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL);
3511 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
3514 execute_expand_omp (void)
3516 build_omp_regions ();
3518 if (!root_omp_region)
3523 fprintf (dump_file, "\nOMP region tree\n\n");
3524 dump_omp_region (dump_file, root_omp_region, 0);
3525 fprintf (dump_file, "\n");
3528 remove_exit_barriers (root_omp_region);
3530 expand_omp (root_omp_region);
3532 free_dominance_info (CDI_DOMINATORS);
3533 free_dominance_info (CDI_POST_DOMINATORS);
3534 cleanup_tree_cfg ();
3536 free_omp_regions ();
3542 gate_expand_omp (void)
3544 return flag_openmp != 0 && errorcount == 0;
3547 struct tree_opt_pass pass_expand_omp =
3549 "ompexp", /* name */
3550 gate_expand_omp, /* gate */
3551 execute_expand_omp, /* execute */
3554 0, /* static_pass_number */
3556 PROP_gimple_any, /* properties_required */
3557 PROP_gimple_lomp, /* properties_provided */
3558 0, /* properties_destroyed */
3559 0, /* todo_flags_start */
3560 TODO_dump_func, /* todo_flags_finish */
3564 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
3566 /* Lower the OpenMP sections directive in *STMT_P. */
3569 lower_omp_sections (tree *stmt_p, omp_context *ctx)
3571 tree new_stmt, stmt, body, bind, block, ilist, olist, new_body;
3573 tree_stmt_iterator tsi;
3578 push_gimplify_context ();
3582 lower_rec_input_clauses (OMP_SECTIONS_CLAUSES (stmt), &ilist, &dlist, ctx);
3584 tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3585 for (len = 0; !tsi_end_p (tsi); len++, tsi_next (&tsi))
3588 tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3589 body = alloc_stmt_list ();
3590 for (i = 0; i < len; i++, tsi_next (&tsi))
3593 tree sec_start, sec_end;
3595 sec_start = tsi_stmt (tsi);
3596 sctx = maybe_lookup_ctx (sec_start);
3599 append_to_statement_list (sec_start, &body);
3601 lower_omp (&OMP_SECTION_BODY (sec_start), sctx);
3602 append_to_statement_list (OMP_SECTION_BODY (sec_start), &body);
3603 OMP_SECTION_BODY (sec_start) = NULL;
3607 tree l = alloc_stmt_list ();
3608 lower_lastprivate_clauses (OMP_SECTIONS_CLAUSES (stmt), NULL,
3610 append_to_statement_list (l, &body);
3611 OMP_SECTION_LAST (sec_start) = 1;
3614 sec_end = make_node (OMP_RETURN);
3615 append_to_statement_list (sec_end, &body);
3618 block = make_node (BLOCK);
3619 bind = build3 (BIND_EXPR, void_type_node, NULL, body, block);
3622 lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
3624 pop_gimplify_context (NULL_TREE);
3625 record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
3627 new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3628 TREE_SIDE_EFFECTS (new_stmt) = 1;
3630 new_body = alloc_stmt_list ();
3631 append_to_statement_list (ilist, &new_body);
3632 append_to_statement_list (stmt, &new_body);
3633 append_to_statement_list (bind, &new_body);
3635 t = make_node (OMP_CONTINUE);
3636 append_to_statement_list (t, &new_body);
3638 append_to_statement_list (olist, &new_body);
3639 append_to_statement_list (dlist, &new_body);
3641 maybe_catch_exception (&new_body);
3643 t = make_node (OMP_RETURN);
3644 OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SECTIONS_CLAUSES (stmt),
3646 append_to_statement_list (t, &new_body);
3648 BIND_EXPR_BODY (new_stmt) = new_body;
3649 OMP_SECTIONS_BODY (stmt) = NULL;
3655 /* A subroutine of lower_omp_single. Expand the simple form of
3656 an OMP_SINGLE, without a copyprivate clause:
3658 if (GOMP_single_start ())
3660 [ GOMP_barrier (); ] -> unless 'nowait' is present.
3662 FIXME. It may be better to delay expanding the logic of this until
3663 pass_expand_omp. The expanded logic may make the job more difficult
3664 to a synchronization analysis pass. */
3667 lower_omp_single_simple (tree single_stmt, tree *pre_p)
3671 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_START], 0);
3672 t = build3 (COND_EXPR, void_type_node, t,
3673 OMP_SINGLE_BODY (single_stmt), NULL);
3674 gimplify_and_add (t, pre_p);
3678 /* A subroutine of lower_omp_single. Expand the simple form of
3679 an OMP_SINGLE, with a copyprivate clause:
3681 #pragma omp single copyprivate (a, b, c)
3683 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
3686 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
3692 GOMP_single_copy_end (©out);
3703 FIXME. It may be better to delay expanding the logic of this until
3704 pass_expand_omp. The expanded logic may make the job more difficult
3705 to a synchronization analysis pass. */
3708 lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
3710 tree ptr_type, t, l0, l1, l2, copyin_seq;
3712 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
3714 ptr_type = build_pointer_type (ctx->record_type);
3715 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
3717 l0 = create_artificial_label ();
3718 l1 = create_artificial_label ();
3719 l2 = create_artificial_label ();
3721 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
3722 t = fold_convert (ptr_type, t);
3723 t = build_gimple_modify_stmt (ctx->receiver_decl, t);
3724 gimplify_and_add (t, pre_p);
3726 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
3727 build_int_cst (ptr_type, 0));
3728 t = build3 (COND_EXPR, void_type_node, t,
3729 build_and_jump (&l0), build_and_jump (&l1));
3730 gimplify_and_add (t, pre_p);
3732 t = build1 (LABEL_EXPR, void_type_node, l0);
3733 gimplify_and_add (t, pre_p);
3735 append_to_statement_list (OMP_SINGLE_BODY (single_stmt), pre_p);
3738 lower_copyprivate_clauses (OMP_SINGLE_CLAUSES (single_stmt), pre_p,
3741 t = build_fold_addr_expr (ctx->sender_decl);
3742 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END], 1, t);
3743 gimplify_and_add (t, pre_p);
3745 t = build_and_jump (&l2);
3746 gimplify_and_add (t, pre_p);
3748 t = build1 (LABEL_EXPR, void_type_node, l1);
3749 gimplify_and_add (t, pre_p);
3751 append_to_statement_list (copyin_seq, pre_p);
3753 t = build1 (LABEL_EXPR, void_type_node, l2);
3754 gimplify_and_add (t, pre_p);
3758 /* Expand code for an OpenMP single directive. */
3761 lower_omp_single (tree *stmt_p, omp_context *ctx)
3763 tree t, bind, block, single_stmt = *stmt_p, dlist;
3765 push_gimplify_context ();
3767 block = make_node (BLOCK);
3768 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3769 TREE_SIDE_EFFECTS (bind) = 1;
3771 lower_rec_input_clauses (OMP_SINGLE_CLAUSES (single_stmt),
3772 &BIND_EXPR_BODY (bind), &dlist, ctx);
3773 lower_omp (&OMP_SINGLE_BODY (single_stmt), ctx);
3775 append_to_statement_list (single_stmt, &BIND_EXPR_BODY (bind));
3777 if (ctx->record_type)
3778 lower_omp_single_copy (single_stmt, &BIND_EXPR_BODY (bind), ctx);
3780 lower_omp_single_simple (single_stmt, &BIND_EXPR_BODY (bind));
3782 OMP_SINGLE_BODY (single_stmt) = NULL;
3784 append_to_statement_list (dlist, &BIND_EXPR_BODY (bind));
3786 maybe_catch_exception (&BIND_EXPR_BODY (bind));
3788 t = make_node (OMP_RETURN);
3789 OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SINGLE_CLAUSES (single_stmt),
3791 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3793 pop_gimplify_context (bind);
3795 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3796 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3800 /* Expand code for an OpenMP master directive. */
3803 lower_omp_master (tree *stmt_p, omp_context *ctx)
3805 tree bind, block, stmt = *stmt_p, lab = NULL, x;
3807 push_gimplify_context ();
3809 block = make_node (BLOCK);
3810 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3811 TREE_SIDE_EFFECTS (bind) = 1;
3813 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3815 x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
3816 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
3817 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
3818 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3820 lower_omp (&OMP_MASTER_BODY (stmt), ctx);
3821 maybe_catch_exception (&OMP_MASTER_BODY (stmt));
3822 append_to_statement_list (OMP_MASTER_BODY (stmt), &BIND_EXPR_BODY (bind));
3823 OMP_MASTER_BODY (stmt) = NULL;
3825 x = build1 (LABEL_EXPR, void_type_node, lab);
3826 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3828 x = make_node (OMP_RETURN);
3829 OMP_RETURN_NOWAIT (x) = 1;
3830 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
3832 pop_gimplify_context (bind);
3834 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3835 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3839 /* Expand code for an OpenMP ordered directive. */
3842 lower_omp_ordered (tree *stmt_p, omp_context *ctx)
3844 tree bind, block, stmt = *stmt_p, x;
3846 push_gimplify_context ();
3848 block = make_node (BLOCK);
3849 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3850 TREE_SIDE_EFFECTS (bind) = 1;
3852 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3854 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
3855 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3857 lower_omp (&OMP_ORDERED_BODY (stmt), ctx);
3858 maybe_catch_exception (&OMP_ORDERED_BODY (stmt));
3859 append_to_statement_list (OMP_ORDERED_BODY (stmt), &BIND_EXPR_BODY (bind));
3860 OMP_ORDERED_BODY (stmt) = NULL;
3862 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
3863 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3865 x = make_node (OMP_RETURN);
3866 OMP_RETURN_NOWAIT (x) = 1;
3867 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
3869 pop_gimplify_context (bind);
3871 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3872 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3876 /* Gimplify an OMP_CRITICAL statement. This is a relatively simple
3877 substitution of a couple of function calls. But in the NAMED case,
3878 requires that languages coordinate a symbol name. It is therefore
3879 best put here in common code. */
3881 static GTY((param1_is (tree), param2_is (tree)))
3882 splay_tree critical_name_mutexes;
3885 lower_omp_critical (tree *stmt_p, omp_context *ctx)
3887 tree bind, block, stmt = *stmt_p;
3888 tree t, lock, unlock, name;
3890 name = OMP_CRITICAL_NAME (stmt);
3896 if (!critical_name_mutexes)
3897 critical_name_mutexes
3898 = splay_tree_new_ggc (splay_tree_compare_pointers);
3900 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
3905 decl = create_tmp_var_raw (ptr_type_node, NULL);
3907 new_str = ACONCAT ((".gomp_critical_user_",
3908 IDENTIFIER_POINTER (name), NULL));
3909 DECL_NAME (decl) = get_identifier (new_str);
3910 TREE_PUBLIC (decl) = 1;
3911 TREE_STATIC (decl) = 1;
3912 DECL_COMMON (decl) = 1;
3913 DECL_ARTIFICIAL (decl) = 1;
3914 DECL_IGNORED_P (decl) = 1;
3915 varpool_finalize_decl (decl);
3917 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
3918 (splay_tree_value) decl);
3921 decl = (tree) n->value;
3923 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
3924 lock = build_call_expr (lock, 1, build_fold_addr_expr (decl));
3926 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
3927 unlock = build_call_expr (unlock, 1, build_fold_addr_expr (decl));
3931 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
3932 lock = build_call_expr (lock, 0);
3934 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
3935 unlock = build_call_expr (unlock, 0);
3938 push_gimplify_context ();
3940 block = make_node (BLOCK);
3941 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3942 TREE_SIDE_EFFECTS (bind) = 1;
3944 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3946 gimplify_and_add (lock, &BIND_EXPR_BODY (bind));
3948 lower_omp (&OMP_CRITICAL_BODY (stmt), ctx);
3949 maybe_catch_exception (&OMP_CRITICAL_BODY (stmt));
3950 append_to_statement_list (OMP_CRITICAL_BODY (stmt), &BIND_EXPR_BODY (bind));
3951 OMP_CRITICAL_BODY (stmt) = NULL;
3953 gimplify_and_add (unlock, &BIND_EXPR_BODY (bind));
3955 t = make_node (OMP_RETURN);
3956 OMP_RETURN_NOWAIT (t) = 1;
3957 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3959 pop_gimplify_context (bind);
3960 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3961 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3965 /* A subroutine of lower_omp_for. Generate code to emit the predicate
3966 for a lastprivate clause. Given a loop control predicate of (V
3967 cond N2), we gate the clause on (!(V cond N2)). The lowered form
3968 is appended to *DLIST, iterator initialization is appended to
3972 lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
3973 tree *dlist, struct omp_context *ctx)
3975 tree clauses, cond, stmts, vinit, t;
3976 enum tree_code cond_code;
3978 cond_code = fd->cond_code;
3979 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
3981 /* When possible, use a strict equality expression. This can let VRP
3982 type optimizations deduce the value and remove a copy. */
3983 if (host_integerp (fd->step, 0))
3985 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->step);
3986 if (step == 1 || step == -1)
3987 cond_code = EQ_EXPR;
3990 cond = build2 (cond_code, boolean_type_node, fd->v, fd->n2);
3992 clauses = OMP_FOR_CLAUSES (fd->for_stmt);
3994 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
3997 append_to_statement_list (stmts, dlist);
3999 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
4001 if (cond_code == EQ_EXPR
4002 && host_integerp (fd->n2, 0)
4003 && ! integer_zerop (fd->n2))
4004 vinit = build_int_cst (TREE_TYPE (fd->v), 0);
4006 /* Initialize the iterator variable, so that threads that don't execute
4007 any iterations don't execute the lastprivate clauses by accident. */
4008 t = build_gimple_modify_stmt (fd->v, vinit);
4009 gimplify_and_add (t, body_p);
4014 /* Lower code for an OpenMP loop directive. */
4017 lower_omp_for (tree *stmt_p, omp_context *ctx)
4019 tree t, stmt, ilist, dlist, new_stmt, *body_p, *rhs_p;
4020 struct omp_for_data fd;
4024 push_gimplify_context ();
4026 lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
4027 lower_omp (&OMP_FOR_BODY (stmt), ctx);
4029 /* Move declaration of temporaries in the loop body before we make
4031 if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
4032 record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt)), ctx->cb.dst_fn);
4034 new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4035 TREE_SIDE_EFFECTS (new_stmt) = 1;
4036 body_p = &BIND_EXPR_BODY (new_stmt);
4038 /* The pre-body and input clauses go before the lowered OMP_FOR. */
4041 append_to_statement_list (OMP_FOR_PRE_BODY (stmt), body_p);
4042 lower_rec_input_clauses (OMP_FOR_CLAUSES (stmt), body_p, &dlist, ctx);
4044 /* Lower the header expressions. At this point, we can assume that
4045 the header is of the form:
4047 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
4049 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
4050 using the .omp_data_s mapping, if needed. */
4051 rhs_p = &GIMPLE_STMT_OPERAND (OMP_FOR_INIT (stmt), 1);
4052 if (!is_gimple_min_invariant (*rhs_p))
4053 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4055 rhs_p = &TREE_OPERAND (OMP_FOR_COND (stmt), 1);
4056 if (!is_gimple_min_invariant (*rhs_p))
4057 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4059 rhs_p = &TREE_OPERAND (GIMPLE_STMT_OPERAND (OMP_FOR_INCR (stmt), 1), 1);
4060 if (!is_gimple_min_invariant (*rhs_p))
4061 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4063 /* Once lowered, extract the bounds and clauses. */
4064 extract_omp_for_data (stmt, &fd);
4066 lower_omp_for_lastprivate (&fd, body_p, &dlist, ctx);
4068 append_to_statement_list (stmt, body_p);
4070 append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
4072 t = make_node (OMP_CONTINUE);
4073 append_to_statement_list (t, body_p);
4075 /* After the loop, add exit clauses. */
4076 lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
4077 append_to_statement_list (dlist, body_p);
4079 maybe_catch_exception (body_p);
4081 /* Region exit marker goes at the end of the loop body. */
4082 t = make_node (OMP_RETURN);
4083 OMP_RETURN_NOWAIT (t) = fd.have_nowait;
4084 append_to_statement_list (t, body_p);
4086 pop_gimplify_context (NULL_TREE);
4087 record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
4089 OMP_FOR_BODY (stmt) = NULL_TREE;
4090 OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
4095 /* Lower the OpenMP parallel directive in *STMT_P. CTX holds context
4096 information for the directive. */
4099 lower_omp_parallel (tree *stmt_p, omp_context *ctx)
4101 tree clauses, par_bind, par_body, new_body, bind;
4102 tree olist, ilist, par_olist, par_ilist;
4103 tree stmt, child_fn, t;
4107 clauses = OMP_PARALLEL_CLAUSES (stmt);
4108 par_bind = OMP_PARALLEL_BODY (stmt);
4109 par_body = BIND_EXPR_BODY (par_bind);
4110 child_fn = ctx->cb.dst_fn;
4112 push_gimplify_context ();
4114 par_olist = NULL_TREE;
4115 par_ilist = NULL_TREE;
4116 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
4117 lower_omp (&par_body, ctx);
4118 lower_reduction_clauses (clauses, &par_olist, ctx);
4120 /* Declare all the variables created by mapping and the variables
4121 declared in the scope of the parallel body. */
4122 record_vars_into (ctx->block_vars, child_fn);
4123 record_vars_into (BIND_EXPR_VARS (par_bind), child_fn);
4125 if (ctx->record_type)
4127 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_data_o");
4128 OMP_PARALLEL_DATA_ARG (stmt) = ctx->sender_decl;
4133 lower_send_clauses (clauses, &ilist, &olist, ctx);
4134 lower_send_shared_vars (&ilist, &olist, ctx);
4136 /* Once all the expansions are done, sequence all the different
4137 fragments inside OMP_PARALLEL_BODY. */
4138 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4139 append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
4141 new_body = alloc_stmt_list ();
4143 if (ctx->record_type)
4145 t = build_fold_addr_expr (ctx->sender_decl);
4146 /* fixup_child_record_type might have changed receiver_decl's type. */
4147 t = fold_convert (TREE_TYPE (ctx->receiver_decl), t);
4148 t = build_gimple_modify_stmt (ctx->receiver_decl, t);
4149 append_to_statement_list (t, &new_body);
4152 append_to_statement_list (par_ilist, &new_body);
4153 append_to_statement_list (par_body, &new_body);
4154 append_to_statement_list (par_olist, &new_body);
4155 maybe_catch_exception (&new_body);
4156 t = make_node (OMP_RETURN);
4157 append_to_statement_list (t, &new_body);
4158 OMP_PARALLEL_BODY (stmt) = new_body;
4160 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4161 append_to_statement_list (olist, &BIND_EXPR_BODY (bind));
4165 pop_gimplify_context (NULL_TREE);
4169 /* Pass *TP back through the gimplifier within the context determined by WI.
4170 This handles replacement of DECL_VALUE_EXPR, as well as adjusting the
4171 flags on ADDR_EXPR. */
4174 lower_regimplify (tree *tp, struct walk_stmt_info *wi)
4176 enum gimplify_status gs;
4180 gs = gimplify_expr (tp, &pre, NULL, is_gimple_lvalue, fb_lvalue);
4181 else if (wi->val_only)
4182 gs = gimplify_expr (tp, &pre, NULL, is_gimple_val, fb_rvalue);
4184 gs = gimplify_expr (tp, &pre, NULL, is_gimple_formal_tmp_var, fb_rvalue);
4185 gcc_assert (gs == GS_ALL_DONE);
4188 tsi_link_before (&wi->tsi, pre, TSI_SAME_STMT);
4191 /* Copy EXP into a temporary. Insert the initialization statement before TSI. */
4194 init_tmp_var (tree exp, tree_stmt_iterator *tsi)
4198 t = create_tmp_var (TREE_TYPE (exp), NULL);
4199 DECL_GIMPLE_REG_P (t) = 1;
4200 stmt = build_gimple_modify_stmt (t, exp);
4201 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4202 tsi_link_before (tsi, stmt, TSI_SAME_STMT);
4207 /* Similarly, but copy from the temporary and insert the statement
4208 after the iterator. */
4211 save_tmp_var (tree exp, tree_stmt_iterator *tsi)
4215 t = create_tmp_var (TREE_TYPE (exp), NULL);
4216 DECL_GIMPLE_REG_P (t) = 1;
4217 stmt = build_gimple_modify_stmt (exp, t);
4218 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4219 tsi_link_after (tsi, stmt, TSI_SAME_STMT);
4224 /* Callback for walk_stmts. Lower the OpenMP directive pointed by TP. */
4227 lower_omp_1 (tree *tp, int *walk_subtrees, void *data)
4229 struct walk_stmt_info *wi = data;
4230 omp_context *ctx = wi->info;
4233 /* If we have issued syntax errors, avoid doing any heavy lifting.
4234 Just replace the OpenMP directives with a NOP to avoid
4235 confusing RTL expansion. */
4236 if (errorcount && OMP_DIRECTIVE_P (*tp))
4238 *tp = build_empty_stmt ();
4243 switch (TREE_CODE (*tp))
4246 ctx = maybe_lookup_ctx (t);
4247 lower_omp_parallel (tp, ctx);
4251 ctx = maybe_lookup_ctx (t);
4253 lower_omp_for (tp, ctx);
4257 ctx = maybe_lookup_ctx (t);
4259 lower_omp_sections (tp, ctx);
4263 ctx = maybe_lookup_ctx (t);
4265 lower_omp_single (tp, ctx);
4269 ctx = maybe_lookup_ctx (t);
4271 lower_omp_master (tp, ctx);
4275 ctx = maybe_lookup_ctx (t);
4277 lower_omp_ordered (tp, ctx);
4281 ctx = maybe_lookup_ctx (t);
4283 lower_omp_critical (tp, ctx);
4287 if (ctx && DECL_HAS_VALUE_EXPR_P (t))
4289 lower_regimplify (&t, wi);
4293 t = save_tmp_var (t, &wi->tsi);
4295 t = init_tmp_var (t, &wi->tsi);
4303 lower_regimplify (tp, wi);
4307 case ARRAY_RANGE_REF:
4311 case VIEW_CONVERT_EXPR:
4313 lower_regimplify (tp, wi);
4320 wi->val_only = true;
4321 lower_regimplify (&TREE_OPERAND (t, 0), wi);
4326 if (!TYPE_P (t) && !DECL_P (t))
4335 lower_omp (tree *stmt_p, omp_context *ctx)
4337 struct walk_stmt_info wi;
4339 memset (&wi, 0, sizeof (wi));
4340 wi.callback = lower_omp_1;
4343 wi.want_locations = true;
4345 walk_stmts (&wi, stmt_p);
4348 /* Main entry point. */
4351 execute_lower_omp (void)
4353 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
4354 delete_omp_context);
4356 scan_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4357 gcc_assert (parallel_nesting_level == 0);
4359 if (all_contexts->root)
4360 lower_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4364 splay_tree_delete (all_contexts);
4365 all_contexts = NULL;
4371 gate_lower_omp (void)
4373 return flag_openmp != 0;
4376 struct tree_opt_pass pass_lower_omp =
4378 "omplower", /* name */
4379 gate_lower_omp, /* gate */
4380 execute_lower_omp, /* execute */
4383 0, /* static_pass_number */
4385 PROP_gimple_any, /* properties_required */
4386 PROP_gimple_lomp, /* properties_provided */
4387 0, /* properties_destroyed */
4388 0, /* todo_flags_start */
4389 TODO_dump_func, /* todo_flags_finish */
4393 /* The following is a utility to diagnose OpenMP structured block violations.
4394 It is not part of the "omplower" pass, as that's invoked too late. It
4395 should be invoked by the respective front ends after gimplification. */
4397 static splay_tree all_labels;
4399 /* Check for mismatched contexts and generate an error if needed. Return
4400 true if an error is detected. */
4403 diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
4407 if ((label_ctx ? TREE_VALUE (label_ctx) : NULL) == branch_ctx)
4410 /* Try to avoid confusing the user by producing and error message
4411 with correct "exit" or "enter" verbage. We prefer "exit"
4412 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
4413 if (branch_ctx == NULL)
4419 if (TREE_VALUE (label_ctx) == branch_ctx)
4424 label_ctx = TREE_CHAIN (label_ctx);
4429 error ("invalid exit from OpenMP structured block");
4431 error ("invalid entry to OpenMP structured block");
4433 *stmt_p = build_empty_stmt ();
4437 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
4438 where in the tree each label is found. */
4441 diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
4443 struct walk_stmt_info *wi = data;
4444 tree context = (tree) wi->info;
4449 switch (TREE_CODE (t))
4454 walk_tree (&OMP_CLAUSES (t), diagnose_sb_1, wi, NULL);
4460 /* The minimal context here is just a tree of statements. */
4461 inner_context = tree_cons (NULL, t, context);
4462 wi->info = inner_context;
4463 walk_stmts (wi, &OMP_BODY (t));
4468 walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_1, wi, NULL);
4469 inner_context = tree_cons (NULL, t, context);
4470 wi->info = inner_context;
4471 walk_tree (&OMP_FOR_INIT (t), diagnose_sb_1, wi, NULL);
4472 walk_tree (&OMP_FOR_COND (t), diagnose_sb_1, wi, NULL);
4473 walk_tree (&OMP_FOR_INCR (t), diagnose_sb_1, wi, NULL);
4474 walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4475 walk_stmts (wi, &OMP_FOR_BODY (t));
4480 splay_tree_insert (all_labels, (splay_tree_key) LABEL_EXPR_LABEL (t),
4481 (splay_tree_value) context);
4491 /* Pass 2: Check each branch and see if its context differs from that of
4492 the destination label's context. */
4495 diagnose_sb_2 (tree *tp, int *walk_subtrees, void *data)
4497 struct walk_stmt_info *wi = data;
4498 tree context = (tree) wi->info;
4503 switch (TREE_CODE (t))
4508 walk_tree (&OMP_CLAUSES (t), diagnose_sb_2, wi, NULL);
4515 walk_stmts (wi, &OMP_BODY (t));
4520 walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_2, wi, NULL);
4522 walk_tree (&OMP_FOR_INIT (t), diagnose_sb_2, wi, NULL);
4523 walk_tree (&OMP_FOR_COND (t), diagnose_sb_2, wi, NULL);
4524 walk_tree (&OMP_FOR_INCR (t), diagnose_sb_2, wi, NULL);
4525 walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4526 walk_stmts (wi, &OMP_FOR_BODY (t));
4532 tree lab = GOTO_DESTINATION (t);
4533 if (TREE_CODE (lab) != LABEL_DECL)
4536 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4537 diagnose_sb_0 (tp, context, n ? (tree) n->value : NULL_TREE);
4543 tree vec = SWITCH_LABELS (t);
4544 int i, len = TREE_VEC_LENGTH (vec);
4545 for (i = 0; i < len; ++i)
4547 tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
4548 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4549 if (diagnose_sb_0 (tp, context, (tree) n->value))
4556 diagnose_sb_0 (tp, context, NULL_TREE);
4567 diagnose_omp_structured_block_errors (tree fndecl)
4569 tree save_current = current_function_decl;
4570 struct walk_stmt_info wi;
4572 current_function_decl = fndecl;
4574 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
4576 memset (&wi, 0, sizeof (wi));
4577 wi.callback = diagnose_sb_1;
4578 walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4580 memset (&wi, 0, sizeof (wi));
4581 wi.callback = diagnose_sb_2;
4582 wi.want_locations = true;
4583 wi.want_return_expr = true;
4584 walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4586 splay_tree_delete (all_labels);
4589 current_function_decl = save_current;
4592 #include "gt-omp-low.h"