1 /* Lowering pass for OpenMP directives. Converts OpenMP directives
2 into explicit calls to the runtime library (libgomp) and data
3 marshalling to implement data sharing and copying clauses.
4 Contributed by Diego Novillo <dnovillo@redhat.com>
6 Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
30 #include "tree-gimple.h"
31 #include "tree-inline.h"
32 #include "langhooks.h"
33 #include "diagnostic.h"
34 #include "tree-flow.h"
40 #include "tree-pass.h"
43 #include "splay-tree.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) == GIMPLE_MODIFY_STMT);
161 fd->v = GIMPLE_STMT_OPERAND (t, 0);
162 gcc_assert (DECL_P (fd->v));
163 gcc_assert (TREE_CODE (TREE_TYPE (fd->v)) == INTEGER_TYPE);
164 fd->n1 = GIMPLE_STMT_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) == GIMPLE_MODIFY_STMT);
191 gcc_assert (GIMPLE_STMT_OPERAND (t, 0) == fd->v);
192 t = GIMPLE_STMT_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 /* Number of sections is equal to the number of edges from the
351 OMP_SECTIONS_SWITCH statement, except for the one to the exit
352 of the sections region. */
353 basic_block bb = single_succ (bb_for_stmt (ws_stmt));
354 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
355 t = tree_cons (NULL, t, NULL);
363 /* Discover whether REGION is a combined parallel+workshare region. */
366 determine_parallel_type (struct omp_region *region)
368 basic_block par_entry_bb, par_exit_bb;
369 basic_block ws_entry_bb, ws_exit_bb;
371 if (region == NULL || region->inner == NULL
372 || region->exit == NULL || region->inner->exit == NULL
373 || region->inner->cont == NULL)
376 /* We only support parallel+for and parallel+sections. */
377 if (region->type != OMP_PARALLEL
378 || (region->inner->type != OMP_FOR
379 && region->inner->type != OMP_SECTIONS))
382 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
383 WS_EXIT_BB -> PAR_EXIT_BB. */
384 par_entry_bb = region->entry;
385 par_exit_bb = region->exit;
386 ws_entry_bb = region->inner->entry;
387 ws_exit_bb = region->inner->exit;
389 if (single_succ (par_entry_bb) == ws_entry_bb
390 && single_succ (ws_exit_bb) == par_exit_bb
391 && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb)
392 && (OMP_PARALLEL_COMBINED (last_stmt (par_entry_bb))
393 || (last_and_only_stmt (ws_entry_bb)
394 && last_and_only_stmt (par_exit_bb))))
396 tree ws_stmt = last_stmt (ws_entry_bb);
398 if (region->inner->type == OMP_FOR)
400 /* If this is a combined parallel loop, we need to determine
401 whether or not to use the combined library calls. There
402 are two cases where we do not apply the transformation:
403 static loops and any kind of ordered loop. In the first
404 case, we already open code the loop so there is no need
405 to do anything else. In the latter case, the combined
406 parallel loop call would still need extra synchronization
407 to implement ordered semantics, so there would not be any
408 gain in using the combined call. */
409 tree clauses = OMP_FOR_CLAUSES (ws_stmt);
410 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
412 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
413 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
415 region->is_combined_parallel = false;
416 region->inner->is_combined_parallel = false;
421 region->is_combined_parallel = true;
422 region->inner->is_combined_parallel = true;
423 region->ws_args = get_ws_args_for (ws_stmt);
428 /* Return true if EXPR is variable sized. */
431 is_variable_sized (const_tree expr)
433 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
436 /* Return true if DECL is a reference type. */
439 is_reference (tree decl)
441 return lang_hooks.decls.omp_privatize_by_reference (decl);
444 /* Lookup variables in the decl or field splay trees. The "maybe" form
445 allows for the variable form to not have been entered, otherwise we
446 assert that the variable must have been entered. */
449 lookup_decl (tree var, omp_context *ctx)
452 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
457 maybe_lookup_decl (tree var, omp_context *ctx)
460 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
461 return n ? *n : NULL_TREE;
465 lookup_field (tree var, omp_context *ctx)
468 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
469 return (tree) n->value;
473 maybe_lookup_field (tree var, omp_context *ctx)
476 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
477 return n ? (tree) n->value : NULL_TREE;
480 /* Return true if DECL should be copied by pointer. SHARED_P is true
481 if DECL is to be shared. */
484 use_pointer_for_field (const_tree decl, bool shared_p)
486 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
489 /* We can only use copy-in/copy-out semantics for shared variables
490 when we know the value is not accessible from an outer scope. */
493 /* ??? Trivially accessible from anywhere. But why would we even
494 be passing an address in this case? Should we simply assert
495 this to be false, or should we have a cleanup pass that removes
496 these from the list of mappings? */
497 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
500 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
501 without analyzing the expression whether or not its location
502 is accessible to anyone else. In the case of nested parallel
503 regions it certainly may be. */
504 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
507 /* Do not use copy-in/copy-out for variables that have their
509 if (TREE_ADDRESSABLE (decl))
516 /* Construct a new automatic decl similar to VAR. */
519 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
521 tree copy = build_decl (VAR_DECL, name, type);
523 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
524 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
525 DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (var);
526 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
527 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
528 TREE_USED (copy) = 1;
529 DECL_CONTEXT (copy) = current_function_decl;
530 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
532 TREE_CHAIN (copy) = ctx->block_vars;
533 ctx->block_vars = copy;
539 omp_copy_decl_1 (tree var, omp_context *ctx)
541 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
544 /* Build tree nodes to access the field for VAR on the receiver side. */
547 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
549 tree x, field = lookup_field (var, ctx);
551 /* If the receiver record type was remapped in the child function,
552 remap the field into the new record type. */
553 x = maybe_lookup_field (field, ctx);
557 x = build_fold_indirect_ref (ctx->receiver_decl);
558 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL);
560 x = build_fold_indirect_ref (x);
565 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
566 of a parallel, this is a component reference; for workshare constructs
567 this is some variable. */
570 build_outer_var_ref (tree var, omp_context *ctx)
574 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
576 else if (is_variable_sized (var))
578 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
579 x = build_outer_var_ref (x, ctx);
580 x = build_fold_indirect_ref (x);
582 else if (is_parallel_ctx (ctx))
584 bool by_ref = use_pointer_for_field (var, false);
585 x = build_receiver_ref (var, by_ref, ctx);
588 x = lookup_decl (var, ctx->outer);
589 else if (is_reference (var))
590 /* This can happen with orphaned constructs. If var is reference, it is
591 possible it is shared and as such valid. */
596 if (is_reference (var))
597 x = build_fold_indirect_ref (x);
602 /* Build tree nodes to access the field for VAR on the sender side. */
605 build_sender_ref (tree var, omp_context *ctx)
607 tree field = lookup_field (var, ctx);
608 return build3 (COMPONENT_REF, TREE_TYPE (field),
609 ctx->sender_decl, field, NULL);
612 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
615 install_var_field (tree var, bool by_ref, omp_context *ctx)
619 gcc_assert (!splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
621 type = TREE_TYPE (var);
623 type = build_pointer_type (type);
625 field = build_decl (FIELD_DECL, DECL_NAME (var), type);
627 /* Remember what variable this field was created for. This does have a
628 side effect of making dwarf2out ignore this member, so for helpful
629 debugging we clear it later in delete_omp_context. */
630 DECL_ABSTRACT_ORIGIN (field) = var;
632 insert_field_into_struct (ctx->record_type, field);
634 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
635 (splay_tree_value) field);
639 install_var_local (tree var, omp_context *ctx)
641 tree new_var = omp_copy_decl_1 (var, ctx);
642 insert_decl_map (&ctx->cb, var, new_var);
646 /* Adjust the replacement for DECL in CTX for the new context. This means
647 copying the DECL_VALUE_EXPR, and fixing up the type. */
650 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
654 new_decl = lookup_decl (decl, ctx);
656 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
658 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
659 && DECL_HAS_VALUE_EXPR_P (decl))
661 tree ve = DECL_VALUE_EXPR (decl);
662 walk_tree (&ve, copy_body_r, &ctx->cb, NULL);
663 SET_DECL_VALUE_EXPR (new_decl, ve);
664 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
667 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
669 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
670 if (size == error_mark_node)
671 size = TYPE_SIZE (TREE_TYPE (new_decl));
672 DECL_SIZE (new_decl) = size;
674 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
675 if (size == error_mark_node)
676 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
677 DECL_SIZE_UNIT (new_decl) = size;
681 /* The callback for remap_decl. Search all containing contexts for a
682 mapping of the variable; this avoids having to duplicate the splay
683 tree ahead of time. We know a mapping doesn't already exist in the
684 given context. Create new mappings to implement default semantics. */
687 omp_copy_decl (tree var, copy_body_data *cb)
689 omp_context *ctx = (omp_context *) cb;
692 if (TREE_CODE (var) == LABEL_DECL)
694 new_var = create_artificial_label ();
695 DECL_CONTEXT (new_var) = current_function_decl;
696 insert_decl_map (&ctx->cb, var, new_var);
700 while (!is_parallel_ctx (ctx))
705 new_var = maybe_lookup_decl (var, ctx);
710 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
713 return error_mark_node;
717 /* Return the parallel region associated with STMT. */
719 /* Debugging dumps for parallel regions. */
720 void dump_omp_region (FILE *, struct omp_region *, int);
721 void debug_omp_region (struct omp_region *);
722 void debug_all_omp_regions (void);
724 /* Dump the parallel region tree rooted at REGION. */
727 dump_omp_region (FILE *file, struct omp_region *region, int indent)
729 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
730 tree_code_name[region->type]);
733 dump_omp_region (file, region->inner, indent + 4);
737 fprintf (file, "%*sbb %d: OMP_CONTINUE\n", indent, "",
738 region->cont->index);
742 fprintf (file, "%*sbb %d: OMP_RETURN\n", indent, "",
743 region->exit->index);
745 fprintf (file, "%*s[no exit marker]\n", indent, "");
748 dump_omp_region (file, region->next, indent);
752 debug_omp_region (struct omp_region *region)
754 dump_omp_region (stderr, region, 0);
758 debug_all_omp_regions (void)
760 dump_omp_region (stderr, root_omp_region, 0);
764 /* Create a new parallel region starting at STMT inside region PARENT. */
767 new_omp_region (basic_block bb, enum tree_code type, struct omp_region *parent)
769 struct omp_region *region = xcalloc (1, sizeof (*region));
771 region->outer = parent;
777 /* This is a nested region. Add it to the list of inner
778 regions in PARENT. */
779 region->next = parent->inner;
780 parent->inner = region;
784 /* This is a toplevel region. Add it to the list of toplevel
785 regions in ROOT_OMP_REGION. */
786 region->next = root_omp_region;
787 root_omp_region = region;
793 /* Release the memory associated with the region tree rooted at REGION. */
796 free_omp_region_1 (struct omp_region *region)
798 struct omp_region *i, *n;
800 for (i = region->inner; i ; i = n)
803 free_omp_region_1 (i);
809 /* Release the memory for the entire omp region tree. */
812 free_omp_regions (void)
814 struct omp_region *r, *n;
815 for (r = root_omp_region; r ; r = n)
818 free_omp_region_1 (r);
820 root_omp_region = NULL;
824 /* Create a new context, with OUTER_CTX being the surrounding context. */
827 new_omp_context (tree stmt, omp_context *outer_ctx)
829 omp_context *ctx = XCNEW (omp_context);
831 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
832 (splay_tree_value) ctx);
837 ctx->outer = outer_ctx;
838 ctx->cb = outer_ctx->cb;
839 ctx->cb.block = NULL;
840 ctx->depth = outer_ctx->depth + 1;
844 ctx->cb.src_fn = current_function_decl;
845 ctx->cb.dst_fn = current_function_decl;
846 ctx->cb.src_node = cgraph_node (current_function_decl);
847 ctx->cb.dst_node = ctx->cb.src_node;
848 ctx->cb.src_cfun = cfun;
849 ctx->cb.copy_decl = omp_copy_decl;
850 ctx->cb.eh_region = -1;
851 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
855 ctx->cb.decl_map = pointer_map_create ();
860 /* Destroy a omp_context data structures. Called through the splay tree
861 value delete callback. */
864 delete_omp_context (splay_tree_value value)
866 omp_context *ctx = (omp_context *) value;
868 pointer_map_destroy (ctx->cb.decl_map);
871 splay_tree_delete (ctx->field_map);
873 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
874 it produces corrupt debug information. */
875 if (ctx->record_type)
878 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
879 DECL_ABSTRACT_ORIGIN (t) = NULL;
885 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
889 fixup_child_record_type (omp_context *ctx)
891 tree f, type = ctx->record_type;
893 /* ??? It isn't sufficient to just call remap_type here, because
894 variably_modified_type_p doesn't work the way we expect for
895 record types. Testing each field for whether it needs remapping
896 and creating a new record by hand works, however. */
897 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
898 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
902 tree name, new_fields = NULL;
904 type = lang_hooks.types.make_type (RECORD_TYPE);
905 name = DECL_NAME (TYPE_NAME (ctx->record_type));
906 name = build_decl (TYPE_DECL, name, type);
907 TYPE_NAME (type) = name;
909 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
911 tree new_f = copy_node (f);
912 DECL_CONTEXT (new_f) = type;
913 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
914 TREE_CHAIN (new_f) = new_fields;
917 /* Arrange to be able to look up the receiver field
918 given the sender field. */
919 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
920 (splay_tree_value) new_f);
922 TYPE_FIELDS (type) = nreverse (new_fields);
926 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
929 /* Instantiate decls as necessary in CTX to satisfy the data sharing
930 specified by CLAUSES. */
933 scan_sharing_clauses (tree clauses, omp_context *ctx)
936 bool scan_array_reductions = false;
938 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
942 switch (OMP_CLAUSE_CODE (c))
944 case OMP_CLAUSE_PRIVATE:
945 decl = OMP_CLAUSE_DECL (c);
946 if (!is_variable_sized (decl))
947 install_var_local (decl, ctx);
950 case OMP_CLAUSE_SHARED:
951 gcc_assert (is_parallel_ctx (ctx));
952 decl = OMP_CLAUSE_DECL (c);
953 gcc_assert (!is_variable_sized (decl));
954 by_ref = use_pointer_for_field (decl, true);
955 /* Global variables don't need to be copied,
956 the receiver side will use them directly. */
957 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
959 if (! TREE_READONLY (decl)
960 || TREE_ADDRESSABLE (decl)
962 || is_reference (decl))
964 install_var_field (decl, by_ref, ctx);
965 install_var_local (decl, ctx);
968 /* We don't need to copy const scalar vars back. */
969 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
972 case OMP_CLAUSE_LASTPRIVATE:
973 /* Let the corresponding firstprivate clause create
975 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
979 case OMP_CLAUSE_FIRSTPRIVATE:
980 case OMP_CLAUSE_REDUCTION:
981 decl = OMP_CLAUSE_DECL (c);
983 if (is_variable_sized (decl))
985 else if (is_parallel_ctx (ctx)
986 && ! is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
989 by_ref = use_pointer_for_field (decl, false);
990 install_var_field (decl, by_ref, ctx);
992 install_var_local (decl, ctx);
995 case OMP_CLAUSE_COPYPRIVATE:
997 scan_omp (&OMP_CLAUSE_DECL (c), ctx->outer);
1000 case OMP_CLAUSE_COPYIN:
1001 decl = OMP_CLAUSE_DECL (c);
1002 by_ref = use_pointer_for_field (decl, false);
1003 install_var_field (decl, by_ref, ctx);
1006 case OMP_CLAUSE_DEFAULT:
1007 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1011 case OMP_CLAUSE_NUM_THREADS:
1012 case OMP_CLAUSE_SCHEDULE:
1014 scan_omp (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1017 case OMP_CLAUSE_NOWAIT:
1018 case OMP_CLAUSE_ORDERED:
1026 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1028 switch (OMP_CLAUSE_CODE (c))
1030 case OMP_CLAUSE_LASTPRIVATE:
1031 /* Let the corresponding firstprivate clause create
1033 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1037 case OMP_CLAUSE_PRIVATE:
1038 case OMP_CLAUSE_FIRSTPRIVATE:
1039 case OMP_CLAUSE_REDUCTION:
1040 decl = OMP_CLAUSE_DECL (c);
1041 if (is_variable_sized (decl))
1042 install_var_local (decl, ctx);
1043 fixup_remapped_decl (decl, ctx,
1044 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1045 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1046 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1047 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1048 scan_array_reductions = true;
1051 case OMP_CLAUSE_SHARED:
1052 decl = OMP_CLAUSE_DECL (c);
1053 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1054 fixup_remapped_decl (decl, ctx, false);
1057 case OMP_CLAUSE_COPYPRIVATE:
1058 case OMP_CLAUSE_COPYIN:
1059 case OMP_CLAUSE_DEFAULT:
1061 case OMP_CLAUSE_NUM_THREADS:
1062 case OMP_CLAUSE_SCHEDULE:
1063 case OMP_CLAUSE_NOWAIT:
1064 case OMP_CLAUSE_ORDERED:
1072 if (scan_array_reductions)
1073 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1074 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1075 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1077 scan_omp (&OMP_CLAUSE_REDUCTION_INIT (c), ctx);
1078 scan_omp (&OMP_CLAUSE_REDUCTION_MERGE (c), ctx);
1082 /* Create a new name for omp child function. Returns an identifier. */
1084 static GTY(()) unsigned int tmp_ompfn_id_num;
1087 create_omp_child_function_name (void)
1089 tree name = DECL_ASSEMBLER_NAME (current_function_decl);
1090 size_t len = IDENTIFIER_LENGTH (name);
1091 char *tmp_name, *prefix;
1093 prefix = alloca (len + sizeof ("_omp_fn"));
1094 memcpy (prefix, IDENTIFIER_POINTER (name), len);
1095 strcpy (prefix + len, "_omp_fn");
1096 #ifndef NO_DOT_IN_LABEL
1098 #elif !defined NO_DOLLAR_IN_LABEL
1101 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, tmp_ompfn_id_num++);
1102 return get_identifier (tmp_name);
1105 /* Build a decl for the omp child function. It'll not contain a body
1106 yet, just the bare decl. */
1109 create_omp_child_function (omp_context *ctx)
1111 tree decl, type, name, t;
1113 name = create_omp_child_function_name ();
1114 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1116 decl = build_decl (FUNCTION_DECL, name, type);
1117 decl = lang_hooks.decls.pushdecl (decl);
1119 ctx->cb.dst_fn = decl;
1121 TREE_STATIC (decl) = 1;
1122 TREE_USED (decl) = 1;
1123 DECL_ARTIFICIAL (decl) = 1;
1124 DECL_IGNORED_P (decl) = 0;
1125 TREE_PUBLIC (decl) = 0;
1126 DECL_UNINLINABLE (decl) = 1;
1127 DECL_EXTERNAL (decl) = 0;
1128 DECL_CONTEXT (decl) = NULL_TREE;
1129 DECL_INITIAL (decl) = make_node (BLOCK);
1131 t = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1132 DECL_ARTIFICIAL (t) = 1;
1133 DECL_IGNORED_P (t) = 1;
1134 DECL_RESULT (decl) = t;
1136 t = build_decl (PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1137 DECL_ARTIFICIAL (t) = 1;
1138 DECL_ARG_TYPE (t) = ptr_type_node;
1139 DECL_CONTEXT (t) = current_function_decl;
1141 DECL_ARGUMENTS (decl) = t;
1142 ctx->receiver_decl = t;
1144 /* Allocate memory for the function structure. The call to
1145 allocate_struct_function clobbers CFUN, so we need to restore
1147 push_struct_function (decl);
1148 DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (ctx->stmt);
1149 cfun->function_end_locus = EXPR_LOCATION (ctx->stmt);
1154 /* Scan an OpenMP parallel directive. */
1157 scan_omp_parallel (tree *stmt_p, omp_context *outer_ctx)
1162 /* Ignore parallel directives with empty bodies, unless there
1163 are copyin clauses. */
1165 && empty_body_p (OMP_PARALLEL_BODY (*stmt_p))
1166 && find_omp_clause (OMP_CLAUSES (*stmt_p), OMP_CLAUSE_COPYIN) == NULL)
1168 *stmt_p = build_empty_stmt ();
1172 ctx = new_omp_context (*stmt_p, outer_ctx);
1173 if (parallel_nesting_level > 1)
1174 ctx->is_nested = true;
1175 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1176 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1177 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1178 name = create_tmp_var_name (".omp_data_s");
1179 name = build_decl (TYPE_DECL, name, ctx->record_type);
1180 TYPE_NAME (ctx->record_type) = name;
1181 create_omp_child_function (ctx);
1182 OMP_PARALLEL_FN (*stmt_p) = ctx->cb.dst_fn;
1184 scan_sharing_clauses (OMP_PARALLEL_CLAUSES (*stmt_p), ctx);
1185 scan_omp (&OMP_PARALLEL_BODY (*stmt_p), ctx);
1187 if (TYPE_FIELDS (ctx->record_type) == NULL)
1188 ctx->record_type = ctx->receiver_decl = NULL;
1191 layout_type (ctx->record_type);
1192 fixup_child_record_type (ctx);
1197 /* Scan an OpenMP loop directive. */
1200 scan_omp_for (tree *stmt_p, omp_context *outer_ctx)
1206 ctx = new_omp_context (stmt, outer_ctx);
1208 scan_sharing_clauses (OMP_FOR_CLAUSES (stmt), ctx);
1210 scan_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
1211 scan_omp (&OMP_FOR_INIT (stmt), ctx);
1212 scan_omp (&OMP_FOR_COND (stmt), ctx);
1213 scan_omp (&OMP_FOR_INCR (stmt), ctx);
1214 scan_omp (&OMP_FOR_BODY (stmt), ctx);
1217 /* Scan an OpenMP sections directive. */
1220 scan_omp_sections (tree *stmt_p, omp_context *outer_ctx)
1226 ctx = new_omp_context (stmt, outer_ctx);
1227 scan_sharing_clauses (OMP_SECTIONS_CLAUSES (stmt), ctx);
1228 scan_omp (&OMP_SECTIONS_BODY (stmt), ctx);
1231 /* Scan an OpenMP single directive. */
1234 scan_omp_single (tree *stmt_p, omp_context *outer_ctx)
1236 tree stmt = *stmt_p;
1240 ctx = new_omp_context (stmt, outer_ctx);
1241 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1242 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1243 name = create_tmp_var_name (".omp_copy_s");
1244 name = build_decl (TYPE_DECL, name, ctx->record_type);
1245 TYPE_NAME (ctx->record_type) = name;
1247 scan_sharing_clauses (OMP_SINGLE_CLAUSES (stmt), ctx);
1248 scan_omp (&OMP_SINGLE_BODY (stmt), ctx);
1250 if (TYPE_FIELDS (ctx->record_type) == NULL)
1251 ctx->record_type = NULL;
1253 layout_type (ctx->record_type);
1257 /* Check OpenMP nesting restrictions. */
1259 check_omp_nesting_restrictions (tree t, omp_context *ctx)
1261 switch (TREE_CODE (t))
1266 for (; ctx != NULL; ctx = ctx->outer)
1267 switch (TREE_CODE (ctx->stmt))
1274 warning (0, "work-sharing region may not be closely nested inside "
1275 "of work-sharing, critical, ordered or master region");
1284 for (; ctx != NULL; ctx = ctx->outer)
1285 switch (TREE_CODE (ctx->stmt))
1290 warning (0, "master region may not be closely nested inside "
1291 "of work-sharing region");
1300 for (; ctx != NULL; ctx = ctx->outer)
1301 switch (TREE_CODE (ctx->stmt))
1304 warning (0, "ordered region may not be closely nested inside "
1305 "of critical region");
1308 if (find_omp_clause (OMP_CLAUSES (ctx->stmt),
1309 OMP_CLAUSE_ORDERED) == NULL)
1310 warning (0, "ordered region must be closely nested inside "
1311 "a loop region with an ordered clause");
1320 for (; ctx != NULL; ctx = ctx->outer)
1321 if (TREE_CODE (ctx->stmt) == OMP_CRITICAL
1322 && OMP_CRITICAL_NAME (t) == OMP_CRITICAL_NAME (ctx->stmt))
1324 warning (0, "critical region may not be nested inside a critical "
1325 "region with the same name");
1335 /* Callback for walk_stmts used to scan for OpenMP directives at TP. */
1338 scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
1340 struct walk_stmt_info *wi = data;
1341 omp_context *ctx = wi->info;
1344 if (EXPR_HAS_LOCATION (t))
1345 input_location = EXPR_LOCATION (t);
1347 /* Check the OpenMP nesting restrictions. */
1348 if (OMP_DIRECTIVE_P (t) && ctx != NULL)
1349 check_omp_nesting_restrictions (t, ctx);
1352 switch (TREE_CODE (t))
1355 parallel_nesting_level++;
1356 scan_omp_parallel (tp, ctx);
1357 parallel_nesting_level--;
1361 scan_omp_for (tp, ctx);
1365 scan_omp_sections (tp, ctx);
1369 scan_omp_single (tp, ctx);
1376 ctx = new_omp_context (*tp, ctx);
1377 scan_omp (&OMP_BODY (*tp), ctx);
1385 for (var = BIND_EXPR_VARS (t); var ; var = TREE_CHAIN (var))
1386 insert_decl_map (&ctx->cb, var, var);
1395 *tp = remap_decl (t, &ctx->cb);
1399 if (ctx && TYPE_P (t))
1400 *tp = remap_type (t, &ctx->cb);
1401 else if (!DECL_P (t))
1410 /* Scan all the statements starting at STMT_P. CTX contains context
1411 information about the OpenMP directives and clauses found during
1415 scan_omp (tree *stmt_p, omp_context *ctx)
1417 location_t saved_location;
1418 struct walk_stmt_info wi;
1420 memset (&wi, 0, sizeof (wi));
1421 wi.callback = scan_omp_1;
1423 wi.want_bind_expr = (ctx != NULL);
1424 wi.want_locations = true;
1426 saved_location = input_location;
1427 walk_stmts (&wi, stmt_p);
1428 input_location = saved_location;
1431 /* Re-gimplification and code generation routines. */
1433 /* Build a call to GOMP_barrier. */
1436 build_omp_barrier (tree *stmt_list)
1438 tree t = build_call_expr (built_in_decls[BUILT_IN_GOMP_BARRIER], 0);
1439 gimplify_and_add (t, stmt_list);
1442 /* If a context was created for STMT when it was scanned, return it. */
1444 static omp_context *
1445 maybe_lookup_ctx (tree stmt)
1448 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
1449 return n ? (omp_context *) n->value : NULL;
1453 /* Find the mapping for DECL in CTX or the immediately enclosing
1454 context that has a mapping for DECL.
1456 If CTX is a nested parallel directive, we may have to use the decl
1457 mappings created in CTX's parent context. Suppose that we have the
1458 following parallel nesting (variable UIDs showed for clarity):
1461 #omp parallel shared(iD.1562) -> outer parallel
1462 iD.1562 = iD.1562 + 1;
1464 #omp parallel shared (iD.1562) -> inner parallel
1465 iD.1562 = iD.1562 - 1;
1467 Each parallel structure will create a distinct .omp_data_s structure
1468 for copying iD.1562 in/out of the directive:
1470 outer parallel .omp_data_s.1.i -> iD.1562
1471 inner parallel .omp_data_s.2.i -> iD.1562
1473 A shared variable mapping will produce a copy-out operation before
1474 the parallel directive and a copy-in operation after it. So, in
1475 this case we would have:
1478 .omp_data_o.1.i = iD.1562;
1479 #omp parallel shared(iD.1562) -> outer parallel
1480 .omp_data_i.1 = &.omp_data_o.1
1481 .omp_data_i.1->i = .omp_data_i.1->i + 1;
1483 .omp_data_o.2.i = iD.1562; -> **
1484 #omp parallel shared(iD.1562) -> inner parallel
1485 .omp_data_i.2 = &.omp_data_o.2
1486 .omp_data_i.2->i = .omp_data_i.2->i - 1;
1489 ** This is a problem. The symbol iD.1562 cannot be referenced
1490 inside the body of the outer parallel region. But since we are
1491 emitting this copy operation while expanding the inner parallel
1492 directive, we need to access the CTX structure of the outer
1493 parallel directive to get the correct mapping:
1495 .omp_data_o.2.i = .omp_data_i.1->i
1497 Since there may be other workshare or parallel directives enclosing
1498 the parallel directive, it may be necessary to walk up the context
1499 parent chain. This is not a problem in general because nested
1500 parallelism happens only rarely. */
1503 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1508 gcc_assert (ctx->is_nested);
1510 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1511 t = maybe_lookup_decl (decl, up);
1513 gcc_assert (t || is_global_var (decl));
1515 return t ? t : decl;
1519 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
1520 in outer contexts. */
1523 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1529 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1530 t = maybe_lookup_decl (decl, up);
1532 return t ? t : decl;
1536 /* Construct the initialization value for reduction CLAUSE. */
1539 omp_reduction_init (tree clause, tree type)
1541 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
1548 case TRUTH_ORIF_EXPR:
1549 case TRUTH_XOR_EXPR:
1551 return fold_convert (type, integer_zero_node);
1554 case TRUTH_AND_EXPR:
1555 case TRUTH_ANDIF_EXPR:
1557 return fold_convert (type, integer_one_node);
1560 return fold_convert (type, integer_minus_one_node);
1563 if (SCALAR_FLOAT_TYPE_P (type))
1565 REAL_VALUE_TYPE max, min;
1566 if (HONOR_INFINITIES (TYPE_MODE (type)))
1569 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
1572 real_maxval (&min, 1, TYPE_MODE (type));
1573 return build_real (type, min);
1577 gcc_assert (INTEGRAL_TYPE_P (type));
1578 return TYPE_MIN_VALUE (type);
1582 if (SCALAR_FLOAT_TYPE_P (type))
1584 REAL_VALUE_TYPE max;
1585 if (HONOR_INFINITIES (TYPE_MODE (type)))
1588 real_maxval (&max, 0, TYPE_MODE (type));
1589 return build_real (type, max);
1593 gcc_assert (INTEGRAL_TYPE_P (type));
1594 return TYPE_MAX_VALUE (type);
1602 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
1603 from the receiver (aka child) side and initializers for REFERENCE_TYPE
1604 private variables. Initialization statements go in ILIST, while calls
1605 to destructors go in DLIST. */
1608 lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
1611 tree_stmt_iterator diter;
1612 tree c, dtor, copyin_seq, x, ptr;
1613 bool copyin_by_ref = false;
1614 bool lastprivate_firstprivate = false;
1617 *dlist = alloc_stmt_list ();
1618 diter = tsi_start (*dlist);
1621 /* Do all the fixed sized types in the first pass, and the variable sized
1622 types in the second pass. This makes sure that the scalar arguments to
1623 the variable sized types are processed before we use them in the
1624 variable sized operations. */
1625 for (pass = 0; pass < 2; ++pass)
1627 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1629 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
1635 case OMP_CLAUSE_PRIVATE:
1636 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
1639 case OMP_CLAUSE_SHARED:
1640 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
1642 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
1645 case OMP_CLAUSE_FIRSTPRIVATE:
1646 case OMP_CLAUSE_COPYIN:
1647 case OMP_CLAUSE_REDUCTION:
1649 case OMP_CLAUSE_LASTPRIVATE:
1650 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1652 lastprivate_firstprivate = true;
1661 new_var = var = OMP_CLAUSE_DECL (c);
1662 if (c_kind != OMP_CLAUSE_COPYIN)
1663 new_var = lookup_decl (var, ctx);
1665 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
1670 else if (is_variable_sized (var))
1672 /* For variable sized types, we need to allocate the
1673 actual storage here. Call alloca and store the
1674 result in the pointer decl that we created elsewhere. */
1678 ptr = DECL_VALUE_EXPR (new_var);
1679 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
1680 ptr = TREE_OPERAND (ptr, 0);
1681 gcc_assert (DECL_P (ptr));
1683 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
1684 x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
1685 x = fold_convert (TREE_TYPE (ptr), x);
1686 x = build_gimple_modify_stmt (ptr, x);
1687 gimplify_and_add (x, ilist);
1689 else if (is_reference (var))
1691 /* For references that are being privatized for Fortran,
1692 allocate new backing storage for the new pointer
1693 variable. This allows us to avoid changing all the
1694 code that expects a pointer to something that expects
1695 a direct variable. Note that this doesn't apply to
1696 C++, since reference types are disallowed in data
1697 sharing clauses there, except for NRV optimized
1702 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
1703 if (TREE_CONSTANT (x))
1705 const char *name = NULL;
1706 if (DECL_NAME (var))
1707 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
1709 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
1711 gimple_add_tmp_var (x);
1712 x = build_fold_addr_expr_with_type (x, TREE_TYPE (new_var));
1716 x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
1717 x = fold_convert (TREE_TYPE (new_var), x);
1720 x = build_gimple_modify_stmt (new_var, x);
1721 gimplify_and_add (x, ilist);
1723 new_var = build_fold_indirect_ref (new_var);
1725 else if (c_kind == OMP_CLAUSE_REDUCTION
1726 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1734 switch (OMP_CLAUSE_CODE (c))
1736 case OMP_CLAUSE_SHARED:
1737 /* Shared global vars are just accessed directly. */
1738 if (is_global_var (new_var))
1740 /* Set up the DECL_VALUE_EXPR for shared variables now. This
1741 needs to be delayed until after fixup_child_record_type so
1742 that we get the correct type during the dereference. */
1743 by_ref = use_pointer_for_field (var, true);
1744 x = build_receiver_ref (var, by_ref, ctx);
1745 SET_DECL_VALUE_EXPR (new_var, x);
1746 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
1748 /* ??? If VAR is not passed by reference, and the variable
1749 hasn't been initialized yet, then we'll get a warning for
1750 the store into the omp_data_s structure. Ideally, we'd be
1751 able to notice this and not store anything at all, but
1752 we're generating code too early. Suppress the warning. */
1754 TREE_NO_WARNING (var) = 1;
1757 case OMP_CLAUSE_LASTPRIVATE:
1758 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1762 case OMP_CLAUSE_PRIVATE:
1763 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var);
1765 gimplify_and_add (x, ilist);
1769 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
1773 gimplify_stmt (&dtor);
1774 tsi_link_before (&diter, dtor, TSI_SAME_STMT);
1778 case OMP_CLAUSE_FIRSTPRIVATE:
1779 x = build_outer_var_ref (var, ctx);
1780 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
1781 gimplify_and_add (x, ilist);
1785 case OMP_CLAUSE_COPYIN:
1786 by_ref = use_pointer_for_field (var, false);
1787 x = build_receiver_ref (var, by_ref, ctx);
1788 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
1789 append_to_statement_list (x, ©in_seq);
1790 copyin_by_ref |= by_ref;
1793 case OMP_CLAUSE_REDUCTION:
1794 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1796 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), ilist);
1797 OMP_CLAUSE_REDUCTION_INIT (c) = NULL;
1801 x = omp_reduction_init (c, TREE_TYPE (new_var));
1802 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
1803 x = build_gimple_modify_stmt (new_var, x);
1804 gimplify_and_add (x, ilist);
1814 /* The copyin sequence is not to be executed by the main thread, since
1815 that would result in self-copies. Perhaps not visible to scalars,
1816 but it certainly is to C++ operator=. */
1819 x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
1820 x = build2 (NE_EXPR, boolean_type_node, x,
1821 build_int_cst (TREE_TYPE (x), 0));
1822 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
1823 gimplify_and_add (x, ilist);
1826 /* If any copyin variable is passed by reference, we must ensure the
1827 master thread doesn't modify it before it is copied over in all
1828 threads. Similarly for variables in both firstprivate and
1829 lastprivate clauses we need to ensure the lastprivate copying
1830 happens after firstprivate copying in all threads. */
1831 if (copyin_by_ref || lastprivate_firstprivate)
1832 build_omp_barrier (ilist);
1836 /* Generate code to implement the LASTPRIVATE clauses. This is used for
1837 both parallel and workshare constructs. PREDICATE may be NULL if it's
1841 lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
1844 tree sub_list, x, c;
1846 /* Early exit if there are no lastprivate clauses. */
1847 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
1848 if (clauses == NULL)
1850 /* If this was a workshare clause, see if it had been combined
1851 with its parallel. In that case, look for the clauses on the
1852 parallel statement itself. */
1853 if (is_parallel_ctx (ctx))
1857 if (ctx == NULL || !is_parallel_ctx (ctx))
1860 clauses = find_omp_clause (OMP_PARALLEL_CLAUSES (ctx->stmt),
1861 OMP_CLAUSE_LASTPRIVATE);
1862 if (clauses == NULL)
1866 sub_list = alloc_stmt_list ();
1868 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1872 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE)
1875 var = OMP_CLAUSE_DECL (c);
1876 new_var = lookup_decl (var, ctx);
1878 x = build_outer_var_ref (var, ctx);
1879 if (is_reference (var))
1880 new_var = build_fold_indirect_ref (new_var);
1881 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
1882 append_to_statement_list (x, &sub_list);
1886 x = build3 (COND_EXPR, void_type_node, predicate, sub_list, NULL);
1890 gimplify_and_add (x, stmt_list);
1894 /* Generate code to implement the REDUCTION clauses. */
1897 lower_reduction_clauses (tree clauses, tree *stmt_list, omp_context *ctx)
1899 tree sub_list = NULL, x, c;
1902 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
1903 update in that case, otherwise use a lock. */
1904 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
1905 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
1907 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1909 /* Never use OMP_ATOMIC for array reductions. */
1919 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1921 tree var, ref, new_var;
1922 enum tree_code code;
1924 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
1927 var = OMP_CLAUSE_DECL (c);
1928 new_var = lookup_decl (var, ctx);
1929 if (is_reference (var))
1930 new_var = build_fold_indirect_ref (new_var);
1931 ref = build_outer_var_ref (var, ctx);
1932 code = OMP_CLAUSE_REDUCTION_CODE (c);
1934 /* reduction(-:var) sums up the partial results, so it acts
1935 identically to reduction(+:var). */
1936 if (code == MINUS_EXPR)
1941 tree addr = build_fold_addr_expr (ref);
1943 addr = save_expr (addr);
1944 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
1945 x = fold_build2 (code, TREE_TYPE (ref), ref, new_var);
1946 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
1947 gimplify_and_add (x, stmt_list);
1951 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1953 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
1955 if (is_reference (var))
1956 ref = build_fold_addr_expr (ref);
1957 SET_DECL_VALUE_EXPR (placeholder, ref);
1958 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
1959 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), &sub_list);
1960 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL;
1961 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
1965 x = build2 (code, TREE_TYPE (ref), ref, new_var);
1966 ref = build_outer_var_ref (var, ctx);
1967 x = build_gimple_modify_stmt (ref, x);
1968 append_to_statement_list (x, &sub_list);
1972 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
1973 gimplify_and_add (x, stmt_list);
1975 gimplify_and_add (sub_list, stmt_list);
1977 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
1978 gimplify_and_add (x, stmt_list);
1982 /* Generate code to implement the COPYPRIVATE clauses. */
1985 lower_copyprivate_clauses (tree clauses, tree *slist, tree *rlist,
1990 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1995 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
1998 var = OMP_CLAUSE_DECL (c);
1999 by_ref = use_pointer_for_field (var, false);
2001 ref = build_sender_ref (var, ctx);
2002 x = (ctx->is_nested) ? lookup_decl_in_outer_ctx (var, ctx) : var;
2003 x = by_ref ? build_fold_addr_expr (x) : x;
2004 x = build_gimple_modify_stmt (ref, x);
2005 gimplify_and_add (x, slist);
2007 ref = build_receiver_ref (var, by_ref, ctx);
2008 if (is_reference (var))
2010 ref = build_fold_indirect_ref (ref);
2011 var = build_fold_indirect_ref (var);
2013 x = lang_hooks.decls.omp_clause_assign_op (c, var, ref);
2014 gimplify_and_add (x, rlist);
2019 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2020 and REDUCTION from the sender (aka parent) side. */
2023 lower_send_clauses (tree clauses, tree *ilist, tree *olist, omp_context *ctx)
2027 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2029 tree val, ref, x, var;
2030 bool by_ref, do_in = false, do_out = false;
2032 switch (OMP_CLAUSE_CODE (c))
2034 case OMP_CLAUSE_FIRSTPRIVATE:
2035 case OMP_CLAUSE_COPYIN:
2036 case OMP_CLAUSE_LASTPRIVATE:
2037 case OMP_CLAUSE_REDUCTION:
2043 var = val = OMP_CLAUSE_DECL (c);
2045 var = lookup_decl_in_outer_ctx (val, ctx);
2047 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2048 && is_global_var (var))
2050 if (is_variable_sized (val))
2052 by_ref = use_pointer_for_field (val, false);
2054 switch (OMP_CLAUSE_CODE (c))
2056 case OMP_CLAUSE_FIRSTPRIVATE:
2057 case OMP_CLAUSE_COPYIN:
2061 case OMP_CLAUSE_LASTPRIVATE:
2062 if (by_ref || is_reference (val))
2064 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2072 case OMP_CLAUSE_REDUCTION:
2074 do_out = !(by_ref || is_reference (val));
2083 ref = build_sender_ref (val, ctx);
2084 x = by_ref ? build_fold_addr_expr (var) : var;
2085 x = build_gimple_modify_stmt (ref, x);
2086 gimplify_and_add (x, ilist);
2091 ref = build_sender_ref (val, ctx);
2092 x = build_gimple_modify_stmt (var, ref);
2093 gimplify_and_add (x, olist);
2098 /* Generate code to implement SHARED from the sender (aka parent) side.
2099 This is trickier, since OMP_PARALLEL_CLAUSES doesn't list things that
2100 got automatically shared. */
2103 lower_send_shared_vars (tree *ilist, tree *olist, omp_context *ctx)
2105 tree var, ovar, nvar, f, x;
2107 if (ctx->record_type == NULL)
2110 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
2112 ovar = DECL_ABSTRACT_ORIGIN (f);
2113 nvar = maybe_lookup_decl (ovar, ctx);
2114 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2119 /* If CTX is a nested parallel directive. Find the immediately
2120 enclosing parallel or workshare construct that contains a
2121 mapping for OVAR. */
2123 var = lookup_decl_in_outer_ctx (ovar, ctx);
2125 if (use_pointer_for_field (ovar, true))
2127 x = build_sender_ref (ovar, ctx);
2128 var = build_fold_addr_expr (var);
2129 x = build_gimple_modify_stmt (x, var);
2130 gimplify_and_add (x, ilist);
2134 x = build_sender_ref (ovar, ctx);
2135 x = build_gimple_modify_stmt (x, var);
2136 gimplify_and_add (x, ilist);
2138 x = build_sender_ref (ovar, ctx);
2139 x = build_gimple_modify_stmt (var, x);
2140 gimplify_and_add (x, olist);
2145 /* Build the function calls to GOMP_parallel_start etc to actually
2146 generate the parallel operation. REGION is the parallel region
2147 being expanded. BB is the block where to insert the code. WS_ARGS
2148 will be set if this is a call to a combined parallel+workshare
2149 construct, it contains the list of additional arguments needed by
2150 the workshare construct. */
2153 expand_parallel_call (struct omp_region *region, basic_block bb,
2154 tree entry_stmt, tree ws_args)
2156 tree t, t1, t2, val, cond, c, list, clauses;
2157 block_stmt_iterator si;
2160 clauses = OMP_PARALLEL_CLAUSES (entry_stmt);
2161 push_gimplify_context ();
2163 /* Determine what flavor of GOMP_parallel_start we will be
2165 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2166 if (is_combined_parallel (region))
2168 switch (region->inner->type)
2171 start_ix = BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2172 + region->inner->sched_kind;
2175 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2182 /* By default, the value of NUM_THREADS is zero (selected at run time)
2183 and there is no conditional. */
2185 val = build_int_cst (unsigned_type_node, 0);
2187 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2189 cond = OMP_CLAUSE_IF_EXPR (c);
2191 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2193 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2195 /* Ensure 'val' is of the correct type. */
2196 val = fold_convert (unsigned_type_node, val);
2198 /* If we found the clause 'if (cond)', build either
2199 (cond != 0) or (cond ? val : 1u). */
2202 block_stmt_iterator si;
2204 cond = gimple_boolify (cond);
2206 if (integer_zerop (val))
2207 val = build2 (EQ_EXPR, unsigned_type_node, cond,
2208 build_int_cst (TREE_TYPE (cond), 0));
2211 basic_block cond_bb, then_bb, else_bb;
2215 tmp = create_tmp_var (TREE_TYPE (val), NULL);
2216 e = split_block (bb, NULL);
2221 then_bb = create_empty_bb (cond_bb);
2222 else_bb = create_empty_bb (then_bb);
2224 t = build3 (COND_EXPR, void_type_node,
2225 cond, NULL_TREE, NULL_TREE);
2227 si = bsi_start (cond_bb);
2228 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2230 si = bsi_start (then_bb);
2231 t = build_gimple_modify_stmt (tmp, val);
2232 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2234 si = bsi_start (else_bb);
2235 t = build_gimple_modify_stmt (tmp,
2236 build_int_cst (unsigned_type_node, 1));
2237 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2239 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
2240 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
2241 make_edge (then_bb, bb, EDGE_FALLTHRU);
2242 make_edge (else_bb, bb, EDGE_FALLTHRU);
2248 val = get_formal_tmp_var (val, &list);
2249 si = bsi_start (bb);
2250 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2254 t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2256 t1 = null_pointer_node;
2258 t1 = build_fold_addr_expr (t);
2259 t2 = build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt));
2263 tree args = tree_cons (NULL, t2,
2264 tree_cons (NULL, t1,
2265 tree_cons (NULL, val, ws_args)));
2266 t = build_function_call_expr (built_in_decls[start_ix], args);
2269 t = build_call_expr (built_in_decls[start_ix], 3, t2, t1, val);
2271 gimplify_and_add (t, &list);
2273 t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2275 t = null_pointer_node;
2277 t = build_fold_addr_expr (t);
2278 t = build_call_expr (OMP_PARALLEL_FN (entry_stmt), 1, t);
2279 gimplify_and_add (t, &list);
2281 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_PARALLEL_END], 0);
2282 gimplify_and_add (t, &list);
2285 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2287 pop_gimplify_context (NULL_TREE);
2291 /* If exceptions are enabled, wrap *STMT_P in a MUST_NOT_THROW catch
2292 handler. This prevents programs from violating the structured
2293 block semantics with throws. */
2296 maybe_catch_exception (tree *stmt_p)
2300 if (!flag_exceptions)
2303 if (lang_protect_cleanup_actions)
2304 t = lang_protect_cleanup_actions ();
2306 t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
2307 f = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
2308 EH_FILTER_MUST_NOT_THROW (f) = 1;
2309 gimplify_and_add (t, &EH_FILTER_FAILURE (f));
2311 t = build2 (TRY_CATCH_EXPR, void_type_node, *stmt_p, NULL);
2312 append_to_statement_list (f, &TREE_OPERAND (t, 1));
2315 append_to_statement_list (t, stmt_p);
2318 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
2321 list2chain (tree list)
2325 for (t = list; t; t = TREE_CHAIN (t))
2327 tree var = TREE_VALUE (t);
2329 TREE_CHAIN (var) = TREE_VALUE (TREE_CHAIN (t));
2331 TREE_CHAIN (var) = NULL_TREE;
2334 return list ? TREE_VALUE (list) : NULL_TREE;
2338 /* Remove barriers in REGION->EXIT's block. Note that this is only
2339 valid for OMP_PARALLEL regions. Since the end of a parallel region
2340 is an implicit barrier, any workshare inside the OMP_PARALLEL that
2341 left a barrier at the end of the OMP_PARALLEL region can now be
2345 remove_exit_barrier (struct omp_region *region)
2347 block_stmt_iterator si;
2348 basic_block exit_bb;
2353 exit_bb = region->exit;
2355 /* If the parallel region doesn't return, we don't have REGION->EXIT
2360 /* The last insn in the block will be the parallel's OMP_RETURN. The
2361 workshare's OMP_RETURN will be in a preceding block. The kinds of
2362 statements that can appear in between are extremely limited -- no
2363 memory operations at all. Here, we allow nothing at all, so the
2364 only thing we allow to precede this OMP_RETURN is a label. */
2365 si = bsi_last (exit_bb);
2366 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2368 if (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) != LABEL_EXPR)
2371 FOR_EACH_EDGE (e, ei, exit_bb->preds)
2373 si = bsi_last (e->src);
2377 if (TREE_CODE (t) == OMP_RETURN)
2378 OMP_RETURN_NOWAIT (t) = 1;
2383 remove_exit_barriers (struct omp_region *region)
2385 if (region->type == OMP_PARALLEL)
2386 remove_exit_barrier (region);
2390 region = region->inner;
2391 remove_exit_barriers (region);
2392 while (region->next)
2394 region = region->next;
2395 remove_exit_barriers (region);
2400 /* Expand the OpenMP parallel directive starting at REGION. */
2403 expand_omp_parallel (struct omp_region *region)
2405 basic_block entry_bb, exit_bb, new_bb;
2406 struct function *child_cfun;
2407 tree child_fn, block, t, ws_args;
2408 block_stmt_iterator si;
2411 bool do_cleanup_cfg = false;
2413 entry_stmt = last_stmt (region->entry);
2414 child_fn = OMP_PARALLEL_FN (entry_stmt);
2415 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
2417 entry_bb = region->entry;
2418 exit_bb = region->exit;
2420 if (is_combined_parallel (region))
2421 ws_args = region->ws_args;
2423 ws_args = NULL_TREE;
2425 if (child_cfun->cfg)
2427 /* Due to inlining, it may happen that we have already outlined
2428 the region, in which case all we need to do is make the
2429 sub-graph unreachable and emit the parallel call. */
2430 edge entry_succ_e, exit_succ_e;
2431 block_stmt_iterator si;
2433 entry_succ_e = single_succ_edge (entry_bb);
2435 si = bsi_last (entry_bb);
2436 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_PARALLEL);
2437 bsi_remove (&si, true);
2440 remove_edge (entry_succ_e);
2443 exit_succ_e = single_succ_edge (exit_bb);
2444 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
2446 do_cleanup_cfg = true;
2450 /* If the parallel region needs data sent from the parent
2451 function, then the very first statement (except possible
2452 tree profile counter updates) of the parallel body
2453 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
2454 &.OMP_DATA_O is passed as an argument to the child function,
2455 we need to replace it with the argument as seen by the child
2458 In most cases, this will end up being the identity assignment
2459 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
2460 a function call that has been inlined, the original PARM_DECL
2461 .OMP_DATA_I may have been converted into a different local
2462 variable. In which case, we need to keep the assignment. */
2463 if (OMP_PARALLEL_DATA_ARG (entry_stmt))
2465 basic_block entry_succ_bb = single_succ (entry_bb);
2466 block_stmt_iterator si;
2468 for (si = bsi_start (entry_succ_bb); ; bsi_next (&si))
2472 gcc_assert (!bsi_end_p (si));
2473 stmt = bsi_stmt (si);
2474 if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
2477 arg = GIMPLE_STMT_OPERAND (stmt, 1);
2479 if (TREE_CODE (arg) == ADDR_EXPR
2480 && TREE_OPERAND (arg, 0)
2481 == OMP_PARALLEL_DATA_ARG (entry_stmt))
2483 if (GIMPLE_STMT_OPERAND (stmt, 0)
2484 == DECL_ARGUMENTS (child_fn))
2485 bsi_remove (&si, true);
2487 GIMPLE_STMT_OPERAND (stmt, 1) = DECL_ARGUMENTS (child_fn);
2493 /* Declare local variables needed in CHILD_CFUN. */
2494 block = DECL_INITIAL (child_fn);
2495 BLOCK_VARS (block) = list2chain (child_cfun->unexpanded_var_list);
2496 DECL_SAVED_TREE (child_fn) = bb_stmt_list (single_succ (entry_bb));
2498 /* Reset DECL_CONTEXT on locals and function arguments. */
2499 for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
2500 DECL_CONTEXT (t) = child_fn;
2502 for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
2503 DECL_CONTEXT (t) = child_fn;
2505 /* Split ENTRY_BB at OMP_PARALLEL so that it can be moved to the
2507 si = bsi_last (entry_bb);
2509 gcc_assert (t && TREE_CODE (t) == OMP_PARALLEL);
2510 bsi_remove (&si, true);
2511 e = split_block (entry_bb, t);
2513 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
2515 /* Move the parallel region into CHILD_CFUN. We need to reset
2516 dominance information because the expansion of the inner
2517 regions has invalidated it. */
2518 free_dominance_info (CDI_DOMINATORS);
2519 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
2521 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
2522 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
2523 = cfun->curr_properties;
2524 cgraph_add_new_function (child_fn, true);
2526 /* Convert OMP_RETURN into a RETURN_EXPR. */
2529 si = bsi_last (exit_bb);
2530 gcc_assert (!bsi_end_p (si)
2531 && TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2532 t = build1 (RETURN_EXPR, void_type_node, NULL);
2533 bsi_insert_after (&si, t, BSI_SAME_STMT);
2534 bsi_remove (&si, true);
2538 /* Emit a library call to launch the children threads. */
2539 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
2543 /* Clean up the unreachable sub-graph we created above. */
2544 free_dominance_info (CDI_DOMINATORS);
2545 free_dominance_info (CDI_POST_DOMINATORS);
2546 cleanup_tree_cfg ();
2551 /* A subroutine of expand_omp_for. Generate code for a parallel
2552 loop with any schedule. Given parameters:
2554 for (V = N1; V cond N2; V += STEP) BODY;
2556 where COND is "<" or ">", we generate pseudocode
2558 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
2559 if (more) goto L0; else goto L3;
2566 if (V cond iend) goto L1; else goto L2;
2568 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
2571 If this is a combined omp parallel loop, instead of the call to
2572 GOMP_loop_foo_start, we emit 'goto L2'. */
2575 expand_omp_for_generic (struct omp_region *region,
2576 struct omp_for_data *fd,
2577 enum built_in_function start_fn,
2578 enum built_in_function next_fn)
2580 tree type, istart0, iend0, iend;
2582 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
2583 basic_block l2_bb = NULL, l3_bb = NULL;
2584 block_stmt_iterator si;
2585 bool in_combined_parallel = is_combined_parallel (region);
2586 bool broken_loop = region->cont == NULL;
2588 gcc_assert (!broken_loop || !in_combined_parallel);
2590 type = TREE_TYPE (fd->v);
2592 istart0 = create_tmp_var (long_integer_type_node, ".istart0");
2593 iend0 = create_tmp_var (long_integer_type_node, ".iend0");
2594 iend = create_tmp_var (type, NULL);
2595 TREE_ADDRESSABLE (istart0) = 1;
2596 TREE_ADDRESSABLE (iend0) = 1;
2598 entry_bb = region->entry;
2599 cont_bb = region->cont;
2600 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
2601 gcc_assert (broken_loop
2602 || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
2603 l0_bb = split_edge (FALLTHRU_EDGE (entry_bb));
2604 l1_bb = single_succ (l0_bb);
2607 l2_bb = create_empty_bb (cont_bb);
2608 gcc_assert (BRANCH_EDGE (cont_bb)->dest == l1_bb);
2609 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
2613 l3_bb = BRANCH_EDGE (entry_bb)->dest;
2614 exit_bb = region->exit;
2616 si = bsi_last (entry_bb);
2617 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2618 if (!in_combined_parallel)
2620 tree t0, t1, t2, t3, t4;
2621 /* If this is not a combined parallel loop, emit a call to
2622 GOMP_loop_foo_start in ENTRY_BB. */
2623 list = alloc_stmt_list ();
2624 t4 = build_fold_addr_expr (iend0);
2625 t3 = build_fold_addr_expr (istart0);
2626 t2 = fold_convert (long_integer_type_node, fd->step);
2627 t1 = fold_convert (long_integer_type_node, fd->n2);
2628 t0 = fold_convert (long_integer_type_node, fd->n1);
2631 t = fold_convert (long_integer_type_node, fd->chunk_size);
2632 t = build_call_expr (built_in_decls[start_fn], 6,
2633 t0, t1, t2, t, t3, t4);
2636 t = build_call_expr (built_in_decls[start_fn], 5,
2637 t0, t1, t2, t3, t4);
2638 t = get_formal_tmp_var (t, &list);
2639 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2640 append_to_statement_list (t, &list);
2641 bsi_insert_after (&si, list, BSI_SAME_STMT);
2643 bsi_remove (&si, true);
2645 /* Iteration setup for sequential loop goes in L0_BB. */
2646 list = alloc_stmt_list ();
2647 t = fold_convert (type, istart0);
2648 t = build_gimple_modify_stmt (fd->v, t);
2649 gimplify_and_add (t, &list);
2651 t = fold_convert (type, iend0);
2652 t = build_gimple_modify_stmt (iend, t);
2653 gimplify_and_add (t, &list);
2655 si = bsi_start (l0_bb);
2656 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2660 /* Code to control the increment and predicate for the sequential
2661 loop goes in the CONT_BB. */
2662 list = alloc_stmt_list ();
2664 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
2665 t = build_gimple_modify_stmt (fd->v, t);
2666 gimplify_and_add (t, &list);
2668 t = build2 (fd->cond_code, boolean_type_node, fd->v, iend);
2669 t = get_formal_tmp_var (t, &list);
2670 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2671 append_to_statement_list (t, &list);
2673 si = bsi_last (cont_bb);
2674 bsi_insert_after (&si, list, BSI_SAME_STMT);
2675 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
2676 bsi_remove (&si, true);
2678 /* Emit code to get the next parallel iteration in L2_BB. */
2679 list = alloc_stmt_list ();
2681 t = build_call_expr (built_in_decls[next_fn], 2,
2682 build_fold_addr_expr (istart0),
2683 build_fold_addr_expr (iend0));
2684 t = get_formal_tmp_var (t, &list);
2685 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2686 append_to_statement_list (t, &list);
2688 si = bsi_start (l2_bb);
2689 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2692 /* Add the loop cleanup function. */
2693 si = bsi_last (exit_bb);
2694 if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
2695 t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
2697 t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
2698 t = build_call_expr (t, 0);
2699 bsi_insert_after (&si, t, BSI_SAME_STMT);
2700 bsi_remove (&si, true);
2702 /* Connect the new blocks. */
2703 if (in_combined_parallel)
2705 remove_edge (BRANCH_EDGE (entry_bb));
2706 redirect_edge_and_branch (single_succ_edge (entry_bb), l2_bb);
2710 find_edge (entry_bb, l0_bb)->flags = EDGE_TRUE_VALUE;
2711 find_edge (entry_bb, l3_bb)->flags = EDGE_FALSE_VALUE;
2716 find_edge (cont_bb, l1_bb)->flags = EDGE_TRUE_VALUE;
2717 remove_edge (find_edge (cont_bb, l3_bb));
2718 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
2720 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
2721 make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
2726 /* A subroutine of expand_omp_for. Generate code for a parallel
2727 loop with static schedule and no specified chunk size. Given
2730 for (V = N1; V cond N2; V += STEP) BODY;
2732 where COND is "<" or ">", we generate pseudocode
2738 n = (adj + N2 - N1) / STEP;
2740 q += (q * nthreads != n);
2742 e0 = min(s0 + q, n);
2743 if (s0 >= e0) goto L2; else goto L0;
2750 if (V cond e) goto L1;
2755 expand_omp_for_static_nochunk (struct omp_region *region,
2756 struct omp_for_data *fd)
2758 tree n, q, s0, e0, e, t, nthreads, threadid;
2760 basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
2762 block_stmt_iterator si;
2764 type = TREE_TYPE (fd->v);
2766 entry_bb = region->entry;
2767 cont_bb = region->cont;
2768 gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
2769 gcc_assert (BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
2770 seq_start_bb = split_edge (FALLTHRU_EDGE (entry_bb));
2771 body_bb = single_succ (seq_start_bb);
2772 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
2773 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
2774 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
2775 exit_bb = region->exit;
2777 /* Iteration space partitioning goes in ENTRY_BB. */
2778 list = alloc_stmt_list ();
2780 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
2781 t = fold_convert (type, t);
2782 nthreads = get_formal_tmp_var (t, &list);
2784 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2785 t = fold_convert (type, t);
2786 threadid = get_formal_tmp_var (t, &list);
2788 fd->n1 = fold_convert (type, fd->n1);
2789 if (!is_gimple_val (fd->n1))
2790 fd->n1 = get_formal_tmp_var (fd->n1, &list);
2792 fd->n2 = fold_convert (type, fd->n2);
2793 if (!is_gimple_val (fd->n2))
2794 fd->n2 = get_formal_tmp_var (fd->n2, &list);
2796 fd->step = fold_convert (type, fd->step);
2797 if (!is_gimple_val (fd->step))
2798 fd->step = get_formal_tmp_var (fd->step, &list);
2800 t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2801 t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2802 t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2803 t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2804 t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2805 t = fold_convert (type, t);
2806 if (is_gimple_val (t))
2809 n = get_formal_tmp_var (t, &list);
2811 t = build2 (TRUNC_DIV_EXPR, type, n, nthreads);
2812 q = get_formal_tmp_var (t, &list);
2814 t = build2 (MULT_EXPR, type, q, nthreads);
2815 t = build2 (NE_EXPR, type, t, n);
2816 t = build2 (PLUS_EXPR, type, q, t);
2817 q = get_formal_tmp_var (t, &list);
2819 t = build2 (MULT_EXPR, type, q, threadid);
2820 s0 = get_formal_tmp_var (t, &list);
2822 t = build2 (PLUS_EXPR, type, s0, q);
2823 t = build2 (MIN_EXPR, type, t, n);
2824 e0 = get_formal_tmp_var (t, &list);
2826 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
2827 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2828 append_to_statement_list (t, &list);
2830 si = bsi_last (entry_bb);
2831 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2832 bsi_insert_after (&si, list, BSI_SAME_STMT);
2833 bsi_remove (&si, true);
2835 /* Setup code for sequential iteration goes in SEQ_START_BB. */
2836 list = alloc_stmt_list ();
2838 t = fold_convert (type, s0);
2839 t = build2 (MULT_EXPR, type, t, fd->step);
2840 t = build2 (PLUS_EXPR, type, t, fd->n1);
2841 t = build_gimple_modify_stmt (fd->v, t);
2842 gimplify_and_add (t, &list);
2844 t = fold_convert (type, e0);
2845 t = build2 (MULT_EXPR, type, t, fd->step);
2846 t = build2 (PLUS_EXPR, type, t, fd->n1);
2847 e = get_formal_tmp_var (t, &list);
2849 si = bsi_start (seq_start_bb);
2850 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2852 /* The code controlling the sequential loop replaces the OMP_CONTINUE. */
2853 list = alloc_stmt_list ();
2855 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
2856 t = build_gimple_modify_stmt (fd->v, t);
2857 gimplify_and_add (t, &list);
2859 t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
2860 t = get_formal_tmp_var (t, &list);
2861 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2862 append_to_statement_list (t, &list);
2864 si = bsi_last (cont_bb);
2865 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
2866 bsi_insert_after (&si, list, BSI_SAME_STMT);
2867 bsi_remove (&si, true);
2869 /* Replace the OMP_RETURN with a barrier, or nothing. */
2870 si = bsi_last (exit_bb);
2871 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
2873 list = alloc_stmt_list ();
2874 build_omp_barrier (&list);
2875 bsi_insert_after (&si, list, BSI_SAME_STMT);
2877 bsi_remove (&si, true);
2879 /* Connect all the blocks. */
2880 find_edge (entry_bb, seq_start_bb)->flags = EDGE_FALSE_VALUE;
2881 find_edge (entry_bb, fin_bb)->flags = EDGE_TRUE_VALUE;
2883 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
2884 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
2888 /* A subroutine of expand_omp_for. Generate code for a parallel
2889 loop with static schedule and a specified chunk size. Given
2892 for (V = N1; V cond N2; V += STEP) BODY;
2894 where COND is "<" or ">", we generate pseudocode
2900 n = (adj + N2 - N1) / STEP;
2903 s0 = (trip * nthreads + threadid) * CHUNK;
2904 e0 = min(s0 + CHUNK, n);
2905 if (s0 < n) goto L1; else goto L4;
2912 if (V cond e) goto L2; else goto L3;
2920 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
2922 tree n, s0, e0, e, t;
2923 tree trip, nthreads, threadid;
2925 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
2926 basic_block trip_update_bb, cont_bb, fin_bb;
2928 block_stmt_iterator si;
2931 type = TREE_TYPE (fd->v);
2933 entry_bb = region->entry;
2934 se = split_block (entry_bb, last_stmt (entry_bb));
2936 iter_part_bb = se->dest;
2937 cont_bb = region->cont;
2938 gcc_assert (EDGE_COUNT (iter_part_bb->succs) == 2);
2939 gcc_assert (BRANCH_EDGE (iter_part_bb)->dest
2940 == FALLTHRU_EDGE (cont_bb)->dest);
2941 seq_start_bb = split_edge (FALLTHRU_EDGE (iter_part_bb));
2942 body_bb = single_succ (seq_start_bb);
2943 gcc_assert (BRANCH_EDGE (cont_bb)->dest == body_bb);
2944 gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
2945 fin_bb = FALLTHRU_EDGE (cont_bb)->dest;
2946 trip_update_bb = split_edge (FALLTHRU_EDGE (cont_bb));
2947 exit_bb = region->exit;
2949 /* Trip and adjustment setup goes in ENTRY_BB. */
2950 list = alloc_stmt_list ();
2952 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
2953 t = fold_convert (type, t);
2954 nthreads = get_formal_tmp_var (t, &list);
2956 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2957 t = fold_convert (type, t);
2958 threadid = get_formal_tmp_var (t, &list);
2960 fd->n1 = fold_convert (type, fd->n1);
2961 if (!is_gimple_val (fd->n1))
2962 fd->n1 = get_formal_tmp_var (fd->n1, &list);
2964 fd->n2 = fold_convert (type, fd->n2);
2965 if (!is_gimple_val (fd->n2))
2966 fd->n2 = get_formal_tmp_var (fd->n2, &list);
2968 fd->step = fold_convert (type, fd->step);
2969 if (!is_gimple_val (fd->step))
2970 fd->step = get_formal_tmp_var (fd->step, &list);
2972 fd->chunk_size = fold_convert (type, fd->chunk_size);
2973 if (!is_gimple_val (fd->chunk_size))
2974 fd->chunk_size = get_formal_tmp_var (fd->chunk_size, &list);
2976 t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2977 t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2978 t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2979 t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2980 t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2981 t = fold_convert (type, t);
2982 if (is_gimple_val (t))
2985 n = get_formal_tmp_var (t, &list);
2987 t = build_int_cst (type, 0);
2988 trip = get_initialized_tmp_var (t, &list, NULL);
2990 si = bsi_last (entry_bb);
2991 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2992 bsi_insert_after (&si, list, BSI_SAME_STMT);
2993 bsi_remove (&si, true);
2995 /* Iteration space partitioning goes in ITER_PART_BB. */
2996 list = alloc_stmt_list ();
2998 t = build2 (MULT_EXPR, type, trip, nthreads);
2999 t = build2 (PLUS_EXPR, type, t, threadid);
3000 t = build2 (MULT_EXPR, type, t, fd->chunk_size);
3001 s0 = get_formal_tmp_var (t, &list);
3003 t = build2 (PLUS_EXPR, type, s0, fd->chunk_size);
3004 t = build2 (MIN_EXPR, type, t, n);
3005 e0 = get_formal_tmp_var (t, &list);
3007 t = build2 (LT_EXPR, boolean_type_node, s0, n);
3008 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
3009 append_to_statement_list (t, &list);
3011 si = bsi_start (iter_part_bb);
3012 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3014 /* Setup code for sequential iteration goes in SEQ_START_BB. */
3015 list = alloc_stmt_list ();
3017 t = fold_convert (type, s0);
3018 t = build2 (MULT_EXPR, type, t, fd->step);
3019 t = build2 (PLUS_EXPR, type, t, fd->n1);
3020 t = build_gimple_modify_stmt (fd->v, t);
3021 gimplify_and_add (t, &list);
3023 t = fold_convert (type, e0);
3024 t = build2 (MULT_EXPR, type, t, fd->step);
3025 t = build2 (PLUS_EXPR, type, t, fd->n1);
3026 e = get_formal_tmp_var (t, &list);
3028 si = bsi_start (seq_start_bb);
3029 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3031 /* The code controlling the sequential loop goes in CONT_BB,
3032 replacing the OMP_CONTINUE. */
3033 list = alloc_stmt_list ();
3035 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
3036 t = build_gimple_modify_stmt (fd->v, t);
3037 gimplify_and_add (t, &list);
3039 t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
3040 t = get_formal_tmp_var (t, &list);
3041 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
3042 append_to_statement_list (t, &list);
3044 si = bsi_last (cont_bb);
3045 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3046 bsi_insert_after (&si, list, BSI_SAME_STMT);
3047 bsi_remove (&si, true);
3049 /* Trip update code goes into TRIP_UPDATE_BB. */
3050 list = alloc_stmt_list ();
3052 t = build_int_cst (type, 1);
3053 t = build2 (PLUS_EXPR, type, trip, t);
3054 t = build_gimple_modify_stmt (trip, t);
3055 gimplify_and_add (t, &list);
3057 si = bsi_start (trip_update_bb);
3058 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3060 /* Replace the OMP_RETURN with a barrier, or nothing. */
3061 si = bsi_last (exit_bb);
3062 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
3064 list = alloc_stmt_list ();
3065 build_omp_barrier (&list);
3066 bsi_insert_after (&si, list, BSI_SAME_STMT);
3068 bsi_remove (&si, true);
3070 /* Connect the new blocks. */
3071 find_edge (iter_part_bb, seq_start_bb)->flags = EDGE_TRUE_VALUE;
3072 find_edge (iter_part_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
3074 find_edge (cont_bb, body_bb)->flags = EDGE_TRUE_VALUE;
3075 find_edge (cont_bb, trip_update_bb)->flags = EDGE_FALSE_VALUE;
3077 redirect_edge_and_branch (single_succ_edge (trip_update_bb), iter_part_bb);
3081 /* Expand the OpenMP loop defined by REGION. */
3084 expand_omp_for (struct omp_region *region)
3086 struct omp_for_data fd;
3088 push_gimplify_context ();
3090 extract_omp_for_data (last_stmt (region->entry), &fd);
3091 region->sched_kind = fd.sched_kind;
3093 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
3095 && region->cont != NULL)
3097 if (fd.chunk_size == NULL)
3098 expand_omp_for_static_nochunk (region, &fd);
3100 expand_omp_for_static_chunk (region, &fd);
3104 int fn_index = fd.sched_kind + fd.have_ordered * 4;
3105 int start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index;
3106 int next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index;
3107 expand_omp_for_generic (region, &fd, start_ix, next_ix);
3110 pop_gimplify_context (NULL);
3114 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
3116 v = GOMP_sections_start (n);
3133 v = GOMP_sections_next ();
3138 If this is a combined parallel sections, replace the call to
3139 GOMP_sections_start with 'goto L1'. */
3142 expand_omp_sections (struct omp_region *region)
3144 tree label_vec, l1, l2, t, u, v, sections_stmt;
3145 unsigned i, casei, len;
3146 basic_block entry_bb, l0_bb, l1_bb, l2_bb, default_bb;
3147 block_stmt_iterator si;
3148 struct omp_region *inner;
3149 bool exit_reachable = region->cont != NULL;
3151 gcc_assert (exit_reachable == (region->exit != NULL));
3152 entry_bb = region->entry;
3153 l0_bb = single_succ (entry_bb);
3154 l1_bb = region->cont;
3155 l2_bb = region->exit;
3158 gcc_assert (single_pred (l2_bb) == l0_bb);
3159 default_bb = create_empty_bb (l1_bb->prev_bb);
3160 l1 = tree_block_label (l1_bb);
3161 l2 = tree_block_label (l2_bb);
3165 default_bb = create_empty_bb (l0_bb);
3167 l2 = tree_block_label (default_bb);
3170 /* We will build a switch() with enough cases for all the
3171 OMP_SECTION regions, a '0' case to handle the end of more work
3172 and a default case to abort if something goes wrong. */
3173 len = EDGE_COUNT (l0_bb->succs);
3174 label_vec = make_tree_vec (len + 1);
3176 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
3177 OMP_SECTIONS statement. */
3178 si = bsi_last (entry_bb);
3179 sections_stmt = bsi_stmt (si);
3180 gcc_assert (TREE_CODE (sections_stmt) == OMP_SECTIONS);
3181 v = OMP_SECTIONS_CONTROL (sections_stmt);
3182 if (!is_combined_parallel (region))
3184 /* If we are not inside a combined parallel+sections region,
3185 call GOMP_sections_start. */
3186 t = build_int_cst (unsigned_type_node,
3187 exit_reachable ? len - 1 : len);
3188 u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
3189 t = build_call_expr (u, 1, t);
3190 t = build_gimple_modify_stmt (v, t);
3191 bsi_insert_after (&si, t, BSI_SAME_STMT);
3193 bsi_remove (&si, true);
3195 /* The switch() statement replacing OMP_SECTIONS_SWITCH goes in L0_BB. */
3196 si = bsi_last (l0_bb);
3197 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTIONS_SWITCH);
3199 t = build3 (SWITCH_EXPR, void_type_node, v, NULL, label_vec);
3200 bsi_insert_after (&si, t, BSI_SAME_STMT);
3201 bsi_remove (&si, true);
3206 t = build3 (CASE_LABEL_EXPR, void_type_node,
3207 build_int_cst (unsigned_type_node, 0), NULL, l2);
3208 TREE_VEC_ELT (label_vec, 0) = t;
3212 /* Convert each OMP_SECTION into a CASE_LABEL_EXPR. */
3213 for (inner = region->inner, casei = 1;
3215 inner = inner->next, i++, casei++)
3217 basic_block s_entry_bb, s_exit_bb;
3219 s_entry_bb = inner->entry;
3220 s_exit_bb = inner->exit;
3222 t = tree_block_label (s_entry_bb);
3223 u = build_int_cst (unsigned_type_node, casei);
3224 u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
3225 TREE_VEC_ELT (label_vec, i) = u;
3227 si = bsi_last (s_entry_bb);
3228 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTION);
3229 gcc_assert (i < len || OMP_SECTION_LAST (bsi_stmt (si)));
3230 bsi_remove (&si, true);
3231 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
3233 if (s_exit_bb == NULL)
3236 si = bsi_last (s_exit_bb);
3237 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3238 bsi_remove (&si, true);
3240 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
3243 /* Error handling code goes in DEFAULT_BB. */
3244 t = tree_block_label (default_bb);
3245 u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
3246 TREE_VEC_ELT (label_vec, len) = u;
3247 make_edge (l0_bb, default_bb, 0);
3249 si = bsi_start (default_bb);
3250 t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
3251 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3255 /* Code to get the next section goes in L1_BB. */
3256 si = bsi_last (l1_bb);
3257 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3259 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
3260 t = build_gimple_modify_stmt (v, t);
3261 bsi_insert_after (&si, t, BSI_SAME_STMT);
3262 bsi_remove (&si, true);
3264 single_succ_edge (l1_bb)->flags = EDGE_FALLTHRU;
3266 /* Cleanup function replaces OMP_RETURN in EXIT_BB. */
3267 si = bsi_last (l2_bb);
3268 if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
3269 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
3271 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
3272 t = build_call_expr (t, 0);
3273 bsi_insert_after (&si, t, BSI_SAME_STMT);
3274 bsi_remove (&si, true);
3277 /* Connect the new blocks. */
3278 if (is_combined_parallel (region))
3280 /* If this was a combined parallel+sections region, we did not
3281 emit a GOMP_sections_start in the entry block, so we just
3282 need to jump to L1_BB to get the next section. */
3283 gcc_assert (exit_reachable);
3284 redirect_edge_and_branch (single_succ_edge (entry_bb), l1_bb);
3289 /* Expand code for an OpenMP single directive. We've already expanded
3290 much of the code, here we simply place the GOMP_barrier call. */
3293 expand_omp_single (struct omp_region *region)
3295 basic_block entry_bb, exit_bb;
3296 block_stmt_iterator si;
3297 bool need_barrier = false;
3299 entry_bb = region->entry;
3300 exit_bb = region->exit;
3302 si = bsi_last (entry_bb);
3303 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
3304 be removed. We need to ensure that the thread that entered the single
3305 does not exit before the data is copied out by the other threads. */
3306 if (find_omp_clause (OMP_SINGLE_CLAUSES (bsi_stmt (si)),
3307 OMP_CLAUSE_COPYPRIVATE))
3308 need_barrier = true;
3309 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE);
3310 bsi_remove (&si, true);
3311 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3313 si = bsi_last (exit_bb);
3314 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)) || need_barrier)
3316 tree t = alloc_stmt_list ();
3317 build_omp_barrier (&t);
3318 bsi_insert_after (&si, t, BSI_SAME_STMT);
3320 bsi_remove (&si, true);
3321 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3325 /* Generic expansion for OpenMP synchronization directives: master,
3326 ordered and critical. All we need to do here is remove the entry
3327 and exit markers for REGION. */
3330 expand_omp_synch (struct omp_region *region)
3332 basic_block entry_bb, exit_bb;
3333 block_stmt_iterator si;
3335 entry_bb = region->entry;
3336 exit_bb = region->exit;
3338 si = bsi_last (entry_bb);
3339 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE
3340 || TREE_CODE (bsi_stmt (si)) == OMP_MASTER
3341 || TREE_CODE (bsi_stmt (si)) == OMP_ORDERED
3342 || TREE_CODE (bsi_stmt (si)) == OMP_CRITICAL);
3343 bsi_remove (&si, true);
3344 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3348 si = bsi_last (exit_bb);
3349 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3350 bsi_remove (&si, true);
3351 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3356 /* Expand the parallel region tree rooted at REGION. Expansion
3357 proceeds in depth-first order. Innermost regions are expanded
3358 first. This way, parallel regions that require a new function to
3359 be created (e.g., OMP_PARALLEL) can be expanded without having any
3360 internal dependencies in their body. */
3363 expand_omp (struct omp_region *region)
3368 expand_omp (region->inner);
3370 switch (region->type)
3373 expand_omp_parallel (region);
3377 expand_omp_for (region);
3381 expand_omp_sections (region);
3385 /* Individual omp sections are handled together with their
3386 parent OMP_SECTIONS region. */
3390 expand_omp_single (region);
3396 expand_omp_synch (region);
3403 region = region->next;
3408 /* Helper for build_omp_regions. Scan the dominator tree starting at
3409 block BB. PARENT is the region that contains BB. */
3412 build_omp_regions_1 (basic_block bb, struct omp_region *parent)
3414 block_stmt_iterator si;
3419 if (!bsi_end_p (si) && OMP_DIRECTIVE_P (bsi_stmt (si)))
3421 struct omp_region *region;
3422 enum tree_code code;
3424 stmt = bsi_stmt (si);
3425 code = TREE_CODE (stmt);
3427 if (code == OMP_RETURN)
3429 /* STMT is the return point out of region PARENT. Mark it
3430 as the exit point and make PARENT the immediately
3431 enclosing region. */
3432 gcc_assert (parent);
3435 parent = parent->outer;
3437 /* If REGION is a parallel region, determine whether it is
3438 a combined parallel+workshare region. */
3439 if (region->type == OMP_PARALLEL)
3440 determine_parallel_type (region);
3442 else if (code == OMP_CONTINUE)
3444 gcc_assert (parent);
3447 else if (code == OMP_SECTIONS_SWITCH)
3449 /* OMP_SECTIONS_SWITCH is part of OMP_SECTIONS, and we do nothing for
3454 /* Otherwise, this directive becomes the parent for a new
3456 region = new_omp_region (bb, code, parent);
3461 for (son = first_dom_son (CDI_DOMINATORS, bb);
3463 son = next_dom_son (CDI_DOMINATORS, son))
3464 build_omp_regions_1 (son, parent);
3468 /* Scan the CFG and build a tree of OMP regions. Return the root of
3469 the OMP region tree. */
3472 build_omp_regions (void)
3474 gcc_assert (root_omp_region == NULL);
3475 calculate_dominance_info (CDI_DOMINATORS);
3476 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL);
3480 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
3483 execute_expand_omp (void)
3485 build_omp_regions ();
3487 if (!root_omp_region)
3492 fprintf (dump_file, "\nOMP region tree\n\n");
3493 dump_omp_region (dump_file, root_omp_region, 0);
3494 fprintf (dump_file, "\n");
3497 remove_exit_barriers (root_omp_region);
3499 expand_omp (root_omp_region);
3501 free_dominance_info (CDI_DOMINATORS);
3502 free_dominance_info (CDI_POST_DOMINATORS);
3503 cleanup_tree_cfg ();
3505 free_omp_regions ();
3511 gate_expand_omp (void)
3513 return flag_openmp != 0 && errorcount == 0;
3516 struct tree_opt_pass pass_expand_omp =
3518 "ompexp", /* name */
3519 gate_expand_omp, /* gate */
3520 execute_expand_omp, /* execute */
3523 0, /* static_pass_number */
3525 PROP_gimple_any, /* properties_required */
3526 PROP_gimple_lomp, /* properties_provided */
3527 0, /* properties_destroyed */
3528 0, /* todo_flags_start */
3529 TODO_dump_func, /* todo_flags_finish */
3533 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
3535 /* Lower the OpenMP sections directive in *STMT_P. */
3538 lower_omp_sections (tree *stmt_p, omp_context *ctx)
3540 tree new_stmt, stmt, body, bind, block, ilist, olist, new_body, control;
3542 tree_stmt_iterator tsi;
3547 push_gimplify_context ();
3551 lower_rec_input_clauses (OMP_SECTIONS_CLAUSES (stmt), &ilist, &dlist, ctx);
3553 tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3554 for (len = 0; !tsi_end_p (tsi); len++, tsi_next (&tsi))
3557 tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3558 body = alloc_stmt_list ();
3559 for (i = 0; i < len; i++, tsi_next (&tsi))
3562 tree sec_start, sec_end;
3564 sec_start = tsi_stmt (tsi);
3565 sctx = maybe_lookup_ctx (sec_start);
3568 append_to_statement_list (sec_start, &body);
3570 lower_omp (&OMP_SECTION_BODY (sec_start), sctx);
3571 append_to_statement_list (OMP_SECTION_BODY (sec_start), &body);
3572 OMP_SECTION_BODY (sec_start) = NULL;
3576 tree l = alloc_stmt_list ();
3577 lower_lastprivate_clauses (OMP_SECTIONS_CLAUSES (stmt), NULL,
3579 append_to_statement_list (l, &body);
3580 OMP_SECTION_LAST (sec_start) = 1;
3583 sec_end = make_node (OMP_RETURN);
3584 append_to_statement_list (sec_end, &body);
3587 block = make_node (BLOCK);
3588 bind = build3 (BIND_EXPR, void_type_node, NULL, body, block);
3591 lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
3593 pop_gimplify_context (NULL_TREE);
3594 record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
3596 new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3597 TREE_SIDE_EFFECTS (new_stmt) = 1;
3599 new_body = alloc_stmt_list ();
3600 append_to_statement_list (ilist, &new_body);
3601 append_to_statement_list (stmt, &new_body);
3602 append_to_statement_list (make_node (OMP_SECTIONS_SWITCH), &new_body);
3603 append_to_statement_list (bind, &new_body);
3605 control = create_tmp_var (unsigned_type_node, ".section");
3606 t = build2 (OMP_CONTINUE, void_type_node, control, control);
3607 OMP_SECTIONS_CONTROL (stmt) = control;
3608 append_to_statement_list (t, &new_body);
3610 append_to_statement_list (olist, &new_body);
3611 append_to_statement_list (dlist, &new_body);
3613 maybe_catch_exception (&new_body);
3615 t = make_node (OMP_RETURN);
3616 OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SECTIONS_CLAUSES (stmt),
3618 append_to_statement_list (t, &new_body);
3620 BIND_EXPR_BODY (new_stmt) = new_body;
3621 OMP_SECTIONS_BODY (stmt) = NULL;
3627 /* A subroutine of lower_omp_single. Expand the simple form of
3628 an OMP_SINGLE, without a copyprivate clause:
3630 if (GOMP_single_start ())
3632 [ GOMP_barrier (); ] -> unless 'nowait' is present.
3634 FIXME. It may be better to delay expanding the logic of this until
3635 pass_expand_omp. The expanded logic may make the job more difficult
3636 to a synchronization analysis pass. */
3639 lower_omp_single_simple (tree single_stmt, tree *pre_p)
3643 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_START], 0);
3644 t = build3 (COND_EXPR, void_type_node, t,
3645 OMP_SINGLE_BODY (single_stmt), NULL);
3646 gimplify_and_add (t, pre_p);
3650 /* A subroutine of lower_omp_single. Expand the simple form of
3651 an OMP_SINGLE, with a copyprivate clause:
3653 #pragma omp single copyprivate (a, b, c)
3655 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
3658 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
3664 GOMP_single_copy_end (©out);
3675 FIXME. It may be better to delay expanding the logic of this until
3676 pass_expand_omp. The expanded logic may make the job more difficult
3677 to a synchronization analysis pass. */
3680 lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
3682 tree ptr_type, t, l0, l1, l2, copyin_seq;
3684 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
3686 ptr_type = build_pointer_type (ctx->record_type);
3687 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
3689 l0 = create_artificial_label ();
3690 l1 = create_artificial_label ();
3691 l2 = create_artificial_label ();
3693 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
3694 t = fold_convert (ptr_type, t);
3695 t = build_gimple_modify_stmt (ctx->receiver_decl, t);
3696 gimplify_and_add (t, pre_p);
3698 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
3699 build_int_cst (ptr_type, 0));
3700 t = build3 (COND_EXPR, void_type_node, t,
3701 build_and_jump (&l0), build_and_jump (&l1));
3702 gimplify_and_add (t, pre_p);
3704 t = build1 (LABEL_EXPR, void_type_node, l0);
3705 gimplify_and_add (t, pre_p);
3707 append_to_statement_list (OMP_SINGLE_BODY (single_stmt), pre_p);
3710 lower_copyprivate_clauses (OMP_SINGLE_CLAUSES (single_stmt), pre_p,
3713 t = build_fold_addr_expr (ctx->sender_decl);
3714 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END], 1, t);
3715 gimplify_and_add (t, pre_p);
3717 t = build_and_jump (&l2);
3718 gimplify_and_add (t, pre_p);
3720 t = build1 (LABEL_EXPR, void_type_node, l1);
3721 gimplify_and_add (t, pre_p);
3723 append_to_statement_list (copyin_seq, pre_p);
3725 t = build1 (LABEL_EXPR, void_type_node, l2);
3726 gimplify_and_add (t, pre_p);
3730 /* Expand code for an OpenMP single directive. */
3733 lower_omp_single (tree *stmt_p, omp_context *ctx)
3735 tree t, bind, block, single_stmt = *stmt_p, dlist;
3737 push_gimplify_context ();
3739 block = make_node (BLOCK);
3740 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3741 TREE_SIDE_EFFECTS (bind) = 1;
3743 lower_rec_input_clauses (OMP_SINGLE_CLAUSES (single_stmt),
3744 &BIND_EXPR_BODY (bind), &dlist, ctx);
3745 lower_omp (&OMP_SINGLE_BODY (single_stmt), ctx);
3747 append_to_statement_list (single_stmt, &BIND_EXPR_BODY (bind));
3749 if (ctx->record_type)
3750 lower_omp_single_copy (single_stmt, &BIND_EXPR_BODY (bind), ctx);
3752 lower_omp_single_simple (single_stmt, &BIND_EXPR_BODY (bind));
3754 OMP_SINGLE_BODY (single_stmt) = NULL;
3756 append_to_statement_list (dlist, &BIND_EXPR_BODY (bind));
3758 maybe_catch_exception (&BIND_EXPR_BODY (bind));
3760 t = make_node (OMP_RETURN);
3761 OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SINGLE_CLAUSES (single_stmt),
3763 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3765 pop_gimplify_context (bind);
3767 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3768 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3772 /* Expand code for an OpenMP master directive. */
3775 lower_omp_master (tree *stmt_p, omp_context *ctx)
3777 tree bind, block, stmt = *stmt_p, lab = NULL, x;
3779 push_gimplify_context ();
3781 block = make_node (BLOCK);
3782 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3783 TREE_SIDE_EFFECTS (bind) = 1;
3785 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3787 x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
3788 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
3789 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
3790 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3792 lower_omp (&OMP_MASTER_BODY (stmt), ctx);
3793 maybe_catch_exception (&OMP_MASTER_BODY (stmt));
3794 append_to_statement_list (OMP_MASTER_BODY (stmt), &BIND_EXPR_BODY (bind));
3795 OMP_MASTER_BODY (stmt) = NULL;
3797 x = build1 (LABEL_EXPR, void_type_node, lab);
3798 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3800 x = make_node (OMP_RETURN);
3801 OMP_RETURN_NOWAIT (x) = 1;
3802 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
3804 pop_gimplify_context (bind);
3806 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3807 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3811 /* Expand code for an OpenMP ordered directive. */
3814 lower_omp_ordered (tree *stmt_p, omp_context *ctx)
3816 tree bind, block, stmt = *stmt_p, x;
3818 push_gimplify_context ();
3820 block = make_node (BLOCK);
3821 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3822 TREE_SIDE_EFFECTS (bind) = 1;
3824 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3826 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
3827 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3829 lower_omp (&OMP_ORDERED_BODY (stmt), ctx);
3830 maybe_catch_exception (&OMP_ORDERED_BODY (stmt));
3831 append_to_statement_list (OMP_ORDERED_BODY (stmt), &BIND_EXPR_BODY (bind));
3832 OMP_ORDERED_BODY (stmt) = NULL;
3834 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
3835 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3837 x = make_node (OMP_RETURN);
3838 OMP_RETURN_NOWAIT (x) = 1;
3839 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
3841 pop_gimplify_context (bind);
3843 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3844 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3848 /* Gimplify an OMP_CRITICAL statement. This is a relatively simple
3849 substitution of a couple of function calls. But in the NAMED case,
3850 requires that languages coordinate a symbol name. It is therefore
3851 best put here in common code. */
3853 static GTY((param1_is (tree), param2_is (tree)))
3854 splay_tree critical_name_mutexes;
3857 lower_omp_critical (tree *stmt_p, omp_context *ctx)
3859 tree bind, block, stmt = *stmt_p;
3860 tree t, lock, unlock, name;
3862 name = OMP_CRITICAL_NAME (stmt);
3868 if (!critical_name_mutexes)
3869 critical_name_mutexes
3870 = splay_tree_new_ggc (splay_tree_compare_pointers);
3872 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
3877 decl = create_tmp_var_raw (ptr_type_node, NULL);
3879 new_str = ACONCAT ((".gomp_critical_user_",
3880 IDENTIFIER_POINTER (name), NULL));
3881 DECL_NAME (decl) = get_identifier (new_str);
3882 TREE_PUBLIC (decl) = 1;
3883 TREE_STATIC (decl) = 1;
3884 DECL_COMMON (decl) = 1;
3885 DECL_ARTIFICIAL (decl) = 1;
3886 DECL_IGNORED_P (decl) = 1;
3887 varpool_finalize_decl (decl);
3889 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
3890 (splay_tree_value) decl);
3893 decl = (tree) n->value;
3895 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
3896 lock = build_call_expr (lock, 1, build_fold_addr_expr (decl));
3898 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
3899 unlock = build_call_expr (unlock, 1, build_fold_addr_expr (decl));
3903 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
3904 lock = build_call_expr (lock, 0);
3906 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
3907 unlock = build_call_expr (unlock, 0);
3910 push_gimplify_context ();
3912 block = make_node (BLOCK);
3913 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3914 TREE_SIDE_EFFECTS (bind) = 1;
3916 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3918 gimplify_and_add (lock, &BIND_EXPR_BODY (bind));
3920 lower_omp (&OMP_CRITICAL_BODY (stmt), ctx);
3921 maybe_catch_exception (&OMP_CRITICAL_BODY (stmt));
3922 append_to_statement_list (OMP_CRITICAL_BODY (stmt), &BIND_EXPR_BODY (bind));
3923 OMP_CRITICAL_BODY (stmt) = NULL;
3925 gimplify_and_add (unlock, &BIND_EXPR_BODY (bind));
3927 t = make_node (OMP_RETURN);
3928 OMP_RETURN_NOWAIT (t) = 1;
3929 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3931 pop_gimplify_context (bind);
3932 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3933 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3937 /* A subroutine of lower_omp_for. Generate code to emit the predicate
3938 for a lastprivate clause. Given a loop control predicate of (V
3939 cond N2), we gate the clause on (!(V cond N2)). The lowered form
3940 is appended to *DLIST, iterator initialization is appended to
3944 lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
3945 tree *dlist, struct omp_context *ctx)
3947 tree clauses, cond, stmts, vinit, t;
3948 enum tree_code cond_code;
3950 cond_code = fd->cond_code;
3951 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
3953 /* When possible, use a strict equality expression. This can let VRP
3954 type optimizations deduce the value and remove a copy. */
3955 if (host_integerp (fd->step, 0))
3957 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->step);
3958 if (step == 1 || step == -1)
3959 cond_code = EQ_EXPR;
3962 cond = build2 (cond_code, boolean_type_node, fd->v, fd->n2);
3964 clauses = OMP_FOR_CLAUSES (fd->for_stmt);
3966 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
3969 append_to_statement_list (stmts, dlist);
3971 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
3973 if (cond_code == EQ_EXPR
3974 && host_integerp (fd->n2, 0)
3975 && ! integer_zerop (fd->n2))
3976 vinit = build_int_cst (TREE_TYPE (fd->v), 0);
3978 /* Initialize the iterator variable, so that threads that don't execute
3979 any iterations don't execute the lastprivate clauses by accident. */
3980 t = build_gimple_modify_stmt (fd->v, vinit);
3981 gimplify_and_add (t, body_p);
3986 /* Lower code for an OpenMP loop directive. */
3989 lower_omp_for (tree *stmt_p, omp_context *ctx)
3991 tree t, stmt, ilist, dlist, new_stmt, *body_p, *rhs_p;
3992 struct omp_for_data fd;
3996 push_gimplify_context ();
3998 lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
3999 lower_omp (&OMP_FOR_BODY (stmt), ctx);
4001 /* Move declaration of temporaries in the loop body before we make
4003 if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
4004 record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt)), ctx->cb.dst_fn);
4006 new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4007 TREE_SIDE_EFFECTS (new_stmt) = 1;
4008 body_p = &BIND_EXPR_BODY (new_stmt);
4010 /* The pre-body and input clauses go before the lowered OMP_FOR. */
4013 append_to_statement_list (OMP_FOR_PRE_BODY (stmt), body_p);
4014 lower_rec_input_clauses (OMP_FOR_CLAUSES (stmt), body_p, &dlist, ctx);
4016 /* Lower the header expressions. At this point, we can assume that
4017 the header is of the form:
4019 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
4021 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
4022 using the .omp_data_s mapping, if needed. */
4023 rhs_p = &GIMPLE_STMT_OPERAND (OMP_FOR_INIT (stmt), 1);
4024 if (!is_gimple_min_invariant (*rhs_p))
4025 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4027 rhs_p = &TREE_OPERAND (OMP_FOR_COND (stmt), 1);
4028 if (!is_gimple_min_invariant (*rhs_p))
4029 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4031 rhs_p = &TREE_OPERAND (GIMPLE_STMT_OPERAND (OMP_FOR_INCR (stmt), 1), 1);
4032 if (!is_gimple_min_invariant (*rhs_p))
4033 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4035 /* Once lowered, extract the bounds and clauses. */
4036 extract_omp_for_data (stmt, &fd);
4038 lower_omp_for_lastprivate (&fd, body_p, &dlist, ctx);
4040 append_to_statement_list (stmt, body_p);
4042 append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
4044 t = build2 (OMP_CONTINUE, void_type_node, fd.v, fd.v);
4045 append_to_statement_list (t, body_p);
4047 /* After the loop, add exit clauses. */
4048 lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
4049 append_to_statement_list (dlist, body_p);
4051 maybe_catch_exception (body_p);
4053 /* Region exit marker goes at the end of the loop body. */
4054 t = make_node (OMP_RETURN);
4055 OMP_RETURN_NOWAIT (t) = fd.have_nowait;
4056 append_to_statement_list (t, body_p);
4058 pop_gimplify_context (NULL_TREE);
4059 record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
4061 OMP_FOR_BODY (stmt) = NULL_TREE;
4062 OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
4066 /* Callback for walk_stmts. Check if *TP only contains OMP_FOR
4070 check_combined_parallel (tree *tp, int *walk_subtrees, void *data)
4072 struct walk_stmt_info *wi = data;
4073 int *info = wi->info;
4076 switch (TREE_CODE (*tp))
4080 *info = *info == 0 ? 1 : -1;
4089 /* Lower the OpenMP parallel directive in *STMT_P. CTX holds context
4090 information for the directive. */
4093 lower_omp_parallel (tree *stmt_p, omp_context *ctx)
4095 tree clauses, par_bind, par_body, new_body, bind;
4096 tree olist, ilist, par_olist, par_ilist;
4097 tree stmt, child_fn, t;
4101 clauses = OMP_PARALLEL_CLAUSES (stmt);
4102 par_bind = OMP_PARALLEL_BODY (stmt);
4103 par_body = BIND_EXPR_BODY (par_bind);
4104 child_fn = ctx->cb.dst_fn;
4105 if (!OMP_PARALLEL_COMBINED (stmt))
4107 struct walk_stmt_info wi;
4110 memset (&wi, 0, sizeof (wi));
4111 wi.callback = check_combined_parallel;
4114 walk_stmts (&wi, &par_bind);
4116 OMP_PARALLEL_COMBINED (stmt) = 1;
4119 push_gimplify_context ();
4121 par_olist = NULL_TREE;
4122 par_ilist = NULL_TREE;
4123 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
4124 lower_omp (&par_body, ctx);
4125 lower_reduction_clauses (clauses, &par_olist, ctx);
4127 /* Declare all the variables created by mapping and the variables
4128 declared in the scope of the parallel body. */
4129 record_vars_into (ctx->block_vars, child_fn);
4130 record_vars_into (BIND_EXPR_VARS (par_bind), child_fn);
4132 if (ctx->record_type)
4134 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_data_o");
4135 OMP_PARALLEL_DATA_ARG (stmt) = ctx->sender_decl;
4140 lower_send_clauses (clauses, &ilist, &olist, ctx);
4141 lower_send_shared_vars (&ilist, &olist, ctx);
4143 /* Once all the expansions are done, sequence all the different
4144 fragments inside OMP_PARALLEL_BODY. */
4145 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4146 append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
4148 new_body = alloc_stmt_list ();
4150 if (ctx->record_type)
4152 t = build_fold_addr_expr (ctx->sender_decl);
4153 /* fixup_child_record_type might have changed receiver_decl's type. */
4154 t = fold_convert (TREE_TYPE (ctx->receiver_decl), t);
4155 t = build_gimple_modify_stmt (ctx->receiver_decl, t);
4156 append_to_statement_list (t, &new_body);
4159 append_to_statement_list (par_ilist, &new_body);
4160 append_to_statement_list (par_body, &new_body);
4161 append_to_statement_list (par_olist, &new_body);
4162 maybe_catch_exception (&new_body);
4163 t = make_node (OMP_RETURN);
4164 append_to_statement_list (t, &new_body);
4165 OMP_PARALLEL_BODY (stmt) = new_body;
4167 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4168 append_to_statement_list (olist, &BIND_EXPR_BODY (bind));
4172 pop_gimplify_context (NULL_TREE);
4176 /* Pass *TP back through the gimplifier within the context determined by WI.
4177 This handles replacement of DECL_VALUE_EXPR, as well as adjusting the
4178 flags on ADDR_EXPR. */
4181 lower_regimplify (tree *tp, struct walk_stmt_info *wi)
4183 enum gimplify_status gs;
4187 gs = gimplify_expr (tp, &pre, NULL, is_gimple_lvalue, fb_lvalue);
4188 else if (wi->val_only)
4189 gs = gimplify_expr (tp, &pre, NULL, is_gimple_val, fb_rvalue);
4191 gs = gimplify_expr (tp, &pre, NULL, is_gimple_formal_tmp_var, fb_rvalue);
4192 gcc_assert (gs == GS_ALL_DONE);
4195 tsi_link_before (&wi->tsi, pre, TSI_SAME_STMT);
4198 /* Copy EXP into a temporary. Insert the initialization statement before TSI. */
4201 init_tmp_var (tree exp, tree_stmt_iterator *tsi)
4205 t = create_tmp_var (TREE_TYPE (exp), NULL);
4206 DECL_GIMPLE_REG_P (t) = 1;
4207 stmt = build_gimple_modify_stmt (t, exp);
4208 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4209 tsi_link_before (tsi, stmt, TSI_SAME_STMT);
4214 /* Similarly, but copy from the temporary and insert the statement
4215 after the iterator. */
4218 save_tmp_var (tree exp, tree_stmt_iterator *tsi)
4222 t = create_tmp_var (TREE_TYPE (exp), NULL);
4223 DECL_GIMPLE_REG_P (t) = 1;
4224 stmt = build_gimple_modify_stmt (exp, t);
4225 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4226 tsi_link_after (tsi, stmt, TSI_SAME_STMT);
4231 /* Callback for walk_stmts. Lower the OpenMP directive pointed by TP. */
4234 lower_omp_1 (tree *tp, int *walk_subtrees, void *data)
4236 struct walk_stmt_info *wi = data;
4237 omp_context *ctx = wi->info;
4240 /* If we have issued syntax errors, avoid doing any heavy lifting.
4241 Just replace the OpenMP directives with a NOP to avoid
4242 confusing RTL expansion. */
4243 if (errorcount && OMP_DIRECTIVE_P (*tp))
4245 *tp = build_empty_stmt ();
4250 switch (TREE_CODE (*tp))
4253 ctx = maybe_lookup_ctx (t);
4254 lower_omp_parallel (tp, ctx);
4258 ctx = maybe_lookup_ctx (t);
4260 lower_omp_for (tp, ctx);
4264 ctx = maybe_lookup_ctx (t);
4266 lower_omp_sections (tp, ctx);
4270 ctx = maybe_lookup_ctx (t);
4272 lower_omp_single (tp, ctx);
4276 ctx = maybe_lookup_ctx (t);
4278 lower_omp_master (tp, ctx);
4282 ctx = maybe_lookup_ctx (t);
4284 lower_omp_ordered (tp, ctx);
4288 ctx = maybe_lookup_ctx (t);
4290 lower_omp_critical (tp, ctx);
4294 if (ctx && DECL_HAS_VALUE_EXPR_P (t))
4296 lower_regimplify (&t, wi);
4300 t = save_tmp_var (t, &wi->tsi);
4302 t = init_tmp_var (t, &wi->tsi);
4310 lower_regimplify (tp, wi);
4314 case ARRAY_RANGE_REF:
4318 case VIEW_CONVERT_EXPR:
4320 lower_regimplify (tp, wi);
4327 wi->val_only = true;
4328 lower_regimplify (&TREE_OPERAND (t, 0), wi);
4333 if (!TYPE_P (t) && !DECL_P (t))
4342 lower_omp (tree *stmt_p, omp_context *ctx)
4344 struct walk_stmt_info wi;
4346 memset (&wi, 0, sizeof (wi));
4347 wi.callback = lower_omp_1;
4350 wi.want_locations = true;
4352 walk_stmts (&wi, stmt_p);
4355 /* Main entry point. */
4358 execute_lower_omp (void)
4360 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
4361 delete_omp_context);
4363 scan_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4364 gcc_assert (parallel_nesting_level == 0);
4366 if (all_contexts->root)
4367 lower_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4371 splay_tree_delete (all_contexts);
4372 all_contexts = NULL;
4378 gate_lower_omp (void)
4380 return flag_openmp != 0;
4383 struct tree_opt_pass pass_lower_omp =
4385 "omplower", /* name */
4386 gate_lower_omp, /* gate */
4387 execute_lower_omp, /* execute */
4390 0, /* static_pass_number */
4392 PROP_gimple_any, /* properties_required */
4393 PROP_gimple_lomp, /* properties_provided */
4394 0, /* properties_destroyed */
4395 0, /* todo_flags_start */
4396 TODO_dump_func, /* todo_flags_finish */
4400 /* The following is a utility to diagnose OpenMP structured block violations.
4401 It is not part of the "omplower" pass, as that's invoked too late. It
4402 should be invoked by the respective front ends after gimplification. */
4404 static splay_tree all_labels;
4406 /* Check for mismatched contexts and generate an error if needed. Return
4407 true if an error is detected. */
4410 diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
4414 if ((label_ctx ? TREE_VALUE (label_ctx) : NULL) == branch_ctx)
4417 /* Try to avoid confusing the user by producing and error message
4418 with correct "exit" or "enter" verbage. We prefer "exit"
4419 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
4420 if (branch_ctx == NULL)
4426 if (TREE_VALUE (label_ctx) == branch_ctx)
4431 label_ctx = TREE_CHAIN (label_ctx);
4436 error ("invalid exit from OpenMP structured block");
4438 error ("invalid entry to OpenMP structured block");
4440 *stmt_p = build_empty_stmt ();
4444 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
4445 where in the tree each label is found. */
4448 diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
4450 struct walk_stmt_info *wi = data;
4451 tree context = (tree) wi->info;
4456 switch (TREE_CODE (t))
4461 walk_tree (&OMP_CLAUSES (t), diagnose_sb_1, wi, NULL);
4467 /* The minimal context here is just a tree of statements. */
4468 inner_context = tree_cons (NULL, t, context);
4469 wi->info = inner_context;
4470 walk_stmts (wi, &OMP_BODY (t));
4475 walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_1, wi, NULL);
4476 inner_context = tree_cons (NULL, t, context);
4477 wi->info = inner_context;
4478 walk_tree (&OMP_FOR_INIT (t), diagnose_sb_1, wi, NULL);
4479 walk_tree (&OMP_FOR_COND (t), diagnose_sb_1, wi, NULL);
4480 walk_tree (&OMP_FOR_INCR (t), diagnose_sb_1, wi, NULL);
4481 walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4482 walk_stmts (wi, &OMP_FOR_BODY (t));
4487 splay_tree_insert (all_labels, (splay_tree_key) LABEL_EXPR_LABEL (t),
4488 (splay_tree_value) context);
4498 /* Pass 2: Check each branch and see if its context differs from that of
4499 the destination label's context. */
4502 diagnose_sb_2 (tree *tp, int *walk_subtrees, void *data)
4504 struct walk_stmt_info *wi = data;
4505 tree context = (tree) wi->info;
4510 switch (TREE_CODE (t))
4515 walk_tree (&OMP_CLAUSES (t), diagnose_sb_2, wi, NULL);
4522 walk_stmts (wi, &OMP_BODY (t));
4527 walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_2, wi, NULL);
4529 walk_tree (&OMP_FOR_INIT (t), diagnose_sb_2, wi, NULL);
4530 walk_tree (&OMP_FOR_COND (t), diagnose_sb_2, wi, NULL);
4531 walk_tree (&OMP_FOR_INCR (t), diagnose_sb_2, wi, NULL);
4532 walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4533 walk_stmts (wi, &OMP_FOR_BODY (t));
4539 tree lab = GOTO_DESTINATION (t);
4540 if (TREE_CODE (lab) != LABEL_DECL)
4543 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4544 diagnose_sb_0 (tp, context, n ? (tree) n->value : NULL_TREE);
4550 tree vec = SWITCH_LABELS (t);
4551 int i, len = TREE_VEC_LENGTH (vec);
4552 for (i = 0; i < len; ++i)
4554 tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
4555 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4556 if (diagnose_sb_0 (tp, context, (tree) n->value))
4563 diagnose_sb_0 (tp, context, NULL_TREE);
4574 diagnose_omp_structured_block_errors (tree fndecl)
4576 tree save_current = current_function_decl;
4577 struct walk_stmt_info wi;
4579 current_function_decl = fndecl;
4581 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
4583 memset (&wi, 0, sizeof (wi));
4584 wi.callback = diagnose_sb_1;
4585 walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4587 memset (&wi, 0, sizeof (wi));
4588 wi.callback = diagnose_sb_2;
4589 wi.want_locations = true;
4590 wi.want_return_expr = true;
4591 walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4593 splay_tree_delete (all_labels);
4596 current_function_decl = save_current;
4599 #include "gt-omp-low.h"