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 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"
46 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
47 phases. The first phase scans the function looking for OMP statements
48 and then for variables that must be replaced to satisfy data sharing
49 clauses. The second phase expands code for the constructs, as well as
50 re-gimplifying things when variables have been replaced with complex
53 Final code generation is done by pass_expand_omp. The flowgraph is
54 scanned for parallel regions which are then moved to a new
55 function, to be invoked by the thread library. */
57 /* Context structure. Used to store information about each parallel
58 directive in the code. */
60 typedef struct omp_context
62 /* This field must be at the beginning, as we do "inheritance": Some
63 callback functions for tree-inline.c (e.g., omp_copy_decl)
64 receive a copy_body_data pointer that is up-casted to an
65 omp_context pointer. */
68 /* The tree of contexts corresponding to the encountered constructs. */
69 struct omp_context *outer;
72 /* Map variables to fields in a structure that allows communication
73 between sending and receiving threads. */
79 /* A chain of variables to add to the top-level block surrounding the
80 construct. In the case of a parallel, this is in the child function. */
83 /* What to do with variables with implicitly determined sharing
85 enum omp_clause_default_kind default_kind;
87 /* Nesting depth of this context. Used to beautify error messages re
88 invalid gotos. The outermost ctx is depth 1, with depth 0 being
89 reserved for the main body of the function. */
92 /* True if this parallel directive is nested within another. */
97 /* A structure describing the main elements of a parallel loop. */
101 tree v, n1, n2, step, chunk_size, for_stmt;
102 enum tree_code cond_code;
104 bool have_nowait, have_ordered;
105 enum omp_clause_schedule_kind sched_kind;
109 static splay_tree all_contexts;
110 static int parallel_nesting_level;
111 struct omp_region *root_omp_region;
113 static void scan_omp (tree *, omp_context *);
114 static void lower_omp (tree *, omp_context *);
115 static tree lookup_decl_in_outer_ctx (tree, omp_context *);
116 static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
118 /* Find an OpenMP clause of type KIND within CLAUSES. */
121 find_omp_clause (tree clauses, enum tree_code kind)
123 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
124 if (OMP_CLAUSE_CODE (clauses) == kind)
130 /* Return true if CTX is for an omp parallel. */
133 is_parallel_ctx (omp_context *ctx)
135 return TREE_CODE (ctx->stmt) == OMP_PARALLEL;
139 /* Return true if REGION is a combined parallel+workshare region. */
142 is_combined_parallel (struct omp_region *region)
144 return region->is_combined_parallel;
148 /* Extract the header elements of parallel loop FOR_STMT and store
152 extract_omp_for_data (tree for_stmt, struct omp_for_data *fd)
156 fd->for_stmt = for_stmt;
159 t = OMP_FOR_INIT (for_stmt);
160 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
161 fd->v = TREE_OPERAND (t, 0);
162 gcc_assert (DECL_P (fd->v));
163 gcc_assert (TREE_CODE (TREE_TYPE (fd->v)) == INTEGER_TYPE);
164 fd->n1 = TREE_OPERAND (t, 1);
166 t = OMP_FOR_COND (for_stmt);
167 fd->cond_code = TREE_CODE (t);
168 gcc_assert (TREE_OPERAND (t, 0) == fd->v);
169 fd->n2 = TREE_OPERAND (t, 1);
170 switch (fd->cond_code)
176 fd->n2 = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->n2), fd->n2,
177 build_int_cst (TREE_TYPE (fd->n2), 1));
178 fd->cond_code = LT_EXPR;
181 fd->n2 = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->n2), fd->n2,
182 build_int_cst (TREE_TYPE (fd->n2), 1));
183 fd->cond_code = GT_EXPR;
189 t = OMP_FOR_INCR (fd->for_stmt);
190 gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
191 gcc_assert (TREE_OPERAND (t, 0) == fd->v);
192 t = TREE_OPERAND (t, 1);
193 gcc_assert (TREE_OPERAND (t, 0) == fd->v);
194 switch (TREE_CODE (t))
197 fd->step = TREE_OPERAND (t, 1);
200 fd->step = TREE_OPERAND (t, 1);
201 fd->step = fold_build1 (NEGATE_EXPR, TREE_TYPE (fd->step), fd->step);
207 fd->have_nowait = fd->have_ordered = false;
208 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
209 fd->chunk_size = NULL_TREE;
211 for (t = OMP_FOR_CLAUSES (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
212 switch (OMP_CLAUSE_CODE (t))
214 case OMP_CLAUSE_NOWAIT:
215 fd->have_nowait = true;
217 case OMP_CLAUSE_ORDERED:
218 fd->have_ordered = true;
220 case OMP_CLAUSE_SCHEDULE:
221 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
222 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
228 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
229 gcc_assert (fd->chunk_size == NULL);
230 else if (fd->chunk_size == NULL)
232 /* We only need to compute a default chunk size for ordered
233 static loops and dynamic loops. */
234 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC || fd->have_ordered)
235 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
236 ? integer_zero_node : integer_one_node;
241 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
242 is the immediate dominator of PAR_ENTRY_BB, return true if there
243 are no data dependencies that would prevent expanding the parallel
244 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
246 When expanding a combined parallel+workshare region, the call to
247 the child function may need additional arguments in the case of
248 OMP_FOR regions. In some cases, these arguments are computed out
249 of variables passed in from the parent to the child via 'struct
250 .omp_data_s'. For instance:
252 #pragma omp parallel for schedule (guided, i * 4)
257 # BLOCK 2 (PAR_ENTRY_BB)
259 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
261 # BLOCK 3 (WS_ENTRY_BB)
262 .omp_data_i = &.omp_data_o;
263 D.1667 = .omp_data_i->i;
265 #pragma omp for schedule (guided, D.1598)
267 When we outline the parallel region, the call to the child function
268 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
269 that value is computed *after* the call site. So, in principle we
270 cannot do the transformation.
272 To see whether the code in WS_ENTRY_BB blocks the combined
273 parallel+workshare call, we collect all the variables used in the
274 OMP_FOR header check whether they appear on the LHS of any
275 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
278 FIXME. If we had the SSA form built at this point, we could merely
279 hoist the code in block 3 into block 2 and be done with it. But at
280 this point we don't have dataflow information and though we could
281 hack something up here, it is really not worth the aggravation. */
284 workshare_safe_to_combine_p (basic_block par_entry_bb, basic_block ws_entry_bb)
286 struct omp_for_data fd;
287 tree par_stmt, ws_stmt;
289 par_stmt = last_stmt (par_entry_bb);
290 ws_stmt = last_stmt (ws_entry_bb);
292 if (TREE_CODE (ws_stmt) == OMP_SECTIONS)
295 gcc_assert (TREE_CODE (ws_stmt) == OMP_FOR);
297 extract_omp_for_data (ws_stmt, &fd);
299 /* FIXME. We give up too easily here. If any of these arguments
300 are not constants, they will likely involve variables that have
301 been mapped into fields of .omp_data_s for sharing with the child
302 function. With appropriate data flow, it would be possible to
304 if (!is_gimple_min_invariant (fd.n1)
305 || !is_gimple_min_invariant (fd.n2)
306 || !is_gimple_min_invariant (fd.step)
307 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
314 /* Collect additional arguments needed to emit a combined
315 parallel+workshare call. WS_STMT is the workshare directive being
319 get_ws_args_for (tree ws_stmt)
323 if (TREE_CODE (ws_stmt) == OMP_FOR)
325 struct omp_for_data fd;
328 extract_omp_for_data (ws_stmt, &fd);
333 t = fold_convert (long_integer_type_node, fd.chunk_size);
334 ws_args = tree_cons (NULL, t, ws_args);
337 t = fold_convert (long_integer_type_node, fd.step);
338 ws_args = tree_cons (NULL, t, ws_args);
340 t = fold_convert (long_integer_type_node, fd.n2);
341 ws_args = tree_cons (NULL, t, ws_args);
343 t = fold_convert (long_integer_type_node, fd.n1);
344 ws_args = tree_cons (NULL, t, ws_args);
348 else if (TREE_CODE (ws_stmt) == OMP_SECTIONS)
350 basic_block bb = bb_for_stmt (ws_stmt);
351 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs));
352 t = tree_cons (NULL, t, NULL);
360 /* Discover whether REGION is a combined parallel+workshare region. */
363 determine_parallel_type (struct omp_region *region)
365 basic_block par_entry_bb, par_exit_bb;
366 basic_block ws_entry_bb, ws_exit_bb;
368 if (region == NULL || region->inner == NULL)
371 /* We only support parallel+for and parallel+sections. */
372 if (region->type != OMP_PARALLEL
373 || (region->inner->type != OMP_FOR
374 && region->inner->type != OMP_SECTIONS))
377 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
378 WS_EXIT_BB -> PAR_EXIT_BB. */
379 par_entry_bb = region->entry;
380 par_exit_bb = region->exit;
381 ws_entry_bb = region->inner->entry;
382 ws_exit_bb = region->inner->exit;
384 if (single_succ (par_entry_bb) == ws_entry_bb
385 && single_succ (ws_exit_bb) == par_exit_bb
386 && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb))
388 tree ws_stmt = last_stmt (region->inner->entry);
390 if (region->inner->type == OMP_FOR)
392 /* If this is a combined parallel loop, we need to determine
393 whether or not to use the combined library calls. There
394 are two cases where we do not apply the transformation:
395 static loops and any kind of ordered loop. In the first
396 case, we already open code the loop so there is no need
397 to do anything else. In the latter case, the combined
398 parallel loop call would still need extra synchronization
399 to implement ordered semantics, so there would not be any
400 gain in using the combined call. */
401 tree clauses = OMP_FOR_CLAUSES (ws_stmt);
402 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
404 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
405 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
407 region->is_combined_parallel = false;
408 region->inner->is_combined_parallel = false;
413 region->is_combined_parallel = true;
414 region->inner->is_combined_parallel = true;
415 region->ws_args = get_ws_args_for (ws_stmt);
420 /* Return true if EXPR is variable sized. */
423 is_variable_sized (tree expr)
425 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
428 /* Return true if DECL is a reference type. */
431 is_reference (tree decl)
433 return lang_hooks.decls.omp_privatize_by_reference (decl);
436 /* Lookup variables in the decl or field splay trees. The "maybe" form
437 allows for the variable form to not have been entered, otherwise we
438 assert that the variable must have been entered. */
441 lookup_decl (tree var, omp_context *ctx)
444 n = splay_tree_lookup (ctx->cb.decl_map, (splay_tree_key) var);
445 return (tree) n->value;
449 maybe_lookup_decl (tree var, omp_context *ctx)
452 n = splay_tree_lookup (ctx->cb.decl_map, (splay_tree_key) var);
453 return n ? (tree) n->value : NULL_TREE;
457 lookup_field (tree var, omp_context *ctx)
460 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
461 return (tree) n->value;
465 maybe_lookup_field (tree var, omp_context *ctx)
468 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
469 return n ? (tree) n->value : NULL_TREE;
472 /* Return true if DECL should be copied by pointer. SHARED_P is true
473 if DECL is to be shared. */
476 use_pointer_for_field (tree decl, bool shared_p)
478 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
481 /* We can only use copy-in/copy-out semantics for shared varibles
482 when we know the value is not accessible from an outer scope. */
485 /* ??? Trivially accessible from anywhere. But why would we even
486 be passing an address in this case? Should we simply assert
487 this to be false, or should we have a cleanup pass that removes
488 these from the list of mappings? */
489 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
492 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
493 without analyzing the expression whether or not its location
494 is accessible to anyone else. In the case of nested parallel
495 regions it certainly may be. */
496 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
499 /* Do not use copy-in/copy-out for variables that have their
501 if (TREE_ADDRESSABLE (decl))
508 /* Construct a new automatic decl similar to VAR. */
511 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
513 tree copy = build_decl (VAR_DECL, name, type);
515 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
516 DECL_COMPLEX_GIMPLE_REG_P (copy) = DECL_COMPLEX_GIMPLE_REG_P (var);
517 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
518 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
519 TREE_USED (copy) = 1;
520 DECL_CONTEXT (copy) = current_function_decl;
521 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
523 TREE_CHAIN (copy) = ctx->block_vars;
524 ctx->block_vars = copy;
530 omp_copy_decl_1 (tree var, omp_context *ctx)
532 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
535 /* Build tree nodes to access the field for VAR on the receiver side. */
538 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
540 tree x, field = lookup_field (var, ctx);
542 /* If the receiver record type was remapped in the child function,
543 remap the field into the new record type. */
544 x = maybe_lookup_field (field, ctx);
548 x = build_fold_indirect_ref (ctx->receiver_decl);
549 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL);
551 x = build_fold_indirect_ref (x);
556 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
557 of a parallel, this is a component reference; for workshare constructs
558 this is some variable. */
561 build_outer_var_ref (tree var, omp_context *ctx)
565 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
567 else if (is_variable_sized (var))
569 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
570 x = build_outer_var_ref (x, ctx);
571 x = build_fold_indirect_ref (x);
573 else if (is_parallel_ctx (ctx))
575 bool by_ref = use_pointer_for_field (var, false);
576 x = build_receiver_ref (var, by_ref, ctx);
579 x = lookup_decl (var, ctx->outer);
580 else if (is_reference (var))
581 /* This can happen with orphaned constructs. If var is reference, it is
582 possible it is shared and as such valid. */
587 if (is_reference (var))
588 x = build_fold_indirect_ref (x);
593 /* Build tree nodes to access the field for VAR on the sender side. */
596 build_sender_ref (tree var, omp_context *ctx)
598 tree field = lookup_field (var, ctx);
599 return build3 (COMPONENT_REF, TREE_TYPE (field),
600 ctx->sender_decl, field, NULL);
603 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
606 install_var_field (tree var, bool by_ref, omp_context *ctx)
610 gcc_assert (!splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
612 type = TREE_TYPE (var);
614 type = build_pointer_type (type);
616 field = build_decl (FIELD_DECL, DECL_NAME (var), type);
618 /* Remember what variable this field was created for. This does have a
619 side effect of making dwarf2out ignore this member, so for helpful
620 debugging we clear it later in delete_omp_context. */
621 DECL_ABSTRACT_ORIGIN (field) = var;
623 insert_field_into_struct (ctx->record_type, field);
625 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
626 (splay_tree_value) field);
630 install_var_local (tree var, omp_context *ctx)
632 tree new_var = omp_copy_decl_1 (var, ctx);
633 insert_decl_map (&ctx->cb, var, new_var);
637 /* Adjust the replacement for DECL in CTX for the new context. This means
638 copying the DECL_VALUE_EXPR, and fixing up the type. */
641 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
645 new_decl = lookup_decl (decl, ctx);
647 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
649 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
650 && DECL_HAS_VALUE_EXPR_P (decl))
652 tree ve = DECL_VALUE_EXPR (decl);
653 walk_tree (&ve, copy_body_r, &ctx->cb, NULL);
654 SET_DECL_VALUE_EXPR (new_decl, ve);
655 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
658 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
660 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
661 if (size == error_mark_node)
662 size = TYPE_SIZE (TREE_TYPE (new_decl));
663 DECL_SIZE (new_decl) = size;
665 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
666 if (size == error_mark_node)
667 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
668 DECL_SIZE_UNIT (new_decl) = size;
672 /* The callback for remap_decl. Search all containing contexts for a
673 mapping of the variable; this avoids having to duplicate the splay
674 tree ahead of time. We know a mapping doesn't already exist in the
675 given context. Create new mappings to implement default semantics. */
678 omp_copy_decl (tree var, copy_body_data *cb)
680 omp_context *ctx = (omp_context *) cb;
683 if (TREE_CODE (var) == LABEL_DECL)
685 new_var = create_artificial_label ();
686 DECL_CONTEXT (new_var) = current_function_decl;
687 insert_decl_map (&ctx->cb, var, new_var);
691 while (!is_parallel_ctx (ctx))
696 new_var = maybe_lookup_decl (var, ctx);
701 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
704 return error_mark_node;
708 /* Return the parallel region associated with STMT. */
710 /* Debugging dumps for parallel regions. */
711 void dump_omp_region (FILE *, struct omp_region *, int);
712 void debug_omp_region (struct omp_region *);
713 void debug_all_omp_regions (void);
715 /* Dump the parallel region tree rooted at REGION. */
718 dump_omp_region (FILE *file, struct omp_region *region, int indent)
720 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
721 tree_code_name[region->type]);
724 dump_omp_region (file, region->inner, indent + 4);
728 fprintf (file, "%*sbb %d: OMP_CONTINUE\n", indent, "",
729 region->cont->index);
733 fprintf (file, "%*sbb %d: OMP_RETURN\n", indent, "",
734 region->exit->index);
736 fprintf (file, "%*s[no exit marker]\n", indent, "");
739 dump_omp_region (file, region->next, indent);
743 debug_omp_region (struct omp_region *region)
745 dump_omp_region (stderr, region, 0);
749 debug_all_omp_regions (void)
751 dump_omp_region (stderr, root_omp_region, 0);
755 /* Create a new parallel region starting at STMT inside region PARENT. */
758 new_omp_region (basic_block bb, enum tree_code type, struct omp_region *parent)
760 struct omp_region *region = xcalloc (1, sizeof (*region));
762 region->outer = parent;
768 /* This is a nested region. Add it to the list of inner
769 regions in PARENT. */
770 region->next = parent->inner;
771 parent->inner = region;
775 /* This is a toplevel region. Add it to the list of toplevel
776 regions in ROOT_OMP_REGION. */
777 region->next = root_omp_region;
778 root_omp_region = region;
784 /* Release the memory associated with the region tree rooted at REGION. */
787 free_omp_region_1 (struct omp_region *region)
789 struct omp_region *i, *n;
791 for (i = region->inner; i ; i = n)
794 free_omp_region_1 (i);
800 /* Release the memory for the entire omp region tree. */
803 free_omp_regions (void)
805 struct omp_region *r, *n;
806 for (r = root_omp_region; r ; r = n)
809 free_omp_region_1 (r);
811 root_omp_region = NULL;
815 /* Create a new context, with OUTER_CTX being the surrounding context. */
818 new_omp_context (tree stmt, omp_context *outer_ctx)
820 omp_context *ctx = XCNEW (omp_context);
822 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
823 (splay_tree_value) ctx);
828 ctx->outer = outer_ctx;
829 ctx->cb = outer_ctx->cb;
830 ctx->cb.block = NULL;
831 ctx->depth = outer_ctx->depth + 1;
835 ctx->cb.src_fn = current_function_decl;
836 ctx->cb.dst_fn = current_function_decl;
837 ctx->cb.src_node = cgraph_node (current_function_decl);
838 ctx->cb.dst_node = ctx->cb.src_node;
839 ctx->cb.src_cfun = cfun;
840 ctx->cb.copy_decl = omp_copy_decl;
841 ctx->cb.eh_region = -1;
842 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
846 ctx->cb.decl_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
851 /* Destroy a omp_context data structures. Called through the splay tree
852 value delete callback. */
855 delete_omp_context (splay_tree_value value)
857 omp_context *ctx = (omp_context *) value;
859 splay_tree_delete (ctx->cb.decl_map);
862 splay_tree_delete (ctx->field_map);
864 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
865 it produces corrupt debug information. */
866 if (ctx->record_type)
869 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
870 DECL_ABSTRACT_ORIGIN (t) = NULL;
876 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
880 fixup_child_record_type (omp_context *ctx)
882 tree f, type = ctx->record_type;
884 /* ??? It isn't sufficient to just call remap_type here, because
885 variably_modified_type_p doesn't work the way we expect for
886 record types. Testing each field for whether it needs remapping
887 and creating a new record by hand works, however. */
888 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
889 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
893 tree name, new_fields = NULL;
895 type = lang_hooks.types.make_type (RECORD_TYPE);
896 name = DECL_NAME (TYPE_NAME (ctx->record_type));
897 name = build_decl (TYPE_DECL, name, type);
898 TYPE_NAME (type) = name;
900 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
902 tree new_f = copy_node (f);
903 DECL_CONTEXT (new_f) = type;
904 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
905 TREE_CHAIN (new_f) = new_fields;
908 /* Arrange to be able to look up the receiver field
909 given the sender field. */
910 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
911 (splay_tree_value) new_f);
913 TYPE_FIELDS (type) = nreverse (new_fields);
917 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
920 /* Instantiate decls as necessary in CTX to satisfy the data sharing
921 specified by CLAUSES. */
924 scan_sharing_clauses (tree clauses, omp_context *ctx)
927 bool scan_array_reductions = false;
929 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
933 switch (OMP_CLAUSE_CODE (c))
935 case OMP_CLAUSE_PRIVATE:
936 decl = OMP_CLAUSE_DECL (c);
937 if (!is_variable_sized (decl))
938 install_var_local (decl, ctx);
941 case OMP_CLAUSE_SHARED:
942 gcc_assert (is_parallel_ctx (ctx));
943 decl = OMP_CLAUSE_DECL (c);
944 gcc_assert (!is_variable_sized (decl));
945 by_ref = use_pointer_for_field (decl, true);
946 /* Global variables don't need to be copied,
947 the receiver side will use them directly. */
948 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
950 if (! TREE_READONLY (decl)
951 || TREE_ADDRESSABLE (decl)
953 || is_reference (decl))
955 install_var_field (decl, by_ref, ctx);
956 install_var_local (decl, ctx);
959 /* We don't need to copy const scalar vars back. */
960 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
963 case OMP_CLAUSE_LASTPRIVATE:
964 /* Let the corresponding firstprivate clause create
966 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
970 case OMP_CLAUSE_FIRSTPRIVATE:
971 case OMP_CLAUSE_REDUCTION:
972 decl = OMP_CLAUSE_DECL (c);
974 if (is_variable_sized (decl))
976 else if (is_parallel_ctx (ctx)
977 && ! is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
980 by_ref = use_pointer_for_field (decl, false);
981 install_var_field (decl, by_ref, ctx);
983 install_var_local (decl, ctx);
986 case OMP_CLAUSE_COPYPRIVATE:
988 scan_omp (&OMP_CLAUSE_DECL (c), ctx->outer);
991 case OMP_CLAUSE_COPYIN:
992 decl = OMP_CLAUSE_DECL (c);
993 by_ref = use_pointer_for_field (decl, false);
994 install_var_field (decl, by_ref, ctx);
997 case OMP_CLAUSE_DEFAULT:
998 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1002 case OMP_CLAUSE_NUM_THREADS:
1003 case OMP_CLAUSE_SCHEDULE:
1005 scan_omp (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1008 case OMP_CLAUSE_NOWAIT:
1009 case OMP_CLAUSE_ORDERED:
1017 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1019 switch (OMP_CLAUSE_CODE (c))
1021 case OMP_CLAUSE_LASTPRIVATE:
1022 /* Let the corresponding firstprivate clause create
1024 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1028 case OMP_CLAUSE_PRIVATE:
1029 case OMP_CLAUSE_FIRSTPRIVATE:
1030 case OMP_CLAUSE_REDUCTION:
1031 decl = OMP_CLAUSE_DECL (c);
1032 if (is_variable_sized (decl))
1033 install_var_local (decl, ctx);
1034 fixup_remapped_decl (decl, ctx,
1035 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1036 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1037 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1038 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1039 scan_array_reductions = true;
1042 case OMP_CLAUSE_SHARED:
1043 decl = OMP_CLAUSE_DECL (c);
1044 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1045 fixup_remapped_decl (decl, ctx, false);
1048 case OMP_CLAUSE_COPYPRIVATE:
1049 case OMP_CLAUSE_COPYIN:
1050 case OMP_CLAUSE_DEFAULT:
1052 case OMP_CLAUSE_NUM_THREADS:
1053 case OMP_CLAUSE_SCHEDULE:
1054 case OMP_CLAUSE_NOWAIT:
1055 case OMP_CLAUSE_ORDERED:
1063 if (scan_array_reductions)
1064 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1065 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1066 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1068 scan_omp (&OMP_CLAUSE_REDUCTION_INIT (c), ctx);
1069 scan_omp (&OMP_CLAUSE_REDUCTION_MERGE (c), ctx);
1073 /* Create a new name for omp child function. Returns an identifier. */
1075 static GTY(()) unsigned int tmp_ompfn_id_num;
1078 create_omp_child_function_name (void)
1080 tree name = DECL_ASSEMBLER_NAME (current_function_decl);
1081 size_t len = IDENTIFIER_LENGTH (name);
1082 char *tmp_name, *prefix;
1084 prefix = alloca (len + sizeof ("_omp_fn"));
1085 memcpy (prefix, IDENTIFIER_POINTER (name), len);
1086 strcpy (prefix + len, "_omp_fn");
1087 #ifndef NO_DOT_IN_LABEL
1089 #elif !defined NO_DOLLAR_IN_LABEL
1092 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, tmp_ompfn_id_num++);
1093 return get_identifier (tmp_name);
1096 /* Build a decl for the omp child function. It'll not contain a body
1097 yet, just the bare decl. */
1100 create_omp_child_function (omp_context *ctx)
1102 tree decl, type, name, t;
1104 name = create_omp_child_function_name ();
1105 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1107 decl = build_decl (FUNCTION_DECL, name, type);
1108 decl = lang_hooks.decls.pushdecl (decl);
1110 ctx->cb.dst_fn = decl;
1112 TREE_STATIC (decl) = 1;
1113 TREE_USED (decl) = 1;
1114 DECL_ARTIFICIAL (decl) = 1;
1115 DECL_IGNORED_P (decl) = 0;
1116 TREE_PUBLIC (decl) = 0;
1117 DECL_UNINLINABLE (decl) = 1;
1118 DECL_EXTERNAL (decl) = 0;
1119 DECL_CONTEXT (decl) = NULL_TREE;
1120 DECL_INITIAL (decl) = make_node (BLOCK);
1122 t = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1123 DECL_ARTIFICIAL (t) = 1;
1124 DECL_IGNORED_P (t) = 1;
1125 DECL_RESULT (decl) = t;
1127 t = build_decl (PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1128 DECL_ARTIFICIAL (t) = 1;
1129 DECL_ARG_TYPE (t) = ptr_type_node;
1130 DECL_CONTEXT (t) = current_function_decl;
1132 DECL_ARGUMENTS (decl) = t;
1133 ctx->receiver_decl = t;
1135 /* Allocate memory for the function structure. The call to
1136 allocate_struct_function clobbers CFUN, so we need to restore
1138 allocate_struct_function (decl);
1139 DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (ctx->stmt);
1140 cfun->function_end_locus = EXPR_LOCATION (ctx->stmt);
1141 cfun = ctx->cb.src_cfun;
1145 /* Scan an OpenMP parallel directive. */
1148 scan_omp_parallel (tree *stmt_p, omp_context *outer_ctx)
1153 /* Ignore parallel directives with empty bodies, unless there
1154 are copyin clauses. */
1156 && empty_body_p (OMP_PARALLEL_BODY (*stmt_p))
1157 && find_omp_clause (OMP_CLAUSES (*stmt_p), OMP_CLAUSE_COPYIN) == NULL)
1159 *stmt_p = build_empty_stmt ();
1163 ctx = new_omp_context (*stmt_p, outer_ctx);
1164 if (parallel_nesting_level > 1)
1165 ctx->is_nested = true;
1166 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1167 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1168 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1169 name = create_tmp_var_name (".omp_data_s");
1170 name = build_decl (TYPE_DECL, name, ctx->record_type);
1171 TYPE_NAME (ctx->record_type) = name;
1172 create_omp_child_function (ctx);
1173 OMP_PARALLEL_FN (*stmt_p) = ctx->cb.dst_fn;
1175 scan_sharing_clauses (OMP_PARALLEL_CLAUSES (*stmt_p), ctx);
1176 scan_omp (&OMP_PARALLEL_BODY (*stmt_p), ctx);
1178 if (TYPE_FIELDS (ctx->record_type) == NULL)
1179 ctx->record_type = ctx->receiver_decl = NULL;
1182 layout_type (ctx->record_type);
1183 fixup_child_record_type (ctx);
1188 /* Scan an OpenMP loop directive. */
1191 scan_omp_for (tree *stmt_p, omp_context *outer_ctx)
1197 ctx = new_omp_context (stmt, outer_ctx);
1199 scan_sharing_clauses (OMP_FOR_CLAUSES (stmt), ctx);
1201 scan_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
1202 scan_omp (&OMP_FOR_INIT (stmt), ctx);
1203 scan_omp (&OMP_FOR_COND (stmt), ctx);
1204 scan_omp (&OMP_FOR_INCR (stmt), ctx);
1205 scan_omp (&OMP_FOR_BODY (stmt), ctx);
1208 /* Scan an OpenMP sections directive. */
1211 scan_omp_sections (tree *stmt_p, omp_context *outer_ctx)
1217 ctx = new_omp_context (stmt, outer_ctx);
1218 scan_sharing_clauses (OMP_SECTIONS_CLAUSES (stmt), ctx);
1219 scan_omp (&OMP_SECTIONS_BODY (stmt), ctx);
1222 /* Scan an OpenMP single directive. */
1225 scan_omp_single (tree *stmt_p, omp_context *outer_ctx)
1227 tree stmt = *stmt_p;
1231 ctx = new_omp_context (stmt, outer_ctx);
1232 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1233 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1234 name = create_tmp_var_name (".omp_copy_s");
1235 name = build_decl (TYPE_DECL, name, ctx->record_type);
1236 TYPE_NAME (ctx->record_type) = name;
1238 scan_sharing_clauses (OMP_SINGLE_CLAUSES (stmt), ctx);
1239 scan_omp (&OMP_SINGLE_BODY (stmt), ctx);
1241 if (TYPE_FIELDS (ctx->record_type) == NULL)
1242 ctx->record_type = NULL;
1244 layout_type (ctx->record_type);
1248 /* Check OpenMP nesting restrictions. */
1250 check_omp_nesting_restrictions (tree t, omp_context *ctx)
1252 switch (TREE_CODE (t))
1257 for (; ctx != NULL; ctx = ctx->outer)
1258 switch (TREE_CODE (ctx->stmt))
1265 warning (0, "work-sharing region may not be closely nested inside "
1266 "of work-sharing, critical, ordered or master region");
1275 for (; ctx != NULL; ctx = ctx->outer)
1276 switch (TREE_CODE (ctx->stmt))
1281 warning (0, "master region may not be closely nested inside "
1282 "of work-sharing region");
1291 for (; ctx != NULL; ctx = ctx->outer)
1292 switch (TREE_CODE (ctx->stmt))
1295 warning (0, "ordered region may not be closely nested inside "
1296 "of critical region");
1299 if (find_omp_clause (OMP_CLAUSES (ctx->stmt),
1300 OMP_CLAUSE_ORDERED) == NULL)
1301 warning (0, "ordered region must be closely nested inside "
1302 "a loop region with an ordered clause");
1311 for (; ctx != NULL; ctx = ctx->outer)
1312 if (TREE_CODE (ctx->stmt) == OMP_CRITICAL
1313 && OMP_CRITICAL_NAME (t) == OMP_CRITICAL_NAME (ctx->stmt))
1315 warning (0, "critical region may not be nested inside a critical "
1316 "region with the same name");
1326 /* Callback for walk_stmts used to scan for OpenMP directives at TP. */
1329 scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
1331 struct walk_stmt_info *wi = data;
1332 omp_context *ctx = wi->info;
1335 if (EXPR_HAS_LOCATION (t))
1336 input_location = EXPR_LOCATION (t);
1338 /* Check the OpenMP nesting restrictions. */
1339 if (OMP_DIRECTIVE_P (t) && ctx != NULL)
1340 check_omp_nesting_restrictions (t, ctx);
1343 switch (TREE_CODE (t))
1346 parallel_nesting_level++;
1347 scan_omp_parallel (tp, ctx);
1348 parallel_nesting_level--;
1352 scan_omp_for (tp, ctx);
1356 scan_omp_sections (tp, ctx);
1360 scan_omp_single (tp, ctx);
1367 ctx = new_omp_context (*tp, ctx);
1368 scan_omp (&OMP_BODY (*tp), ctx);
1376 for (var = BIND_EXPR_VARS (t); var ; var = TREE_CHAIN (var))
1377 insert_decl_map (&ctx->cb, var, var);
1386 *tp = remap_decl (t, &ctx->cb);
1390 if (ctx && TYPE_P (t))
1391 *tp = remap_type (t, &ctx->cb);
1392 else if (!DECL_P (t))
1401 /* Scan all the statements starting at STMT_P. CTX contains context
1402 information about the OpenMP directives and clauses found during
1406 scan_omp (tree *stmt_p, omp_context *ctx)
1408 location_t saved_location;
1409 struct walk_stmt_info wi;
1411 memset (&wi, 0, sizeof (wi));
1412 wi.callback = scan_omp_1;
1414 wi.want_bind_expr = (ctx != NULL);
1415 wi.want_locations = true;
1417 saved_location = input_location;
1418 walk_stmts (&wi, stmt_p);
1419 input_location = saved_location;
1422 /* Re-gimplification and code generation routines. */
1424 /* Build a call to GOMP_barrier. */
1427 build_omp_barrier (tree *stmt_list)
1431 t = built_in_decls[BUILT_IN_GOMP_BARRIER];
1432 t = build_function_call_expr (t, NULL);
1433 gimplify_and_add (t, stmt_list);
1436 /* If a context was created for STMT when it was scanned, return it. */
1438 static omp_context *
1439 maybe_lookup_ctx (tree stmt)
1442 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
1443 return n ? (omp_context *) n->value : NULL;
1447 /* Find the mapping for DECL in CTX or the immediately enclosing
1448 context that has a mapping for DECL.
1450 If CTX is a nested parallel directive, we may have to use the decl
1451 mappings created in CTX's parent context. Suppose that we have the
1452 following parallel nesting (variable UIDs showed for clarity):
1455 #omp parallel shared(iD.1562) -> outer parallel
1456 iD.1562 = iD.1562 + 1;
1458 #omp parallel shared (iD.1562) -> inner parallel
1459 iD.1562 = iD.1562 - 1;
1461 Each parallel structure will create a distinct .omp_data_s structure
1462 for copying iD.1562 in/out of the directive:
1464 outer parallel .omp_data_s.1.i -> iD.1562
1465 inner parallel .omp_data_s.2.i -> iD.1562
1467 A shared variable mapping will produce a copy-out operation before
1468 the parallel directive and a copy-in operation after it. So, in
1469 this case we would have:
1472 .omp_data_o.1.i = iD.1562;
1473 #omp parallel shared(iD.1562) -> outer parallel
1474 .omp_data_i.1 = &.omp_data_o.1
1475 .omp_data_i.1->i = .omp_data_i.1->i + 1;
1477 .omp_data_o.2.i = iD.1562; -> **
1478 #omp parallel shared(iD.1562) -> inner parallel
1479 .omp_data_i.2 = &.omp_data_o.2
1480 .omp_data_i.2->i = .omp_data_i.2->i - 1;
1483 ** This is a problem. The symbol iD.1562 cannot be referenced
1484 inside the body of the outer parallel region. But since we are
1485 emitting this copy operation while expanding the inner parallel
1486 directive, we need to access the CTX structure of the outer
1487 parallel directive to get the correct mapping:
1489 .omp_data_o.2.i = .omp_data_i.1->i
1491 Since there may be other workshare or parallel directives enclosing
1492 the parallel directive, it may be necessary to walk up the context
1493 parent chain. This is not a problem in general because nested
1494 parallelism happens only rarely. */
1497 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1502 gcc_assert (ctx->is_nested);
1504 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1505 t = maybe_lookup_decl (decl, up);
1513 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
1514 in outer contexts. */
1517 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1523 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1524 t = maybe_lookup_decl (decl, up);
1526 return t ? t : decl;
1530 /* Construct the initialization value for reduction CLAUSE. */
1533 omp_reduction_init (tree clause, tree type)
1535 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
1542 case TRUTH_ORIF_EXPR:
1543 case TRUTH_XOR_EXPR:
1545 return fold_convert (type, integer_zero_node);
1548 case TRUTH_AND_EXPR:
1549 case TRUTH_ANDIF_EXPR:
1551 return fold_convert (type, integer_one_node);
1554 return fold_convert (type, integer_minus_one_node);
1557 if (SCALAR_FLOAT_TYPE_P (type))
1559 REAL_VALUE_TYPE max, min;
1560 if (HONOR_INFINITIES (TYPE_MODE (type)))
1563 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
1566 real_maxval (&min, 1, TYPE_MODE (type));
1567 return build_real (type, min);
1571 gcc_assert (INTEGRAL_TYPE_P (type));
1572 return TYPE_MIN_VALUE (type);
1576 if (SCALAR_FLOAT_TYPE_P (type))
1578 REAL_VALUE_TYPE max;
1579 if (HONOR_INFINITIES (TYPE_MODE (type)))
1582 real_maxval (&max, 0, TYPE_MODE (type));
1583 return build_real (type, max);
1587 gcc_assert (INTEGRAL_TYPE_P (type));
1588 return TYPE_MAX_VALUE (type);
1596 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
1597 from the receiver (aka child) side and initializers for REFERENCE_TYPE
1598 private variables. Initialization statements go in ILIST, while calls
1599 to destructors go in DLIST. */
1602 lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
1605 tree_stmt_iterator diter;
1606 tree c, dtor, copyin_seq, x, args, ptr;
1607 bool copyin_by_ref = false;
1608 bool lastprivate_firstprivate = false;
1611 *dlist = alloc_stmt_list ();
1612 diter = tsi_start (*dlist);
1615 /* Do all the fixed sized types in the first pass, and the variable sized
1616 types in the second pass. This makes sure that the scalar arguments to
1617 the variable sized types are processed before we use them in the
1618 variable sized operations. */
1619 for (pass = 0; pass < 2; ++pass)
1621 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1623 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
1629 case OMP_CLAUSE_PRIVATE:
1630 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
1633 case OMP_CLAUSE_SHARED:
1634 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
1636 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
1639 case OMP_CLAUSE_FIRSTPRIVATE:
1640 case OMP_CLAUSE_COPYIN:
1641 case OMP_CLAUSE_REDUCTION:
1643 case OMP_CLAUSE_LASTPRIVATE:
1644 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1646 lastprivate_firstprivate = true;
1655 new_var = var = OMP_CLAUSE_DECL (c);
1656 if (c_kind != OMP_CLAUSE_COPYIN)
1657 new_var = lookup_decl (var, ctx);
1659 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
1664 else if (is_variable_sized (var))
1666 /* For variable sized types, we need to allocate the
1667 actual storage here. Call alloca and store the
1668 result in the pointer decl that we created elsewhere. */
1672 ptr = DECL_VALUE_EXPR (new_var);
1673 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
1674 ptr = TREE_OPERAND (ptr, 0);
1675 gcc_assert (DECL_P (ptr));
1677 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
1678 args = tree_cons (NULL, x, NULL);
1679 x = built_in_decls[BUILT_IN_ALLOCA];
1680 x = build_function_call_expr (x, args);
1681 x = fold_convert (TREE_TYPE (ptr), x);
1682 x = build2 (MODIFY_EXPR, void_type_node, ptr, x);
1683 gimplify_and_add (x, ilist);
1685 else if (is_reference (var))
1687 /* For references that are being privatized for Fortran,
1688 allocate new backing storage for the new pointer
1689 variable. This allows us to avoid changing all the
1690 code that expects a pointer to something that expects
1691 a direct variable. Note that this doesn't apply to
1692 C++, since reference types are disallowed in data
1693 sharing clauses there, except for NRV optimized
1698 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
1699 if (TREE_CONSTANT (x))
1701 const char *name = NULL;
1702 if (DECL_NAME (var))
1703 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
1705 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
1707 gimple_add_tmp_var (x);
1708 x = build_fold_addr_expr_with_type (x, TREE_TYPE (new_var));
1712 args = tree_cons (NULL, x, NULL);
1713 x = built_in_decls[BUILT_IN_ALLOCA];
1714 x = build_function_call_expr (x, args);
1715 x = fold_convert (TREE_TYPE (new_var), x);
1718 x = build2 (MODIFY_EXPR, void_type_node, new_var, x);
1719 gimplify_and_add (x, ilist);
1721 new_var = build_fold_indirect_ref (new_var);
1723 else if (c_kind == OMP_CLAUSE_REDUCTION
1724 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1732 switch (OMP_CLAUSE_CODE (c))
1734 case OMP_CLAUSE_SHARED:
1735 /* Shared global vars are just accessed directly. */
1736 if (is_global_var (new_var))
1738 /* Set up the DECL_VALUE_EXPR for shared variables now. This
1739 needs to be delayed until after fixup_child_record_type so
1740 that we get the correct type during the dereference. */
1741 by_ref = use_pointer_for_field (var, true);
1742 x = build_receiver_ref (var, by_ref, ctx);
1743 SET_DECL_VALUE_EXPR (new_var, x);
1744 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
1746 /* ??? If VAR is not passed by reference, and the variable
1747 hasn't been initialized yet, then we'll get a warning for
1748 the store into the omp_data_s structure. Ideally, we'd be
1749 able to notice this and not store anything at all, but
1750 we're generating code too early. Suppress the warning. */
1752 TREE_NO_WARNING (var) = 1;
1755 case OMP_CLAUSE_LASTPRIVATE:
1756 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1760 case OMP_CLAUSE_PRIVATE:
1761 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var);
1763 gimplify_and_add (x, ilist);
1767 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
1771 gimplify_stmt (&dtor);
1772 tsi_link_before (&diter, dtor, TSI_SAME_STMT);
1776 case OMP_CLAUSE_FIRSTPRIVATE:
1777 x = build_outer_var_ref (var, ctx);
1778 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
1779 gimplify_and_add (x, ilist);
1783 case OMP_CLAUSE_COPYIN:
1784 by_ref = use_pointer_for_field (var, false);
1785 x = build_receiver_ref (var, by_ref, ctx);
1786 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
1787 append_to_statement_list (x, ©in_seq);
1788 copyin_by_ref |= by_ref;
1791 case OMP_CLAUSE_REDUCTION:
1792 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1794 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), ilist);
1795 OMP_CLAUSE_REDUCTION_INIT (c) = NULL;
1799 x = omp_reduction_init (c, TREE_TYPE (new_var));
1800 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
1801 x = build2 (MODIFY_EXPR, void_type_node, new_var, x);
1802 gimplify_and_add (x, ilist);
1812 /* The copyin sequence is not to be executed by the main thread, since
1813 that would result in self-copies. Perhaps not visible to scalars,
1814 but it certainly is to C++ operator=. */
1817 x = built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM];
1818 x = build_function_call_expr (x, NULL);
1819 x = build2 (NE_EXPR, boolean_type_node, x,
1820 build_int_cst (TREE_TYPE (x), 0));
1821 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
1822 gimplify_and_add (x, ilist);
1825 /* If any copyin variable is passed by reference, we must ensure the
1826 master thread doesn't modify it before it is copied over in all
1827 threads. Similarly for variables in both firstprivate and
1828 lastprivate clauses we need to ensure the lastprivate copying
1829 happens after firstprivate copying in all threads. */
1830 if (copyin_by_ref || lastprivate_firstprivate)
1831 build_omp_barrier (ilist);
1835 /* Generate code to implement the LASTPRIVATE clauses. This is used for
1836 both parallel and workshare constructs. PREDICATE may be NULL if it's
1840 lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
1843 tree sub_list, x, c;
1845 /* Early exit if there are no lastprivate clauses. */
1846 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
1847 if (clauses == NULL)
1849 /* If this was a workshare clause, see if it had been combined
1850 with its parallel. In that case, look for the clauses on the
1851 parallel statement itself. */
1852 if (is_parallel_ctx (ctx))
1856 if (ctx == NULL || !is_parallel_ctx (ctx))
1859 clauses = find_omp_clause (OMP_PARALLEL_CLAUSES (ctx->stmt),
1860 OMP_CLAUSE_LASTPRIVATE);
1861 if (clauses == NULL)
1865 sub_list = alloc_stmt_list ();
1867 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1871 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE)
1874 var = OMP_CLAUSE_DECL (c);
1875 new_var = lookup_decl (var, ctx);
1877 x = build_outer_var_ref (var, ctx);
1878 if (is_reference (var))
1879 new_var = build_fold_indirect_ref (new_var);
1880 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
1881 append_to_statement_list (x, &sub_list);
1885 x = build3 (COND_EXPR, void_type_node, predicate, sub_list, NULL);
1889 gimplify_and_add (x, stmt_list);
1893 /* Generate code to implement the REDUCTION clauses. */
1896 lower_reduction_clauses (tree clauses, tree *stmt_list, omp_context *ctx)
1898 tree sub_list = NULL, x, c;
1901 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
1902 update in that case, otherwise use a lock. */
1903 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
1904 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
1906 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1908 /* Never use OMP_ATOMIC for array reductions. */
1918 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1920 tree var, ref, new_var;
1921 enum tree_code code;
1923 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
1926 var = OMP_CLAUSE_DECL (c);
1927 new_var = lookup_decl (var, ctx);
1928 if (is_reference (var))
1929 new_var = build_fold_indirect_ref (new_var);
1930 ref = build_outer_var_ref (var, ctx);
1931 code = OMP_CLAUSE_REDUCTION_CODE (c);
1933 /* reduction(-:var) sums up the partial results, so it acts
1934 identically to reduction(+:var). */
1935 if (code == MINUS_EXPR)
1940 tree addr = build_fold_addr_expr (ref);
1942 addr = save_expr (addr);
1943 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
1944 x = fold_build2 (code, TREE_TYPE (ref), ref, new_var);
1945 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
1946 gimplify_and_add (x, stmt_list);
1950 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1952 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
1954 if (is_reference (var))
1955 ref = build_fold_addr_expr (ref);
1956 SET_DECL_VALUE_EXPR (placeholder, ref);
1957 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
1958 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), &sub_list);
1959 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL;
1960 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
1964 x = build2 (code, TREE_TYPE (ref), ref, new_var);
1965 ref = build_outer_var_ref (var, ctx);
1966 x = build2 (MODIFY_EXPR, void_type_node, ref, x);
1967 append_to_statement_list (x, &sub_list);
1971 x = built_in_decls[BUILT_IN_GOMP_ATOMIC_START];
1972 x = build_function_call_expr (x, NULL);
1973 gimplify_and_add (x, stmt_list);
1975 gimplify_and_add (sub_list, stmt_list);
1977 x = built_in_decls[BUILT_IN_GOMP_ATOMIC_END];
1978 x = build_function_call_expr (x, NULL);
1979 gimplify_and_add (x, stmt_list);
1983 /* Generate code to implement the COPYPRIVATE clauses. */
1986 lower_copyprivate_clauses (tree clauses, tree *slist, tree *rlist,
1991 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1996 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
1999 var = OMP_CLAUSE_DECL (c);
2000 by_ref = use_pointer_for_field (var, false);
2002 ref = build_sender_ref (var, ctx);
2003 x = (ctx->is_nested) ? lookup_decl_in_outer_ctx (var, ctx) : var;
2004 x = by_ref ? build_fold_addr_expr (x) : x;
2005 x = build2 (MODIFY_EXPR, void_type_node, ref, x);
2006 gimplify_and_add (x, slist);
2008 ref = build_receiver_ref (var, by_ref, ctx);
2009 if (is_reference (var))
2011 ref = build_fold_indirect_ref (ref);
2012 var = build_fold_indirect_ref (var);
2014 x = lang_hooks.decls.omp_clause_assign_op (c, var, ref);
2015 gimplify_and_add (x, rlist);
2020 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2021 and REDUCTION from the sender (aka parent) side. */
2024 lower_send_clauses (tree clauses, tree *ilist, tree *olist, omp_context *ctx)
2028 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2030 tree val, ref, x, var;
2031 bool by_ref, do_in = false, do_out = false;
2033 switch (OMP_CLAUSE_CODE (c))
2035 case OMP_CLAUSE_FIRSTPRIVATE:
2036 case OMP_CLAUSE_COPYIN:
2037 case OMP_CLAUSE_LASTPRIVATE:
2038 case OMP_CLAUSE_REDUCTION:
2044 var = val = OMP_CLAUSE_DECL (c);
2046 var = lookup_decl_in_outer_ctx (val, ctx);
2048 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2049 && is_global_var (var))
2051 if (is_variable_sized (val))
2053 by_ref = use_pointer_for_field (val, false);
2055 switch (OMP_CLAUSE_CODE (c))
2057 case OMP_CLAUSE_FIRSTPRIVATE:
2058 case OMP_CLAUSE_COPYIN:
2062 case OMP_CLAUSE_LASTPRIVATE:
2063 if (by_ref || is_reference (val))
2065 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2073 case OMP_CLAUSE_REDUCTION:
2075 do_out = !(by_ref || is_reference (val));
2084 ref = build_sender_ref (val, ctx);
2085 x = by_ref ? build_fold_addr_expr (var) : var;
2086 x = build2 (MODIFY_EXPR, void_type_node, ref, x);
2087 gimplify_and_add (x, ilist);
2092 ref = build_sender_ref (val, ctx);
2093 x = build2 (MODIFY_EXPR, void_type_node, var, ref);
2094 gimplify_and_add (x, olist);
2099 /* Generate code to implement SHARED from the sender (aka parent) side.
2100 This is trickier, since OMP_PARALLEL_CLAUSES doesn't list things that
2101 got automatically shared. */
2104 lower_send_shared_vars (tree *ilist, tree *olist, omp_context *ctx)
2106 tree var, ovar, nvar, f, x;
2108 if (ctx->record_type == NULL)
2111 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
2113 ovar = DECL_ABSTRACT_ORIGIN (f);
2114 nvar = maybe_lookup_decl (ovar, ctx);
2115 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2120 /* If CTX is a nested parallel directive. Find the immediately
2121 enclosing parallel or workshare construct that contains a
2122 mapping for OVAR. */
2124 var = lookup_decl_in_outer_ctx (ovar, ctx);
2126 if (use_pointer_for_field (ovar, true))
2128 x = build_sender_ref (ovar, ctx);
2129 var = build_fold_addr_expr (var);
2130 x = build2 (MODIFY_EXPR, void_type_node, x, var);
2131 gimplify_and_add (x, ilist);
2135 x = build_sender_ref (ovar, ctx);
2136 x = build2 (MODIFY_EXPR, void_type_node, x, var);
2137 gimplify_and_add (x, ilist);
2139 x = build_sender_ref (ovar, ctx);
2140 x = build2 (MODIFY_EXPR, void_type_node, var, x);
2141 gimplify_and_add (x, olist);
2146 /* Build the function calls to GOMP_parallel_start etc to actually
2147 generate the parallel operation. REGION is the parallel region
2148 being expanded. BB is the block where to insert the code. WS_ARGS
2149 will be set if this is a call to a combined parallel+workshare
2150 construct, it contains the list of additional arguments needed by
2151 the workshare construct. */
2154 expand_parallel_call (struct omp_region *region, basic_block bb,
2155 tree entry_stmt, tree ws_args)
2157 tree t, args, val, cond, c, list, clauses;
2158 block_stmt_iterator si;
2161 clauses = OMP_PARALLEL_CLAUSES (entry_stmt);
2162 push_gimplify_context ();
2164 /* Determine what flavor of GOMP_parallel_start we will be
2166 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2167 if (is_combined_parallel (region))
2169 switch (region->inner->type)
2172 start_ix = BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2173 + region->inner->sched_kind;
2176 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2183 /* By default, the value of NUM_THREADS is zero (selected at run time)
2184 and there is no conditional. */
2186 val = build_int_cst (unsigned_type_node, 0);
2188 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2190 cond = OMP_CLAUSE_IF_EXPR (c);
2192 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2194 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2196 /* Ensure 'val' is of the correct type. */
2197 val = fold_convert (unsigned_type_node, val);
2199 /* If we found the clause 'if (cond)', build either
2200 (cond != 0) or (cond ? val : 1u). */
2203 block_stmt_iterator si;
2205 cond = gimple_boolify (cond);
2207 if (integer_zerop (val))
2208 val = build2 (EQ_EXPR, unsigned_type_node, cond,
2209 build_int_cst (TREE_TYPE (cond), 0));
2212 basic_block cond_bb, then_bb, else_bb;
2214 tree t, then_lab, else_lab, tmp;
2216 tmp = create_tmp_var (TREE_TYPE (val), NULL);
2217 e = split_block (bb, NULL);
2222 then_bb = create_empty_bb (cond_bb);
2223 else_bb = create_empty_bb (then_bb);
2224 then_lab = create_artificial_label ();
2225 else_lab = create_artificial_label ();
2227 t = build3 (COND_EXPR, void_type_node,
2229 build_and_jump (&then_lab),
2230 build_and_jump (&else_lab));
2232 si = bsi_start (cond_bb);
2233 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2235 si = bsi_start (then_bb);
2236 t = build1 (LABEL_EXPR, void_type_node, then_lab);
2237 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2238 t = build2 (MODIFY_EXPR, void_type_node, tmp, val);
2239 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2241 si = bsi_start (else_bb);
2242 t = build1 (LABEL_EXPR, void_type_node, else_lab);
2243 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2244 t = build2 (MODIFY_EXPR, void_type_node, tmp,
2245 build_int_cst (unsigned_type_node, 1));
2246 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2248 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
2249 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
2250 make_edge (then_bb, bb, EDGE_FALLTHRU);
2251 make_edge (else_bb, bb, EDGE_FALLTHRU);
2257 val = get_formal_tmp_var (val, &list);
2258 si = bsi_start (bb);
2259 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2263 args = tree_cons (NULL, val, NULL);
2264 t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2266 t = null_pointer_node;
2268 t = build_fold_addr_expr (t);
2269 args = tree_cons (NULL, t, args);
2270 t = build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt));
2271 args = tree_cons (NULL, t, args);
2274 args = chainon (args, ws_args);
2276 t = built_in_decls[start_ix];
2277 t = build_function_call_expr (t, args);
2278 gimplify_and_add (t, &list);
2280 t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2282 t = null_pointer_node;
2284 t = build_fold_addr_expr (t);
2285 args = tree_cons (NULL, t, NULL);
2286 t = build_function_call_expr (OMP_PARALLEL_FN (entry_stmt), args);
2287 gimplify_and_add (t, &list);
2289 t = built_in_decls[BUILT_IN_GOMP_PARALLEL_END];
2290 t = build_function_call_expr (t, NULL);
2291 gimplify_and_add (t, &list);
2294 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2296 pop_gimplify_context (NULL_TREE);
2300 /* If exceptions are enabled, wrap *STMT_P in a MUST_NOT_THROW catch
2301 handler. This prevents programs from violating the structured
2302 block semantics with throws. */
2305 maybe_catch_exception (tree *stmt_p)
2309 if (!flag_exceptions)
2312 if (lang_protect_cleanup_actions)
2313 t = lang_protect_cleanup_actions ();
2316 t = built_in_decls[BUILT_IN_TRAP];
2317 t = build_function_call_expr (t, NULL);
2319 f = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
2320 EH_FILTER_MUST_NOT_THROW (f) = 1;
2321 gimplify_and_add (t, &EH_FILTER_FAILURE (f));
2323 t = build2 (TRY_CATCH_EXPR, void_type_node, *stmt_p, NULL);
2324 append_to_statement_list (f, &TREE_OPERAND (t, 1));
2327 append_to_statement_list (t, stmt_p);
2330 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
2333 list2chain (tree list)
2337 for (t = list; t; t = TREE_CHAIN (t))
2339 tree var = TREE_VALUE (t);
2341 TREE_CHAIN (var) = TREE_VALUE (TREE_CHAIN (t));
2343 TREE_CHAIN (var) = NULL_TREE;
2346 return list ? TREE_VALUE (list) : NULL_TREE;
2350 /* Remove barriers in REGION->EXIT's block. Note that this is only
2351 valid for OMP_PARALLEL regions. Since the end of a parallel region
2352 is an implicit barrier, any workshare inside the OMP_PARALLEL that
2353 left a barrier at the end of the OMP_PARALLEL region can now be
2357 remove_exit_barrier (struct omp_region *region)
2359 block_stmt_iterator si;
2360 basic_block exit_bb;
2365 exit_bb = region->exit;
2367 /* If the parallel region doesn't return, we don't have REGION->EXIT
2372 /* The last insn in the block will be the parallel's OMP_RETURN. The
2373 workshare's OMP_RETURN will be in a preceding block. The kinds of
2374 statements that can appear in between are extremely limited -- no
2375 memory operations at all. Here, we allow nothing at all, so the
2376 only thing we allow to precede this OMP_RETURN is a label. */
2377 si = bsi_last (exit_bb);
2378 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2380 if (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) != LABEL_EXPR)
2383 FOR_EACH_EDGE (e, ei, exit_bb->preds)
2385 si = bsi_last (e->src);
2389 if (TREE_CODE (t) == OMP_RETURN)
2390 OMP_RETURN_NOWAIT (t) = 1;
2395 remove_exit_barriers (struct omp_region *region)
2397 if (region->type == OMP_PARALLEL)
2398 remove_exit_barrier (region);
2402 region = region->inner;
2403 remove_exit_barriers (region);
2404 while (region->next)
2406 region = region->next;
2407 remove_exit_barriers (region);
2412 /* Expand the OpenMP parallel directive starting at REGION. */
2415 expand_omp_parallel (struct omp_region *region)
2417 basic_block entry_bb, exit_bb, new_bb;
2418 struct function *child_cfun, *saved_cfun;
2419 tree child_fn, block, t, ws_args;
2420 block_stmt_iterator si;
2424 entry_stmt = last_stmt (region->entry);
2425 child_fn = OMP_PARALLEL_FN (entry_stmt);
2426 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
2429 entry_bb = region->entry;
2430 exit_bb = region->exit;
2432 if (is_combined_parallel (region))
2433 ws_args = region->ws_args;
2435 ws_args = NULL_TREE;
2437 if (child_cfun->cfg)
2439 /* Due to inlining, it may happen that we have already outlined
2440 the region, in which case all we need to do is make the
2441 sub-graph unreachable and emit the parallel call. */
2442 edge entry_succ_e, exit_succ_e;
2443 block_stmt_iterator si;
2445 entry_succ_e = single_succ_edge (entry_bb);
2446 exit_succ_e = single_succ_edge (exit_bb);
2448 si = bsi_last (entry_bb);
2449 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_PARALLEL);
2450 bsi_remove (&si, true);
2453 remove_edge (entry_succ_e);
2454 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
2458 /* If the parallel region needs data sent from the parent
2459 function, then the very first statement of the parallel body
2460 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
2461 &.OMP_DATA_O is passed as an argument to the child function,
2462 we need to replace it with the argument as seen by the child
2465 In most cases, this will end up being the identity assignment
2466 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
2467 a function call that has been inlined, the original PARM_DECL
2468 .OMP_DATA_I may have been converted into a different local
2469 variable. In which case, we need to keep the assignment. */
2470 if (OMP_PARALLEL_DATA_ARG (entry_stmt))
2472 basic_block entry_succ_bb = single_succ (entry_bb);
2473 block_stmt_iterator si = bsi_start (entry_succ_bb);
2476 gcc_assert (!bsi_end_p (si));
2478 stmt = bsi_stmt (si);
2479 gcc_assert (TREE_CODE (stmt) == MODIFY_EXPR
2480 && TREE_CODE (TREE_OPERAND (stmt, 1)) == ADDR_EXPR
2481 && TREE_OPERAND (TREE_OPERAND (stmt, 1), 0)
2482 == OMP_PARALLEL_DATA_ARG (entry_stmt));
2484 if (TREE_OPERAND (stmt, 0) == DECL_ARGUMENTS (child_fn))
2485 bsi_remove (&si, true);
2487 TREE_OPERAND (stmt, 1) = DECL_ARGUMENTS (child_fn);
2490 /* Declare local variables needed in CHILD_CFUN. */
2491 block = DECL_INITIAL (child_fn);
2492 BLOCK_VARS (block) = list2chain (child_cfun->unexpanded_var_list);
2493 DECL_SAVED_TREE (child_fn) = single_succ (entry_bb)->stmt_list;
2495 /* Reset DECL_CONTEXT on locals and function arguments. */
2496 for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
2497 DECL_CONTEXT (t) = child_fn;
2499 for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
2500 DECL_CONTEXT (t) = child_fn;
2502 /* Split ENTRY_BB at OMP_PARALLEL so that it can be moved to the
2504 si = bsi_last (entry_bb);
2506 gcc_assert (t && TREE_CODE (t) == OMP_PARALLEL);
2507 bsi_remove (&si, true);
2508 e = split_block (entry_bb, t);
2510 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
2512 /* Move the parallel region into CHILD_CFUN. We need to reset
2513 dominance information because the expansion of the inner
2514 regions has invalidated it. */
2515 free_dominance_info (CDI_DOMINATORS);
2516 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
2518 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
2519 cgraph_add_new_function (child_fn);
2521 /* Convert OMP_RETURN into a RETURN_EXPR. */
2524 si = bsi_last (exit_bb);
2525 gcc_assert (!bsi_end_p (si)
2526 && TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2527 t = build1 (RETURN_EXPR, void_type_node, NULL);
2528 bsi_insert_after (&si, t, TSI_SAME_STMT);
2529 bsi_remove (&si, true);
2533 /* Emit a library call to launch the children threads. */
2534 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
2538 /* A subroutine of expand_omp_for. Generate code for a parallel
2539 loop with any schedule. Given parameters:
2541 for (V = N1; V cond N2; V += STEP) BODY;
2543 where COND is "<" or ">", we generate pseudocode
2545 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
2546 if (more) goto L0; else goto L3;
2553 if (V cond iend) goto L1; else goto L2;
2555 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
2558 If this is a combined omp parallel loop, instead of the call to
2559 GOMP_loop_foo_start, we emit 'goto L3'. */
2562 expand_omp_for_generic (struct omp_region *region,
2563 struct omp_for_data *fd,
2564 enum built_in_function start_fn,
2565 enum built_in_function next_fn)
2567 tree l0, l1, l2, l3;
2568 tree type, istart0, iend0, iend;
2570 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l3_bb;
2571 block_stmt_iterator si;
2572 bool in_combined_parallel = is_combined_parallel (region);
2574 type = TREE_TYPE (fd->v);
2576 istart0 = create_tmp_var (long_integer_type_node, ".istart0");
2577 iend0 = create_tmp_var (long_integer_type_node, ".iend0");
2578 iend = create_tmp_var (type, NULL);
2579 TREE_ADDRESSABLE (istart0) = 1;
2580 TREE_ADDRESSABLE (iend0) = 1;
2582 entry_bb = region->entry;
2583 l0_bb = create_empty_bb (entry_bb);
2584 l1_bb = single_succ (entry_bb);
2585 cont_bb = region->cont;
2586 l2_bb = create_empty_bb (cont_bb);
2587 l3_bb = single_succ (cont_bb);
2588 exit_bb = region->exit;
2590 l0 = tree_block_label (l0_bb);
2591 l1 = tree_block_label (l1_bb);
2592 l2 = tree_block_label (l2_bb);
2593 l3 = tree_block_label (l3_bb);
2595 si = bsi_last (entry_bb);
2596 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2597 if (!in_combined_parallel)
2599 /* If this is not a combined parallel loop, emit a call to
2600 GOMP_loop_foo_start in ENTRY_BB. */
2601 list = alloc_stmt_list ();
2602 t = build_fold_addr_expr (iend0);
2603 args = tree_cons (NULL, t, NULL);
2604 t = build_fold_addr_expr (istart0);
2605 args = tree_cons (NULL, t, args);
2608 t = fold_convert (long_integer_type_node, fd->chunk_size);
2609 args = tree_cons (NULL, t, args);
2611 t = fold_convert (long_integer_type_node, fd->step);
2612 args = tree_cons (NULL, t, args);
2613 t = fold_convert (long_integer_type_node, fd->n2);
2614 args = tree_cons (NULL, t, args);
2615 t = fold_convert (long_integer_type_node, fd->n1);
2616 args = tree_cons (NULL, t, args);
2617 t = build_function_call_expr (built_in_decls[start_fn], args);
2618 t = get_formal_tmp_var (t, &list);
2619 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
2620 build_and_jump (&l3));
2621 append_to_statement_list (t, &list);
2622 bsi_insert_after (&si, list, BSI_SAME_STMT);
2624 bsi_remove (&si, true);
2626 /* Iteration setup for sequential loop goes in L0_BB. */
2627 list = alloc_stmt_list ();
2628 t = fold_convert (type, istart0);
2629 t = build2 (MODIFY_EXPR, void_type_node, fd->v, t);
2630 gimplify_and_add (t, &list);
2632 t = fold_convert (type, iend0);
2633 t = build2 (MODIFY_EXPR, void_type_node, iend, t);
2634 gimplify_and_add (t, &list);
2636 si = bsi_start (l0_bb);
2637 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2639 /* Code to control the increment and predicate for the sequential
2640 loop goes in the first half of EXIT_BB (we split EXIT_BB so
2641 that we can inherit all the edges going out of the loop
2643 list = alloc_stmt_list ();
2645 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
2646 t = build2 (MODIFY_EXPR, void_type_node, fd->v, t);
2647 gimplify_and_add (t, &list);
2649 t = build2 (fd->cond_code, boolean_type_node, fd->v, iend);
2650 t = get_formal_tmp_var (t, &list);
2651 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1),
2652 build_and_jump (&l2));
2653 append_to_statement_list (t, &list);
2655 si = bsi_last (cont_bb);
2656 bsi_insert_after (&si, list, BSI_SAME_STMT);
2657 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
2658 bsi_remove (&si, true);
2660 /* Emit code to get the next parallel iteration in L2_BB. */
2661 list = alloc_stmt_list ();
2663 t = build_fold_addr_expr (iend0);
2664 args = tree_cons (NULL, t, NULL);
2665 t = build_fold_addr_expr (istart0);
2666 args = tree_cons (NULL, t, args);
2667 t = build_function_call_expr (built_in_decls[next_fn], args);
2668 t = get_formal_tmp_var (t, &list);
2669 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l0),
2670 build_and_jump (&l3));
2671 append_to_statement_list (t, &list);
2673 si = bsi_start (l2_bb);
2674 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2676 /* Add the loop cleanup function. */
2677 si = bsi_last (exit_bb);
2678 if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
2679 t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
2681 t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
2682 t = build_function_call_expr (t, NULL);
2683 bsi_insert_after (&si, t, BSI_SAME_STMT);
2684 bsi_remove (&si, true);
2686 /* Connect the new blocks. */
2687 remove_edge (single_succ_edge (entry_bb));
2688 if (in_combined_parallel)
2689 make_edge (entry_bb, l2_bb, EDGE_FALLTHRU);
2692 make_edge (entry_bb, l0_bb, EDGE_TRUE_VALUE);
2693 make_edge (entry_bb, l3_bb, EDGE_FALSE_VALUE);
2696 make_edge (l0_bb, l1_bb, EDGE_FALLTHRU);
2698 remove_edge (single_succ_edge (cont_bb));
2699 make_edge (cont_bb, l1_bb, EDGE_TRUE_VALUE);
2700 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
2702 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
2703 make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
2707 /* A subroutine of expand_omp_for. Generate code for a parallel
2708 loop with static schedule and no specified chunk size. Given
2711 for (V = N1; V cond N2; V += STEP) BODY;
2713 where COND is "<" or ">", we generate pseudocode
2719 n = (adj + N2 - N1) / STEP;
2721 q += (q * nthreads != n);
2723 e0 = min(s0 + q, n);
2724 if (s0 >= e0) goto L2; else goto L0;
2731 if (V cond e) goto L1;
2736 expand_omp_for_static_nochunk (struct omp_region *region,
2737 struct omp_for_data *fd)
2739 tree l0, l1, l2, n, q, s0, e0, e, t, nthreads, threadid;
2740 tree type, utype, list;
2741 basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
2743 block_stmt_iterator si;
2745 type = TREE_TYPE (fd->v);
2746 utype = lang_hooks.types.unsigned_type (type);
2748 entry_bb = region->entry;
2749 seq_start_bb = create_empty_bb (entry_bb);
2750 body_bb = single_succ (entry_bb);
2751 cont_bb = region->cont;
2752 fin_bb = single_succ (cont_bb);
2753 exit_bb = region->exit;
2755 l0 = tree_block_label (seq_start_bb);
2756 l1 = tree_block_label (body_bb);
2757 l2 = tree_block_label (fin_bb);
2759 /* Iteration space partitioning goes in ENTRY_BB. */
2760 list = alloc_stmt_list ();
2762 t = built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS];
2763 t = build_function_call_expr (t, NULL);
2764 t = fold_convert (utype, t);
2765 nthreads = get_formal_tmp_var (t, &list);
2767 t = built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM];
2768 t = build_function_call_expr (t, NULL);
2769 t = fold_convert (utype, t);
2770 threadid = get_formal_tmp_var (t, &list);
2772 fd->n1 = fold_convert (type, fd->n1);
2773 if (!is_gimple_val (fd->n1))
2774 fd->n1 = get_formal_tmp_var (fd->n1, &list);
2776 fd->n2 = fold_convert (type, fd->n2);
2777 if (!is_gimple_val (fd->n2))
2778 fd->n2 = get_formal_tmp_var (fd->n2, &list);
2780 fd->step = fold_convert (type, fd->step);
2781 if (!is_gimple_val (fd->step))
2782 fd->step = get_formal_tmp_var (fd->step, &list);
2784 t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2785 t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2786 t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2787 t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2788 t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2789 t = fold_convert (utype, t);
2790 if (is_gimple_val (t))
2793 n = get_formal_tmp_var (t, &list);
2795 t = build2 (TRUNC_DIV_EXPR, utype, n, nthreads);
2796 q = get_formal_tmp_var (t, &list);
2798 t = build2 (MULT_EXPR, utype, q, nthreads);
2799 t = build2 (NE_EXPR, utype, t, n);
2800 t = build2 (PLUS_EXPR, utype, q, t);
2801 q = get_formal_tmp_var (t, &list);
2803 t = build2 (MULT_EXPR, utype, q, threadid);
2804 s0 = get_formal_tmp_var (t, &list);
2806 t = build2 (PLUS_EXPR, utype, s0, q);
2807 t = build2 (MIN_EXPR, utype, t, n);
2808 e0 = get_formal_tmp_var (t, &list);
2810 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
2811 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l2),
2812 build_and_jump (&l0));
2813 append_to_statement_list (t, &list);
2815 si = bsi_last (entry_bb);
2816 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2817 bsi_insert_after (&si, list, BSI_SAME_STMT);
2818 bsi_remove (&si, true);
2820 /* Setup code for sequential iteration goes in SEQ_START_BB. */
2821 list = alloc_stmt_list ();
2823 t = fold_convert (type, s0);
2824 t = build2 (MULT_EXPR, type, t, fd->step);
2825 t = build2 (PLUS_EXPR, type, t, fd->n1);
2826 t = build2 (MODIFY_EXPR, void_type_node, fd->v, t);
2827 gimplify_and_add (t, &list);
2829 t = fold_convert (type, e0);
2830 t = build2 (MULT_EXPR, type, t, fd->step);
2831 t = build2 (PLUS_EXPR, type, t, fd->n1);
2832 e = get_formal_tmp_var (t, &list);
2834 si = bsi_start (seq_start_bb);
2835 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2837 /* The code controlling the sequential loop replaces the OMP_CONTINUE. */
2838 list = alloc_stmt_list ();
2840 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
2841 t = build2 (MODIFY_EXPR, void_type_node, fd->v, t);
2842 gimplify_and_add (t, &list);
2844 t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
2845 t = get_formal_tmp_var (t, &list);
2846 t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&l1),
2847 build_and_jump (&l2));
2848 append_to_statement_list (t, &list);
2850 si = bsi_last (cont_bb);
2851 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
2852 bsi_insert_after (&si, list, BSI_SAME_STMT);
2853 bsi_remove (&si, true);
2855 /* Replace the OMP_RETURN with a barrier, or nothing. */
2856 si = bsi_last (exit_bb);
2857 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
2859 list = alloc_stmt_list ();
2860 build_omp_barrier (&list);
2861 bsi_insert_after (&si, list, BSI_SAME_STMT);
2863 bsi_remove (&si, true);
2865 /* Connect all the blocks. */
2866 make_edge (seq_start_bb, body_bb, EDGE_FALLTHRU);
2868 remove_edge (single_succ_edge (entry_bb));
2869 make_edge (entry_bb, fin_bb, EDGE_TRUE_VALUE);
2870 make_edge (entry_bb, seq_start_bb, EDGE_FALSE_VALUE);
2872 make_edge (cont_bb, body_bb, EDGE_TRUE_VALUE);
2873 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
2877 /* A subroutine of expand_omp_for. Generate code for a parallel
2878 loop with static schedule and a specified chunk size. Given
2881 for (V = N1; V cond N2; V += STEP) BODY;
2883 where COND is "<" or ">", we generate pseudocode
2889 n = (adj + N2 - N1) / STEP;
2892 s0 = (trip * nthreads + threadid) * CHUNK;
2893 e0 = min(s0 + CHUNK, n);
2894 if (s0 < n) goto L1; else goto L4;
2901 if (V cond e) goto L2; else goto L3;
2909 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
2911 tree l0, l1, l2, l3, l4, n, s0, e0, e, t;
2912 tree trip, nthreads, threadid;
2914 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
2915 basic_block trip_update_bb, cont_bb, fin_bb;
2917 block_stmt_iterator si;
2919 type = TREE_TYPE (fd->v);
2920 utype = lang_hooks.types.unsigned_type (type);
2922 entry_bb = region->entry;
2923 iter_part_bb = create_empty_bb (entry_bb);
2924 seq_start_bb = create_empty_bb (iter_part_bb);
2925 body_bb = single_succ (entry_bb);
2926 cont_bb = region->cont;
2927 trip_update_bb = create_empty_bb (cont_bb);
2928 fin_bb = single_succ (cont_bb);
2929 exit_bb = region->exit;
2931 l0 = tree_block_label (iter_part_bb);
2932 l1 = tree_block_label (seq_start_bb);
2933 l2 = tree_block_label (body_bb);
2934 l3 = tree_block_label (trip_update_bb);
2935 l4 = tree_block_label (fin_bb);
2937 /* Trip and adjustment setup goes in ENTRY_BB. */
2938 list = alloc_stmt_list ();
2940 t = built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS];
2941 t = build_function_call_expr (t, NULL);
2942 t = fold_convert (utype, t);
2943 nthreads = get_formal_tmp_var (t, &list);
2945 t = built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM];
2946 t = build_function_call_expr (t, NULL);
2947 t = fold_convert (utype, t);
2948 threadid = get_formal_tmp_var (t, &list);
2950 fd->n1 = fold_convert (type, fd->n1);
2951 if (!is_gimple_val (fd->n1))
2952 fd->n1 = get_formal_tmp_var (fd->n1, &list);
2954 fd->n2 = fold_convert (type, fd->n2);
2955 if (!is_gimple_val (fd->n2))
2956 fd->n2 = get_formal_tmp_var (fd->n2, &list);
2958 fd->step = fold_convert (type, fd->step);
2959 if (!is_gimple_val (fd->step))
2960 fd->step = get_formal_tmp_var (fd->step, &list);
2962 fd->chunk_size = fold_convert (utype, fd->chunk_size);
2963 if (!is_gimple_val (fd->chunk_size))
2964 fd->chunk_size = get_formal_tmp_var (fd->chunk_size, &list);
2966 t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2967 t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2968 t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2969 t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2970 t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2971 t = fold_convert (utype, t);
2972 if (is_gimple_val (t))
2975 n = get_formal_tmp_var (t, &list);
2977 t = build_int_cst (utype, 0);
2978 trip = get_initialized_tmp_var (t, &list, NULL);
2980 si = bsi_last (entry_bb);
2981 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2982 bsi_insert_after (&si, list, BSI_SAME_STMT);
2983 bsi_remove (&si, true);
2985 /* Iteration space partitioning goes in ITER_PART_BB. */
2986 list = alloc_stmt_list ();
2988 t = build2 (MULT_EXPR, utype, trip, nthreads);
2989 t = build2 (PLUS_EXPR, utype, t, threadid);
2990 t = build2 (MULT_EXPR, utype, t, fd->chunk_size);
2991 s0 = get_formal_tmp_var (t, &list);
2993 t = build2 (PLUS_EXPR, utype, s0, fd->chunk_size);
2994 t = build2 (MIN_EXPR, utype, t, n);
2995 e0 = get_formal_tmp_var (t, &list);
2997 t = build2 (LT_EXPR, boolean_type_node, s0, n);
2998 t = build3 (COND_EXPR, void_type_node, t,
2999 build_and_jump (&l1), build_and_jump (&l4));
3000 append_to_statement_list (t, &list);
3002 si = bsi_start (iter_part_bb);
3003 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3005 /* Setup code for sequential iteration goes in SEQ_START_BB. */
3006 list = alloc_stmt_list ();
3008 t = fold_convert (type, s0);
3009 t = build2 (MULT_EXPR, type, t, fd->step);
3010 t = build2 (PLUS_EXPR, type, t, fd->n1);
3011 t = build2 (MODIFY_EXPR, void_type_node, fd->v, t);
3012 gimplify_and_add (t, &list);
3014 t = fold_convert (type, e0);
3015 t = build2 (MULT_EXPR, type, t, fd->step);
3016 t = build2 (PLUS_EXPR, type, t, fd->n1);
3017 e = get_formal_tmp_var (t, &list);
3019 si = bsi_start (seq_start_bb);
3020 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3022 /* The code controlling the sequential loop goes in CONT_BB,
3023 replacing the OMP_CONTINUE. */
3024 list = alloc_stmt_list ();
3026 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
3027 t = build2 (MODIFY_EXPR, void_type_node, fd->v, t);
3028 gimplify_and_add (t, &list);
3030 t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
3031 t = get_formal_tmp_var (t, &list);
3032 t = build3 (COND_EXPR, void_type_node, t,
3033 build_and_jump (&l2), build_and_jump (&l3));
3034 append_to_statement_list (t, &list);
3036 si = bsi_last (cont_bb);
3037 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3038 bsi_insert_after (&si, list, BSI_SAME_STMT);
3039 bsi_remove (&si, true);
3041 /* Trip update code goes into TRIP_UPDATE_BB. */
3042 list = alloc_stmt_list ();
3044 t = build_int_cst (utype, 1);
3045 t = build2 (PLUS_EXPR, utype, trip, t);
3046 t = build2 (MODIFY_EXPR, void_type_node, trip, t);
3047 gimplify_and_add (t, &list);
3049 si = bsi_start (trip_update_bb);
3050 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3052 /* Replace the OMP_RETURN with a barrier, or nothing. */
3053 si = bsi_last (exit_bb);
3054 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
3056 list = alloc_stmt_list ();
3057 build_omp_barrier (&list);
3058 bsi_insert_after (&si, list, BSI_SAME_STMT);
3060 bsi_remove (&si, true);
3062 /* Connect the new blocks. */
3063 remove_edge (single_succ_edge (entry_bb));
3064 make_edge (entry_bb, iter_part_bb, EDGE_FALLTHRU);
3066 make_edge (iter_part_bb, seq_start_bb, EDGE_TRUE_VALUE);
3067 make_edge (iter_part_bb, fin_bb, EDGE_FALSE_VALUE);
3069 make_edge (seq_start_bb, body_bb, EDGE_FALLTHRU);
3071 remove_edge (single_succ_edge (cont_bb));
3072 make_edge (cont_bb, body_bb, EDGE_TRUE_VALUE);
3073 make_edge (cont_bb, trip_update_bb, EDGE_FALSE_VALUE);
3075 make_edge (trip_update_bb, iter_part_bb, EDGE_FALLTHRU);
3079 /* Expand the OpenMP loop defined by REGION. */
3082 expand_omp_for (struct omp_region *region)
3084 struct omp_for_data fd;
3086 push_gimplify_context ();
3088 extract_omp_for_data (last_stmt (region->entry), &fd);
3089 region->sched_kind = fd.sched_kind;
3091 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC && !fd.have_ordered)
3093 if (fd.chunk_size == NULL)
3094 expand_omp_for_static_nochunk (region, &fd);
3096 expand_omp_for_static_chunk (region, &fd);
3100 int fn_index = fd.sched_kind + fd.have_ordered * 4;
3101 int start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index;
3102 int next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index;
3103 expand_omp_for_generic (region, &fd, start_ix, next_ix);
3106 pop_gimplify_context (NULL);
3110 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
3112 v = GOMP_sections_start (n);
3129 v = GOMP_sections_next ();
3134 If this is a combined parallel sections, replace the call to
3135 GOMP_sections_start with 'goto L1'. */
3138 expand_omp_sections (struct omp_region *region)
3140 tree label_vec, l0, l1, l2, t, u, v, sections_stmt;
3142 basic_block entry_bb, exit_bb, l0_bb, l1_bb, l2_bb, default_bb;
3143 block_stmt_iterator si;
3144 struct omp_region *inner;
3147 entry_bb = region->entry;
3148 l0_bb = create_empty_bb (entry_bb);
3149 l1_bb = region->cont;
3150 l2_bb = single_succ (l1_bb);
3151 default_bb = create_empty_bb (l1_bb->prev_bb);
3152 exit_bb = region->exit;
3154 l0 = tree_block_label (l0_bb);
3155 l1 = tree_block_label (l1_bb);
3156 l2 = tree_block_label (l2_bb);
3158 v = create_tmp_var (unsigned_type_node, ".section");
3160 /* We will build a switch() with enough cases for all the
3161 OMP_SECTION regions, a '0' case to handle the end of more work
3162 and a default case to abort if something goes wrong. */
3163 len = EDGE_COUNT (entry_bb->succs);
3164 label_vec = make_tree_vec (len + 2);
3166 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
3167 OMP_SECTIONS statement. */
3168 si = bsi_last (entry_bb);
3169 sections_stmt = bsi_stmt (si);
3170 gcc_assert (TREE_CODE (sections_stmt) == OMP_SECTIONS);
3171 if (!is_combined_parallel (region))
3173 /* If we are not inside a combined parallel+sections region,
3174 call GOMP_sections_start. */
3175 t = build_int_cst (unsigned_type_node, len);
3176 t = tree_cons (NULL, t, NULL);
3177 u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
3178 t = build_function_call_expr (u, t);
3179 t = build2 (MODIFY_EXPR, void_type_node, v, t);
3180 bsi_insert_after (&si, t, BSI_SAME_STMT);
3182 bsi_remove (&si, true);
3184 /* The switch() statement replacing OMP_SECTIONS goes in L0_BB. */
3185 si = bsi_start (l0_bb);
3187 t = build3 (SWITCH_EXPR, void_type_node, v, NULL, label_vec);
3188 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3190 t = build3 (CASE_LABEL_EXPR, void_type_node,
3191 build_int_cst (unsigned_type_node, 0), NULL, l2);
3192 TREE_VEC_ELT (label_vec, 0) = t;
3193 make_edge (l0_bb, l2_bb, 0);
3195 /* Convert each OMP_SECTION into a CASE_LABEL_EXPR. */
3196 for (inner = region->inner, i = 1; inner; inner = inner->next, ++i)
3198 basic_block s_entry_bb, s_exit_bb;
3200 s_entry_bb = inner->entry;
3201 s_exit_bb = inner->exit;
3203 t = tree_block_label (s_entry_bb);
3204 u = build_int_cst (unsigned_type_node, i);
3205 u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
3206 TREE_VEC_ELT (label_vec, i) = u;
3208 si = bsi_last (s_entry_bb);
3209 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTION);
3210 gcc_assert (i < len || OMP_SECTION_LAST (bsi_stmt (si)));
3211 bsi_remove (&si, true);
3213 si = bsi_last (s_exit_bb);
3214 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3215 bsi_remove (&si, true);
3217 e = single_pred_edge (s_entry_bb);
3219 redirect_edge_pred (e, l0_bb);
3221 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
3222 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
3225 /* Error handling code goes in DEFAULT_BB. */
3226 t = tree_block_label (default_bb);
3227 u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
3228 TREE_VEC_ELT (label_vec, len + 1) = u;
3229 make_edge (l0_bb, default_bb, 0);
3231 si = bsi_start (default_bb);
3232 t = built_in_decls[BUILT_IN_TRAP];
3233 t = build_function_call_expr (t, NULL);
3234 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3236 /* Code to get the next section goes in L1_BB. */
3237 si = bsi_last (l1_bb);
3238 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3240 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT];
3241 t = build_function_call_expr (t, NULL);
3242 t = build2 (MODIFY_EXPR, void_type_node, v, t);
3243 bsi_insert_after (&si, t, BSI_SAME_STMT);
3244 bsi_remove (&si, true);
3246 /* Cleanup function replaces OMP_RETURN in EXIT_BB. */
3247 si = bsi_last (exit_bb);
3248 if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
3249 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
3251 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
3252 t = build_function_call_expr (t, NULL);
3253 bsi_insert_after (&si, t, BSI_SAME_STMT);
3254 bsi_remove (&si, true);
3256 /* Connect the new blocks. */
3257 if (is_combined_parallel (region))
3259 /* If this was a combined parallel+sections region, we did not
3260 emit a GOMP_sections_start in the entry block, so we just
3261 need to jump to L1_BB to get the next section. */
3262 make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
3265 make_edge (entry_bb, l0_bb, EDGE_FALLTHRU);
3267 e = single_succ_edge (l1_bb);
3268 redirect_edge_succ (e, l0_bb);
3269 e->flags = EDGE_FALLTHRU;
3273 /* Expand code for an OpenMP single directive. We've already expanded
3274 much of the code, here we simply place the GOMP_barrier call. */
3277 expand_omp_single (struct omp_region *region)
3279 basic_block entry_bb, exit_bb;
3280 block_stmt_iterator si;
3281 bool need_barrier = false;
3283 entry_bb = region->entry;
3284 exit_bb = region->exit;
3286 si = bsi_last (entry_bb);
3287 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
3288 be removed. We need to ensure that the thread that entered the single
3289 does not exit before the data is copied out by the other threads. */
3290 if (find_omp_clause (OMP_SINGLE_CLAUSES (bsi_stmt (si)),
3291 OMP_CLAUSE_COPYPRIVATE))
3292 need_barrier = true;
3293 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE);
3294 bsi_remove (&si, true);
3295 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3297 si = bsi_last (exit_bb);
3298 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)) || need_barrier)
3300 tree t = alloc_stmt_list ();
3301 build_omp_barrier (&t);
3302 bsi_insert_after (&si, t, BSI_SAME_STMT);
3304 bsi_remove (&si, true);
3305 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3309 /* Generic expansion for OpenMP synchronization directives: master,
3310 ordered and critical. All we need to do here is remove the entry
3311 and exit markers for REGION. */
3314 expand_omp_synch (struct omp_region *region)
3316 basic_block entry_bb, exit_bb;
3317 block_stmt_iterator si;
3319 entry_bb = region->entry;
3320 exit_bb = region->exit;
3322 si = bsi_last (entry_bb);
3323 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE
3324 || TREE_CODE (bsi_stmt (si)) == OMP_MASTER
3325 || TREE_CODE (bsi_stmt (si)) == OMP_ORDERED
3326 || TREE_CODE (bsi_stmt (si)) == OMP_CRITICAL);
3327 bsi_remove (&si, true);
3328 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3330 si = bsi_last (exit_bb);
3331 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3332 bsi_remove (&si, true);
3333 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3337 /* Expand the parallel region tree rooted at REGION. Expansion
3338 proceeds in depth-first order. Innermost regions are expanded
3339 first. This way, parallel regions that require a new function to
3340 be created (e.g., OMP_PARALLEL) can be expanded without having any
3341 internal dependencies in their body. */
3344 expand_omp (struct omp_region *region)
3349 expand_omp (region->inner);
3351 switch (region->type)
3354 expand_omp_parallel (region);
3358 expand_omp_for (region);
3362 expand_omp_sections (region);
3366 /* Individual omp sections are handled together with their
3367 parent OMP_SECTIONS region. */
3371 expand_omp_single (region);
3377 expand_omp_synch (region);
3384 region = region->next;
3389 /* Helper for build_omp_regions. Scan the dominator tree starting at
3390 block BB. PARENT is the region that contains BB. */
3393 build_omp_regions_1 (basic_block bb, struct omp_region *parent)
3395 block_stmt_iterator si;
3400 if (!bsi_end_p (si) && OMP_DIRECTIVE_P (bsi_stmt (si)))
3402 struct omp_region *region;
3403 enum tree_code code;
3405 stmt = bsi_stmt (si);
3406 code = TREE_CODE (stmt);
3408 if (code == OMP_RETURN)
3410 /* STMT is the return point out of region PARENT. Mark it
3411 as the exit point and make PARENT the immediately
3412 enclosing region. */
3413 gcc_assert (parent);
3416 parent = parent->outer;
3418 /* If REGION is a parallel region, determine whether it is
3419 a combined parallel+workshare region. */
3420 if (region->type == OMP_PARALLEL)
3421 determine_parallel_type (region);
3423 else if (code == OMP_CONTINUE)
3425 gcc_assert (parent);
3430 /* Otherwise, this directive becomes the parent for a new
3432 region = new_omp_region (bb, code, parent);
3437 for (son = first_dom_son (CDI_DOMINATORS, bb);
3439 son = next_dom_son (CDI_DOMINATORS, son))
3440 build_omp_regions_1 (son, parent);
3444 /* Scan the CFG and build a tree of OMP regions. Return the root of
3445 the OMP region tree. */
3448 build_omp_regions (void)
3450 gcc_assert (root_omp_region == NULL);
3451 calculate_dominance_info (CDI_DOMINATORS);
3452 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL);
3456 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
3459 execute_expand_omp (void)
3461 build_omp_regions ();
3463 if (!root_omp_region)
3468 fprintf (dump_file, "\nOMP region tree\n\n");
3469 dump_omp_region (dump_file, root_omp_region, 0);
3470 fprintf (dump_file, "\n");
3473 remove_exit_barriers (root_omp_region);
3475 expand_omp (root_omp_region);
3477 free_dominance_info (CDI_DOMINATORS);
3478 free_dominance_info (CDI_POST_DOMINATORS);
3479 cleanup_tree_cfg ();
3481 free_omp_regions ();
3487 gate_expand_omp (void)
3489 return flag_openmp != 0 && errorcount == 0;
3492 struct tree_opt_pass pass_expand_omp =
3494 "ompexp", /* name */
3495 gate_expand_omp, /* gate */
3496 execute_expand_omp, /* execute */
3499 0, /* static_pass_number */
3501 PROP_gimple_any, /* properties_required */
3502 PROP_gimple_lomp, /* properties_provided */
3503 0, /* properties_destroyed */
3504 0, /* todo_flags_start */
3505 TODO_dump_func, /* todo_flags_finish */
3509 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
3511 /* Lower the OpenMP sections directive in *STMT_P. */
3514 lower_omp_sections (tree *stmt_p, omp_context *ctx)
3516 tree new_stmt, stmt, body, bind, block, ilist, olist, new_body;
3518 tree_stmt_iterator tsi;
3523 push_gimplify_context ();
3527 lower_rec_input_clauses (OMP_SECTIONS_CLAUSES (stmt), &ilist, &dlist, ctx);
3529 tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3530 for (len = 0; !tsi_end_p (tsi); len++, tsi_next (&tsi))
3533 tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3534 body = alloc_stmt_list ();
3535 for (i = 0; i < len; i++, tsi_next (&tsi))
3538 tree sec_start, sec_end;
3540 sec_start = tsi_stmt (tsi);
3541 sctx = maybe_lookup_ctx (sec_start);
3544 append_to_statement_list (sec_start, &body);
3546 lower_omp (&OMP_SECTION_BODY (sec_start), sctx);
3547 append_to_statement_list (OMP_SECTION_BODY (sec_start), &body);
3548 OMP_SECTION_BODY (sec_start) = NULL;
3552 tree l = alloc_stmt_list ();
3553 lower_lastprivate_clauses (OMP_SECTIONS_CLAUSES (stmt), NULL,
3555 append_to_statement_list (l, &body);
3556 OMP_SECTION_LAST (sec_start) = 1;
3559 sec_end = make_node (OMP_RETURN);
3560 append_to_statement_list (sec_end, &body);
3563 block = make_node (BLOCK);
3564 bind = build3 (BIND_EXPR, void_type_node, NULL, body, block);
3567 lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
3569 pop_gimplify_context (NULL_TREE);
3570 record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
3572 new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3573 TREE_SIDE_EFFECTS (new_stmt) = 1;
3575 new_body = alloc_stmt_list ();
3576 append_to_statement_list (ilist, &new_body);
3577 append_to_statement_list (stmt, &new_body);
3578 append_to_statement_list (bind, &new_body);
3580 t = make_node (OMP_CONTINUE);
3581 append_to_statement_list (t, &new_body);
3583 append_to_statement_list (olist, &new_body);
3584 append_to_statement_list (dlist, &new_body);
3586 maybe_catch_exception (&new_body);
3588 t = make_node (OMP_RETURN);
3589 OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SECTIONS_CLAUSES (stmt),
3591 append_to_statement_list (t, &new_body);
3593 BIND_EXPR_BODY (new_stmt) = new_body;
3594 OMP_SECTIONS_BODY (stmt) = NULL;
3600 /* A subroutine of lower_omp_single. Expand the simple form of
3601 an OMP_SINGLE, without a copyprivate clause:
3603 if (GOMP_single_start ())
3605 [ GOMP_barrier (); ] -> unless 'nowait' is present.
3607 FIXME. It may be better to delay expanding the logic of this until
3608 pass_expand_omp. The expanded logic may make the job more difficult
3609 to a synchronization analysis pass. */
3612 lower_omp_single_simple (tree single_stmt, tree *pre_p)
3616 t = built_in_decls[BUILT_IN_GOMP_SINGLE_START];
3617 t = build_function_call_expr (t, NULL);
3618 t = build3 (COND_EXPR, void_type_node, t,
3619 OMP_SINGLE_BODY (single_stmt), NULL);
3620 gimplify_and_add (t, pre_p);
3624 /* A subroutine of lower_omp_single. Expand the simple form of
3625 an OMP_SINGLE, with a copyprivate clause:
3627 #pragma omp single copyprivate (a, b, c)
3629 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
3632 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
3638 GOMP_single_copy_end (©out);
3649 FIXME. It may be better to delay expanding the logic of this until
3650 pass_expand_omp. The expanded logic may make the job more difficult
3651 to a synchronization analysis pass. */
3654 lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
3656 tree ptr_type, t, args, l0, l1, l2, copyin_seq;
3658 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
3660 ptr_type = build_pointer_type (ctx->record_type);
3661 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
3663 l0 = create_artificial_label ();
3664 l1 = create_artificial_label ();
3665 l2 = create_artificial_label ();
3667 t = built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START];
3668 t = build_function_call_expr (t, NULL);
3669 t = fold_convert (ptr_type, t);
3670 t = build2 (MODIFY_EXPR, void_type_node, ctx->receiver_decl, t);
3671 gimplify_and_add (t, pre_p);
3673 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
3674 build_int_cst (ptr_type, 0));
3675 t = build3 (COND_EXPR, void_type_node, t,
3676 build_and_jump (&l0), build_and_jump (&l1));
3677 gimplify_and_add (t, pre_p);
3679 t = build1 (LABEL_EXPR, void_type_node, l0);
3680 gimplify_and_add (t, pre_p);
3682 append_to_statement_list (OMP_SINGLE_BODY (single_stmt), pre_p);
3685 lower_copyprivate_clauses (OMP_SINGLE_CLAUSES (single_stmt), pre_p,
3688 t = build_fold_addr_expr (ctx->sender_decl);
3689 args = tree_cons (NULL, t, NULL);
3690 t = built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END];
3691 t = build_function_call_expr (t, args);
3692 gimplify_and_add (t, pre_p);
3694 t = build_and_jump (&l2);
3695 gimplify_and_add (t, pre_p);
3697 t = build1 (LABEL_EXPR, void_type_node, l1);
3698 gimplify_and_add (t, pre_p);
3700 append_to_statement_list (copyin_seq, pre_p);
3702 t = build1 (LABEL_EXPR, void_type_node, l2);
3703 gimplify_and_add (t, pre_p);
3707 /* Expand code for an OpenMP single directive. */
3710 lower_omp_single (tree *stmt_p, omp_context *ctx)
3712 tree t, bind, block, single_stmt = *stmt_p, dlist;
3714 push_gimplify_context ();
3716 block = make_node (BLOCK);
3717 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3718 TREE_SIDE_EFFECTS (bind) = 1;
3720 lower_rec_input_clauses (OMP_SINGLE_CLAUSES (single_stmt),
3721 &BIND_EXPR_BODY (bind), &dlist, ctx);
3722 lower_omp (&OMP_SINGLE_BODY (single_stmt), ctx);
3724 append_to_statement_list (single_stmt, &BIND_EXPR_BODY (bind));
3726 if (ctx->record_type)
3727 lower_omp_single_copy (single_stmt, &BIND_EXPR_BODY (bind), ctx);
3729 lower_omp_single_simple (single_stmt, &BIND_EXPR_BODY (bind));
3731 OMP_SINGLE_BODY (single_stmt) = NULL;
3733 append_to_statement_list (dlist, &BIND_EXPR_BODY (bind));
3735 maybe_catch_exception (&BIND_EXPR_BODY (bind));
3737 t = make_node (OMP_RETURN);
3738 OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SINGLE_CLAUSES (single_stmt),
3740 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3742 pop_gimplify_context (bind);
3744 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3745 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3749 /* Expand code for an OpenMP master directive. */
3752 lower_omp_master (tree *stmt_p, omp_context *ctx)
3754 tree bind, block, stmt = *stmt_p, lab = NULL, x;
3756 push_gimplify_context ();
3758 block = make_node (BLOCK);
3759 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3760 TREE_SIDE_EFFECTS (bind) = 1;
3762 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3764 x = built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM];
3765 x = build_function_call_expr (x, NULL);
3766 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
3767 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
3768 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3770 lower_omp (&OMP_MASTER_BODY (stmt), ctx);
3771 maybe_catch_exception (&OMP_MASTER_BODY (stmt));
3772 append_to_statement_list (OMP_MASTER_BODY (stmt), &BIND_EXPR_BODY (bind));
3773 OMP_MASTER_BODY (stmt) = NULL;
3775 x = build1 (LABEL_EXPR, void_type_node, lab);
3776 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3778 x = make_node (OMP_RETURN);
3779 OMP_RETURN_NOWAIT (x) = 1;
3780 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
3782 pop_gimplify_context (bind);
3784 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3785 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3789 /* Expand code for an OpenMP ordered directive. */
3792 lower_omp_ordered (tree *stmt_p, omp_context *ctx)
3794 tree bind, block, stmt = *stmt_p, x;
3796 push_gimplify_context ();
3798 block = make_node (BLOCK);
3799 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3800 TREE_SIDE_EFFECTS (bind) = 1;
3802 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3804 x = built_in_decls[BUILT_IN_GOMP_ORDERED_START];
3805 x = build_function_call_expr (x, NULL);
3806 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3808 lower_omp (&OMP_ORDERED_BODY (stmt), ctx);
3809 maybe_catch_exception (&OMP_ORDERED_BODY (stmt));
3810 append_to_statement_list (OMP_ORDERED_BODY (stmt), &BIND_EXPR_BODY (bind));
3811 OMP_ORDERED_BODY (stmt) = NULL;
3813 x = built_in_decls[BUILT_IN_GOMP_ORDERED_END];
3814 x = build_function_call_expr (x, NULL);
3815 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3817 x = make_node (OMP_RETURN);
3818 OMP_RETURN_NOWAIT (x) = 1;
3819 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
3821 pop_gimplify_context (bind);
3823 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3824 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3828 /* Gimplify an OMP_CRITICAL statement. This is a relatively simple
3829 substitution of a couple of function calls. But in the NAMED case,
3830 requires that languages coordinate a symbol name. It is therefore
3831 best put here in common code. */
3833 static GTY((param1_is (tree), param2_is (tree)))
3834 splay_tree critical_name_mutexes;
3837 lower_omp_critical (tree *stmt_p, omp_context *ctx)
3839 tree bind, block, stmt = *stmt_p;
3840 tree t, lock, unlock, name;
3842 name = OMP_CRITICAL_NAME (stmt);
3848 if (!critical_name_mutexes)
3849 critical_name_mutexes
3850 = splay_tree_new_ggc (splay_tree_compare_pointers);
3852 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
3857 decl = create_tmp_var_raw (ptr_type_node, NULL);
3859 new_str = ACONCAT ((".gomp_critical_user_",
3860 IDENTIFIER_POINTER (name), NULL));
3861 DECL_NAME (decl) = get_identifier (new_str);
3862 TREE_PUBLIC (decl) = 1;
3863 TREE_STATIC (decl) = 1;
3864 DECL_COMMON (decl) = 1;
3865 DECL_ARTIFICIAL (decl) = 1;
3866 DECL_IGNORED_P (decl) = 1;
3867 cgraph_varpool_finalize_decl (decl);
3869 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
3870 (splay_tree_value) decl);
3873 decl = (tree) n->value;
3875 args = tree_cons (NULL, build_fold_addr_expr (decl), NULL);
3876 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
3877 lock = build_function_call_expr (lock, args);
3879 args = tree_cons (NULL, build_fold_addr_expr (decl), NULL);
3880 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
3881 unlock = build_function_call_expr (unlock, args);
3885 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
3886 lock = build_function_call_expr (lock, NULL);
3888 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
3889 unlock = build_function_call_expr (unlock, NULL);
3892 push_gimplify_context ();
3894 block = make_node (BLOCK);
3895 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3896 TREE_SIDE_EFFECTS (bind) = 1;
3898 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3900 gimplify_and_add (lock, &BIND_EXPR_BODY (bind));
3902 lower_omp (&OMP_CRITICAL_BODY (stmt), ctx);
3903 maybe_catch_exception (&OMP_CRITICAL_BODY (stmt));
3904 append_to_statement_list (OMP_CRITICAL_BODY (stmt), &BIND_EXPR_BODY (bind));
3905 OMP_CRITICAL_BODY (stmt) = NULL;
3907 gimplify_and_add (unlock, &BIND_EXPR_BODY (bind));
3909 t = make_node (OMP_RETURN);
3910 OMP_RETURN_NOWAIT (t) = 1;
3911 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3913 pop_gimplify_context (bind);
3914 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3915 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3919 /* A subroutine of lower_omp_for. Generate code to emit the predicate
3920 for a lastprivate clause. Given a loop control predicate of (V
3921 cond N2), we gate the clause on (!(V cond N2)). The lowered form
3922 is appended to *BODY_P. */
3925 lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
3926 struct omp_context *ctx)
3929 enum tree_code cond_code;
3931 cond_code = fd->cond_code;
3932 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
3934 /* When possible, use a strict equality expression. This can let VRP
3935 type optimizations deduce the value and remove a copy. */
3936 if (host_integerp (fd->step, 0))
3938 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->step);
3939 if (step == 1 || step == -1)
3940 cond_code = EQ_EXPR;
3943 cond = build2 (cond_code, boolean_type_node, fd->v, fd->n2);
3945 clauses = OMP_FOR_CLAUSES (fd->for_stmt);
3946 lower_lastprivate_clauses (clauses, cond, body_p, ctx);
3950 /* Lower code for an OpenMP loop directive. */
3953 lower_omp_for (tree *stmt_p, omp_context *ctx)
3955 tree t, stmt, ilist, dlist, new_stmt, *body_p, *rhs_p;
3956 struct omp_for_data fd;
3960 push_gimplify_context ();
3962 lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
3963 lower_omp (&OMP_FOR_BODY (stmt), ctx);
3965 /* Move declaration of temporaries in the loop body before we make
3967 if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
3968 record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt)), ctx->cb.dst_fn);
3970 new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3971 TREE_SIDE_EFFECTS (new_stmt) = 1;
3972 body_p = &BIND_EXPR_BODY (new_stmt);
3974 /* The pre-body and input clauses go before the lowered OMP_FOR. */
3977 append_to_statement_list (OMP_FOR_PRE_BODY (stmt), body_p);
3978 lower_rec_input_clauses (OMP_FOR_CLAUSES (stmt), body_p, &dlist, ctx);
3980 /* Lower the header expressions. At this point, we can assume that
3981 the header is of the form:
3983 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
3985 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
3986 using the .omp_data_s mapping, if needed. */
3987 rhs_p = &TREE_OPERAND (OMP_FOR_INIT (stmt), 1);
3988 if (!is_gimple_min_invariant (*rhs_p))
3989 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
3991 rhs_p = &TREE_OPERAND (OMP_FOR_COND (stmt), 1);
3992 if (!is_gimple_min_invariant (*rhs_p))
3993 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
3995 rhs_p = &TREE_OPERAND (TREE_OPERAND (OMP_FOR_INCR (stmt), 1), 1);
3996 if (!is_gimple_min_invariant (*rhs_p))
3997 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
3999 /* Once lowered, extract the bounds and clauses. */
4000 extract_omp_for_data (stmt, &fd);
4002 append_to_statement_list (stmt, body_p);
4004 append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
4006 t = make_node (OMP_CONTINUE);
4007 append_to_statement_list (t, body_p);
4009 /* After the loop, add exit clauses. */
4010 lower_omp_for_lastprivate (&fd, &dlist, ctx);
4011 lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
4012 append_to_statement_list (dlist, body_p);
4014 maybe_catch_exception (body_p);
4016 /* Region exit marker goes at the end of the loop body. */
4017 t = make_node (OMP_RETURN);
4018 OMP_RETURN_NOWAIT (t) = fd.have_nowait;
4019 append_to_statement_list (t, body_p);
4021 pop_gimplify_context (NULL_TREE);
4022 record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
4024 OMP_FOR_BODY (stmt) = NULL_TREE;
4025 OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
4030 /* Lower the OpenMP parallel directive in *STMT_P. CTX holds context
4031 information for the directive. */
4034 lower_omp_parallel (tree *stmt_p, omp_context *ctx)
4036 tree clauses, par_bind, par_body, new_body, bind;
4037 tree olist, ilist, par_olist, par_ilist;
4038 tree stmt, child_fn, t;
4042 clauses = OMP_PARALLEL_CLAUSES (stmt);
4043 par_bind = OMP_PARALLEL_BODY (stmt);
4044 par_body = BIND_EXPR_BODY (par_bind);
4045 child_fn = ctx->cb.dst_fn;
4047 push_gimplify_context ();
4049 par_olist = NULL_TREE;
4050 par_ilist = NULL_TREE;
4051 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
4052 lower_omp (&par_body, ctx);
4053 lower_reduction_clauses (clauses, &par_olist, ctx);
4055 /* Declare all the variables created by mapping and the variables
4056 declared in the scope of the parallel body. */
4057 record_vars_into (ctx->block_vars, child_fn);
4058 record_vars_into (BIND_EXPR_VARS (par_bind), child_fn);
4060 if (ctx->record_type)
4062 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_data_o");
4063 OMP_PARALLEL_DATA_ARG (stmt) = ctx->sender_decl;
4068 lower_send_clauses (clauses, &ilist, &olist, ctx);
4069 lower_send_shared_vars (&ilist, &olist, ctx);
4071 /* Once all the expansions are done, sequence all the different
4072 fragments inside OMP_PARALLEL_BODY. */
4073 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4074 append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
4076 new_body = alloc_stmt_list ();
4078 if (ctx->record_type)
4080 t = build_fold_addr_expr (ctx->sender_decl);
4081 t = build2 (MODIFY_EXPR, void_type_node, ctx->receiver_decl, t);
4082 append_to_statement_list (t, &new_body);
4085 append_to_statement_list (par_ilist, &new_body);
4086 append_to_statement_list (par_body, &new_body);
4087 append_to_statement_list (par_olist, &new_body);
4088 maybe_catch_exception (&new_body);
4089 t = make_node (OMP_RETURN);
4090 append_to_statement_list (t, &new_body);
4091 OMP_PARALLEL_BODY (stmt) = new_body;
4093 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4094 append_to_statement_list (olist, &BIND_EXPR_BODY (bind));
4098 pop_gimplify_context (NULL_TREE);
4102 /* Pass *TP back through the gimplifier within the context determined by WI.
4103 This handles replacement of DECL_VALUE_EXPR, as well as adjusting the
4104 flags on ADDR_EXPR. */
4107 lower_regimplify (tree *tp, struct walk_stmt_info *wi)
4109 enum gimplify_status gs;
4113 gs = gimplify_expr (tp, &pre, NULL, is_gimple_lvalue, fb_lvalue);
4114 else if (wi->val_only)
4115 gs = gimplify_expr (tp, &pre, NULL, is_gimple_val, fb_rvalue);
4117 gs = gimplify_expr (tp, &pre, NULL, is_gimple_formal_tmp_var, fb_rvalue);
4118 gcc_assert (gs == GS_ALL_DONE);
4121 tsi_link_before (&wi->tsi, pre, TSI_SAME_STMT);
4125 /* Callback for walk_stmts. Lower the OpenMP directive pointed by TP. */
4128 lower_omp_1 (tree *tp, int *walk_subtrees, void *data)
4130 struct walk_stmt_info *wi = data;
4131 omp_context *ctx = wi->info;
4134 /* If we have issued syntax errors, avoid doing any heavy lifting.
4135 Just replace the OpenMP directives with a NOP to avoid
4136 confusing RTL expansion. */
4137 if (errorcount && OMP_DIRECTIVE_P (*tp))
4139 *tp = build_empty_stmt ();
4144 switch (TREE_CODE (*tp))
4147 ctx = maybe_lookup_ctx (t);
4148 lower_omp_parallel (tp, ctx);
4152 ctx = maybe_lookup_ctx (t);
4154 lower_omp_for (tp, ctx);
4158 ctx = maybe_lookup_ctx (t);
4160 lower_omp_sections (tp, ctx);
4164 ctx = maybe_lookup_ctx (t);
4166 lower_omp_single (tp, ctx);
4170 ctx = maybe_lookup_ctx (t);
4172 lower_omp_master (tp, ctx);
4176 ctx = maybe_lookup_ctx (t);
4178 lower_omp_ordered (tp, ctx);
4182 ctx = maybe_lookup_ctx (t);
4184 lower_omp_critical (tp, ctx);
4188 if (ctx && DECL_HAS_VALUE_EXPR_P (t))
4189 lower_regimplify (tp, wi);
4194 lower_regimplify (tp, wi);
4198 case ARRAY_RANGE_REF:
4202 case VIEW_CONVERT_EXPR:
4204 lower_regimplify (tp, wi);
4211 wi->val_only = true;
4212 lower_regimplify (&TREE_OPERAND (t, 0), wi);
4217 if (!TYPE_P (t) && !DECL_P (t))
4226 lower_omp (tree *stmt_p, omp_context *ctx)
4228 struct walk_stmt_info wi;
4230 memset (&wi, 0, sizeof (wi));
4231 wi.callback = lower_omp_1;
4234 wi.want_locations = true;
4236 walk_stmts (&wi, stmt_p);
4239 /* Main entry point. */
4242 execute_lower_omp (void)
4244 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
4245 delete_omp_context);
4247 scan_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4248 gcc_assert (parallel_nesting_level == 0);
4250 if (all_contexts->root)
4251 lower_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4255 splay_tree_delete (all_contexts);
4256 all_contexts = NULL;
4262 gate_lower_omp (void)
4264 return flag_openmp != 0;
4267 struct tree_opt_pass pass_lower_omp =
4269 "omplower", /* name */
4270 gate_lower_omp, /* gate */
4271 execute_lower_omp, /* execute */
4274 0, /* static_pass_number */
4276 PROP_gimple_any, /* properties_required */
4277 PROP_gimple_lomp, /* properties_provided */
4278 0, /* properties_destroyed */
4279 0, /* todo_flags_start */
4280 TODO_dump_func, /* todo_flags_finish */
4284 /* The following is a utility to diagnose OpenMP structured block violations.
4285 It is not part of the "omplower" pass, as that's invoked too late. It
4286 should be invoked by the respective front ends after gimplification. */
4288 static splay_tree all_labels;
4290 /* Check for mismatched contexts and generate an error if needed. Return
4291 true if an error is detected. */
4294 diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
4298 if ((label_ctx ? TREE_VALUE (label_ctx) : NULL) == branch_ctx)
4301 /* Try to avoid confusing the user by producing and error message
4302 with correct "exit" or "enter" verbage. We prefer "exit"
4303 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
4304 if (branch_ctx == NULL)
4310 if (TREE_VALUE (label_ctx) == branch_ctx)
4315 label_ctx = TREE_CHAIN (label_ctx);
4320 error ("invalid exit from OpenMP structured block");
4322 error ("invalid entry to OpenMP structured block");
4324 *stmt_p = build_empty_stmt ();
4328 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
4329 where in the tree each label is found. */
4332 diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
4334 struct walk_stmt_info *wi = data;
4335 tree context = (tree) wi->info;
4340 switch (TREE_CODE (t))
4345 walk_tree (&OMP_CLAUSES (t), diagnose_sb_1, wi, NULL);
4351 /* The minimal context here is just a tree of statements. */
4352 inner_context = tree_cons (NULL, t, context);
4353 wi->info = inner_context;
4354 walk_stmts (wi, &OMP_BODY (t));
4359 walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_1, wi, NULL);
4360 inner_context = tree_cons (NULL, t, context);
4361 wi->info = inner_context;
4362 walk_tree (&OMP_FOR_INIT (t), diagnose_sb_1, wi, NULL);
4363 walk_tree (&OMP_FOR_COND (t), diagnose_sb_1, wi, NULL);
4364 walk_tree (&OMP_FOR_INCR (t), diagnose_sb_1, wi, NULL);
4365 walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4366 walk_stmts (wi, &OMP_FOR_BODY (t));
4371 splay_tree_insert (all_labels, (splay_tree_key) LABEL_EXPR_LABEL (t),
4372 (splay_tree_value) context);
4382 /* Pass 2: Check each branch and see if its context differs from that of
4383 the destination label's context. */
4386 diagnose_sb_2 (tree *tp, int *walk_subtrees, void *data)
4388 struct walk_stmt_info *wi = data;
4389 tree context = (tree) wi->info;
4394 switch (TREE_CODE (t))
4399 walk_tree (&OMP_CLAUSES (t), diagnose_sb_2, wi, NULL);
4406 walk_stmts (wi, &OMP_BODY (t));
4411 walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_2, wi, NULL);
4413 walk_tree (&OMP_FOR_INIT (t), diagnose_sb_2, wi, NULL);
4414 walk_tree (&OMP_FOR_COND (t), diagnose_sb_2, wi, NULL);
4415 walk_tree (&OMP_FOR_INCR (t), diagnose_sb_2, wi, NULL);
4416 walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4417 walk_stmts (wi, &OMP_FOR_BODY (t));
4423 tree lab = GOTO_DESTINATION (t);
4424 if (TREE_CODE (lab) != LABEL_DECL)
4427 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4428 diagnose_sb_0 (tp, context, n ? (tree) n->value : NULL_TREE);
4434 tree vec = SWITCH_LABELS (t);
4435 int i, len = TREE_VEC_LENGTH (vec);
4436 for (i = 0; i < len; ++i)
4438 tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
4439 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4440 if (diagnose_sb_0 (tp, context, (tree) n->value))
4447 diagnose_sb_0 (tp, context, NULL_TREE);
4458 diagnose_omp_structured_block_errors (tree fndecl)
4460 tree save_current = current_function_decl;
4461 struct walk_stmt_info wi;
4463 current_function_decl = fndecl;
4465 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
4467 memset (&wi, 0, sizeof (wi));
4468 wi.callback = diagnose_sb_1;
4469 walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4471 memset (&wi, 0, sizeof (wi));
4472 wi.callback = diagnose_sb_2;
4473 wi.want_locations = true;
4474 wi.want_return_expr = true;
4475 walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4477 splay_tree_delete (all_labels);
4480 current_function_decl = save_current;
4483 #include "gt-omp-low.h"