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 basic_block bb = bb_for_stmt (ws_stmt);
351 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs));
352 t = tree_cons (NULL, t, NULL);
360 /* Discover whether REGION is a combined parallel+workshare region. */
363 determine_parallel_type (struct omp_region *region)
365 basic_block par_entry_bb, par_exit_bb;
366 basic_block ws_entry_bb, ws_exit_bb;
368 if (region == NULL || region->inner == NULL
369 || region->exit == NULL || region->inner->exit == NULL)
372 /* We only support parallel+for and parallel+sections. */
373 if (region->type != OMP_PARALLEL
374 || (region->inner->type != OMP_FOR
375 && region->inner->type != OMP_SECTIONS))
378 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
379 WS_EXIT_BB -> PAR_EXIT_BB. */
380 par_entry_bb = region->entry;
381 par_exit_bb = region->exit;
382 ws_entry_bb = region->inner->entry;
383 ws_exit_bb = region->inner->exit;
385 if (single_succ (par_entry_bb) == ws_entry_bb
386 && single_succ (ws_exit_bb) == par_exit_bb
387 && workshare_safe_to_combine_p (par_entry_bb, ws_entry_bb)
388 && (OMP_PARALLEL_COMBINED (last_stmt (par_entry_bb))
389 || (last_and_only_stmt (ws_entry_bb)
390 && last_and_only_stmt (par_exit_bb))))
392 tree ws_stmt = last_stmt (ws_entry_bb);
394 if (region->inner->type == OMP_FOR)
396 /* If this is a combined parallel loop, we need to determine
397 whether or not to use the combined library calls. There
398 are two cases where we do not apply the transformation:
399 static loops and any kind of ordered loop. In the first
400 case, we already open code the loop so there is no need
401 to do anything else. In the latter case, the combined
402 parallel loop call would still need extra synchronization
403 to implement ordered semantics, so there would not be any
404 gain in using the combined call. */
405 tree clauses = OMP_FOR_CLAUSES (ws_stmt);
406 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
408 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
409 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
411 region->is_combined_parallel = false;
412 region->inner->is_combined_parallel = false;
417 region->is_combined_parallel = true;
418 region->inner->is_combined_parallel = true;
419 region->ws_args = get_ws_args_for (ws_stmt);
424 /* Return true if EXPR is variable sized. */
427 is_variable_sized (tree expr)
429 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
432 /* Return true if DECL is a reference type. */
435 is_reference (tree decl)
437 return lang_hooks.decls.omp_privatize_by_reference (decl);
440 /* Lookup variables in the decl or field splay trees. The "maybe" form
441 allows for the variable form to not have been entered, otherwise we
442 assert that the variable must have been entered. */
445 lookup_decl (tree var, omp_context *ctx)
448 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
453 maybe_lookup_decl (tree var, omp_context *ctx)
456 n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
457 return n ? *n : NULL_TREE;
461 lookup_field (tree var, omp_context *ctx)
464 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
465 return (tree) n->value;
469 maybe_lookup_field (tree var, omp_context *ctx)
472 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
473 return n ? (tree) n->value : NULL_TREE;
476 /* Return true if DECL should be copied by pointer. SHARED_P is true
477 if DECL is to be shared. */
480 use_pointer_for_field (tree decl, bool shared_p)
482 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
485 /* We can only use copy-in/copy-out semantics for shared variables
486 when we know the value is not accessible from an outer scope. */
489 /* ??? Trivially accessible from anywhere. But why would we even
490 be passing an address in this case? Should we simply assert
491 this to be false, or should we have a cleanup pass that removes
492 these from the list of mappings? */
493 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
496 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
497 without analyzing the expression whether or not its location
498 is accessible to anyone else. In the case of nested parallel
499 regions it certainly may be. */
500 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
503 /* Do not use copy-in/copy-out for variables that have their
505 if (TREE_ADDRESSABLE (decl))
512 /* Construct a new automatic decl similar to VAR. */
515 omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
517 tree copy = build_decl (VAR_DECL, name, type);
519 TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (var);
520 DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (var);
521 DECL_NO_TBAA_P (copy) = DECL_NO_TBAA_P (var);
522 DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
523 DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
524 TREE_USED (copy) = 1;
525 DECL_CONTEXT (copy) = current_function_decl;
526 DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
528 TREE_CHAIN (copy) = ctx->block_vars;
529 ctx->block_vars = copy;
535 omp_copy_decl_1 (tree var, omp_context *ctx)
537 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
540 /* Build tree nodes to access the field for VAR on the receiver side. */
543 build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
545 tree x, field = lookup_field (var, ctx);
547 /* If the receiver record type was remapped in the child function,
548 remap the field into the new record type. */
549 x = maybe_lookup_field (field, ctx);
553 x = build_fold_indirect_ref (ctx->receiver_decl);
554 x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL);
556 x = build_fold_indirect_ref (x);
561 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
562 of a parallel, this is a component reference; for workshare constructs
563 this is some variable. */
566 build_outer_var_ref (tree var, omp_context *ctx)
570 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
572 else if (is_variable_sized (var))
574 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
575 x = build_outer_var_ref (x, ctx);
576 x = build_fold_indirect_ref (x);
578 else if (is_parallel_ctx (ctx))
580 bool by_ref = use_pointer_for_field (var, false);
581 x = build_receiver_ref (var, by_ref, ctx);
584 x = lookup_decl (var, ctx->outer);
585 else if (is_reference (var))
586 /* This can happen with orphaned constructs. If var is reference, it is
587 possible it is shared and as such valid. */
592 if (is_reference (var))
593 x = build_fold_indirect_ref (x);
598 /* Build tree nodes to access the field for VAR on the sender side. */
601 build_sender_ref (tree var, omp_context *ctx)
603 tree field = lookup_field (var, ctx);
604 return build3 (COMPONENT_REF, TREE_TYPE (field),
605 ctx->sender_decl, field, NULL);
608 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
611 install_var_field (tree var, bool by_ref, omp_context *ctx)
615 gcc_assert (!splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
617 type = TREE_TYPE (var);
619 type = build_pointer_type (type);
621 field = build_decl (FIELD_DECL, DECL_NAME (var), type);
623 /* Remember what variable this field was created for. This does have a
624 side effect of making dwarf2out ignore this member, so for helpful
625 debugging we clear it later in delete_omp_context. */
626 DECL_ABSTRACT_ORIGIN (field) = var;
628 insert_field_into_struct (ctx->record_type, field);
630 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
631 (splay_tree_value) field);
635 install_var_local (tree var, omp_context *ctx)
637 tree new_var = omp_copy_decl_1 (var, ctx);
638 insert_decl_map (&ctx->cb, var, new_var);
642 /* Adjust the replacement for DECL in CTX for the new context. This means
643 copying the DECL_VALUE_EXPR, and fixing up the type. */
646 fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
650 new_decl = lookup_decl (decl, ctx);
652 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
654 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
655 && DECL_HAS_VALUE_EXPR_P (decl))
657 tree ve = DECL_VALUE_EXPR (decl);
658 walk_tree (&ve, copy_body_r, &ctx->cb, NULL);
659 SET_DECL_VALUE_EXPR (new_decl, ve);
660 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
663 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
665 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
666 if (size == error_mark_node)
667 size = TYPE_SIZE (TREE_TYPE (new_decl));
668 DECL_SIZE (new_decl) = size;
670 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
671 if (size == error_mark_node)
672 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
673 DECL_SIZE_UNIT (new_decl) = size;
677 /* The callback for remap_decl. Search all containing contexts for a
678 mapping of the variable; this avoids having to duplicate the splay
679 tree ahead of time. We know a mapping doesn't already exist in the
680 given context. Create new mappings to implement default semantics. */
683 omp_copy_decl (tree var, copy_body_data *cb)
685 omp_context *ctx = (omp_context *) cb;
688 if (TREE_CODE (var) == LABEL_DECL)
690 new_var = create_artificial_label ();
691 DECL_CONTEXT (new_var) = current_function_decl;
692 insert_decl_map (&ctx->cb, var, new_var);
696 while (!is_parallel_ctx (ctx))
701 new_var = maybe_lookup_decl (var, ctx);
706 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
709 return error_mark_node;
713 /* Return the parallel region associated with STMT. */
715 /* Debugging dumps for parallel regions. */
716 void dump_omp_region (FILE *, struct omp_region *, int);
717 void debug_omp_region (struct omp_region *);
718 void debug_all_omp_regions (void);
720 /* Dump the parallel region tree rooted at REGION. */
723 dump_omp_region (FILE *file, struct omp_region *region, int indent)
725 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
726 tree_code_name[region->type]);
729 dump_omp_region (file, region->inner, indent + 4);
733 fprintf (file, "%*sbb %d: OMP_CONTINUE\n", indent, "",
734 region->cont->index);
738 fprintf (file, "%*sbb %d: OMP_RETURN\n", indent, "",
739 region->exit->index);
741 fprintf (file, "%*s[no exit marker]\n", indent, "");
744 dump_omp_region (file, region->next, indent);
748 debug_omp_region (struct omp_region *region)
750 dump_omp_region (stderr, region, 0);
754 debug_all_omp_regions (void)
756 dump_omp_region (stderr, root_omp_region, 0);
760 /* Create a new parallel region starting at STMT inside region PARENT. */
763 new_omp_region (basic_block bb, enum tree_code type, struct omp_region *parent)
765 struct omp_region *region = xcalloc (1, sizeof (*region));
767 region->outer = parent;
773 /* This is a nested region. Add it to the list of inner
774 regions in PARENT. */
775 region->next = parent->inner;
776 parent->inner = region;
780 /* This is a toplevel region. Add it to the list of toplevel
781 regions in ROOT_OMP_REGION. */
782 region->next = root_omp_region;
783 root_omp_region = region;
789 /* Release the memory associated with the region tree rooted at REGION. */
792 free_omp_region_1 (struct omp_region *region)
794 struct omp_region *i, *n;
796 for (i = region->inner; i ; i = n)
799 free_omp_region_1 (i);
805 /* Release the memory for the entire omp region tree. */
808 free_omp_regions (void)
810 struct omp_region *r, *n;
811 for (r = root_omp_region; r ; r = n)
814 free_omp_region_1 (r);
816 root_omp_region = NULL;
820 /* Create a new context, with OUTER_CTX being the surrounding context. */
823 new_omp_context (tree stmt, omp_context *outer_ctx)
825 omp_context *ctx = XCNEW (omp_context);
827 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
828 (splay_tree_value) ctx);
833 ctx->outer = outer_ctx;
834 ctx->cb = outer_ctx->cb;
835 ctx->cb.block = NULL;
836 ctx->depth = outer_ctx->depth + 1;
840 ctx->cb.src_fn = current_function_decl;
841 ctx->cb.dst_fn = current_function_decl;
842 ctx->cb.src_node = cgraph_node (current_function_decl);
843 ctx->cb.dst_node = ctx->cb.src_node;
844 ctx->cb.src_cfun = cfun;
845 ctx->cb.copy_decl = omp_copy_decl;
846 ctx->cb.eh_region = -1;
847 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
851 ctx->cb.decl_map = pointer_map_create ();
856 /* Destroy a omp_context data structures. Called through the splay tree
857 value delete callback. */
860 delete_omp_context (splay_tree_value value)
862 omp_context *ctx = (omp_context *) value;
864 pointer_map_destroy (ctx->cb.decl_map);
867 splay_tree_delete (ctx->field_map);
869 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
870 it produces corrupt debug information. */
871 if (ctx->record_type)
874 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
875 DECL_ABSTRACT_ORIGIN (t) = NULL;
881 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
885 fixup_child_record_type (omp_context *ctx)
887 tree f, type = ctx->record_type;
889 /* ??? It isn't sufficient to just call remap_type here, because
890 variably_modified_type_p doesn't work the way we expect for
891 record types. Testing each field for whether it needs remapping
892 and creating a new record by hand works, however. */
893 for (f = TYPE_FIELDS (type); f ; f = TREE_CHAIN (f))
894 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
898 tree name, new_fields = NULL;
900 type = lang_hooks.types.make_type (RECORD_TYPE);
901 name = DECL_NAME (TYPE_NAME (ctx->record_type));
902 name = build_decl (TYPE_DECL, name, type);
903 TYPE_NAME (type) = name;
905 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
907 tree new_f = copy_node (f);
908 DECL_CONTEXT (new_f) = type;
909 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
910 TREE_CHAIN (new_f) = new_fields;
913 /* Arrange to be able to look up the receiver field
914 given the sender field. */
915 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
916 (splay_tree_value) new_f);
918 TYPE_FIELDS (type) = nreverse (new_fields);
922 TREE_TYPE (ctx->receiver_decl) = build_pointer_type (type);
925 /* Instantiate decls as necessary in CTX to satisfy the data sharing
926 specified by CLAUSES. */
929 scan_sharing_clauses (tree clauses, omp_context *ctx)
932 bool scan_array_reductions = false;
934 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
938 switch (OMP_CLAUSE_CODE (c))
940 case OMP_CLAUSE_PRIVATE:
941 decl = OMP_CLAUSE_DECL (c);
942 if (!is_variable_sized (decl))
943 install_var_local (decl, ctx);
946 case OMP_CLAUSE_SHARED:
947 gcc_assert (is_parallel_ctx (ctx));
948 decl = OMP_CLAUSE_DECL (c);
949 gcc_assert (!is_variable_sized (decl));
950 by_ref = use_pointer_for_field (decl, true);
951 /* Global variables don't need to be copied,
952 the receiver side will use them directly. */
953 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
955 if (! TREE_READONLY (decl)
956 || TREE_ADDRESSABLE (decl)
958 || is_reference (decl))
960 install_var_field (decl, by_ref, ctx);
961 install_var_local (decl, ctx);
964 /* We don't need to copy const scalar vars back. */
965 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
968 case OMP_CLAUSE_LASTPRIVATE:
969 /* Let the corresponding firstprivate clause create
971 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
975 case OMP_CLAUSE_FIRSTPRIVATE:
976 case OMP_CLAUSE_REDUCTION:
977 decl = OMP_CLAUSE_DECL (c);
979 if (is_variable_sized (decl))
981 else if (is_parallel_ctx (ctx)
982 && ! is_global_var (maybe_lookup_decl_in_outer_ctx (decl,
985 by_ref = use_pointer_for_field (decl, false);
986 install_var_field (decl, by_ref, ctx);
988 install_var_local (decl, ctx);
991 case OMP_CLAUSE_COPYPRIVATE:
993 scan_omp (&OMP_CLAUSE_DECL (c), ctx->outer);
996 case OMP_CLAUSE_COPYIN:
997 decl = OMP_CLAUSE_DECL (c);
998 by_ref = use_pointer_for_field (decl, false);
999 install_var_field (decl, by_ref, ctx);
1002 case OMP_CLAUSE_DEFAULT:
1003 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1007 case OMP_CLAUSE_NUM_THREADS:
1008 case OMP_CLAUSE_SCHEDULE:
1010 scan_omp (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1013 case OMP_CLAUSE_NOWAIT:
1014 case OMP_CLAUSE_ORDERED:
1022 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1024 switch (OMP_CLAUSE_CODE (c))
1026 case OMP_CLAUSE_LASTPRIVATE:
1027 /* Let the corresponding firstprivate clause create
1029 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1033 case OMP_CLAUSE_PRIVATE:
1034 case OMP_CLAUSE_FIRSTPRIVATE:
1035 case OMP_CLAUSE_REDUCTION:
1036 decl = OMP_CLAUSE_DECL (c);
1037 if (is_variable_sized (decl))
1038 install_var_local (decl, ctx);
1039 fixup_remapped_decl (decl, ctx,
1040 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1041 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1042 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1043 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1044 scan_array_reductions = true;
1047 case OMP_CLAUSE_SHARED:
1048 decl = OMP_CLAUSE_DECL (c);
1049 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1050 fixup_remapped_decl (decl, ctx, false);
1053 case OMP_CLAUSE_COPYPRIVATE:
1054 case OMP_CLAUSE_COPYIN:
1055 case OMP_CLAUSE_DEFAULT:
1057 case OMP_CLAUSE_NUM_THREADS:
1058 case OMP_CLAUSE_SCHEDULE:
1059 case OMP_CLAUSE_NOWAIT:
1060 case OMP_CLAUSE_ORDERED:
1068 if (scan_array_reductions)
1069 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1070 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1071 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1073 scan_omp (&OMP_CLAUSE_REDUCTION_INIT (c), ctx);
1074 scan_omp (&OMP_CLAUSE_REDUCTION_MERGE (c), ctx);
1078 /* Create a new name for omp child function. Returns an identifier. */
1080 static GTY(()) unsigned int tmp_ompfn_id_num;
1083 create_omp_child_function_name (void)
1085 tree name = DECL_ASSEMBLER_NAME (current_function_decl);
1086 size_t len = IDENTIFIER_LENGTH (name);
1087 char *tmp_name, *prefix;
1089 prefix = alloca (len + sizeof ("_omp_fn"));
1090 memcpy (prefix, IDENTIFIER_POINTER (name), len);
1091 strcpy (prefix + len, "_omp_fn");
1092 #ifndef NO_DOT_IN_LABEL
1094 #elif !defined NO_DOLLAR_IN_LABEL
1097 ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix, tmp_ompfn_id_num++);
1098 return get_identifier (tmp_name);
1101 /* Build a decl for the omp child function. It'll not contain a body
1102 yet, just the bare decl. */
1105 create_omp_child_function (omp_context *ctx)
1107 tree decl, type, name, t;
1109 name = create_omp_child_function_name ();
1110 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
1112 decl = build_decl (FUNCTION_DECL, name, type);
1113 decl = lang_hooks.decls.pushdecl (decl);
1115 ctx->cb.dst_fn = decl;
1117 TREE_STATIC (decl) = 1;
1118 TREE_USED (decl) = 1;
1119 DECL_ARTIFICIAL (decl) = 1;
1120 DECL_IGNORED_P (decl) = 0;
1121 TREE_PUBLIC (decl) = 0;
1122 DECL_UNINLINABLE (decl) = 1;
1123 DECL_EXTERNAL (decl) = 0;
1124 DECL_CONTEXT (decl) = NULL_TREE;
1125 DECL_INITIAL (decl) = make_node (BLOCK);
1127 t = build_decl (RESULT_DECL, NULL_TREE, void_type_node);
1128 DECL_ARTIFICIAL (t) = 1;
1129 DECL_IGNORED_P (t) = 1;
1130 DECL_RESULT (decl) = t;
1132 t = build_decl (PARM_DECL, get_identifier (".omp_data_i"), ptr_type_node);
1133 DECL_ARTIFICIAL (t) = 1;
1134 DECL_ARG_TYPE (t) = ptr_type_node;
1135 DECL_CONTEXT (t) = current_function_decl;
1137 DECL_ARGUMENTS (decl) = t;
1138 ctx->receiver_decl = t;
1140 /* Allocate memory for the function structure. The call to
1141 allocate_struct_function clobbers CFUN, so we need to restore
1143 allocate_struct_function (decl);
1144 DECL_SOURCE_LOCATION (decl) = EXPR_LOCATION (ctx->stmt);
1145 cfun->function_end_locus = EXPR_LOCATION (ctx->stmt);
1146 cfun = ctx->cb.src_cfun;
1150 /* Scan an OpenMP parallel directive. */
1153 scan_omp_parallel (tree *stmt_p, omp_context *outer_ctx)
1158 /* Ignore parallel directives with empty bodies, unless there
1159 are copyin clauses. */
1161 && empty_body_p (OMP_PARALLEL_BODY (*stmt_p))
1162 && find_omp_clause (OMP_CLAUSES (*stmt_p), OMP_CLAUSE_COPYIN) == NULL)
1164 *stmt_p = build_empty_stmt ();
1168 ctx = new_omp_context (*stmt_p, outer_ctx);
1169 if (parallel_nesting_level > 1)
1170 ctx->is_nested = true;
1171 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1172 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
1173 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1174 name = create_tmp_var_name (".omp_data_s");
1175 name = build_decl (TYPE_DECL, name, ctx->record_type);
1176 TYPE_NAME (ctx->record_type) = name;
1177 create_omp_child_function (ctx);
1178 OMP_PARALLEL_FN (*stmt_p) = ctx->cb.dst_fn;
1180 scan_sharing_clauses (OMP_PARALLEL_CLAUSES (*stmt_p), ctx);
1181 scan_omp (&OMP_PARALLEL_BODY (*stmt_p), ctx);
1183 if (TYPE_FIELDS (ctx->record_type) == NULL)
1184 ctx->record_type = ctx->receiver_decl = NULL;
1187 layout_type (ctx->record_type);
1188 fixup_child_record_type (ctx);
1193 /* Scan an OpenMP loop directive. */
1196 scan_omp_for (tree *stmt_p, omp_context *outer_ctx)
1202 ctx = new_omp_context (stmt, outer_ctx);
1204 scan_sharing_clauses (OMP_FOR_CLAUSES (stmt), ctx);
1206 scan_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
1207 scan_omp (&OMP_FOR_INIT (stmt), ctx);
1208 scan_omp (&OMP_FOR_COND (stmt), ctx);
1209 scan_omp (&OMP_FOR_INCR (stmt), ctx);
1210 scan_omp (&OMP_FOR_BODY (stmt), ctx);
1213 /* Scan an OpenMP sections directive. */
1216 scan_omp_sections (tree *stmt_p, omp_context *outer_ctx)
1222 ctx = new_omp_context (stmt, outer_ctx);
1223 scan_sharing_clauses (OMP_SECTIONS_CLAUSES (stmt), ctx);
1224 scan_omp (&OMP_SECTIONS_BODY (stmt), ctx);
1227 /* Scan an OpenMP single directive. */
1230 scan_omp_single (tree *stmt_p, omp_context *outer_ctx)
1232 tree stmt = *stmt_p;
1236 ctx = new_omp_context (stmt, outer_ctx);
1237 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1238 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
1239 name = create_tmp_var_name (".omp_copy_s");
1240 name = build_decl (TYPE_DECL, name, ctx->record_type);
1241 TYPE_NAME (ctx->record_type) = name;
1243 scan_sharing_clauses (OMP_SINGLE_CLAUSES (stmt), ctx);
1244 scan_omp (&OMP_SINGLE_BODY (stmt), ctx);
1246 if (TYPE_FIELDS (ctx->record_type) == NULL)
1247 ctx->record_type = NULL;
1249 layout_type (ctx->record_type);
1253 /* Check OpenMP nesting restrictions. */
1255 check_omp_nesting_restrictions (tree t, omp_context *ctx)
1257 switch (TREE_CODE (t))
1262 for (; ctx != NULL; ctx = ctx->outer)
1263 switch (TREE_CODE (ctx->stmt))
1270 warning (0, "work-sharing region may not be closely nested inside "
1271 "of work-sharing, critical, ordered or master region");
1280 for (; ctx != NULL; ctx = ctx->outer)
1281 switch (TREE_CODE (ctx->stmt))
1286 warning (0, "master region may not be closely nested inside "
1287 "of work-sharing region");
1296 for (; ctx != NULL; ctx = ctx->outer)
1297 switch (TREE_CODE (ctx->stmt))
1300 warning (0, "ordered region may not be closely nested inside "
1301 "of critical region");
1304 if (find_omp_clause (OMP_CLAUSES (ctx->stmt),
1305 OMP_CLAUSE_ORDERED) == NULL)
1306 warning (0, "ordered region must be closely nested inside "
1307 "a loop region with an ordered clause");
1316 for (; ctx != NULL; ctx = ctx->outer)
1317 if (TREE_CODE (ctx->stmt) == OMP_CRITICAL
1318 && OMP_CRITICAL_NAME (t) == OMP_CRITICAL_NAME (ctx->stmt))
1320 warning (0, "critical region may not be nested inside a critical "
1321 "region with the same name");
1331 /* Callback for walk_stmts used to scan for OpenMP directives at TP. */
1334 scan_omp_1 (tree *tp, int *walk_subtrees, void *data)
1336 struct walk_stmt_info *wi = data;
1337 omp_context *ctx = wi->info;
1340 if (EXPR_HAS_LOCATION (t))
1341 input_location = EXPR_LOCATION (t);
1343 /* Check the OpenMP nesting restrictions. */
1344 if (OMP_DIRECTIVE_P (t) && ctx != NULL)
1345 check_omp_nesting_restrictions (t, ctx);
1348 switch (TREE_CODE (t))
1351 parallel_nesting_level++;
1352 scan_omp_parallel (tp, ctx);
1353 parallel_nesting_level--;
1357 scan_omp_for (tp, ctx);
1361 scan_omp_sections (tp, ctx);
1365 scan_omp_single (tp, ctx);
1372 ctx = new_omp_context (*tp, ctx);
1373 scan_omp (&OMP_BODY (*tp), ctx);
1381 for (var = BIND_EXPR_VARS (t); var ; var = TREE_CHAIN (var))
1382 insert_decl_map (&ctx->cb, var, var);
1391 *tp = remap_decl (t, &ctx->cb);
1395 if (ctx && TYPE_P (t))
1396 *tp = remap_type (t, &ctx->cb);
1397 else if (!DECL_P (t))
1406 /* Scan all the statements starting at STMT_P. CTX contains context
1407 information about the OpenMP directives and clauses found during
1411 scan_omp (tree *stmt_p, omp_context *ctx)
1413 location_t saved_location;
1414 struct walk_stmt_info wi;
1416 memset (&wi, 0, sizeof (wi));
1417 wi.callback = scan_omp_1;
1419 wi.want_bind_expr = (ctx != NULL);
1420 wi.want_locations = true;
1422 saved_location = input_location;
1423 walk_stmts (&wi, stmt_p);
1424 input_location = saved_location;
1427 /* Re-gimplification and code generation routines. */
1429 /* Build a call to GOMP_barrier. */
1432 build_omp_barrier (tree *stmt_list)
1434 tree t = build_call_expr (built_in_decls[BUILT_IN_GOMP_BARRIER], 0);
1435 gimplify_and_add (t, stmt_list);
1438 /* If a context was created for STMT when it was scanned, return it. */
1440 static omp_context *
1441 maybe_lookup_ctx (tree stmt)
1444 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
1445 return n ? (omp_context *) n->value : NULL;
1449 /* Find the mapping for DECL in CTX or the immediately enclosing
1450 context that has a mapping for DECL.
1452 If CTX is a nested parallel directive, we may have to use the decl
1453 mappings created in CTX's parent context. Suppose that we have the
1454 following parallel nesting (variable UIDs showed for clarity):
1457 #omp parallel shared(iD.1562) -> outer parallel
1458 iD.1562 = iD.1562 + 1;
1460 #omp parallel shared (iD.1562) -> inner parallel
1461 iD.1562 = iD.1562 - 1;
1463 Each parallel structure will create a distinct .omp_data_s structure
1464 for copying iD.1562 in/out of the directive:
1466 outer parallel .omp_data_s.1.i -> iD.1562
1467 inner parallel .omp_data_s.2.i -> iD.1562
1469 A shared variable mapping will produce a copy-out operation before
1470 the parallel directive and a copy-in operation after it. So, in
1471 this case we would have:
1474 .omp_data_o.1.i = iD.1562;
1475 #omp parallel shared(iD.1562) -> outer parallel
1476 .omp_data_i.1 = &.omp_data_o.1
1477 .omp_data_i.1->i = .omp_data_i.1->i + 1;
1479 .omp_data_o.2.i = iD.1562; -> **
1480 #omp parallel shared(iD.1562) -> inner parallel
1481 .omp_data_i.2 = &.omp_data_o.2
1482 .omp_data_i.2->i = .omp_data_i.2->i - 1;
1485 ** This is a problem. The symbol iD.1562 cannot be referenced
1486 inside the body of the outer parallel region. But since we are
1487 emitting this copy operation while expanding the inner parallel
1488 directive, we need to access the CTX structure of the outer
1489 parallel directive to get the correct mapping:
1491 .omp_data_o.2.i = .omp_data_i.1->i
1493 Since there may be other workshare or parallel directives enclosing
1494 the parallel directive, it may be necessary to walk up the context
1495 parent chain. This is not a problem in general because nested
1496 parallelism happens only rarely. */
1499 lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1504 gcc_assert (ctx->is_nested);
1506 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1507 t = maybe_lookup_decl (decl, up);
1509 gcc_assert (t || is_global_var (decl));
1511 return t ? t : decl;
1515 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
1516 in outer contexts. */
1519 maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
1525 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
1526 t = maybe_lookup_decl (decl, up);
1528 return t ? t : decl;
1532 /* Construct the initialization value for reduction CLAUSE. */
1535 omp_reduction_init (tree clause, tree type)
1537 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
1544 case TRUTH_ORIF_EXPR:
1545 case TRUTH_XOR_EXPR:
1547 return fold_convert (type, integer_zero_node);
1550 case TRUTH_AND_EXPR:
1551 case TRUTH_ANDIF_EXPR:
1553 return fold_convert (type, integer_one_node);
1556 return fold_convert (type, integer_minus_one_node);
1559 if (SCALAR_FLOAT_TYPE_P (type))
1561 REAL_VALUE_TYPE max, min;
1562 if (HONOR_INFINITIES (TYPE_MODE (type)))
1565 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
1568 real_maxval (&min, 1, TYPE_MODE (type));
1569 return build_real (type, min);
1573 gcc_assert (INTEGRAL_TYPE_P (type));
1574 return TYPE_MIN_VALUE (type);
1578 if (SCALAR_FLOAT_TYPE_P (type))
1580 REAL_VALUE_TYPE max;
1581 if (HONOR_INFINITIES (TYPE_MODE (type)))
1584 real_maxval (&max, 0, TYPE_MODE (type));
1585 return build_real (type, max);
1589 gcc_assert (INTEGRAL_TYPE_P (type));
1590 return TYPE_MAX_VALUE (type);
1598 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
1599 from the receiver (aka child) side and initializers for REFERENCE_TYPE
1600 private variables. Initialization statements go in ILIST, while calls
1601 to destructors go in DLIST. */
1604 lower_rec_input_clauses (tree clauses, tree *ilist, tree *dlist,
1607 tree_stmt_iterator diter;
1608 tree c, dtor, copyin_seq, x, ptr;
1609 bool copyin_by_ref = false;
1610 bool lastprivate_firstprivate = false;
1613 *dlist = alloc_stmt_list ();
1614 diter = tsi_start (*dlist);
1617 /* Do all the fixed sized types in the first pass, and the variable sized
1618 types in the second pass. This makes sure that the scalar arguments to
1619 the variable sized types are processed before we use them in the
1620 variable sized operations. */
1621 for (pass = 0; pass < 2; ++pass)
1623 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1625 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
1631 case OMP_CLAUSE_PRIVATE:
1632 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
1635 case OMP_CLAUSE_SHARED:
1636 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
1638 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
1641 case OMP_CLAUSE_FIRSTPRIVATE:
1642 case OMP_CLAUSE_COPYIN:
1643 case OMP_CLAUSE_REDUCTION:
1645 case OMP_CLAUSE_LASTPRIVATE:
1646 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1648 lastprivate_firstprivate = true;
1657 new_var = var = OMP_CLAUSE_DECL (c);
1658 if (c_kind != OMP_CLAUSE_COPYIN)
1659 new_var = lookup_decl (var, ctx);
1661 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
1666 else if (is_variable_sized (var))
1668 /* For variable sized types, we need to allocate the
1669 actual storage here. Call alloca and store the
1670 result in the pointer decl that we created elsewhere. */
1674 ptr = DECL_VALUE_EXPR (new_var);
1675 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
1676 ptr = TREE_OPERAND (ptr, 0);
1677 gcc_assert (DECL_P (ptr));
1679 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
1680 x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
1681 x = fold_convert (TREE_TYPE (ptr), x);
1682 x = build_gimple_modify_stmt (ptr, x);
1683 gimplify_and_add (x, ilist);
1685 else if (is_reference (var))
1687 /* For references that are being privatized for Fortran,
1688 allocate new backing storage for the new pointer
1689 variable. This allows us to avoid changing all the
1690 code that expects a pointer to something that expects
1691 a direct variable. Note that this doesn't apply to
1692 C++, since reference types are disallowed in data
1693 sharing clauses there, except for NRV optimized
1698 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
1699 if (TREE_CONSTANT (x))
1701 const char *name = NULL;
1702 if (DECL_NAME (var))
1703 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
1705 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
1707 gimple_add_tmp_var (x);
1708 x = build_fold_addr_expr_with_type (x, TREE_TYPE (new_var));
1712 x = build_call_expr (built_in_decls[BUILT_IN_ALLOCA], 1, x);
1713 x = fold_convert (TREE_TYPE (new_var), x);
1716 x = build_gimple_modify_stmt (new_var, x);
1717 gimplify_and_add (x, ilist);
1719 new_var = build_fold_indirect_ref (new_var);
1721 else if (c_kind == OMP_CLAUSE_REDUCTION
1722 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1730 switch (OMP_CLAUSE_CODE (c))
1732 case OMP_CLAUSE_SHARED:
1733 /* Shared global vars are just accessed directly. */
1734 if (is_global_var (new_var))
1736 /* Set up the DECL_VALUE_EXPR for shared variables now. This
1737 needs to be delayed until after fixup_child_record_type so
1738 that we get the correct type during the dereference. */
1739 by_ref = use_pointer_for_field (var, true);
1740 x = build_receiver_ref (var, by_ref, ctx);
1741 SET_DECL_VALUE_EXPR (new_var, x);
1742 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
1744 /* ??? If VAR is not passed by reference, and the variable
1745 hasn't been initialized yet, then we'll get a warning for
1746 the store into the omp_data_s structure. Ideally, we'd be
1747 able to notice this and not store anything at all, but
1748 we're generating code too early. Suppress the warning. */
1750 TREE_NO_WARNING (var) = 1;
1753 case OMP_CLAUSE_LASTPRIVATE:
1754 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1758 case OMP_CLAUSE_PRIVATE:
1759 x = lang_hooks.decls.omp_clause_default_ctor (c, new_var);
1761 gimplify_and_add (x, ilist);
1765 x = lang_hooks.decls.omp_clause_dtor (c, new_var);
1769 gimplify_stmt (&dtor);
1770 tsi_link_before (&diter, dtor, TSI_SAME_STMT);
1774 case OMP_CLAUSE_FIRSTPRIVATE:
1775 x = build_outer_var_ref (var, ctx);
1776 x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
1777 gimplify_and_add (x, ilist);
1781 case OMP_CLAUSE_COPYIN:
1782 by_ref = use_pointer_for_field (var, false);
1783 x = build_receiver_ref (var, by_ref, ctx);
1784 x = lang_hooks.decls.omp_clause_assign_op (c, new_var, x);
1785 append_to_statement_list (x, ©in_seq);
1786 copyin_by_ref |= by_ref;
1789 case OMP_CLAUSE_REDUCTION:
1790 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1792 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c), ilist);
1793 OMP_CLAUSE_REDUCTION_INIT (c) = NULL;
1797 x = omp_reduction_init (c, TREE_TYPE (new_var));
1798 gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
1799 x = build_gimple_modify_stmt (new_var, x);
1800 gimplify_and_add (x, ilist);
1810 /* The copyin sequence is not to be executed by the main thread, since
1811 that would result in self-copies. Perhaps not visible to scalars,
1812 but it certainly is to C++ operator=. */
1815 x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
1816 x = build2 (NE_EXPR, boolean_type_node, x,
1817 build_int_cst (TREE_TYPE (x), 0));
1818 x = build3 (COND_EXPR, void_type_node, x, copyin_seq, NULL);
1819 gimplify_and_add (x, ilist);
1822 /* If any copyin variable is passed by reference, we must ensure the
1823 master thread doesn't modify it before it is copied over in all
1824 threads. Similarly for variables in both firstprivate and
1825 lastprivate clauses we need to ensure the lastprivate copying
1826 happens after firstprivate copying in all threads. */
1827 if (copyin_by_ref || lastprivate_firstprivate)
1828 build_omp_barrier (ilist);
1832 /* Generate code to implement the LASTPRIVATE clauses. This is used for
1833 both parallel and workshare constructs. PREDICATE may be NULL if it's
1837 lower_lastprivate_clauses (tree clauses, tree predicate, tree *stmt_list,
1840 tree sub_list, x, c;
1842 /* Early exit if there are no lastprivate clauses. */
1843 clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
1844 if (clauses == NULL)
1846 /* If this was a workshare clause, see if it had been combined
1847 with its parallel. In that case, look for the clauses on the
1848 parallel statement itself. */
1849 if (is_parallel_ctx (ctx))
1853 if (ctx == NULL || !is_parallel_ctx (ctx))
1856 clauses = find_omp_clause (OMP_PARALLEL_CLAUSES (ctx->stmt),
1857 OMP_CLAUSE_LASTPRIVATE);
1858 if (clauses == NULL)
1862 sub_list = alloc_stmt_list ();
1864 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1868 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE)
1871 var = OMP_CLAUSE_DECL (c);
1872 new_var = lookup_decl (var, ctx);
1874 x = build_outer_var_ref (var, ctx);
1875 if (is_reference (var))
1876 new_var = build_fold_indirect_ref (new_var);
1877 x = lang_hooks.decls.omp_clause_assign_op (c, x, new_var);
1878 append_to_statement_list (x, &sub_list);
1882 x = build3 (COND_EXPR, void_type_node, predicate, sub_list, NULL);
1886 gimplify_and_add (x, stmt_list);
1890 /* Generate code to implement the REDUCTION clauses. */
1893 lower_reduction_clauses (tree clauses, tree *stmt_list, omp_context *ctx)
1895 tree sub_list = NULL, x, c;
1898 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
1899 update in that case, otherwise use a lock. */
1900 for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
1901 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
1903 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1905 /* Never use OMP_ATOMIC for array reductions. */
1915 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1917 tree var, ref, new_var;
1918 enum tree_code code;
1920 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_REDUCTION)
1923 var = OMP_CLAUSE_DECL (c);
1924 new_var = lookup_decl (var, ctx);
1925 if (is_reference (var))
1926 new_var = build_fold_indirect_ref (new_var);
1927 ref = build_outer_var_ref (var, ctx);
1928 code = OMP_CLAUSE_REDUCTION_CODE (c);
1930 /* reduction(-:var) sums up the partial results, so it acts
1931 identically to reduction(+:var). */
1932 if (code == MINUS_EXPR)
1937 tree addr = build_fold_addr_expr (ref);
1939 addr = save_expr (addr);
1940 ref = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (addr)), addr);
1941 x = fold_build2 (code, TREE_TYPE (ref), ref, new_var);
1942 x = build2 (OMP_ATOMIC, void_type_node, addr, x);
1943 gimplify_and_add (x, stmt_list);
1947 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1949 tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
1951 if (is_reference (var))
1952 ref = build_fold_addr_expr (ref);
1953 SET_DECL_VALUE_EXPR (placeholder, ref);
1954 DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
1955 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c), &sub_list);
1956 OMP_CLAUSE_REDUCTION_MERGE (c) = NULL;
1957 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
1961 x = build2 (code, TREE_TYPE (ref), ref, new_var);
1962 ref = build_outer_var_ref (var, ctx);
1963 x = build_gimple_modify_stmt (ref, x);
1964 append_to_statement_list (x, &sub_list);
1968 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_START], 0);
1969 gimplify_and_add (x, stmt_list);
1971 gimplify_and_add (sub_list, stmt_list);
1973 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ATOMIC_END], 0);
1974 gimplify_and_add (x, stmt_list);
1978 /* Generate code to implement the COPYPRIVATE clauses. */
1981 lower_copyprivate_clauses (tree clauses, tree *slist, tree *rlist,
1986 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
1991 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYPRIVATE)
1994 var = OMP_CLAUSE_DECL (c);
1995 by_ref = use_pointer_for_field (var, false);
1997 ref = build_sender_ref (var, ctx);
1998 x = (ctx->is_nested) ? lookup_decl_in_outer_ctx (var, ctx) : var;
1999 x = by_ref ? build_fold_addr_expr (x) : x;
2000 x = build_gimple_modify_stmt (ref, x);
2001 gimplify_and_add (x, slist);
2003 ref = build_receiver_ref (var, by_ref, ctx);
2004 if (is_reference (var))
2006 ref = build_fold_indirect_ref (ref);
2007 var = build_fold_indirect_ref (var);
2009 x = lang_hooks.decls.omp_clause_assign_op (c, var, ref);
2010 gimplify_and_add (x, rlist);
2015 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2016 and REDUCTION from the sender (aka parent) side. */
2019 lower_send_clauses (tree clauses, tree *ilist, tree *olist, omp_context *ctx)
2023 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
2025 tree val, ref, x, var;
2026 bool by_ref, do_in = false, do_out = false;
2028 switch (OMP_CLAUSE_CODE (c))
2030 case OMP_CLAUSE_FIRSTPRIVATE:
2031 case OMP_CLAUSE_COPYIN:
2032 case OMP_CLAUSE_LASTPRIVATE:
2033 case OMP_CLAUSE_REDUCTION:
2039 var = val = OMP_CLAUSE_DECL (c);
2041 var = lookup_decl_in_outer_ctx (val, ctx);
2043 if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_COPYIN
2044 && is_global_var (var))
2046 if (is_variable_sized (val))
2048 by_ref = use_pointer_for_field (val, false);
2050 switch (OMP_CLAUSE_CODE (c))
2052 case OMP_CLAUSE_FIRSTPRIVATE:
2053 case OMP_CLAUSE_COPYIN:
2057 case OMP_CLAUSE_LASTPRIVATE:
2058 if (by_ref || is_reference (val))
2060 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
2068 case OMP_CLAUSE_REDUCTION:
2070 do_out = !(by_ref || is_reference (val));
2079 ref = build_sender_ref (val, ctx);
2080 x = by_ref ? build_fold_addr_expr (var) : var;
2081 x = build_gimple_modify_stmt (ref, x);
2082 gimplify_and_add (x, ilist);
2087 ref = build_sender_ref (val, ctx);
2088 x = build_gimple_modify_stmt (var, ref);
2089 gimplify_and_add (x, olist);
2094 /* Generate code to implement SHARED from the sender (aka parent) side.
2095 This is trickier, since OMP_PARALLEL_CLAUSES doesn't list things that
2096 got automatically shared. */
2099 lower_send_shared_vars (tree *ilist, tree *olist, omp_context *ctx)
2101 tree var, ovar, nvar, f, x;
2103 if (ctx->record_type == NULL)
2106 for (f = TYPE_FIELDS (ctx->record_type); f ; f = TREE_CHAIN (f))
2108 ovar = DECL_ABSTRACT_ORIGIN (f);
2109 nvar = maybe_lookup_decl (ovar, ctx);
2110 if (!nvar || !DECL_HAS_VALUE_EXPR_P (nvar))
2115 /* If CTX is a nested parallel directive. Find the immediately
2116 enclosing parallel or workshare construct that contains a
2117 mapping for OVAR. */
2119 var = lookup_decl_in_outer_ctx (ovar, ctx);
2121 if (use_pointer_for_field (ovar, true))
2123 x = build_sender_ref (ovar, ctx);
2124 var = build_fold_addr_expr (var);
2125 x = build_gimple_modify_stmt (x, var);
2126 gimplify_and_add (x, ilist);
2130 x = build_sender_ref (ovar, ctx);
2131 x = build_gimple_modify_stmt (x, var);
2132 gimplify_and_add (x, ilist);
2134 x = build_sender_ref (ovar, ctx);
2135 x = build_gimple_modify_stmt (var, x);
2136 gimplify_and_add (x, olist);
2141 /* Build the function calls to GOMP_parallel_start etc to actually
2142 generate the parallel operation. REGION is the parallel region
2143 being expanded. BB is the block where to insert the code. WS_ARGS
2144 will be set if this is a call to a combined parallel+workshare
2145 construct, it contains the list of additional arguments needed by
2146 the workshare construct. */
2149 expand_parallel_call (struct omp_region *region, basic_block bb,
2150 tree entry_stmt, tree ws_args)
2152 tree t, t1, t2, val, cond, c, list, clauses;
2153 block_stmt_iterator si;
2156 clauses = OMP_PARALLEL_CLAUSES (entry_stmt);
2157 push_gimplify_context ();
2159 /* Determine what flavor of GOMP_parallel_start we will be
2161 start_ix = BUILT_IN_GOMP_PARALLEL_START;
2162 if (is_combined_parallel (region))
2164 switch (region->inner->type)
2167 start_ix = BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2168 + region->inner->sched_kind;
2171 start_ix = BUILT_IN_GOMP_PARALLEL_SECTIONS_START;
2178 /* By default, the value of NUM_THREADS is zero (selected at run time)
2179 and there is no conditional. */
2181 val = build_int_cst (unsigned_type_node, 0);
2183 c = find_omp_clause (clauses, OMP_CLAUSE_IF);
2185 cond = OMP_CLAUSE_IF_EXPR (c);
2187 c = find_omp_clause (clauses, OMP_CLAUSE_NUM_THREADS);
2189 val = OMP_CLAUSE_NUM_THREADS_EXPR (c);
2191 /* Ensure 'val' is of the correct type. */
2192 val = fold_convert (unsigned_type_node, val);
2194 /* If we found the clause 'if (cond)', build either
2195 (cond != 0) or (cond ? val : 1u). */
2198 block_stmt_iterator si;
2200 cond = gimple_boolify (cond);
2202 if (integer_zerop (val))
2203 val = build2 (EQ_EXPR, unsigned_type_node, cond,
2204 build_int_cst (TREE_TYPE (cond), 0));
2207 basic_block cond_bb, then_bb, else_bb;
2211 tmp = create_tmp_var (TREE_TYPE (val), NULL);
2212 e = split_block (bb, NULL);
2217 then_bb = create_empty_bb (cond_bb);
2218 else_bb = create_empty_bb (then_bb);
2220 t = build3 (COND_EXPR, void_type_node,
2221 cond, NULL_TREE, NULL_TREE);
2223 si = bsi_start (cond_bb);
2224 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2226 si = bsi_start (then_bb);
2227 t = build_gimple_modify_stmt (tmp, val);
2228 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2230 si = bsi_start (else_bb);
2231 t = build_gimple_modify_stmt (tmp,
2232 build_int_cst (unsigned_type_node, 1));
2233 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
2235 make_edge (cond_bb, then_bb, EDGE_TRUE_VALUE);
2236 make_edge (cond_bb, else_bb, EDGE_FALSE_VALUE);
2237 make_edge (then_bb, bb, EDGE_FALLTHRU);
2238 make_edge (else_bb, bb, EDGE_FALLTHRU);
2244 val = get_formal_tmp_var (val, &list);
2245 si = bsi_start (bb);
2246 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2250 t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2252 t1 = null_pointer_node;
2254 t1 = build_fold_addr_expr (t);
2255 t2 = build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt));
2259 tree args = tree_cons (NULL, t2,
2260 tree_cons (NULL, t1,
2261 tree_cons (NULL, val, ws_args)));
2262 t = build_function_call_expr (built_in_decls[start_ix], args);
2265 t = build_call_expr (built_in_decls[start_ix], 3, t2, t1, val);
2267 gimplify_and_add (t, &list);
2269 t = OMP_PARALLEL_DATA_ARG (entry_stmt);
2271 t = null_pointer_node;
2273 t = build_fold_addr_expr (t);
2274 t = build_call_expr (OMP_PARALLEL_FN (entry_stmt), 1, t);
2275 gimplify_and_add (t, &list);
2277 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_PARALLEL_END], 0);
2278 gimplify_and_add (t, &list);
2281 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2283 pop_gimplify_context (NULL_TREE);
2287 /* If exceptions are enabled, wrap *STMT_P in a MUST_NOT_THROW catch
2288 handler. This prevents programs from violating the structured
2289 block semantics with throws. */
2292 maybe_catch_exception (tree *stmt_p)
2296 if (!flag_exceptions)
2299 if (lang_protect_cleanup_actions)
2300 t = lang_protect_cleanup_actions ();
2302 t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
2303 f = build2 (EH_FILTER_EXPR, void_type_node, NULL, NULL);
2304 EH_FILTER_MUST_NOT_THROW (f) = 1;
2305 gimplify_and_add (t, &EH_FILTER_FAILURE (f));
2307 t = build2 (TRY_CATCH_EXPR, void_type_node, *stmt_p, NULL);
2308 append_to_statement_list (f, &TREE_OPERAND (t, 1));
2311 append_to_statement_list (t, stmt_p);
2314 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
2317 list2chain (tree list)
2321 for (t = list; t; t = TREE_CHAIN (t))
2323 tree var = TREE_VALUE (t);
2325 TREE_CHAIN (var) = TREE_VALUE (TREE_CHAIN (t));
2327 TREE_CHAIN (var) = NULL_TREE;
2330 return list ? TREE_VALUE (list) : NULL_TREE;
2334 /* Remove barriers in REGION->EXIT's block. Note that this is only
2335 valid for OMP_PARALLEL regions. Since the end of a parallel region
2336 is an implicit barrier, any workshare inside the OMP_PARALLEL that
2337 left a barrier at the end of the OMP_PARALLEL region can now be
2341 remove_exit_barrier (struct omp_region *region)
2343 block_stmt_iterator si;
2344 basic_block exit_bb;
2349 exit_bb = region->exit;
2351 /* If the parallel region doesn't return, we don't have REGION->EXIT
2356 /* The last insn in the block will be the parallel's OMP_RETURN. The
2357 workshare's OMP_RETURN will be in a preceding block. The kinds of
2358 statements that can appear in between are extremely limited -- no
2359 memory operations at all. Here, we allow nothing at all, so the
2360 only thing we allow to precede this OMP_RETURN is a label. */
2361 si = bsi_last (exit_bb);
2362 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2364 if (!bsi_end_p (si) && TREE_CODE (bsi_stmt (si)) != LABEL_EXPR)
2367 FOR_EACH_EDGE (e, ei, exit_bb->preds)
2369 si = bsi_last (e->src);
2373 if (TREE_CODE (t) == OMP_RETURN)
2374 OMP_RETURN_NOWAIT (t) = 1;
2379 remove_exit_barriers (struct omp_region *region)
2381 if (region->type == OMP_PARALLEL)
2382 remove_exit_barrier (region);
2386 region = region->inner;
2387 remove_exit_barriers (region);
2388 while (region->next)
2390 region = region->next;
2391 remove_exit_barriers (region);
2396 /* Expand the OpenMP parallel directive starting at REGION. */
2399 expand_omp_parallel (struct omp_region *region)
2401 basic_block entry_bb, exit_bb, new_bb;
2402 struct function *child_cfun, *saved_cfun;
2403 tree child_fn, block, t, ws_args;
2404 block_stmt_iterator si;
2407 bool do_cleanup_cfg = false;
2409 entry_stmt = last_stmt (region->entry);
2410 child_fn = OMP_PARALLEL_FN (entry_stmt);
2411 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
2414 entry_bb = region->entry;
2415 exit_bb = region->exit;
2417 if (is_combined_parallel (region))
2418 ws_args = region->ws_args;
2420 ws_args = NULL_TREE;
2422 if (child_cfun->cfg)
2424 /* Due to inlining, it may happen that we have already outlined
2425 the region, in which case all we need to do is make the
2426 sub-graph unreachable and emit the parallel call. */
2427 edge entry_succ_e, exit_succ_e;
2428 block_stmt_iterator si;
2430 entry_succ_e = single_succ_edge (entry_bb);
2432 si = bsi_last (entry_bb);
2433 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_PARALLEL);
2434 bsi_remove (&si, true);
2437 remove_edge (entry_succ_e);
2440 exit_succ_e = single_succ_edge (exit_bb);
2441 make_edge (new_bb, exit_succ_e->dest, EDGE_FALLTHRU);
2443 do_cleanup_cfg = true;
2447 /* If the parallel region needs data sent from the parent
2448 function, then the very first statement (except possible
2449 tree profile counter updates) of the parallel body
2450 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
2451 &.OMP_DATA_O is passed as an argument to the child function,
2452 we need to replace it with the argument as seen by the child
2455 In most cases, this will end up being the identity assignment
2456 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
2457 a function call that has been inlined, the original PARM_DECL
2458 .OMP_DATA_I may have been converted into a different local
2459 variable. In which case, we need to keep the assignment. */
2460 if (OMP_PARALLEL_DATA_ARG (entry_stmt))
2462 basic_block entry_succ_bb = single_succ (entry_bb);
2463 block_stmt_iterator si;
2465 for (si = bsi_start (entry_succ_bb); ; bsi_next (&si))
2469 gcc_assert (!bsi_end_p (si));
2470 stmt = bsi_stmt (si);
2471 if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
2474 arg = GIMPLE_STMT_OPERAND (stmt, 1);
2476 if (TREE_CODE (arg) == ADDR_EXPR
2477 && TREE_OPERAND (arg, 0)
2478 == OMP_PARALLEL_DATA_ARG (entry_stmt))
2480 if (GIMPLE_STMT_OPERAND (stmt, 0)
2481 == DECL_ARGUMENTS (child_fn))
2482 bsi_remove (&si, true);
2484 GIMPLE_STMT_OPERAND (stmt, 1) = DECL_ARGUMENTS (child_fn);
2490 /* Declare local variables needed in CHILD_CFUN. */
2491 block = DECL_INITIAL (child_fn);
2492 BLOCK_VARS (block) = list2chain (child_cfun->unexpanded_var_list);
2493 DECL_SAVED_TREE (child_fn) = bb_stmt_list (single_succ (entry_bb));
2495 /* Reset DECL_CONTEXT on locals and function arguments. */
2496 for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
2497 DECL_CONTEXT (t) = child_fn;
2499 for (t = DECL_ARGUMENTS (child_fn); t; t = TREE_CHAIN (t))
2500 DECL_CONTEXT (t) = child_fn;
2502 /* Split ENTRY_BB at OMP_PARALLEL so that it can be moved to the
2504 si = bsi_last (entry_bb);
2506 gcc_assert (t && TREE_CODE (t) == OMP_PARALLEL);
2507 bsi_remove (&si, true);
2508 e = split_block (entry_bb, t);
2510 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
2512 /* Move the parallel region into CHILD_CFUN. We need to reset
2513 dominance information because the expansion of the inner
2514 regions has invalidated it. */
2515 free_dominance_info (CDI_DOMINATORS);
2516 new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb);
2518 single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
2519 DECL_STRUCT_FUNCTION (child_fn)->curr_properties
2520 = cfun->curr_properties;
2521 cgraph_add_new_function (child_fn, true);
2523 /* Convert OMP_RETURN into a RETURN_EXPR. */
2526 si = bsi_last (exit_bb);
2527 gcc_assert (!bsi_end_p (si)
2528 && TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
2529 t = build1 (RETURN_EXPR, void_type_node, NULL);
2530 bsi_insert_after (&si, t, BSI_SAME_STMT);
2531 bsi_remove (&si, true);
2535 /* Emit a library call to launch the children threads. */
2536 expand_parallel_call (region, new_bb, entry_stmt, ws_args);
2540 /* Clean up the unreachable sub-graph we created above. */
2541 free_dominance_info (CDI_DOMINATORS);
2542 free_dominance_info (CDI_POST_DOMINATORS);
2543 cleanup_tree_cfg ();
2548 /* A subroutine of expand_omp_for. Generate code for a parallel
2549 loop with any schedule. Given parameters:
2551 for (V = N1; V cond N2; V += STEP) BODY;
2553 where COND is "<" or ">", we generate pseudocode
2555 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
2556 if (more) goto L0; else goto L3;
2563 if (V cond iend) goto L1; else goto L2;
2565 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
2568 If this is a combined omp parallel loop, instead of the call to
2569 GOMP_loop_foo_start, we emit 'goto L3'. */
2572 expand_omp_for_generic (struct omp_region *region,
2573 struct omp_for_data *fd,
2574 enum built_in_function start_fn,
2575 enum built_in_function next_fn)
2577 tree type, istart0, iend0, iend;
2579 basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb;
2580 basic_block l2_bb = NULL, l3_bb = NULL;
2581 block_stmt_iterator si;
2582 bool in_combined_parallel = is_combined_parallel (region);
2584 type = TREE_TYPE (fd->v);
2586 istart0 = create_tmp_var (long_integer_type_node, ".istart0");
2587 iend0 = create_tmp_var (long_integer_type_node, ".iend0");
2588 iend = create_tmp_var (type, NULL);
2589 TREE_ADDRESSABLE (istart0) = 1;
2590 TREE_ADDRESSABLE (iend0) = 1;
2592 gcc_assert ((region->cont != NULL) ^ (region->exit == NULL));
2594 entry_bb = region->entry;
2595 l0_bb = create_empty_bb (entry_bb);
2596 l1_bb = single_succ (entry_bb);
2598 cont_bb = region->cont;
2599 exit_bb = region->exit;
2602 l2_bb = create_empty_bb (cont_bb);
2603 l3_bb = single_succ (cont_bb);
2606 si = bsi_last (entry_bb);
2607 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2608 if (!in_combined_parallel)
2610 tree t0, t1, t2, t3, t4;
2611 /* If this is not a combined parallel loop, emit a call to
2612 GOMP_loop_foo_start in ENTRY_BB. */
2613 list = alloc_stmt_list ();
2614 t4 = build_fold_addr_expr (iend0);
2615 t3 = build_fold_addr_expr (istart0);
2616 t2 = fold_convert (long_integer_type_node, fd->step);
2617 t1 = fold_convert (long_integer_type_node, fd->n2);
2618 t0 = fold_convert (long_integer_type_node, fd->n1);
2621 t = fold_convert (long_integer_type_node, fd->chunk_size);
2622 t = build_call_expr (built_in_decls[start_fn], 6,
2623 t0, t1, t2, t, t3, t4);
2626 t = build_call_expr (built_in_decls[start_fn], 5,
2627 t0, t1, t2, t3, t4);
2628 t = get_formal_tmp_var (t, &list);
2631 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2632 append_to_statement_list (t, &list);
2634 bsi_insert_after (&si, list, BSI_SAME_STMT);
2636 bsi_remove (&si, true);
2638 /* Iteration setup for sequential loop goes in L0_BB. */
2639 list = alloc_stmt_list ();
2640 t = fold_convert (type, istart0);
2641 t = build_gimple_modify_stmt (fd->v, t);
2642 gimplify_and_add (t, &list);
2644 t = fold_convert (type, iend0);
2645 t = build_gimple_modify_stmt (iend, t);
2646 gimplify_and_add (t, &list);
2648 si = bsi_start (l0_bb);
2649 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2651 /* Handle the rare case where BODY doesn't ever return. */
2652 if (cont_bb == NULL)
2654 remove_edge (single_succ_edge (entry_bb));
2655 make_edge (entry_bb, l0_bb, EDGE_FALLTHRU);
2656 make_edge (l0_bb, l1_bb, EDGE_FALLTHRU);
2660 /* Code to control the increment and predicate for the sequential
2661 loop goes in the first half of EXIT_BB (we split EXIT_BB so
2662 that we can inherit all the edges going out of the loop
2664 list = alloc_stmt_list ();
2666 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
2667 t = build_gimple_modify_stmt (fd->v, t);
2668 gimplify_and_add (t, &list);
2670 t = build2 (fd->cond_code, boolean_type_node, fd->v, iend);
2671 t = get_formal_tmp_var (t, &list);
2672 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2673 append_to_statement_list (t, &list);
2675 si = bsi_last (cont_bb);
2676 bsi_insert_after (&si, list, BSI_SAME_STMT);
2677 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
2678 bsi_remove (&si, true);
2680 /* Emit code to get the next parallel iteration in L2_BB. */
2681 list = alloc_stmt_list ();
2683 t = build_call_expr (built_in_decls[next_fn], 2,
2684 build_fold_addr_expr (istart0),
2685 build_fold_addr_expr (iend0));
2686 t = get_formal_tmp_var (t, &list);
2687 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2688 append_to_statement_list (t, &list);
2690 si = bsi_start (l2_bb);
2691 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2693 /* Add the loop cleanup function. */
2694 si = bsi_last (exit_bb);
2695 if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
2696 t = built_in_decls[BUILT_IN_GOMP_LOOP_END_NOWAIT];
2698 t = built_in_decls[BUILT_IN_GOMP_LOOP_END];
2699 t = build_call_expr (t, 0);
2700 bsi_insert_after (&si, t, BSI_SAME_STMT);
2701 bsi_remove (&si, true);
2703 /* Connect the new blocks. */
2704 remove_edge (single_succ_edge (entry_bb));
2705 if (in_combined_parallel)
2706 make_edge (entry_bb, l2_bb, EDGE_FALLTHRU);
2709 make_edge (entry_bb, l0_bb, EDGE_TRUE_VALUE);
2710 make_edge (entry_bb, l3_bb, EDGE_FALSE_VALUE);
2713 make_edge (l0_bb, l1_bb, EDGE_FALLTHRU);
2715 remove_edge (single_succ_edge (cont_bb));
2716 make_edge (cont_bb, l1_bb, EDGE_TRUE_VALUE);
2717 make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
2719 make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
2720 make_edge (l2_bb, l3_bb, EDGE_FALSE_VALUE);
2724 /* A subroutine of expand_omp_for. Generate code for a parallel
2725 loop with static schedule and no specified chunk size. Given
2728 for (V = N1; V cond N2; V += STEP) BODY;
2730 where COND is "<" or ">", we generate pseudocode
2736 n = (adj + N2 - N1) / STEP;
2738 q += (q * nthreads != n);
2740 e0 = min(s0 + q, n);
2741 if (s0 >= e0) goto L2; else goto L0;
2748 if (V cond e) goto L1;
2753 expand_omp_for_static_nochunk (struct omp_region *region,
2754 struct omp_for_data *fd)
2756 tree n, q, s0, e0, e, t, nthreads, threadid;
2758 basic_block entry_bb, exit_bb, seq_start_bb, body_bb, cont_bb;
2760 block_stmt_iterator si;
2762 type = TREE_TYPE (fd->v);
2764 entry_bb = region->entry;
2765 seq_start_bb = create_empty_bb (entry_bb);
2766 body_bb = single_succ (entry_bb);
2767 cont_bb = region->cont;
2768 fin_bb = single_succ (cont_bb);
2769 exit_bb = region->exit;
2771 /* Iteration space partitioning goes in ENTRY_BB. */
2772 list = alloc_stmt_list ();
2774 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
2775 t = fold_convert (type, t);
2776 nthreads = get_formal_tmp_var (t, &list);
2778 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2779 t = fold_convert (type, t);
2780 threadid = get_formal_tmp_var (t, &list);
2782 fd->n1 = fold_convert (type, fd->n1);
2783 if (!is_gimple_val (fd->n1))
2784 fd->n1 = get_formal_tmp_var (fd->n1, &list);
2786 fd->n2 = fold_convert (type, fd->n2);
2787 if (!is_gimple_val (fd->n2))
2788 fd->n2 = get_formal_tmp_var (fd->n2, &list);
2790 fd->step = fold_convert (type, fd->step);
2791 if (!is_gimple_val (fd->step))
2792 fd->step = get_formal_tmp_var (fd->step, &list);
2794 t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2795 t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2796 t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2797 t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2798 t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2799 t = fold_convert (type, t);
2800 if (is_gimple_val (t))
2803 n = get_formal_tmp_var (t, &list);
2805 t = build2 (TRUNC_DIV_EXPR, type, n, nthreads);
2806 q = get_formal_tmp_var (t, &list);
2808 t = build2 (MULT_EXPR, type, q, nthreads);
2809 t = build2 (NE_EXPR, type, t, n);
2810 t = build2 (PLUS_EXPR, type, q, t);
2811 q = get_formal_tmp_var (t, &list);
2813 t = build2 (MULT_EXPR, type, q, threadid);
2814 s0 = get_formal_tmp_var (t, &list);
2816 t = build2 (PLUS_EXPR, type, s0, q);
2817 t = build2 (MIN_EXPR, type, t, n);
2818 e0 = get_formal_tmp_var (t, &list);
2820 t = build2 (GE_EXPR, boolean_type_node, s0, e0);
2821 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2822 append_to_statement_list (t, &list);
2824 si = bsi_last (entry_bb);
2825 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2826 bsi_insert_after (&si, list, BSI_SAME_STMT);
2827 bsi_remove (&si, true);
2829 /* Setup code for sequential iteration goes in SEQ_START_BB. */
2830 list = alloc_stmt_list ();
2832 t = fold_convert (type, s0);
2833 t = build2 (MULT_EXPR, type, t, fd->step);
2834 t = build2 (PLUS_EXPR, type, t, fd->n1);
2835 t = build_gimple_modify_stmt (fd->v, t);
2836 gimplify_and_add (t, &list);
2838 t = fold_convert (type, e0);
2839 t = build2 (MULT_EXPR, type, t, fd->step);
2840 t = build2 (PLUS_EXPR, type, t, fd->n1);
2841 e = get_formal_tmp_var (t, &list);
2843 si = bsi_start (seq_start_bb);
2844 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
2846 /* The code controlling the sequential loop replaces the OMP_CONTINUE. */
2847 list = alloc_stmt_list ();
2849 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
2850 t = build_gimple_modify_stmt (fd->v, t);
2851 gimplify_and_add (t, &list);
2853 t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
2854 t = get_formal_tmp_var (t, &list);
2855 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2856 append_to_statement_list (t, &list);
2858 si = bsi_last (cont_bb);
2859 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
2860 bsi_insert_after (&si, list, BSI_SAME_STMT);
2861 bsi_remove (&si, true);
2863 /* Replace the OMP_RETURN with a barrier, or nothing. */
2864 si = bsi_last (exit_bb);
2865 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
2867 list = alloc_stmt_list ();
2868 build_omp_barrier (&list);
2869 bsi_insert_after (&si, list, BSI_SAME_STMT);
2871 bsi_remove (&si, true);
2873 /* Connect all the blocks. */
2874 make_edge (seq_start_bb, body_bb, EDGE_FALLTHRU);
2876 remove_edge (single_succ_edge (entry_bb));
2877 make_edge (entry_bb, fin_bb, EDGE_TRUE_VALUE);
2878 make_edge (entry_bb, seq_start_bb, EDGE_FALSE_VALUE);
2880 make_edge (cont_bb, body_bb, EDGE_TRUE_VALUE);
2881 find_edge (cont_bb, fin_bb)->flags = EDGE_FALSE_VALUE;
2885 /* A subroutine of expand_omp_for. Generate code for a parallel
2886 loop with static schedule and a specified chunk size. Given
2889 for (V = N1; V cond N2; V += STEP) BODY;
2891 where COND is "<" or ">", we generate pseudocode
2897 n = (adj + N2 - N1) / STEP;
2900 s0 = (trip * nthreads + threadid) * CHUNK;
2901 e0 = min(s0 + CHUNK, n);
2902 if (s0 < n) goto L1; else goto L4;
2909 if (V cond e) goto L2; else goto L3;
2917 expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
2919 tree n, s0, e0, e, t;
2920 tree trip, nthreads, threadid;
2922 basic_block entry_bb, exit_bb, body_bb, seq_start_bb, iter_part_bb;
2923 basic_block trip_update_bb, cont_bb, fin_bb;
2925 block_stmt_iterator si;
2927 type = TREE_TYPE (fd->v);
2929 entry_bb = region->entry;
2930 iter_part_bb = create_empty_bb (entry_bb);
2931 seq_start_bb = create_empty_bb (iter_part_bb);
2932 body_bb = single_succ (entry_bb);
2933 cont_bb = region->cont;
2934 trip_update_bb = create_empty_bb (cont_bb);
2935 fin_bb = single_succ (cont_bb);
2936 exit_bb = region->exit;
2938 /* Trip and adjustment setup goes in ENTRY_BB. */
2939 list = alloc_stmt_list ();
2941 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_NUM_THREADS], 0);
2942 t = fold_convert (type, t);
2943 nthreads = get_formal_tmp_var (t, &list);
2945 t = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
2946 t = fold_convert (type, t);
2947 threadid = get_formal_tmp_var (t, &list);
2949 fd->n1 = fold_convert (type, fd->n1);
2950 if (!is_gimple_val (fd->n1))
2951 fd->n1 = get_formal_tmp_var (fd->n1, &list);
2953 fd->n2 = fold_convert (type, fd->n2);
2954 if (!is_gimple_val (fd->n2))
2955 fd->n2 = get_formal_tmp_var (fd->n2, &list);
2957 fd->step = fold_convert (type, fd->step);
2958 if (!is_gimple_val (fd->step))
2959 fd->step = get_formal_tmp_var (fd->step, &list);
2961 fd->chunk_size = fold_convert (type, fd->chunk_size);
2962 if (!is_gimple_val (fd->chunk_size))
2963 fd->chunk_size = get_formal_tmp_var (fd->chunk_size, &list);
2965 t = build_int_cst (type, (fd->cond_code == LT_EXPR ? -1 : 1));
2966 t = fold_build2 (PLUS_EXPR, type, fd->step, t);
2967 t = fold_build2 (PLUS_EXPR, type, t, fd->n2);
2968 t = fold_build2 (MINUS_EXPR, type, t, fd->n1);
2969 t = fold_build2 (TRUNC_DIV_EXPR, type, t, fd->step);
2970 t = fold_convert (type, t);
2971 if (is_gimple_val (t))
2974 n = get_formal_tmp_var (t, &list);
2976 t = build_int_cst (type, 0);
2977 trip = get_initialized_tmp_var (t, &list, NULL);
2979 si = bsi_last (entry_bb);
2980 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_FOR);
2981 bsi_insert_after (&si, list, BSI_SAME_STMT);
2982 bsi_remove (&si, true);
2984 /* Iteration space partitioning goes in ITER_PART_BB. */
2985 list = alloc_stmt_list ();
2987 t = build2 (MULT_EXPR, type, trip, nthreads);
2988 t = build2 (PLUS_EXPR, type, t, threadid);
2989 t = build2 (MULT_EXPR, type, t, fd->chunk_size);
2990 s0 = get_formal_tmp_var (t, &list);
2992 t = build2 (PLUS_EXPR, type, s0, fd->chunk_size);
2993 t = build2 (MIN_EXPR, type, t, n);
2994 e0 = get_formal_tmp_var (t, &list);
2996 t = build2 (LT_EXPR, boolean_type_node, s0, n);
2997 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
2998 append_to_statement_list (t, &list);
3000 si = bsi_start (iter_part_bb);
3001 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3003 /* Setup code for sequential iteration goes in SEQ_START_BB. */
3004 list = alloc_stmt_list ();
3006 t = fold_convert (type, s0);
3007 t = build2 (MULT_EXPR, type, t, fd->step);
3008 t = build2 (PLUS_EXPR, type, t, fd->n1);
3009 t = build_gimple_modify_stmt (fd->v, t);
3010 gimplify_and_add (t, &list);
3012 t = fold_convert (type, e0);
3013 t = build2 (MULT_EXPR, type, t, fd->step);
3014 t = build2 (PLUS_EXPR, type, t, fd->n1);
3015 e = get_formal_tmp_var (t, &list);
3017 si = bsi_start (seq_start_bb);
3018 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3020 /* The code controlling the sequential loop goes in CONT_BB,
3021 replacing the OMP_CONTINUE. */
3022 list = alloc_stmt_list ();
3024 t = build2 (PLUS_EXPR, type, fd->v, fd->step);
3025 t = build_gimple_modify_stmt (fd->v, t);
3026 gimplify_and_add (t, &list);
3028 t = build2 (fd->cond_code, boolean_type_node, fd->v, e);
3029 t = get_formal_tmp_var (t, &list);
3030 t = build3 (COND_EXPR, void_type_node, t, NULL_TREE, NULL_TREE);
3031 append_to_statement_list (t, &list);
3033 si = bsi_last (cont_bb);
3034 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3035 bsi_insert_after (&si, list, BSI_SAME_STMT);
3036 bsi_remove (&si, true);
3038 /* Trip update code goes into TRIP_UPDATE_BB. */
3039 list = alloc_stmt_list ();
3041 t = build_int_cst (type, 1);
3042 t = build2 (PLUS_EXPR, type, trip, t);
3043 t = build_gimple_modify_stmt (trip, t);
3044 gimplify_and_add (t, &list);
3046 si = bsi_start (trip_update_bb);
3047 bsi_insert_after (&si, list, BSI_CONTINUE_LINKING);
3049 /* Replace the OMP_RETURN with a barrier, or nothing. */
3050 si = bsi_last (exit_bb);
3051 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)))
3053 list = alloc_stmt_list ();
3054 build_omp_barrier (&list);
3055 bsi_insert_after (&si, list, BSI_SAME_STMT);
3057 bsi_remove (&si, true);
3059 /* Connect the new blocks. */
3060 remove_edge (single_succ_edge (entry_bb));
3061 make_edge (entry_bb, iter_part_bb, EDGE_FALLTHRU);
3063 make_edge (iter_part_bb, seq_start_bb, EDGE_TRUE_VALUE);
3064 make_edge (iter_part_bb, fin_bb, EDGE_FALSE_VALUE);
3066 make_edge (seq_start_bb, body_bb, EDGE_FALLTHRU);
3068 remove_edge (single_succ_edge (cont_bb));
3069 make_edge (cont_bb, body_bb, EDGE_TRUE_VALUE);
3070 make_edge (cont_bb, trip_update_bb, EDGE_FALSE_VALUE);
3072 make_edge (trip_update_bb, iter_part_bb, EDGE_FALLTHRU);
3076 /* Expand the OpenMP loop defined by REGION. */
3079 expand_omp_for (struct omp_region *region)
3081 struct omp_for_data fd;
3083 push_gimplify_context ();
3085 extract_omp_for_data (last_stmt (region->entry), &fd);
3086 region->sched_kind = fd.sched_kind;
3088 if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
3093 if (fd.chunk_size == NULL)
3094 expand_omp_for_static_nochunk (region, &fd);
3096 expand_omp_for_static_chunk (region, &fd);
3100 int fn_index = fd.sched_kind + fd.have_ordered * 4;
3101 int start_ix = BUILT_IN_GOMP_LOOP_STATIC_START + fn_index;
3102 int next_ix = BUILT_IN_GOMP_LOOP_STATIC_NEXT + fn_index;
3103 expand_omp_for_generic (region, &fd, start_ix, next_ix);
3106 pop_gimplify_context (NULL);
3110 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
3112 v = GOMP_sections_start (n);
3129 v = GOMP_sections_next ();
3134 If this is a combined parallel sections, replace the call to
3135 GOMP_sections_start with 'goto L1'. */
3138 expand_omp_sections (struct omp_region *region)
3140 tree label_vec, l0, l1, l2, t, u, v, sections_stmt;
3142 basic_block entry_bb, exit_bb, l0_bb, l1_bb, l2_bb, default_bb;
3143 block_stmt_iterator si;
3144 struct omp_region *inner;
3147 entry_bb = region->entry;
3148 l0_bb = create_empty_bb (entry_bb);
3149 l0 = tree_block_label (l0_bb);
3151 gcc_assert ((region->cont != NULL) ^ (region->exit == NULL));
3152 l1_bb = region->cont;
3155 l2_bb = single_succ (l1_bb);
3156 default_bb = create_empty_bb (l1_bb->prev_bb);
3158 l1 = tree_block_label (l1_bb);
3162 l2_bb = create_empty_bb (l0_bb);
3167 l2 = tree_block_label (l2_bb);
3169 exit_bb = region->exit;
3171 v = create_tmp_var (unsigned_type_node, ".section");
3173 /* We will build a switch() with enough cases for all the
3174 OMP_SECTION regions, a '0' case to handle the end of more work
3175 and a default case to abort if something goes wrong. */
3176 len = EDGE_COUNT (entry_bb->succs);
3177 label_vec = make_tree_vec (len + 2);
3179 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
3180 OMP_SECTIONS statement. */
3181 si = bsi_last (entry_bb);
3182 sections_stmt = bsi_stmt (si);
3183 gcc_assert (TREE_CODE (sections_stmt) == OMP_SECTIONS);
3184 if (!is_combined_parallel (region))
3186 /* If we are not inside a combined parallel+sections region,
3187 call GOMP_sections_start. */
3188 t = build_int_cst (unsigned_type_node, len);
3189 u = built_in_decls[BUILT_IN_GOMP_SECTIONS_START];
3190 t = build_call_expr (u, 1, t);
3191 t = build_gimple_modify_stmt (v, t);
3192 bsi_insert_after (&si, t, BSI_SAME_STMT);
3194 bsi_remove (&si, true);
3196 /* The switch() statement replacing OMP_SECTIONS goes in L0_BB. */
3197 si = bsi_start (l0_bb);
3199 t = build3 (SWITCH_EXPR, void_type_node, v, NULL, label_vec);
3200 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3202 t = build3 (CASE_LABEL_EXPR, void_type_node,
3203 build_int_cst (unsigned_type_node, 0), NULL, l2);
3204 TREE_VEC_ELT (label_vec, 0) = t;
3205 make_edge (l0_bb, l2_bb, 0);
3207 /* Convert each OMP_SECTION into a CASE_LABEL_EXPR. */
3208 for (inner = region->inner, i = 1; inner; inner = inner->next, ++i)
3210 basic_block s_entry_bb, s_exit_bb;
3212 s_entry_bb = inner->entry;
3213 s_exit_bb = inner->exit;
3215 t = tree_block_label (s_entry_bb);
3216 u = build_int_cst (unsigned_type_node, i);
3217 u = build3 (CASE_LABEL_EXPR, void_type_node, u, NULL, t);
3218 TREE_VEC_ELT (label_vec, i) = u;
3220 si = bsi_last (s_entry_bb);
3221 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SECTION);
3222 gcc_assert (i < len || OMP_SECTION_LAST (bsi_stmt (si)));
3223 bsi_remove (&si, true);
3225 e = single_pred_edge (s_entry_bb);
3227 redirect_edge_pred (e, l0_bb);
3229 single_succ_edge (s_entry_bb)->flags = EDGE_FALLTHRU;
3231 if (s_exit_bb == NULL)
3234 si = bsi_last (s_exit_bb);
3235 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3236 bsi_remove (&si, true);
3238 single_succ_edge (s_exit_bb)->flags = EDGE_FALLTHRU;
3241 /* Error handling code goes in DEFAULT_BB. */
3242 t = tree_block_label (default_bb);
3243 u = build3 (CASE_LABEL_EXPR, void_type_node, NULL, NULL, t);
3244 TREE_VEC_ELT (label_vec, len + 1) = u;
3245 make_edge (l0_bb, default_bb, 0);
3247 si = bsi_start (default_bb);
3248 t = build_call_expr (built_in_decls[BUILT_IN_TRAP], 0);
3249 bsi_insert_after (&si, t, BSI_CONTINUE_LINKING);
3251 /* Code to get the next section goes in L1_BB. */
3254 si = bsi_last (l1_bb);
3255 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_CONTINUE);
3257 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SECTIONS_NEXT], 0);
3258 t = build_gimple_modify_stmt (v, t);
3259 bsi_insert_after (&si, t, BSI_SAME_STMT);
3260 bsi_remove (&si, true);
3263 /* Cleanup function replaces OMP_RETURN in EXIT_BB. */
3266 si = bsi_last (exit_bb);
3267 if (OMP_RETURN_NOWAIT (bsi_stmt (si)))
3268 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END_NOWAIT];
3270 t = built_in_decls[BUILT_IN_GOMP_SECTIONS_END];
3271 t = build_call_expr (t, 0);
3272 bsi_insert_after (&si, t, BSI_SAME_STMT);
3273 bsi_remove (&si, true);
3276 /* Connect the new blocks. */
3277 if (is_combined_parallel (region))
3279 /* If this was a combined parallel+sections region, we did not
3280 emit a GOMP_sections_start in the entry block, so we just
3281 need to jump to L1_BB to get the next section. */
3282 make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
3285 make_edge (entry_bb, l0_bb, EDGE_FALLTHRU);
3289 e = single_succ_edge (l1_bb);
3290 redirect_edge_succ (e, l0_bb);
3291 e->flags = EDGE_FALLTHRU;
3296 /* Expand code for an OpenMP single directive. We've already expanded
3297 much of the code, here we simply place the GOMP_barrier call. */
3300 expand_omp_single (struct omp_region *region)
3302 basic_block entry_bb, exit_bb;
3303 block_stmt_iterator si;
3304 bool need_barrier = false;
3306 entry_bb = region->entry;
3307 exit_bb = region->exit;
3309 si = bsi_last (entry_bb);
3310 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
3311 be removed. We need to ensure that the thread that entered the single
3312 does not exit before the data is copied out by the other threads. */
3313 if (find_omp_clause (OMP_SINGLE_CLAUSES (bsi_stmt (si)),
3314 OMP_CLAUSE_COPYPRIVATE))
3315 need_barrier = true;
3316 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE);
3317 bsi_remove (&si, true);
3318 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3320 si = bsi_last (exit_bb);
3321 if (!OMP_RETURN_NOWAIT (bsi_stmt (si)) || need_barrier)
3323 tree t = alloc_stmt_list ();
3324 build_omp_barrier (&t);
3325 bsi_insert_after (&si, t, BSI_SAME_STMT);
3327 bsi_remove (&si, true);
3328 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3332 /* Generic expansion for OpenMP synchronization directives: master,
3333 ordered and critical. All we need to do here is remove the entry
3334 and exit markers for REGION. */
3337 expand_omp_synch (struct omp_region *region)
3339 basic_block entry_bb, exit_bb;
3340 block_stmt_iterator si;
3342 entry_bb = region->entry;
3343 exit_bb = region->exit;
3345 si = bsi_last (entry_bb);
3346 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_SINGLE
3347 || TREE_CODE (bsi_stmt (si)) == OMP_MASTER
3348 || TREE_CODE (bsi_stmt (si)) == OMP_ORDERED
3349 || TREE_CODE (bsi_stmt (si)) == OMP_CRITICAL);
3350 bsi_remove (&si, true);
3351 single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
3355 si = bsi_last (exit_bb);
3356 gcc_assert (TREE_CODE (bsi_stmt (si)) == OMP_RETURN);
3357 bsi_remove (&si, true);
3358 single_succ_edge (exit_bb)->flags = EDGE_FALLTHRU;
3363 /* Expand the parallel region tree rooted at REGION. Expansion
3364 proceeds in depth-first order. Innermost regions are expanded
3365 first. This way, parallel regions that require a new function to
3366 be created (e.g., OMP_PARALLEL) can be expanded without having any
3367 internal dependencies in their body. */
3370 expand_omp (struct omp_region *region)
3375 expand_omp (region->inner);
3377 switch (region->type)
3380 expand_omp_parallel (region);
3384 expand_omp_for (region);
3388 expand_omp_sections (region);
3392 /* Individual omp sections are handled together with their
3393 parent OMP_SECTIONS region. */
3397 expand_omp_single (region);
3403 expand_omp_synch (region);
3410 region = region->next;
3415 /* Helper for build_omp_regions. Scan the dominator tree starting at
3416 block BB. PARENT is the region that contains BB. */
3419 build_omp_regions_1 (basic_block bb, struct omp_region *parent)
3421 block_stmt_iterator si;
3426 if (!bsi_end_p (si) && OMP_DIRECTIVE_P (bsi_stmt (si)))
3428 struct omp_region *region;
3429 enum tree_code code;
3431 stmt = bsi_stmt (si);
3432 code = TREE_CODE (stmt);
3434 if (code == OMP_RETURN)
3436 /* STMT is the return point out of region PARENT. Mark it
3437 as the exit point and make PARENT the immediately
3438 enclosing region. */
3439 gcc_assert (parent);
3442 parent = parent->outer;
3444 /* If REGION is a parallel region, determine whether it is
3445 a combined parallel+workshare region. */
3446 if (region->type == OMP_PARALLEL)
3447 determine_parallel_type (region);
3449 else if (code == OMP_CONTINUE)
3451 gcc_assert (parent);
3456 /* Otherwise, this directive becomes the parent for a new
3458 region = new_omp_region (bb, code, parent);
3463 for (son = first_dom_son (CDI_DOMINATORS, bb);
3465 son = next_dom_son (CDI_DOMINATORS, son))
3466 build_omp_regions_1 (son, parent);
3470 /* Scan the CFG and build a tree of OMP regions. Return the root of
3471 the OMP region tree. */
3474 build_omp_regions (void)
3476 gcc_assert (root_omp_region == NULL);
3477 calculate_dominance_info (CDI_DOMINATORS);
3478 build_omp_regions_1 (ENTRY_BLOCK_PTR, NULL);
3482 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
3485 execute_expand_omp (void)
3487 build_omp_regions ();
3489 if (!root_omp_region)
3494 fprintf (dump_file, "\nOMP region tree\n\n");
3495 dump_omp_region (dump_file, root_omp_region, 0);
3496 fprintf (dump_file, "\n");
3499 remove_exit_barriers (root_omp_region);
3501 expand_omp (root_omp_region);
3503 free_dominance_info (CDI_DOMINATORS);
3504 free_dominance_info (CDI_POST_DOMINATORS);
3505 cleanup_tree_cfg ();
3507 free_omp_regions ();
3513 gate_expand_omp (void)
3515 return flag_openmp != 0 && errorcount == 0;
3518 struct tree_opt_pass pass_expand_omp =
3520 "ompexp", /* name */
3521 gate_expand_omp, /* gate */
3522 execute_expand_omp, /* execute */
3525 0, /* static_pass_number */
3527 PROP_gimple_any, /* properties_required */
3528 PROP_gimple_lomp, /* properties_provided */
3529 0, /* properties_destroyed */
3530 0, /* todo_flags_start */
3531 TODO_dump_func, /* todo_flags_finish */
3535 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
3537 /* Lower the OpenMP sections directive in *STMT_P. */
3540 lower_omp_sections (tree *stmt_p, omp_context *ctx)
3542 tree new_stmt, stmt, body, bind, block, ilist, olist, new_body;
3544 tree_stmt_iterator tsi;
3549 push_gimplify_context ();
3553 lower_rec_input_clauses (OMP_SECTIONS_CLAUSES (stmt), &ilist, &dlist, ctx);
3555 tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3556 for (len = 0; !tsi_end_p (tsi); len++, tsi_next (&tsi))
3559 tsi = tsi_start (OMP_SECTIONS_BODY (stmt));
3560 body = alloc_stmt_list ();
3561 for (i = 0; i < len; i++, tsi_next (&tsi))
3564 tree sec_start, sec_end;
3566 sec_start = tsi_stmt (tsi);
3567 sctx = maybe_lookup_ctx (sec_start);
3570 append_to_statement_list (sec_start, &body);
3572 lower_omp (&OMP_SECTION_BODY (sec_start), sctx);
3573 append_to_statement_list (OMP_SECTION_BODY (sec_start), &body);
3574 OMP_SECTION_BODY (sec_start) = NULL;
3578 tree l = alloc_stmt_list ();
3579 lower_lastprivate_clauses (OMP_SECTIONS_CLAUSES (stmt), NULL,
3581 append_to_statement_list (l, &body);
3582 OMP_SECTION_LAST (sec_start) = 1;
3585 sec_end = make_node (OMP_RETURN);
3586 append_to_statement_list (sec_end, &body);
3589 block = make_node (BLOCK);
3590 bind = build3 (BIND_EXPR, void_type_node, NULL, body, block);
3593 lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt), &olist, ctx);
3595 pop_gimplify_context (NULL_TREE);
3596 record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
3598 new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
3599 TREE_SIDE_EFFECTS (new_stmt) = 1;
3601 new_body = alloc_stmt_list ();
3602 append_to_statement_list (ilist, &new_body);
3603 append_to_statement_list (stmt, &new_body);
3604 append_to_statement_list (bind, &new_body);
3606 t = make_node (OMP_CONTINUE);
3607 append_to_statement_list (t, &new_body);
3609 append_to_statement_list (olist, &new_body);
3610 append_to_statement_list (dlist, &new_body);
3612 maybe_catch_exception (&new_body);
3614 t = make_node (OMP_RETURN);
3615 OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SECTIONS_CLAUSES (stmt),
3617 append_to_statement_list (t, &new_body);
3619 BIND_EXPR_BODY (new_stmt) = new_body;
3620 OMP_SECTIONS_BODY (stmt) = NULL;
3626 /* A subroutine of lower_omp_single. Expand the simple form of
3627 an OMP_SINGLE, without a copyprivate clause:
3629 if (GOMP_single_start ())
3631 [ GOMP_barrier (); ] -> unless 'nowait' is present.
3633 FIXME. It may be better to delay expanding the logic of this until
3634 pass_expand_omp. The expanded logic may make the job more difficult
3635 to a synchronization analysis pass. */
3638 lower_omp_single_simple (tree single_stmt, tree *pre_p)
3642 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_START], 0);
3643 t = build3 (COND_EXPR, void_type_node, t,
3644 OMP_SINGLE_BODY (single_stmt), NULL);
3645 gimplify_and_add (t, pre_p);
3649 /* A subroutine of lower_omp_single. Expand the simple form of
3650 an OMP_SINGLE, with a copyprivate clause:
3652 #pragma omp single copyprivate (a, b, c)
3654 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
3657 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
3663 GOMP_single_copy_end (©out);
3674 FIXME. It may be better to delay expanding the logic of this until
3675 pass_expand_omp. The expanded logic may make the job more difficult
3676 to a synchronization analysis pass. */
3679 lower_omp_single_copy (tree single_stmt, tree *pre_p, omp_context *ctx)
3681 tree ptr_type, t, l0, l1, l2, copyin_seq;
3683 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_copy_o");
3685 ptr_type = build_pointer_type (ctx->record_type);
3686 ctx->receiver_decl = create_tmp_var (ptr_type, ".omp_copy_i");
3688 l0 = create_artificial_label ();
3689 l1 = create_artificial_label ();
3690 l2 = create_artificial_label ();
3692 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_START], 0);
3693 t = fold_convert (ptr_type, t);
3694 t = build_gimple_modify_stmt (ctx->receiver_decl, t);
3695 gimplify_and_add (t, pre_p);
3697 t = build2 (EQ_EXPR, boolean_type_node, ctx->receiver_decl,
3698 build_int_cst (ptr_type, 0));
3699 t = build3 (COND_EXPR, void_type_node, t,
3700 build_and_jump (&l0), build_and_jump (&l1));
3701 gimplify_and_add (t, pre_p);
3703 t = build1 (LABEL_EXPR, void_type_node, l0);
3704 gimplify_and_add (t, pre_p);
3706 append_to_statement_list (OMP_SINGLE_BODY (single_stmt), pre_p);
3709 lower_copyprivate_clauses (OMP_SINGLE_CLAUSES (single_stmt), pre_p,
3712 t = build_fold_addr_expr (ctx->sender_decl);
3713 t = build_call_expr (built_in_decls[BUILT_IN_GOMP_SINGLE_COPY_END], 1, t);
3714 gimplify_and_add (t, pre_p);
3716 t = build_and_jump (&l2);
3717 gimplify_and_add (t, pre_p);
3719 t = build1 (LABEL_EXPR, void_type_node, l1);
3720 gimplify_and_add (t, pre_p);
3722 append_to_statement_list (copyin_seq, pre_p);
3724 t = build1 (LABEL_EXPR, void_type_node, l2);
3725 gimplify_and_add (t, pre_p);
3729 /* Expand code for an OpenMP single directive. */
3732 lower_omp_single (tree *stmt_p, omp_context *ctx)
3734 tree t, bind, block, single_stmt = *stmt_p, dlist;
3736 push_gimplify_context ();
3738 block = make_node (BLOCK);
3739 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3740 TREE_SIDE_EFFECTS (bind) = 1;
3742 lower_rec_input_clauses (OMP_SINGLE_CLAUSES (single_stmt),
3743 &BIND_EXPR_BODY (bind), &dlist, ctx);
3744 lower_omp (&OMP_SINGLE_BODY (single_stmt), ctx);
3746 append_to_statement_list (single_stmt, &BIND_EXPR_BODY (bind));
3748 if (ctx->record_type)
3749 lower_omp_single_copy (single_stmt, &BIND_EXPR_BODY (bind), ctx);
3751 lower_omp_single_simple (single_stmt, &BIND_EXPR_BODY (bind));
3753 OMP_SINGLE_BODY (single_stmt) = NULL;
3755 append_to_statement_list (dlist, &BIND_EXPR_BODY (bind));
3757 maybe_catch_exception (&BIND_EXPR_BODY (bind));
3759 t = make_node (OMP_RETURN);
3760 OMP_RETURN_NOWAIT (t) = !!find_omp_clause (OMP_SINGLE_CLAUSES (single_stmt),
3762 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3764 pop_gimplify_context (bind);
3766 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3767 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3771 /* Expand code for an OpenMP master directive. */
3774 lower_omp_master (tree *stmt_p, omp_context *ctx)
3776 tree bind, block, stmt = *stmt_p, lab = NULL, x;
3778 push_gimplify_context ();
3780 block = make_node (BLOCK);
3781 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3782 TREE_SIDE_EFFECTS (bind) = 1;
3784 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3786 x = build_call_expr (built_in_decls[BUILT_IN_OMP_GET_THREAD_NUM], 0);
3787 x = build2 (EQ_EXPR, boolean_type_node, x, integer_zero_node);
3788 x = build3 (COND_EXPR, void_type_node, x, NULL, build_and_jump (&lab));
3789 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3791 lower_omp (&OMP_MASTER_BODY (stmt), ctx);
3792 maybe_catch_exception (&OMP_MASTER_BODY (stmt));
3793 append_to_statement_list (OMP_MASTER_BODY (stmt), &BIND_EXPR_BODY (bind));
3794 OMP_MASTER_BODY (stmt) = NULL;
3796 x = build1 (LABEL_EXPR, void_type_node, lab);
3797 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3799 x = make_node (OMP_RETURN);
3800 OMP_RETURN_NOWAIT (x) = 1;
3801 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
3803 pop_gimplify_context (bind);
3805 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3806 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3810 /* Expand code for an OpenMP ordered directive. */
3813 lower_omp_ordered (tree *stmt_p, omp_context *ctx)
3815 tree bind, block, stmt = *stmt_p, x;
3817 push_gimplify_context ();
3819 block = make_node (BLOCK);
3820 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3821 TREE_SIDE_EFFECTS (bind) = 1;
3823 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3825 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_START], 0);
3826 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3828 lower_omp (&OMP_ORDERED_BODY (stmt), ctx);
3829 maybe_catch_exception (&OMP_ORDERED_BODY (stmt));
3830 append_to_statement_list (OMP_ORDERED_BODY (stmt), &BIND_EXPR_BODY (bind));
3831 OMP_ORDERED_BODY (stmt) = NULL;
3833 x = build_call_expr (built_in_decls[BUILT_IN_GOMP_ORDERED_END], 0);
3834 gimplify_and_add (x, &BIND_EXPR_BODY (bind));
3836 x = make_node (OMP_RETURN);
3837 OMP_RETURN_NOWAIT (x) = 1;
3838 append_to_statement_list (x, &BIND_EXPR_BODY (bind));
3840 pop_gimplify_context (bind);
3842 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3843 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3847 /* Gimplify an OMP_CRITICAL statement. This is a relatively simple
3848 substitution of a couple of function calls. But in the NAMED case,
3849 requires that languages coordinate a symbol name. It is therefore
3850 best put here in common code. */
3852 static GTY((param1_is (tree), param2_is (tree)))
3853 splay_tree critical_name_mutexes;
3856 lower_omp_critical (tree *stmt_p, omp_context *ctx)
3858 tree bind, block, stmt = *stmt_p;
3859 tree t, lock, unlock, name;
3861 name = OMP_CRITICAL_NAME (stmt);
3867 if (!critical_name_mutexes)
3868 critical_name_mutexes
3869 = splay_tree_new_ggc (splay_tree_compare_pointers);
3871 n = splay_tree_lookup (critical_name_mutexes, (splay_tree_key) name);
3876 decl = create_tmp_var_raw (ptr_type_node, NULL);
3878 new_str = ACONCAT ((".gomp_critical_user_",
3879 IDENTIFIER_POINTER (name), NULL));
3880 DECL_NAME (decl) = get_identifier (new_str);
3881 TREE_PUBLIC (decl) = 1;
3882 TREE_STATIC (decl) = 1;
3883 DECL_COMMON (decl) = 1;
3884 DECL_ARTIFICIAL (decl) = 1;
3885 DECL_IGNORED_P (decl) = 1;
3886 varpool_finalize_decl (decl);
3888 splay_tree_insert (critical_name_mutexes, (splay_tree_key) name,
3889 (splay_tree_value) decl);
3892 decl = (tree) n->value;
3894 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_START];
3895 lock = build_call_expr (lock, 1, build_fold_addr_expr (decl));
3897 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_NAME_END];
3898 unlock = build_call_expr (unlock, 1, build_fold_addr_expr (decl));
3902 lock = built_in_decls[BUILT_IN_GOMP_CRITICAL_START];
3903 lock = build_call_expr (lock, 0);
3905 unlock = built_in_decls[BUILT_IN_GOMP_CRITICAL_END];
3906 unlock = build_call_expr (unlock, 0);
3909 push_gimplify_context ();
3911 block = make_node (BLOCK);
3912 *stmt_p = bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, block);
3913 TREE_SIDE_EFFECTS (bind) = 1;
3915 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
3917 gimplify_and_add (lock, &BIND_EXPR_BODY (bind));
3919 lower_omp (&OMP_CRITICAL_BODY (stmt), ctx);
3920 maybe_catch_exception (&OMP_CRITICAL_BODY (stmt));
3921 append_to_statement_list (OMP_CRITICAL_BODY (stmt), &BIND_EXPR_BODY (bind));
3922 OMP_CRITICAL_BODY (stmt) = NULL;
3924 gimplify_and_add (unlock, &BIND_EXPR_BODY (bind));
3926 t = make_node (OMP_RETURN);
3927 OMP_RETURN_NOWAIT (t) = 1;
3928 append_to_statement_list (t, &BIND_EXPR_BODY (bind));
3930 pop_gimplify_context (bind);
3931 BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
3932 BLOCK_VARS (block) = BIND_EXPR_VARS (bind);
3936 /* A subroutine of lower_omp_for. Generate code to emit the predicate
3937 for a lastprivate clause. Given a loop control predicate of (V
3938 cond N2), we gate the clause on (!(V cond N2)). The lowered form
3939 is appended to *DLIST, iterator initialization is appended to
3943 lower_omp_for_lastprivate (struct omp_for_data *fd, tree *body_p,
3944 tree *dlist, struct omp_context *ctx)
3946 tree clauses, cond, stmts, vinit, t;
3947 enum tree_code cond_code;
3949 cond_code = fd->cond_code;
3950 cond_code = cond_code == LT_EXPR ? GE_EXPR : LE_EXPR;
3952 /* When possible, use a strict equality expression. This can let VRP
3953 type optimizations deduce the value and remove a copy. */
3954 if (host_integerp (fd->step, 0))
3956 HOST_WIDE_INT step = TREE_INT_CST_LOW (fd->step);
3957 if (step == 1 || step == -1)
3958 cond_code = EQ_EXPR;
3961 cond = build2 (cond_code, boolean_type_node, fd->v, fd->n2);
3963 clauses = OMP_FOR_CLAUSES (fd->for_stmt);
3965 lower_lastprivate_clauses (clauses, cond, &stmts, ctx);
3968 append_to_statement_list (stmts, dlist);
3970 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
3972 if (cond_code == EQ_EXPR
3973 && host_integerp (fd->n2, 0)
3974 && ! integer_zerop (fd->n2))
3975 vinit = build_int_cst (TREE_TYPE (fd->v), 0);
3977 /* Initialize the iterator variable, so that threads that don't execute
3978 any iterations don't execute the lastprivate clauses by accident. */
3979 t = build_gimple_modify_stmt (fd->v, vinit);
3980 gimplify_and_add (t, body_p);
3985 /* Lower code for an OpenMP loop directive. */
3988 lower_omp_for (tree *stmt_p, omp_context *ctx)
3990 tree t, stmt, ilist, dlist, new_stmt, *body_p, *rhs_p;
3991 struct omp_for_data fd;
3995 push_gimplify_context ();
3997 lower_omp (&OMP_FOR_PRE_BODY (stmt), ctx);
3998 lower_omp (&OMP_FOR_BODY (stmt), ctx);
4000 /* Move declaration of temporaries in the loop body before we make
4002 if (TREE_CODE (OMP_FOR_BODY (stmt)) == BIND_EXPR)
4003 record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt)), ctx->cb.dst_fn);
4005 new_stmt = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4006 TREE_SIDE_EFFECTS (new_stmt) = 1;
4007 body_p = &BIND_EXPR_BODY (new_stmt);
4009 /* The pre-body and input clauses go before the lowered OMP_FOR. */
4012 append_to_statement_list (OMP_FOR_PRE_BODY (stmt), body_p);
4013 lower_rec_input_clauses (OMP_FOR_CLAUSES (stmt), body_p, &dlist, ctx);
4015 /* Lower the header expressions. At this point, we can assume that
4016 the header is of the form:
4018 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
4020 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
4021 using the .omp_data_s mapping, if needed. */
4022 rhs_p = &GIMPLE_STMT_OPERAND (OMP_FOR_INIT (stmt), 1);
4023 if (!is_gimple_min_invariant (*rhs_p))
4024 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4026 rhs_p = &TREE_OPERAND (OMP_FOR_COND (stmt), 1);
4027 if (!is_gimple_min_invariant (*rhs_p))
4028 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4030 rhs_p = &TREE_OPERAND (GIMPLE_STMT_OPERAND (OMP_FOR_INCR (stmt), 1), 1);
4031 if (!is_gimple_min_invariant (*rhs_p))
4032 *rhs_p = get_formal_tmp_var (*rhs_p, body_p);
4034 /* Once lowered, extract the bounds and clauses. */
4035 extract_omp_for_data (stmt, &fd);
4037 lower_omp_for_lastprivate (&fd, body_p, &dlist, ctx);
4039 append_to_statement_list (stmt, body_p);
4041 append_to_statement_list (OMP_FOR_BODY (stmt), body_p);
4043 t = make_node (OMP_CONTINUE);
4044 append_to_statement_list (t, body_p);
4046 /* After the loop, add exit clauses. */
4047 lower_reduction_clauses (OMP_FOR_CLAUSES (stmt), body_p, ctx);
4048 append_to_statement_list (dlist, body_p);
4050 maybe_catch_exception (body_p);
4052 /* Region exit marker goes at the end of the loop body. */
4053 t = make_node (OMP_RETURN);
4054 OMP_RETURN_NOWAIT (t) = fd.have_nowait;
4055 append_to_statement_list (t, body_p);
4057 pop_gimplify_context (NULL_TREE);
4058 record_vars_into (ctx->block_vars, ctx->cb.dst_fn);
4060 OMP_FOR_BODY (stmt) = NULL_TREE;
4061 OMP_FOR_PRE_BODY (stmt) = NULL_TREE;
4065 /* Callback for walk_stmts. Check if *TP only contains OMP_FOR
4069 check_combined_parallel (tree *tp, int *walk_subtrees, void *data)
4071 struct walk_stmt_info *wi = data;
4072 int *info = wi->info;
4075 switch (TREE_CODE (*tp))
4079 *info = *info == 0 ? 1 : -1;
4088 /* Lower the OpenMP parallel directive in *STMT_P. CTX holds context
4089 information for the directive. */
4092 lower_omp_parallel (tree *stmt_p, omp_context *ctx)
4094 tree clauses, par_bind, par_body, new_body, bind;
4095 tree olist, ilist, par_olist, par_ilist;
4096 tree stmt, child_fn, t;
4100 clauses = OMP_PARALLEL_CLAUSES (stmt);
4101 par_bind = OMP_PARALLEL_BODY (stmt);
4102 par_body = BIND_EXPR_BODY (par_bind);
4103 child_fn = ctx->cb.dst_fn;
4104 if (!OMP_PARALLEL_COMBINED (stmt))
4106 struct walk_stmt_info wi;
4109 memset (&wi, 0, sizeof (wi));
4110 wi.callback = check_combined_parallel;
4113 walk_stmts (&wi, &par_bind);
4115 OMP_PARALLEL_COMBINED (stmt) = 1;
4118 push_gimplify_context ();
4120 par_olist = NULL_TREE;
4121 par_ilist = NULL_TREE;
4122 lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
4123 lower_omp (&par_body, ctx);
4124 lower_reduction_clauses (clauses, &par_olist, ctx);
4126 /* Declare all the variables created by mapping and the variables
4127 declared in the scope of the parallel body. */
4128 record_vars_into (ctx->block_vars, child_fn);
4129 record_vars_into (BIND_EXPR_VARS (par_bind), child_fn);
4131 if (ctx->record_type)
4133 ctx->sender_decl = create_tmp_var (ctx->record_type, ".omp_data_o");
4134 OMP_PARALLEL_DATA_ARG (stmt) = ctx->sender_decl;
4139 lower_send_clauses (clauses, &ilist, &olist, ctx);
4140 lower_send_shared_vars (&ilist, &olist, ctx);
4142 /* Once all the expansions are done, sequence all the different
4143 fragments inside OMP_PARALLEL_BODY. */
4144 bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL);
4145 append_to_statement_list (ilist, &BIND_EXPR_BODY (bind));
4147 new_body = alloc_stmt_list ();
4149 if (ctx->record_type)
4151 t = build_fold_addr_expr (ctx->sender_decl);
4152 /* fixup_child_record_type might have changed receiver_decl's type. */
4153 t = fold_convert (TREE_TYPE (ctx->receiver_decl), t);
4154 t = build_gimple_modify_stmt (ctx->receiver_decl, t);
4155 append_to_statement_list (t, &new_body);
4158 append_to_statement_list (par_ilist, &new_body);
4159 append_to_statement_list (par_body, &new_body);
4160 append_to_statement_list (par_olist, &new_body);
4161 maybe_catch_exception (&new_body);
4162 t = make_node (OMP_RETURN);
4163 append_to_statement_list (t, &new_body);
4164 OMP_PARALLEL_BODY (stmt) = new_body;
4166 append_to_statement_list (stmt, &BIND_EXPR_BODY (bind));
4167 append_to_statement_list (olist, &BIND_EXPR_BODY (bind));
4171 pop_gimplify_context (NULL_TREE);
4175 /* Pass *TP back through the gimplifier within the context determined by WI.
4176 This handles replacement of DECL_VALUE_EXPR, as well as adjusting the
4177 flags on ADDR_EXPR. */
4180 lower_regimplify (tree *tp, struct walk_stmt_info *wi)
4182 enum gimplify_status gs;
4186 gs = gimplify_expr (tp, &pre, NULL, is_gimple_lvalue, fb_lvalue);
4187 else if (wi->val_only)
4188 gs = gimplify_expr (tp, &pre, NULL, is_gimple_val, fb_rvalue);
4190 gs = gimplify_expr (tp, &pre, NULL, is_gimple_formal_tmp_var, fb_rvalue);
4191 gcc_assert (gs == GS_ALL_DONE);
4194 tsi_link_before (&wi->tsi, pre, TSI_SAME_STMT);
4197 /* Copy EXP into a temporary. Insert the initialization statement before TSI. */
4200 init_tmp_var (tree exp, tree_stmt_iterator *tsi)
4204 t = create_tmp_var (TREE_TYPE (exp), NULL);
4205 DECL_GIMPLE_REG_P (t) = 1;
4206 stmt = build_gimple_modify_stmt (t, exp);
4207 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4208 tsi_link_before (tsi, stmt, TSI_SAME_STMT);
4213 /* Similarly, but copy from the temporary and insert the statement
4214 after the iterator. */
4217 save_tmp_var (tree exp, tree_stmt_iterator *tsi)
4221 t = create_tmp_var (TREE_TYPE (exp), NULL);
4222 DECL_GIMPLE_REG_P (t) = 1;
4223 stmt = build_gimple_modify_stmt (exp, t);
4224 SET_EXPR_LOCUS (stmt, EXPR_LOCUS (tsi_stmt (*tsi)));
4225 tsi_link_after (tsi, stmt, TSI_SAME_STMT);
4230 /* Callback for walk_stmts. Lower the OpenMP directive pointed by TP. */
4233 lower_omp_1 (tree *tp, int *walk_subtrees, void *data)
4235 struct walk_stmt_info *wi = data;
4236 omp_context *ctx = wi->info;
4239 /* If we have issued syntax errors, avoid doing any heavy lifting.
4240 Just replace the OpenMP directives with a NOP to avoid
4241 confusing RTL expansion. */
4242 if (errorcount && OMP_DIRECTIVE_P (*tp))
4244 *tp = build_empty_stmt ();
4249 switch (TREE_CODE (*tp))
4252 ctx = maybe_lookup_ctx (t);
4253 lower_omp_parallel (tp, ctx);
4257 ctx = maybe_lookup_ctx (t);
4259 lower_omp_for (tp, ctx);
4263 ctx = maybe_lookup_ctx (t);
4265 lower_omp_sections (tp, ctx);
4269 ctx = maybe_lookup_ctx (t);
4271 lower_omp_single (tp, ctx);
4275 ctx = maybe_lookup_ctx (t);
4277 lower_omp_master (tp, ctx);
4281 ctx = maybe_lookup_ctx (t);
4283 lower_omp_ordered (tp, ctx);
4287 ctx = maybe_lookup_ctx (t);
4289 lower_omp_critical (tp, ctx);
4293 if (ctx && DECL_HAS_VALUE_EXPR_P (t))
4295 lower_regimplify (&t, wi);
4299 t = save_tmp_var (t, &wi->tsi);
4301 t = init_tmp_var (t, &wi->tsi);
4309 lower_regimplify (tp, wi);
4313 case ARRAY_RANGE_REF:
4317 case VIEW_CONVERT_EXPR:
4319 lower_regimplify (tp, wi);
4326 wi->val_only = true;
4327 lower_regimplify (&TREE_OPERAND (t, 0), wi);
4332 if (!TYPE_P (t) && !DECL_P (t))
4341 lower_omp (tree *stmt_p, omp_context *ctx)
4343 struct walk_stmt_info wi;
4345 memset (&wi, 0, sizeof (wi));
4346 wi.callback = lower_omp_1;
4349 wi.want_locations = true;
4351 walk_stmts (&wi, stmt_p);
4354 /* Main entry point. */
4357 execute_lower_omp (void)
4359 all_contexts = splay_tree_new (splay_tree_compare_pointers, 0,
4360 delete_omp_context);
4362 scan_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4363 gcc_assert (parallel_nesting_level == 0);
4365 if (all_contexts->root)
4366 lower_omp (&DECL_SAVED_TREE (current_function_decl), NULL);
4370 splay_tree_delete (all_contexts);
4371 all_contexts = NULL;
4377 gate_lower_omp (void)
4379 return flag_openmp != 0;
4382 struct tree_opt_pass pass_lower_omp =
4384 "omplower", /* name */
4385 gate_lower_omp, /* gate */
4386 execute_lower_omp, /* execute */
4389 0, /* static_pass_number */
4391 PROP_gimple_any, /* properties_required */
4392 PROP_gimple_lomp, /* properties_provided */
4393 0, /* properties_destroyed */
4394 0, /* todo_flags_start */
4395 TODO_dump_func, /* todo_flags_finish */
4399 /* The following is a utility to diagnose OpenMP structured block violations.
4400 It is not part of the "omplower" pass, as that's invoked too late. It
4401 should be invoked by the respective front ends after gimplification. */
4403 static splay_tree all_labels;
4405 /* Check for mismatched contexts and generate an error if needed. Return
4406 true if an error is detected. */
4409 diagnose_sb_0 (tree *stmt_p, tree branch_ctx, tree label_ctx)
4413 if ((label_ctx ? TREE_VALUE (label_ctx) : NULL) == branch_ctx)
4416 /* Try to avoid confusing the user by producing and error message
4417 with correct "exit" or "enter" verbage. We prefer "exit"
4418 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
4419 if (branch_ctx == NULL)
4425 if (TREE_VALUE (label_ctx) == branch_ctx)
4430 label_ctx = TREE_CHAIN (label_ctx);
4435 error ("invalid exit from OpenMP structured block");
4437 error ("invalid entry to OpenMP structured block");
4439 *stmt_p = build_empty_stmt ();
4443 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
4444 where in the tree each label is found. */
4447 diagnose_sb_1 (tree *tp, int *walk_subtrees, void *data)
4449 struct walk_stmt_info *wi = data;
4450 tree context = (tree) wi->info;
4455 switch (TREE_CODE (t))
4460 walk_tree (&OMP_CLAUSES (t), diagnose_sb_1, wi, NULL);
4466 /* The minimal context here is just a tree of statements. */
4467 inner_context = tree_cons (NULL, t, context);
4468 wi->info = inner_context;
4469 walk_stmts (wi, &OMP_BODY (t));
4474 walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_1, wi, NULL);
4475 inner_context = tree_cons (NULL, t, context);
4476 wi->info = inner_context;
4477 walk_tree (&OMP_FOR_INIT (t), diagnose_sb_1, wi, NULL);
4478 walk_tree (&OMP_FOR_COND (t), diagnose_sb_1, wi, NULL);
4479 walk_tree (&OMP_FOR_INCR (t), diagnose_sb_1, wi, NULL);
4480 walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4481 walk_stmts (wi, &OMP_FOR_BODY (t));
4486 splay_tree_insert (all_labels, (splay_tree_key) LABEL_EXPR_LABEL (t),
4487 (splay_tree_value) context);
4497 /* Pass 2: Check each branch and see if its context differs from that of
4498 the destination label's context. */
4501 diagnose_sb_2 (tree *tp, int *walk_subtrees, void *data)
4503 struct walk_stmt_info *wi = data;
4504 tree context = (tree) wi->info;
4509 switch (TREE_CODE (t))
4514 walk_tree (&OMP_CLAUSES (t), diagnose_sb_2, wi, NULL);
4521 walk_stmts (wi, &OMP_BODY (t));
4526 walk_tree (&OMP_FOR_CLAUSES (t), diagnose_sb_2, wi, NULL);
4528 walk_tree (&OMP_FOR_INIT (t), diagnose_sb_2, wi, NULL);
4529 walk_tree (&OMP_FOR_COND (t), diagnose_sb_2, wi, NULL);
4530 walk_tree (&OMP_FOR_INCR (t), diagnose_sb_2, wi, NULL);
4531 walk_stmts (wi, &OMP_FOR_PRE_BODY (t));
4532 walk_stmts (wi, &OMP_FOR_BODY (t));
4538 tree lab = GOTO_DESTINATION (t);
4539 if (TREE_CODE (lab) != LABEL_DECL)
4542 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4543 diagnose_sb_0 (tp, context, n ? (tree) n->value : NULL_TREE);
4549 tree vec = SWITCH_LABELS (t);
4550 int i, len = TREE_VEC_LENGTH (vec);
4551 for (i = 0; i < len; ++i)
4553 tree lab = CASE_LABEL (TREE_VEC_ELT (vec, i));
4554 n = splay_tree_lookup (all_labels, (splay_tree_key) lab);
4555 if (diagnose_sb_0 (tp, context, (tree) n->value))
4562 diagnose_sb_0 (tp, context, NULL_TREE);
4573 diagnose_omp_structured_block_errors (tree fndecl)
4575 tree save_current = current_function_decl;
4576 struct walk_stmt_info wi;
4578 current_function_decl = fndecl;
4580 all_labels = splay_tree_new (splay_tree_compare_pointers, 0, 0);
4582 memset (&wi, 0, sizeof (wi));
4583 wi.callback = diagnose_sb_1;
4584 walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4586 memset (&wi, 0, sizeof (wi));
4587 wi.callback = diagnose_sb_2;
4588 wi.want_locations = true;
4589 wi.want_return_expr = true;
4590 walk_stmts (&wi, &DECL_SAVED_TREE (fndecl));
4592 splay_tree_delete (all_labels);
4595 current_function_decl = save_current;
4598 #include "gt-omp-low.h"