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 (SSA_VAR_P (fd
->v
));
163 gcc_assert (TREE_CODE (TREE_TYPE (fd
->v
)) == INTEGER_TYPE
);
164 var
= TREE_CODE (fd
->v
) == SSA_NAME
? SSA_NAME_VAR (fd
->v
) : fd
->v
;
165 fd
->n1
= GIMPLE_STMT_OPERAND (t
, 1);
167 t
= OMP_FOR_COND (for_stmt
);
168 fd
->cond_code
= TREE_CODE (t
);
169 gcc_assert (TREE_OPERAND (t
, 0) == var
);
170 fd
->n2
= TREE_OPERAND (t
, 1);
171 switch (fd
->cond_code
)
177 fd
->n2
= fold_build2 (PLUS_EXPR
, TREE_TYPE (fd
->n2
), fd
->n2
,
178 build_int_cst (TREE_TYPE (fd
->n2
), 1));
179 fd
->cond_code
= LT_EXPR
;
182 fd
->n2
= fold_build2 (MINUS_EXPR
, TREE_TYPE (fd
->n2
), fd
->n2
,
183 build_int_cst (TREE_TYPE (fd
->n2
), 1));
184 fd
->cond_code
= GT_EXPR
;
190 t
= OMP_FOR_INCR (fd
->for_stmt
);
191 gcc_assert (TREE_CODE (t
) == GIMPLE_MODIFY_STMT
);
192 gcc_assert (GIMPLE_STMT_OPERAND (t
, 0) == var
);
193 t
= GIMPLE_STMT_OPERAND (t
, 1);
194 gcc_assert (TREE_OPERAND (t
, 0) == var
);
195 switch (TREE_CODE (t
))
198 fd
->step
= TREE_OPERAND (t
, 1);
201 fd
->step
= TREE_OPERAND (t
, 1);
202 fd
->step
= fold_build1 (NEGATE_EXPR
, TREE_TYPE (fd
->step
), fd
->step
);
208 fd
->have_nowait
= fd
->have_ordered
= false;
209 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
210 fd
->chunk_size
= NULL_TREE
;
212 for (t
= OMP_FOR_CLAUSES (for_stmt
); t
; t
= OMP_CLAUSE_CHAIN (t
))
213 switch (OMP_CLAUSE_CODE (t
))
215 case OMP_CLAUSE_NOWAIT
:
216 fd
->have_nowait
= true;
218 case OMP_CLAUSE_ORDERED
:
219 fd
->have_ordered
= true;
221 case OMP_CLAUSE_SCHEDULE
:
222 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_KIND (t
);
223 fd
->chunk_size
= OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t
);
229 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
230 gcc_assert (fd
->chunk_size
== NULL
);
231 else if (fd
->chunk_size
== NULL
)
233 /* We only need to compute a default chunk size for ordered
234 static loops and dynamic loops. */
235 if (fd
->sched_kind
!= OMP_CLAUSE_SCHEDULE_STATIC
|| fd
->have_ordered
)
236 fd
->chunk_size
= (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
237 ? integer_zero_node
: integer_one_node
;
242 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
243 is the immediate dominator of PAR_ENTRY_BB, return true if there
244 are no data dependencies that would prevent expanding the parallel
245 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
247 When expanding a combined parallel+workshare region, the call to
248 the child function may need additional arguments in the case of
249 OMP_FOR regions. In some cases, these arguments are computed out
250 of variables passed in from the parent to the child via 'struct
251 .omp_data_s'. For instance:
253 #pragma omp parallel for schedule (guided, i * 4)
258 # BLOCK 2 (PAR_ENTRY_BB)
260 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
262 # BLOCK 3 (WS_ENTRY_BB)
263 .omp_data_i = &.omp_data_o;
264 D.1667 = .omp_data_i->i;
266 #pragma omp for schedule (guided, D.1598)
268 When we outline the parallel region, the call to the child function
269 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
270 that value is computed *after* the call site. So, in principle we
271 cannot do the transformation.
273 To see whether the code in WS_ENTRY_BB blocks the combined
274 parallel+workshare call, we collect all the variables used in the
275 OMP_FOR header check whether they appear on the LHS of any
276 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
279 FIXME. If we had the SSA form built at this point, we could merely
280 hoist the code in block 3 into block 2 and be done with it. But at
281 this point we don't have dataflow information and though we could
282 hack something up here, it is really not worth the aggravation. */
285 workshare_safe_to_combine_p (basic_block par_entry_bb
, basic_block ws_entry_bb
)
287 struct omp_for_data fd
;
288 tree par_stmt
, ws_stmt
;
290 par_stmt
= last_stmt (par_entry_bb
);
291 ws_stmt
= last_stmt (ws_entry_bb
);
293 if (TREE_CODE (ws_stmt
) == OMP_SECTIONS
)
296 gcc_assert (TREE_CODE (ws_stmt
) == OMP_FOR
);
298 extract_omp_for_data (ws_stmt
, &fd
);
300 /* FIXME. We give up too easily here. If any of these arguments
301 are not constants, they will likely involve variables that have
302 been mapped into fields of .omp_data_s for sharing with the child
303 function. With appropriate data flow, it would be possible to
305 if (!is_gimple_min_invariant (fd
.n1
)
306 || !is_gimple_min_invariant (fd
.n2
)
307 || !is_gimple_min_invariant (fd
.step
)
308 || (fd
.chunk_size
&& !is_gimple_min_invariant (fd
.chunk_size
)))
315 /* Collect additional arguments needed to emit a combined
316 parallel+workshare call. WS_STMT is the workshare directive being
320 get_ws_args_for (tree ws_stmt
)
324 if (TREE_CODE (ws_stmt
) == OMP_FOR
)
326 struct omp_for_data fd
;
329 extract_omp_for_data (ws_stmt
, &fd
);
334 t
= fold_convert (long_integer_type_node
, fd
.chunk_size
);
335 ws_args
= tree_cons (NULL
, t
, ws_args
);
338 t
= fold_convert (long_integer_type_node
, fd
.step
);
339 ws_args
= tree_cons (NULL
, t
, ws_args
);
341 t
= fold_convert (long_integer_type_node
, fd
.n2
);
342 ws_args
= tree_cons (NULL
, t
, ws_args
);
344 t
= fold_convert (long_integer_type_node
, fd
.n1
);
345 ws_args
= tree_cons (NULL
, t
, ws_args
);
349 else if (TREE_CODE (ws_stmt
) == OMP_SECTIONS
)
351 /* Number of sections is equal to the number of edges from the
352 OMP_SECTIONS_SWITCH statement, except for the one to the exit
353 of the sections region. */
354 basic_block bb
= single_succ (bb_for_stmt (ws_stmt
));
355 t
= build_int_cst (unsigned_type_node
, EDGE_COUNT (bb
->succs
) - 1);
356 t
= tree_cons (NULL
, t
, NULL
);
364 /* Discover whether REGION is a combined parallel+workshare region. */
367 determine_parallel_type (struct omp_region
*region
)
369 basic_block par_entry_bb
, par_exit_bb
;
370 basic_block ws_entry_bb
, ws_exit_bb
;
372 if (region
== NULL
|| region
->inner
== NULL
373 || region
->exit
== NULL
|| region
->inner
->exit
== NULL
374 || region
->inner
->cont
== NULL
)
377 /* We only support parallel+for and parallel+sections. */
378 if (region
->type
!= OMP_PARALLEL
379 || (region
->inner
->type
!= OMP_FOR
380 && region
->inner
->type
!= OMP_SECTIONS
))
383 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
384 WS_EXIT_BB -> PAR_EXIT_BB. */
385 par_entry_bb
= region
->entry
;
386 par_exit_bb
= region
->exit
;
387 ws_entry_bb
= region
->inner
->entry
;
388 ws_exit_bb
= region
->inner
->exit
;
390 if (single_succ (par_entry_bb
) == ws_entry_bb
391 && single_succ (ws_exit_bb
) == par_exit_bb
392 && workshare_safe_to_combine_p (par_entry_bb
, ws_entry_bb
)
393 && (OMP_PARALLEL_COMBINED (last_stmt (par_entry_bb
))
394 || (last_and_only_stmt (ws_entry_bb
)
395 && last_and_only_stmt (par_exit_bb
))))
397 tree ws_stmt
= last_stmt (ws_entry_bb
);
399 if (region
->inner
->type
== OMP_FOR
)
401 /* If this is a combined parallel loop, we need to determine
402 whether or not to use the combined library calls. There
403 are two cases where we do not apply the transformation:
404 static loops and any kind of ordered loop. In the first
405 case, we already open code the loop so there is no need
406 to do anything else. In the latter case, the combined
407 parallel loop call would still need extra synchronization
408 to implement ordered semantics, so there would not be any
409 gain in using the combined call. */
410 tree clauses
= OMP_FOR_CLAUSES (ws_stmt
);
411 tree c
= find_omp_clause (clauses
, OMP_CLAUSE_SCHEDULE
);
413 || OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_STATIC
414 || find_omp_clause (clauses
, OMP_CLAUSE_ORDERED
))
416 region
->is_combined_parallel
= false;
417 region
->inner
->is_combined_parallel
= false;
422 region
->is_combined_parallel
= true;
423 region
->inner
->is_combined_parallel
= true;
424 region
->ws_args
= get_ws_args_for (ws_stmt
);
429 /* Return true if EXPR is variable sized. */
432 is_variable_sized (const_tree expr
)
434 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr
)));
437 /* Return true if DECL is a reference type. */
440 is_reference (tree decl
)
442 return lang_hooks
.decls
.omp_privatize_by_reference (decl
);
445 /* Lookup variables in the decl or field splay trees. The "maybe" form
446 allows for the variable form to not have been entered, otherwise we
447 assert that the variable must have been entered. */
450 lookup_decl (tree var
, omp_context
*ctx
)
453 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
458 maybe_lookup_decl (tree var
, omp_context
*ctx
)
461 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
462 return n
? *n
: NULL_TREE
;
466 lookup_field (tree var
, omp_context
*ctx
)
469 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
470 return (tree
) n
->value
;
474 maybe_lookup_field (tree var
, omp_context
*ctx
)
477 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
478 return n
? (tree
) n
->value
: NULL_TREE
;
481 /* Return true if DECL should be copied by pointer. SHARED_P is true
482 if DECL is to be shared. */
485 use_pointer_for_field (const_tree decl
, bool shared_p
)
487 if (AGGREGATE_TYPE_P (TREE_TYPE (decl
)))
490 /* We can only use copy-in/copy-out semantics for shared variables
491 when we know the value is not accessible from an outer scope. */
494 /* ??? Trivially accessible from anywhere. But why would we even
495 be passing an address in this case? Should we simply assert
496 this to be false, or should we have a cleanup pass that removes
497 these from the list of mappings? */
498 if (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
501 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
502 without analyzing the expression whether or not its location
503 is accessible to anyone else. In the case of nested parallel
504 regions it certainly may be. */
505 if (TREE_CODE (decl
) != RESULT_DECL
&& DECL_HAS_VALUE_EXPR_P (decl
))
508 /* Do not use copy-in/copy-out for variables that have their
510 if (TREE_ADDRESSABLE (decl
))
517 /* Create a new VAR_DECL and copy information from VAR to it. */
520 copy_var_decl (tree var
, tree name
, tree type
)
522 tree copy
= build_decl (VAR_DECL
, name
, type
);
524 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (var
);
525 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (var
);
526 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (var
);
527 DECL_NO_TBAA_P (copy
) = DECL_NO_TBAA_P (var
);
528 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (var
);
529 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (var
);
530 DECL_CONTEXT (copy
) = DECL_CONTEXT (var
);
531 TREE_USED (copy
) = 1;
532 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
537 /* Construct a new automatic decl similar to VAR. */
540 omp_copy_decl_2 (tree var
, tree name
, tree type
, omp_context
*ctx
)
542 tree copy
= copy_var_decl (var
, name
, type
);
544 DECL_CONTEXT (copy
) = current_function_decl
;
545 TREE_CHAIN (copy
) = ctx
->block_vars
;
546 ctx
->block_vars
= copy
;
552 omp_copy_decl_1 (tree var
, omp_context
*ctx
)
554 return omp_copy_decl_2 (var
, DECL_NAME (var
), TREE_TYPE (var
), ctx
);
557 /* Build tree nodes to access the field for VAR on the receiver side. */
560 build_receiver_ref (tree var
, bool by_ref
, omp_context
*ctx
)
562 tree x
, field
= lookup_field (var
, ctx
);
564 /* If the receiver record type was remapped in the child function,
565 remap the field into the new record type. */
566 x
= maybe_lookup_field (field
, ctx
);
570 x
= build_fold_indirect_ref (ctx
->receiver_decl
);
571 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL
);
573 x
= build_fold_indirect_ref (x
);
578 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
579 of a parallel, this is a component reference; for workshare constructs
580 this is some variable. */
583 build_outer_var_ref (tree var
, omp_context
*ctx
)
587 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
, ctx
)))
589 else if (is_variable_sized (var
))
591 x
= TREE_OPERAND (DECL_VALUE_EXPR (var
), 0);
592 x
= build_outer_var_ref (x
, ctx
);
593 x
= build_fold_indirect_ref (x
);
595 else if (is_parallel_ctx (ctx
))
597 bool by_ref
= use_pointer_for_field (var
, false);
598 x
= build_receiver_ref (var
, by_ref
, ctx
);
601 x
= lookup_decl (var
, ctx
->outer
);
602 else if (is_reference (var
))
603 /* This can happen with orphaned constructs. If var is reference, it is
604 possible it is shared and as such valid. */
609 if (is_reference (var
))
610 x
= build_fold_indirect_ref (x
);
615 /* Build tree nodes to access the field for VAR on the sender side. */
618 build_sender_ref (tree var
, omp_context
*ctx
)
620 tree field
= lookup_field (var
, ctx
);
621 return build3 (COMPONENT_REF
, TREE_TYPE (field
),
622 ctx
->sender_decl
, field
, NULL
);
625 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
628 install_var_field (tree var
, bool by_ref
, omp_context
*ctx
)
632 gcc_assert (!splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
));
634 type
= TREE_TYPE (var
);
636 type
= build_pointer_type (type
);
638 field
= build_decl (FIELD_DECL
, DECL_NAME (var
), type
);
640 /* Remember what variable this field was created for. This does have a
641 side effect of making dwarf2out ignore this member, so for helpful
642 debugging we clear it later in delete_omp_context. */
643 DECL_ABSTRACT_ORIGIN (field
) = var
;
645 insert_field_into_struct (ctx
->record_type
, field
);
647 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) var
,
648 (splay_tree_value
) field
);
652 install_var_local (tree var
, omp_context
*ctx
)
654 tree new_var
= omp_copy_decl_1 (var
, ctx
);
655 insert_decl_map (&ctx
->cb
, var
, new_var
);
659 /* Adjust the replacement for DECL in CTX for the new context. This means
660 copying the DECL_VALUE_EXPR, and fixing up the type. */
663 fixup_remapped_decl (tree decl
, omp_context
*ctx
, bool private_debug
)
667 new_decl
= lookup_decl (decl
, ctx
);
669 TREE_TYPE (new_decl
) = remap_type (TREE_TYPE (decl
), &ctx
->cb
);
671 if ((!TREE_CONSTANT (DECL_SIZE (new_decl
)) || private_debug
)
672 && DECL_HAS_VALUE_EXPR_P (decl
))
674 tree ve
= DECL_VALUE_EXPR (decl
);
675 walk_tree (&ve
, copy_body_r
, &ctx
->cb
, NULL
);
676 SET_DECL_VALUE_EXPR (new_decl
, ve
);
677 DECL_HAS_VALUE_EXPR_P (new_decl
) = 1;
680 if (!TREE_CONSTANT (DECL_SIZE (new_decl
)))
682 size
= remap_decl (DECL_SIZE (decl
), &ctx
->cb
);
683 if (size
== error_mark_node
)
684 size
= TYPE_SIZE (TREE_TYPE (new_decl
));
685 DECL_SIZE (new_decl
) = size
;
687 size
= remap_decl (DECL_SIZE_UNIT (decl
), &ctx
->cb
);
688 if (size
== error_mark_node
)
689 size
= TYPE_SIZE_UNIT (TREE_TYPE (new_decl
));
690 DECL_SIZE_UNIT (new_decl
) = size
;
694 /* The callback for remap_decl. Search all containing contexts for a
695 mapping of the variable; this avoids having to duplicate the splay
696 tree ahead of time. We know a mapping doesn't already exist in the
697 given context. Create new mappings to implement default semantics. */
700 omp_copy_decl (tree var
, copy_body_data
*cb
)
702 omp_context
*ctx
= (omp_context
*) cb
;
705 if (TREE_CODE (var
) == LABEL_DECL
)
707 new_var
= create_artificial_label ();
708 DECL_CONTEXT (new_var
) = current_function_decl
;
709 insert_decl_map (&ctx
->cb
, var
, new_var
);
713 while (!is_parallel_ctx (ctx
))
718 new_var
= maybe_lookup_decl (var
, ctx
);
723 if (is_global_var (var
) || decl_function_context (var
) != ctx
->cb
.src_fn
)
726 return error_mark_node
;
730 /* Return the parallel region associated with STMT. */
732 /* Debugging dumps for parallel regions. */
733 void dump_omp_region (FILE *, struct omp_region
*, int);
734 void debug_omp_region (struct omp_region
*);
735 void debug_all_omp_regions (void);
737 /* Dump the parallel region tree rooted at REGION. */
740 dump_omp_region (FILE *file
, struct omp_region
*region
, int indent
)
742 fprintf (file
, "%*sbb %d: %s\n", indent
, "", region
->entry
->index
,
743 tree_code_name
[region
->type
]);
746 dump_omp_region (file
, region
->inner
, indent
+ 4);
750 fprintf (file
, "%*sbb %d: OMP_CONTINUE\n", indent
, "",
751 region
->cont
->index
);
755 fprintf (file
, "%*sbb %d: OMP_RETURN\n", indent
, "",
756 region
->exit
->index
);
758 fprintf (file
, "%*s[no exit marker]\n", indent
, "");
761 dump_omp_region (file
, region
->next
, indent
);
765 debug_omp_region (struct omp_region
*region
)
767 dump_omp_region (stderr
, region
, 0);
771 debug_all_omp_regions (void)
773 dump_omp_region (stderr
, root_omp_region
, 0);
777 /* Create a new parallel region starting at STMT inside region PARENT. */
780 new_omp_region (basic_block bb
, enum tree_code type
, struct omp_region
*parent
)
782 struct omp_region
*region
= xcalloc (1, sizeof (*region
));
784 region
->outer
= parent
;
790 /* This is a nested region. Add it to the list of inner
791 regions in PARENT. */
792 region
->next
= parent
->inner
;
793 parent
->inner
= region
;
797 /* This is a toplevel region. Add it to the list of toplevel
798 regions in ROOT_OMP_REGION. */
799 region
->next
= root_omp_region
;
800 root_omp_region
= region
;
806 /* Release the memory associated with the region tree rooted at REGION. */
809 free_omp_region_1 (struct omp_region
*region
)
811 struct omp_region
*i
, *n
;
813 for (i
= region
->inner
; i
; i
= n
)
816 free_omp_region_1 (i
);
822 /* Release the memory for the entire omp region tree. */
825 free_omp_regions (void)
827 struct omp_region
*r
, *n
;
828 for (r
= root_omp_region
; r
; r
= n
)
831 free_omp_region_1 (r
);
833 root_omp_region
= NULL
;
837 /* Create a new context, with OUTER_CTX being the surrounding context. */
840 new_omp_context (tree stmt
, omp_context
*outer_ctx
)
842 omp_context
*ctx
= XCNEW (omp_context
);
844 splay_tree_insert (all_contexts
, (splay_tree_key
) stmt
,
845 (splay_tree_value
) ctx
);
850 ctx
->outer
= outer_ctx
;
851 ctx
->cb
= outer_ctx
->cb
;
852 ctx
->cb
.block
= NULL
;
853 ctx
->depth
= outer_ctx
->depth
+ 1;
857 ctx
->cb
.src_fn
= current_function_decl
;
858 ctx
->cb
.dst_fn
= current_function_decl
;
859 ctx
->cb
.src_node
= cgraph_node (current_function_decl
);
860 ctx
->cb
.dst_node
= ctx
->cb
.src_node
;
861 ctx
->cb
.src_cfun
= cfun
;
862 ctx
->cb
.copy_decl
= omp_copy_decl
;
863 ctx
->cb
.eh_region
= -1;
864 ctx
->cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
868 ctx
->cb
.decl_map
= pointer_map_create ();
873 /* Destroy a omp_context data structures. Called through the splay tree
874 value delete callback. */
877 delete_omp_context (splay_tree_value value
)
879 omp_context
*ctx
= (omp_context
*) value
;
881 pointer_map_destroy (ctx
->cb
.decl_map
);
884 splay_tree_delete (ctx
->field_map
);
886 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
887 it produces corrupt debug information. */
888 if (ctx
->record_type
)
891 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= TREE_CHAIN (t
))
892 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
898 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
902 fixup_child_record_type (omp_context
*ctx
)
904 tree f
, type
= ctx
->record_type
;
906 /* ??? It isn't sufficient to just call remap_type here, because
907 variably_modified_type_p doesn't work the way we expect for
908 record types. Testing each field for whether it needs remapping
909 and creating a new record by hand works, however. */
910 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
911 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
915 tree name
, new_fields
= NULL
;
917 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
918 name
= DECL_NAME (TYPE_NAME (ctx
->record_type
));
919 name
= build_decl (TYPE_DECL
, name
, type
);
920 TYPE_NAME (type
) = name
;
922 for (f
= TYPE_FIELDS (ctx
->record_type
); f
; f
= TREE_CHAIN (f
))
924 tree new_f
= copy_node (f
);
925 DECL_CONTEXT (new_f
) = type
;
926 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &ctx
->cb
);
927 TREE_CHAIN (new_f
) = new_fields
;
930 /* Arrange to be able to look up the receiver field
931 given the sender field. */
932 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) f
,
933 (splay_tree_value
) new_f
);
935 TYPE_FIELDS (type
) = nreverse (new_fields
);
939 TREE_TYPE (ctx
->receiver_decl
) = build_pointer_type (type
);
942 /* Instantiate decls as necessary in CTX to satisfy the data sharing
943 specified by CLAUSES. */
946 scan_sharing_clauses (tree clauses
, omp_context
*ctx
)
949 bool scan_array_reductions
= false;
951 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
955 switch (OMP_CLAUSE_CODE (c
))
957 case OMP_CLAUSE_PRIVATE
:
958 decl
= OMP_CLAUSE_DECL (c
);
959 if (!is_variable_sized (decl
))
960 install_var_local (decl
, ctx
);
963 case OMP_CLAUSE_SHARED
:
964 gcc_assert (is_parallel_ctx (ctx
));
965 decl
= OMP_CLAUSE_DECL (c
);
966 gcc_assert (!is_variable_sized (decl
));
967 by_ref
= use_pointer_for_field (decl
, true);
968 /* Global variables don't need to be copied,
969 the receiver side will use them directly. */
970 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
972 if (! TREE_READONLY (decl
)
973 || TREE_ADDRESSABLE (decl
)
975 || is_reference (decl
))
977 install_var_field (decl
, by_ref
, ctx
);
978 install_var_local (decl
, ctx
);
981 /* We don't need to copy const scalar vars back. */
982 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_FIRSTPRIVATE
);
985 case OMP_CLAUSE_LASTPRIVATE
:
986 /* Let the corresponding firstprivate clause create
988 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
992 case OMP_CLAUSE_FIRSTPRIVATE
:
993 case OMP_CLAUSE_REDUCTION
:
994 decl
= OMP_CLAUSE_DECL (c
);
996 if (is_variable_sized (decl
))
998 else if (is_parallel_ctx (ctx
)
999 && ! is_global_var (maybe_lookup_decl_in_outer_ctx (decl
,
1002 by_ref
= use_pointer_for_field (decl
, false);
1003 install_var_field (decl
, by_ref
, ctx
);
1005 install_var_local (decl
, ctx
);
1008 case OMP_CLAUSE_COPYPRIVATE
:
1010 scan_omp (&OMP_CLAUSE_DECL (c
), ctx
->outer
);
1013 case OMP_CLAUSE_COPYIN
:
1014 decl
= OMP_CLAUSE_DECL (c
);
1015 by_ref
= use_pointer_for_field (decl
, false);
1016 install_var_field (decl
, by_ref
, ctx
);
1019 case OMP_CLAUSE_DEFAULT
:
1020 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
1024 case OMP_CLAUSE_NUM_THREADS
:
1025 case OMP_CLAUSE_SCHEDULE
:
1027 scan_omp (&OMP_CLAUSE_OPERAND (c
, 0), ctx
->outer
);
1030 case OMP_CLAUSE_NOWAIT
:
1031 case OMP_CLAUSE_ORDERED
:
1039 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1041 switch (OMP_CLAUSE_CODE (c
))
1043 case OMP_CLAUSE_LASTPRIVATE
:
1044 /* Let the corresponding firstprivate clause create
1046 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1050 case OMP_CLAUSE_PRIVATE
:
1051 case OMP_CLAUSE_FIRSTPRIVATE
:
1052 case OMP_CLAUSE_REDUCTION
:
1053 decl
= OMP_CLAUSE_DECL (c
);
1054 if (is_variable_sized (decl
))
1055 install_var_local (decl
, ctx
);
1056 fixup_remapped_decl (decl
, ctx
,
1057 OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_PRIVATE
1058 && OMP_CLAUSE_PRIVATE_DEBUG (c
));
1059 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1060 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1061 scan_array_reductions
= true;
1064 case OMP_CLAUSE_SHARED
:
1065 decl
= OMP_CLAUSE_DECL (c
);
1066 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1067 fixup_remapped_decl (decl
, ctx
, false);
1070 case OMP_CLAUSE_COPYPRIVATE
:
1071 case OMP_CLAUSE_COPYIN
:
1072 case OMP_CLAUSE_DEFAULT
:
1074 case OMP_CLAUSE_NUM_THREADS
:
1075 case OMP_CLAUSE_SCHEDULE
:
1076 case OMP_CLAUSE_NOWAIT
:
1077 case OMP_CLAUSE_ORDERED
:
1085 if (scan_array_reductions
)
1086 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1087 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1088 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1090 scan_omp (&OMP_CLAUSE_REDUCTION_INIT (c
), ctx
);
1091 scan_omp (&OMP_CLAUSE_REDUCTION_MERGE (c
), ctx
);
1095 /* Create a new name for omp child function. Returns an identifier. */
1097 static GTY(()) unsigned int tmp_ompfn_id_num
;
1100 create_omp_child_function_name (void)
1102 tree name
= DECL_ASSEMBLER_NAME (current_function_decl
);
1103 size_t len
= IDENTIFIER_LENGTH (name
);
1104 char *tmp_name
, *prefix
;
1106 prefix
= alloca (len
+ sizeof ("_omp_fn"));
1107 memcpy (prefix
, IDENTIFIER_POINTER (name
), len
);
1108 strcpy (prefix
+ len
, "_omp_fn");
1109 #ifndef NO_DOT_IN_LABEL
1111 #elif !defined NO_DOLLAR_IN_LABEL
1114 ASM_FORMAT_PRIVATE_NAME (tmp_name
, prefix
, tmp_ompfn_id_num
++);
1115 return get_identifier (tmp_name
);
1118 /* Build a decl for the omp child function. It'll not contain a body
1119 yet, just the bare decl. */
1122 create_omp_child_function (omp_context
*ctx
)
1124 tree decl
, type
, name
, t
;
1126 name
= create_omp_child_function_name ();
1127 type
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
1129 decl
= build_decl (FUNCTION_DECL
, name
, type
);
1130 decl
= lang_hooks
.decls
.pushdecl (decl
);
1132 ctx
->cb
.dst_fn
= decl
;
1134 TREE_STATIC (decl
) = 1;
1135 TREE_USED (decl
) = 1;
1136 DECL_ARTIFICIAL (decl
) = 1;
1137 DECL_IGNORED_P (decl
) = 0;
1138 TREE_PUBLIC (decl
) = 0;
1139 DECL_UNINLINABLE (decl
) = 1;
1140 DECL_EXTERNAL (decl
) = 0;
1141 DECL_CONTEXT (decl
) = NULL_TREE
;
1142 DECL_INITIAL (decl
) = make_node (BLOCK
);
1144 t
= build_decl (RESULT_DECL
, NULL_TREE
, void_type_node
);
1145 DECL_ARTIFICIAL (t
) = 1;
1146 DECL_IGNORED_P (t
) = 1;
1147 DECL_RESULT (decl
) = t
;
1149 t
= build_decl (PARM_DECL
, get_identifier (".omp_data_i"), ptr_type_node
);
1150 DECL_ARTIFICIAL (t
) = 1;
1151 DECL_ARG_TYPE (t
) = ptr_type_node
;
1152 DECL_CONTEXT (t
) = current_function_decl
;
1154 DECL_ARGUMENTS (decl
) = t
;
1155 ctx
->receiver_decl
= t
;
1157 /* Allocate memory for the function structure. The call to
1158 allocate_struct_function clobbers CFUN, so we need to restore
1160 push_struct_function (decl
);
1161 DECL_SOURCE_LOCATION (decl
) = EXPR_LOCATION (ctx
->stmt
);
1162 cfun
->function_end_locus
= EXPR_LOCATION (ctx
->stmt
);
1167 /* Scan an OpenMP parallel directive. */
1170 scan_omp_parallel (tree
*stmt_p
, omp_context
*outer_ctx
)
1175 /* Ignore parallel directives with empty bodies, unless there
1176 are copyin clauses. */
1178 && empty_body_p (OMP_PARALLEL_BODY (*stmt_p
))
1179 && find_omp_clause (OMP_CLAUSES (*stmt_p
), OMP_CLAUSE_COPYIN
) == NULL
)
1181 *stmt_p
= build_empty_stmt ();
1185 ctx
= new_omp_context (*stmt_p
, outer_ctx
);
1186 if (parallel_nesting_level
> 1)
1187 ctx
->is_nested
= true;
1188 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1189 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1190 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1191 name
= create_tmp_var_name (".omp_data_s");
1192 name
= build_decl (TYPE_DECL
, name
, ctx
->record_type
);
1193 TYPE_NAME (ctx
->record_type
) = name
;
1194 create_omp_child_function (ctx
);
1195 OMP_PARALLEL_FN (*stmt_p
) = ctx
->cb
.dst_fn
;
1197 scan_sharing_clauses (OMP_PARALLEL_CLAUSES (*stmt_p
), ctx
);
1198 scan_omp (&OMP_PARALLEL_BODY (*stmt_p
), ctx
);
1200 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1201 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1204 layout_type (ctx
->record_type
);
1205 fixup_child_record_type (ctx
);
1210 /* Scan an OpenMP loop directive. */
1213 scan_omp_for (tree
*stmt_p
, omp_context
*outer_ctx
)
1219 ctx
= new_omp_context (stmt
, outer_ctx
);
1221 scan_sharing_clauses (OMP_FOR_CLAUSES (stmt
), ctx
);
1223 scan_omp (&OMP_FOR_PRE_BODY (stmt
), ctx
);
1224 scan_omp (&OMP_FOR_INIT (stmt
), ctx
);
1225 scan_omp (&OMP_FOR_COND (stmt
), ctx
);
1226 scan_omp (&OMP_FOR_INCR (stmt
), ctx
);
1227 scan_omp (&OMP_FOR_BODY (stmt
), ctx
);
1230 /* Scan an OpenMP sections directive. */
1233 scan_omp_sections (tree
*stmt_p
, omp_context
*outer_ctx
)
1239 ctx
= new_omp_context (stmt
, outer_ctx
);
1240 scan_sharing_clauses (OMP_SECTIONS_CLAUSES (stmt
), ctx
);
1241 scan_omp (&OMP_SECTIONS_BODY (stmt
), ctx
);
1244 /* Scan an OpenMP single directive. */
1247 scan_omp_single (tree
*stmt_p
, omp_context
*outer_ctx
)
1249 tree stmt
= *stmt_p
;
1253 ctx
= new_omp_context (stmt
, outer_ctx
);
1254 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1255 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1256 name
= create_tmp_var_name (".omp_copy_s");
1257 name
= build_decl (TYPE_DECL
, name
, ctx
->record_type
);
1258 TYPE_NAME (ctx
->record_type
) = name
;
1260 scan_sharing_clauses (OMP_SINGLE_CLAUSES (stmt
), ctx
);
1261 scan_omp (&OMP_SINGLE_BODY (stmt
), ctx
);
1263 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1264 ctx
->record_type
= NULL
;
1266 layout_type (ctx
->record_type
);
1270 /* Check OpenMP nesting restrictions. */
1272 check_omp_nesting_restrictions (tree t
, omp_context
*ctx
)
1274 switch (TREE_CODE (t
))
1279 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1280 switch (TREE_CODE (ctx
->stmt
))
1287 warning (0, "work-sharing region may not be closely nested inside "
1288 "of work-sharing, critical, ordered or master region");
1297 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1298 switch (TREE_CODE (ctx
->stmt
))
1303 warning (0, "master region may not be closely nested inside "
1304 "of work-sharing region");
1313 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1314 switch (TREE_CODE (ctx
->stmt
))
1317 warning (0, "ordered region may not be closely nested inside "
1318 "of critical region");
1321 if (find_omp_clause (OMP_CLAUSES (ctx
->stmt
),
1322 OMP_CLAUSE_ORDERED
) == NULL
)
1323 warning (0, "ordered region must be closely nested inside "
1324 "a loop region with an ordered clause");
1333 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1334 if (TREE_CODE (ctx
->stmt
) == OMP_CRITICAL
1335 && OMP_CRITICAL_NAME (t
) == OMP_CRITICAL_NAME (ctx
->stmt
))
1337 warning (0, "critical region may not be nested inside a critical "
1338 "region with the same name");
1348 /* Callback for walk_stmts used to scan for OpenMP directives at TP. */
1351 scan_omp_1 (tree
*tp
, int *walk_subtrees
, void *data
)
1353 struct walk_stmt_info
*wi
= data
;
1354 omp_context
*ctx
= wi
->info
;
1357 if (EXPR_HAS_LOCATION (t
))
1358 input_location
= EXPR_LOCATION (t
);
1360 /* Check the OpenMP nesting restrictions. */
1361 if (OMP_DIRECTIVE_P (t
) && ctx
!= NULL
)
1362 check_omp_nesting_restrictions (t
, ctx
);
1365 switch (TREE_CODE (t
))
1368 parallel_nesting_level
++;
1369 scan_omp_parallel (tp
, ctx
);
1370 parallel_nesting_level
--;
1374 scan_omp_for (tp
, ctx
);
1378 scan_omp_sections (tp
, ctx
);
1382 scan_omp_single (tp
, ctx
);
1389 ctx
= new_omp_context (*tp
, ctx
);
1390 scan_omp (&OMP_BODY (*tp
), ctx
);
1398 for (var
= BIND_EXPR_VARS (t
); var
; var
= TREE_CHAIN (var
))
1399 insert_decl_map (&ctx
->cb
, var
, var
);
1408 *tp
= remap_decl (t
, &ctx
->cb
);
1412 if (ctx
&& TYPE_P (t
))
1413 *tp
= remap_type (t
, &ctx
->cb
);
1414 else if (!DECL_P (t
))
1423 /* Scan all the statements starting at STMT_P. CTX contains context
1424 information about the OpenMP directives and clauses found during
1428 scan_omp (tree
*stmt_p
, omp_context
*ctx
)
1430 location_t saved_location
;
1431 struct walk_stmt_info wi
;
1433 memset (&wi
, 0, sizeof (wi
));
1434 wi
.callback
= scan_omp_1
;
1436 wi
.want_bind_expr
= (ctx
!= NULL
);
1437 wi
.want_locations
= true;
1439 saved_location
= input_location
;
1440 walk_stmts (&wi
, stmt_p
);
1441 input_location
= saved_location
;
1444 /* Re-gimplification and code generation routines. */
1446 /* Build a call to GOMP_barrier. */
1449 build_omp_barrier (void)
1451 return build_call_expr (built_in_decls
[BUILT_IN_GOMP_BARRIER
], 0);
1454 /* If a context was created for STMT when it was scanned, return it. */
1456 static omp_context
*
1457 maybe_lookup_ctx (tree stmt
)
1460 n
= splay_tree_lookup (all_contexts
, (splay_tree_key
) stmt
);
1461 return n
? (omp_context
*) n
->value
: NULL
;
1465 /* Find the mapping for DECL in CTX or the immediately enclosing
1466 context that has a mapping for DECL.
1468 If CTX is a nested parallel directive, we may have to use the decl
1469 mappings created in CTX's parent context. Suppose that we have the
1470 following parallel nesting (variable UIDs showed for clarity):
1473 #omp parallel shared(iD.1562) -> outer parallel
1474 iD.1562 = iD.1562 + 1;
1476 #omp parallel shared (iD.1562) -> inner parallel
1477 iD.1562 = iD.1562 - 1;
1479 Each parallel structure will create a distinct .omp_data_s structure
1480 for copying iD.1562 in/out of the directive:
1482 outer parallel .omp_data_s.1.i -> iD.1562
1483 inner parallel .omp_data_s.2.i -> iD.1562
1485 A shared variable mapping will produce a copy-out operation before
1486 the parallel directive and a copy-in operation after it. So, in
1487 this case we would have:
1490 .omp_data_o.1.i = iD.1562;
1491 #omp parallel shared(iD.1562) -> outer parallel
1492 .omp_data_i.1 = &.omp_data_o.1
1493 .omp_data_i.1->i = .omp_data_i.1->i + 1;
1495 .omp_data_o.2.i = iD.1562; -> **
1496 #omp parallel shared(iD.1562) -> inner parallel
1497 .omp_data_i.2 = &.omp_data_o.2
1498 .omp_data_i.2->i = .omp_data_i.2->i - 1;
1501 ** This is a problem. The symbol iD.1562 cannot be referenced
1502 inside the body of the outer parallel region. But since we are
1503 emitting this copy operation while expanding the inner parallel
1504 directive, we need to access the CTX structure of the outer
1505 parallel directive to get the correct mapping:
1507 .omp_data_o.2.i = .omp_data_i.1->i
1509 Since there may be other workshare or parallel directives enclosing
1510 the parallel directive, it may be necessary to walk up the context
1511 parent chain. This is not a problem in general because nested
1512 parallelism happens only rarely. */
1515 lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
1520 gcc_assert (ctx
->is_nested
);
1522 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
1523 t
= maybe_lookup_decl (decl
, up
);
1525 gcc_assert (t
|| is_global_var (decl
));
1527 return t
? t
: decl
;
1531 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
1532 in outer contexts. */
1535 maybe_lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
1541 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
1542 t
= maybe_lookup_decl (decl
, up
);
1544 return t
? t
: decl
;
1548 /* Construct the initialization value for reduction CLAUSE. */
1551 omp_reduction_init (tree clause
, tree type
)
1553 switch (OMP_CLAUSE_REDUCTION_CODE (clause
))
1560 case TRUTH_ORIF_EXPR
:
1561 case TRUTH_XOR_EXPR
:
1563 return fold_convert (type
, integer_zero_node
);
1566 case TRUTH_AND_EXPR
:
1567 case TRUTH_ANDIF_EXPR
:
1569 return fold_convert (type
, integer_one_node
);
1572 return fold_convert (type
, integer_minus_one_node
);
1575 if (SCALAR_FLOAT_TYPE_P (type
))
1577 REAL_VALUE_TYPE max
, min
;
1578 if (HONOR_INFINITIES (TYPE_MODE (type
)))
1581 real_arithmetic (&min
, NEGATE_EXPR
, &max
, NULL
);
1584 real_maxval (&min
, 1, TYPE_MODE (type
));
1585 return build_real (type
, min
);
1589 gcc_assert (INTEGRAL_TYPE_P (type
));
1590 return TYPE_MIN_VALUE (type
);
1594 if (SCALAR_FLOAT_TYPE_P (type
))
1596 REAL_VALUE_TYPE max
;
1597 if (HONOR_INFINITIES (TYPE_MODE (type
)))
1600 real_maxval (&max
, 0, TYPE_MODE (type
));
1601 return build_real (type
, max
);
1605 gcc_assert (INTEGRAL_TYPE_P (type
));
1606 return TYPE_MAX_VALUE (type
);
1614 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
1615 from the receiver (aka child) side and initializers for REFERENCE_TYPE
1616 private variables. Initialization statements go in ILIST, while calls
1617 to destructors go in DLIST. */
1620 lower_rec_input_clauses (tree clauses
, tree
*ilist
, tree
*dlist
,
1623 tree_stmt_iterator diter
;
1624 tree c
, dtor
, copyin_seq
, x
, ptr
;
1625 bool copyin_by_ref
= false;
1626 bool lastprivate_firstprivate
= false;
1629 *dlist
= alloc_stmt_list ();
1630 diter
= tsi_start (*dlist
);
1633 /* Do all the fixed sized types in the first pass, and the variable sized
1634 types in the second pass. This makes sure that the scalar arguments to
1635 the variable sized types are processed before we use them in the
1636 variable sized operations. */
1637 for (pass
= 0; pass
< 2; ++pass
)
1639 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1641 enum omp_clause_code c_kind
= OMP_CLAUSE_CODE (c
);
1647 case OMP_CLAUSE_PRIVATE
:
1648 if (OMP_CLAUSE_PRIVATE_DEBUG (c
))
1651 case OMP_CLAUSE_SHARED
:
1652 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c
), ctx
) == NULL
)
1654 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c
)));
1657 case OMP_CLAUSE_FIRSTPRIVATE
:
1658 case OMP_CLAUSE_COPYIN
:
1659 case OMP_CLAUSE_REDUCTION
:
1661 case OMP_CLAUSE_LASTPRIVATE
:
1662 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1664 lastprivate_firstprivate
= true;
1673 new_var
= var
= OMP_CLAUSE_DECL (c
);
1674 if (c_kind
!= OMP_CLAUSE_COPYIN
)
1675 new_var
= lookup_decl (var
, ctx
);
1677 if (c_kind
== OMP_CLAUSE_SHARED
|| c_kind
== OMP_CLAUSE_COPYIN
)
1682 else if (is_variable_sized (var
))
1684 /* For variable sized types, we need to allocate the
1685 actual storage here. Call alloca and store the
1686 result in the pointer decl that we created elsewhere. */
1690 ptr
= DECL_VALUE_EXPR (new_var
);
1691 gcc_assert (TREE_CODE (ptr
) == INDIRECT_REF
);
1692 ptr
= TREE_OPERAND (ptr
, 0);
1693 gcc_assert (DECL_P (ptr
));
1695 x
= TYPE_SIZE_UNIT (TREE_TYPE (new_var
));
1696 x
= build_call_expr (built_in_decls
[BUILT_IN_ALLOCA
], 1, x
);
1697 x
= fold_convert (TREE_TYPE (ptr
), x
);
1698 x
= build_gimple_modify_stmt (ptr
, x
);
1699 gimplify_and_add (x
, ilist
);
1701 else if (is_reference (var
))
1703 /* For references that are being privatized for Fortran,
1704 allocate new backing storage for the new pointer
1705 variable. This allows us to avoid changing all the
1706 code that expects a pointer to something that expects
1707 a direct variable. Note that this doesn't apply to
1708 C++, since reference types are disallowed in data
1709 sharing clauses there, except for NRV optimized
1714 x
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var
)));
1715 if (TREE_CONSTANT (x
))
1717 const char *name
= NULL
;
1718 if (DECL_NAME (var
))
1719 name
= IDENTIFIER_POINTER (DECL_NAME (new_var
));
1721 x
= create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var
)),
1723 gimple_add_tmp_var (x
);
1724 x
= build_fold_addr_expr_with_type (x
, TREE_TYPE (new_var
));
1728 x
= build_call_expr (built_in_decls
[BUILT_IN_ALLOCA
], 1, x
);
1729 x
= fold_convert (TREE_TYPE (new_var
), x
);
1732 x
= build_gimple_modify_stmt (new_var
, x
);
1733 gimplify_and_add (x
, ilist
);
1735 new_var
= build_fold_indirect_ref (new_var
);
1737 else if (c_kind
== OMP_CLAUSE_REDUCTION
1738 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1746 switch (OMP_CLAUSE_CODE (c
))
1748 case OMP_CLAUSE_SHARED
:
1749 /* Shared global vars are just accessed directly. */
1750 if (is_global_var (new_var
))
1752 /* Set up the DECL_VALUE_EXPR for shared variables now. This
1753 needs to be delayed until after fixup_child_record_type so
1754 that we get the correct type during the dereference. */
1755 by_ref
= use_pointer_for_field (var
, true);
1756 x
= build_receiver_ref (var
, by_ref
, ctx
);
1757 SET_DECL_VALUE_EXPR (new_var
, x
);
1758 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
1760 /* ??? If VAR is not passed by reference, and the variable
1761 hasn't been initialized yet, then we'll get a warning for
1762 the store into the omp_data_s structure. Ideally, we'd be
1763 able to notice this and not store anything at all, but
1764 we're generating code too early. Suppress the warning. */
1766 TREE_NO_WARNING (var
) = 1;
1769 case OMP_CLAUSE_LASTPRIVATE
:
1770 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1774 case OMP_CLAUSE_PRIVATE
:
1775 x
= lang_hooks
.decls
.omp_clause_default_ctor (c
, new_var
);
1777 gimplify_and_add (x
, ilist
);
1781 x
= lang_hooks
.decls
.omp_clause_dtor (c
, new_var
);
1785 gimplify_stmt (&dtor
);
1786 tsi_link_before (&diter
, dtor
, TSI_SAME_STMT
);
1790 case OMP_CLAUSE_FIRSTPRIVATE
:
1791 x
= build_outer_var_ref (var
, ctx
);
1792 x
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, new_var
, x
);
1793 gimplify_and_add (x
, ilist
);
1797 case OMP_CLAUSE_COPYIN
:
1798 by_ref
= use_pointer_for_field (var
, false);
1799 x
= build_receiver_ref (var
, by_ref
, ctx
);
1800 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, x
);
1801 append_to_statement_list (x
, ©in_seq
);
1802 copyin_by_ref
|= by_ref
;
1805 case OMP_CLAUSE_REDUCTION
:
1806 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1808 gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c
), ilist
);
1809 OMP_CLAUSE_REDUCTION_INIT (c
) = NULL
;
1813 x
= omp_reduction_init (c
, TREE_TYPE (new_var
));
1814 gcc_assert (TREE_CODE (TREE_TYPE (new_var
)) != ARRAY_TYPE
);
1815 x
= build_gimple_modify_stmt (new_var
, x
);
1816 gimplify_and_add (x
, ilist
);
1826 /* The copyin sequence is not to be executed by the main thread, since
1827 that would result in self-copies. Perhaps not visible to scalars,
1828 but it certainly is to C++ operator=. */
1831 x
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
1832 x
= build2 (NE_EXPR
, boolean_type_node
, x
,
1833 build_int_cst (TREE_TYPE (x
), 0));
1834 x
= build3 (COND_EXPR
, void_type_node
, x
, copyin_seq
, NULL
);
1835 gimplify_and_add (x
, ilist
);
1838 /* If any copyin variable is passed by reference, we must ensure the
1839 master thread doesn't modify it before it is copied over in all
1840 threads. Similarly for variables in both firstprivate and
1841 lastprivate clauses we need to ensure the lastprivate copying
1842 happens after firstprivate copying in all threads. */
1843 if (copyin_by_ref
|| lastprivate_firstprivate
)
1844 gimplify_and_add (build_omp_barrier (), ilist
);
1848 /* Generate code to implement the LASTPRIVATE clauses. This is used for
1849 both parallel and workshare constructs. PREDICATE may be NULL if it's
1853 lower_lastprivate_clauses (tree clauses
, tree predicate
, tree
*stmt_list
,
1856 tree sub_list
, x
, c
;
1858 /* Early exit if there are no lastprivate clauses. */
1859 clauses
= find_omp_clause (clauses
, OMP_CLAUSE_LASTPRIVATE
);
1860 if (clauses
== NULL
)
1862 /* If this was a workshare clause, see if it had been combined
1863 with its parallel. In that case, look for the clauses on the
1864 parallel statement itself. */
1865 if (is_parallel_ctx (ctx
))
1869 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
1872 clauses
= find_omp_clause (OMP_PARALLEL_CLAUSES (ctx
->stmt
),
1873 OMP_CLAUSE_LASTPRIVATE
);
1874 if (clauses
== NULL
)
1878 sub_list
= alloc_stmt_list ();
1880 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1884 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_LASTPRIVATE
)
1887 var
= OMP_CLAUSE_DECL (c
);
1888 new_var
= lookup_decl (var
, ctx
);
1890 x
= build_outer_var_ref (var
, ctx
);
1891 if (is_reference (var
))
1892 new_var
= build_fold_indirect_ref (new_var
);
1893 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, x
, new_var
);
1894 append_to_statement_list (x
, &sub_list
);
1898 x
= build3 (COND_EXPR
, void_type_node
, predicate
, sub_list
, NULL
);
1902 gimplify_and_add (x
, stmt_list
);
1906 /* Generate code to implement the REDUCTION clauses. */
1909 lower_reduction_clauses (tree clauses
, tree
*stmt_list
, omp_context
*ctx
)
1911 tree sub_list
= NULL
, x
, c
;
1914 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
1915 update in that case, otherwise use a lock. */
1916 for (c
= clauses
; c
&& count
< 2; c
= OMP_CLAUSE_CHAIN (c
))
1917 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
1919 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1921 /* Never use OMP_ATOMIC for array reductions. */
1931 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1933 tree var
, ref
, new_var
;
1934 enum tree_code code
;
1936 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
)
1939 var
= OMP_CLAUSE_DECL (c
);
1940 new_var
= lookup_decl (var
, ctx
);
1941 if (is_reference (var
))
1942 new_var
= build_fold_indirect_ref (new_var
);
1943 ref
= build_outer_var_ref (var
, ctx
);
1944 code
= OMP_CLAUSE_REDUCTION_CODE (c
);
1946 /* reduction(-:var) sums up the partial results, so it acts
1947 identically to reduction(+:var). */
1948 if (code
== MINUS_EXPR
)
1953 tree addr
= build_fold_addr_expr (ref
);
1955 addr
= save_expr (addr
);
1956 ref
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (addr
)), addr
);
1957 x
= fold_build2 (code
, TREE_TYPE (ref
), ref
, new_var
);
1958 x
= build2 (OMP_ATOMIC
, void_type_node
, addr
, x
);
1959 gimplify_and_add (x
, stmt_list
);
1963 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1965 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
1967 if (is_reference (var
))
1968 ref
= build_fold_addr_expr (ref
);
1969 SET_DECL_VALUE_EXPR (placeholder
, ref
);
1970 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
1971 gimplify_and_add (OMP_CLAUSE_REDUCTION_MERGE (c
), &sub_list
);
1972 OMP_CLAUSE_REDUCTION_MERGE (c
) = NULL
;
1973 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
) = NULL
;
1977 x
= build2 (code
, TREE_TYPE (ref
), ref
, new_var
);
1978 ref
= build_outer_var_ref (var
, ctx
);
1979 x
= build_gimple_modify_stmt (ref
, x
);
1980 append_to_statement_list (x
, &sub_list
);
1984 x
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_ATOMIC_START
], 0);
1985 gimplify_and_add (x
, stmt_list
);
1987 gimplify_and_add (sub_list
, stmt_list
);
1989 x
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_ATOMIC_END
], 0);
1990 gimplify_and_add (x
, stmt_list
);
1994 /* Generate code to implement the COPYPRIVATE clauses. */
1997 lower_copyprivate_clauses (tree clauses
, tree
*slist
, tree
*rlist
,
2002 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2007 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYPRIVATE
)
2010 var
= OMP_CLAUSE_DECL (c
);
2011 by_ref
= use_pointer_for_field (var
, false);
2013 ref
= build_sender_ref (var
, ctx
);
2014 x
= (ctx
->is_nested
) ? lookup_decl_in_outer_ctx (var
, ctx
) : var
;
2015 x
= by_ref
? build_fold_addr_expr (x
) : x
;
2016 x
= build_gimple_modify_stmt (ref
, x
);
2017 gimplify_and_add (x
, slist
);
2019 ref
= build_receiver_ref (var
, by_ref
, ctx
);
2020 if (is_reference (var
))
2022 ref
= build_fold_indirect_ref (ref
);
2023 var
= build_fold_indirect_ref (var
);
2025 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, var
, ref
);
2026 gimplify_and_add (x
, rlist
);
2031 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2032 and REDUCTION from the sender (aka parent) side. */
2035 lower_send_clauses (tree clauses
, tree
*ilist
, tree
*olist
, omp_context
*ctx
)
2039 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2041 tree val
, ref
, x
, var
;
2042 bool by_ref
, do_in
= false, do_out
= false;
2044 switch (OMP_CLAUSE_CODE (c
))
2046 case OMP_CLAUSE_FIRSTPRIVATE
:
2047 case OMP_CLAUSE_COPYIN
:
2048 case OMP_CLAUSE_LASTPRIVATE
:
2049 case OMP_CLAUSE_REDUCTION
:
2055 var
= val
= OMP_CLAUSE_DECL (c
);
2057 var
= lookup_decl_in_outer_ctx (val
, ctx
);
2059 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYIN
2060 && is_global_var (var
))
2062 if (is_variable_sized (val
))
2064 by_ref
= use_pointer_for_field (val
, false);
2066 switch (OMP_CLAUSE_CODE (c
))
2068 case OMP_CLAUSE_FIRSTPRIVATE
:
2069 case OMP_CLAUSE_COPYIN
:
2073 case OMP_CLAUSE_LASTPRIVATE
:
2074 if (by_ref
|| is_reference (val
))
2076 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2084 case OMP_CLAUSE_REDUCTION
:
2086 do_out
= !(by_ref
|| is_reference (val
));
2095 ref
= build_sender_ref (val
, ctx
);
2096 x
= by_ref
? build_fold_addr_expr (var
) : var
;
2097 x
= build_gimple_modify_stmt (ref
, x
);
2098 gimplify_and_add (x
, ilist
);
2103 ref
= build_sender_ref (val
, ctx
);
2104 x
= build_gimple_modify_stmt (var
, ref
);
2105 gimplify_and_add (x
, olist
);
2110 /* Generate code to implement SHARED from the sender (aka parent) side.
2111 This is trickier, since OMP_PARALLEL_CLAUSES doesn't list things that
2112 got automatically shared. */
2115 lower_send_shared_vars (tree
*ilist
, tree
*olist
, omp_context
*ctx
)
2117 tree var
, ovar
, nvar
, f
, x
;
2119 if (ctx
->record_type
== NULL
)
2122 for (f
= TYPE_FIELDS (ctx
->record_type
); f
; f
= TREE_CHAIN (f
))
2124 ovar
= DECL_ABSTRACT_ORIGIN (f
);
2125 nvar
= maybe_lookup_decl (ovar
, ctx
);
2126 if (!nvar
|| !DECL_HAS_VALUE_EXPR_P (nvar
))
2131 /* If CTX is a nested parallel directive. Find the immediately
2132 enclosing parallel or workshare construct that contains a
2133 mapping for OVAR. */
2135 var
= lookup_decl_in_outer_ctx (ovar
, ctx
);
2137 if (use_pointer_for_field (ovar
, true))
2139 x
= build_sender_ref (ovar
, ctx
);
2140 var
= build_fold_addr_expr (var
);
2141 x
= build_gimple_modify_stmt (x
, var
);
2142 gimplify_and_add (x
, ilist
);
2146 x
= build_sender_ref (ovar
, ctx
);
2147 x
= build_gimple_modify_stmt (x
, var
);
2148 gimplify_and_add (x
, ilist
);
2150 x
= build_sender_ref (ovar
, ctx
);
2151 x
= build_gimple_modify_stmt (var
, x
);
2152 gimplify_and_add (x
, olist
);
2157 /* Build the function calls to GOMP_parallel_start etc to actually
2158 generate the parallel operation. REGION is the parallel region
2159 being expanded. BB is the block where to insert the code. WS_ARGS
2160 will be set if this is a call to a combined parallel+workshare
2161 construct, it contains the list of additional arguments needed by
2162 the workshare construct. */
2165 expand_parallel_call (struct omp_region
*region
, basic_block bb
,
2166 tree entry_stmt
, tree ws_args
)
2168 tree t
, t1
, t2
, val
, cond
, c
, clauses
;
2169 block_stmt_iterator si
;
2172 clauses
= OMP_PARALLEL_CLAUSES (entry_stmt
);
2174 /* Determine what flavor of GOMP_parallel_start we will be
2176 start_ix
= BUILT_IN_GOMP_PARALLEL_START
;
2177 if (is_combined_parallel (region
))
2179 switch (region
->inner
->type
)
2182 start_ix
= BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2183 + region
->inner
->sched_kind
;
2186 start_ix
= BUILT_IN_GOMP_PARALLEL_SECTIONS_START
;
2193 /* By default, the value of NUM_THREADS is zero (selected at run time)
2194 and there is no conditional. */
2196 val
= build_int_cst (unsigned_type_node
, 0);
2198 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
2200 cond
= OMP_CLAUSE_IF_EXPR (c
);
2202 c
= find_omp_clause (clauses
, OMP_CLAUSE_NUM_THREADS
);
2204 val
= OMP_CLAUSE_NUM_THREADS_EXPR (c
);
2206 /* Ensure 'val' is of the correct type. */
2207 val
= fold_convert (unsigned_type_node
, val
);
2209 /* If we found the clause 'if (cond)', build either
2210 (cond != 0) or (cond ? val : 1u). */
2213 block_stmt_iterator si
;
2215 cond
= gimple_boolify (cond
);
2217 if (integer_zerop (val
))
2218 val
= fold_build2 (EQ_EXPR
, unsigned_type_node
, cond
,
2219 build_int_cst (TREE_TYPE (cond
), 0));
2222 basic_block cond_bb
, then_bb
, else_bb
;
2223 edge e
, e_then
, e_else
;
2224 tree t
, tmp_then
, tmp_else
, tmp_join
, tmp_var
;
2226 tmp_var
= create_tmp_var (TREE_TYPE (val
), NULL
);
2227 if (gimple_in_ssa_p (cfun
))
2229 tmp_then
= make_ssa_name (tmp_var
, NULL_TREE
);
2230 tmp_else
= make_ssa_name (tmp_var
, NULL_TREE
);
2231 tmp_join
= make_ssa_name (tmp_var
, NULL_TREE
);
2240 e
= split_block (bb
, NULL
);
2245 then_bb
= create_empty_bb (cond_bb
);
2246 else_bb
= create_empty_bb (then_bb
);
2247 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
2248 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
2250 t
= build3 (COND_EXPR
, void_type_node
,
2251 cond
, NULL_TREE
, NULL_TREE
);
2253 si
= bsi_start (cond_bb
);
2254 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
2256 si
= bsi_start (then_bb
);
2257 t
= build_gimple_modify_stmt (tmp_then
, val
);
2258 if (gimple_in_ssa_p (cfun
))
2259 SSA_NAME_DEF_STMT (tmp_then
) = t
;
2260 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
2262 si
= bsi_start (else_bb
);
2263 t
= build_gimple_modify_stmt (tmp_else
,
2264 build_int_cst (unsigned_type_node
, 1));
2265 if (gimple_in_ssa_p (cfun
))
2266 SSA_NAME_DEF_STMT (tmp_else
) = t
;
2267 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
2269 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
2270 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
2271 e_then
= make_edge (then_bb
, bb
, EDGE_FALLTHRU
);
2272 e_else
= make_edge (else_bb
, bb
, EDGE_FALLTHRU
);
2274 if (gimple_in_ssa_p (cfun
))
2276 tree phi
= create_phi_node (tmp_join
, bb
);
2277 SSA_NAME_DEF_STMT (tmp_join
) = phi
;
2278 add_phi_arg (phi
, tmp_then
, e_then
);
2279 add_phi_arg (phi
, tmp_else
, e_else
);
2285 si
= bsi_start (bb
);
2286 val
= force_gimple_operand_bsi (&si
, val
, true, NULL_TREE
,
2287 false, BSI_CONTINUE_LINKING
);
2291 t
= OMP_PARALLEL_DATA_ARG (entry_stmt
);
2293 t1
= null_pointer_node
;
2295 t1
= build_fold_addr_expr (t
);
2296 t2
= build_fold_addr_expr (OMP_PARALLEL_FN (entry_stmt
));
2300 tree args
= tree_cons (NULL
, t2
,
2301 tree_cons (NULL
, t1
,
2302 tree_cons (NULL
, val
, ws_args
)));
2303 t
= build_function_call_expr (built_in_decls
[start_ix
], args
);
2306 t
= build_call_expr (built_in_decls
[start_ix
], 3, t2
, t1
, val
);
2308 force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2309 false, BSI_CONTINUE_LINKING
);
2311 t
= OMP_PARALLEL_DATA_ARG (entry_stmt
);
2313 t
= null_pointer_node
;
2315 t
= build_fold_addr_expr (t
);
2316 t
= build_call_expr (OMP_PARALLEL_FN (entry_stmt
), 1, t
);
2317 force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2318 false, BSI_CONTINUE_LINKING
);
2320 t
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_PARALLEL_END
], 0);
2321 force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2322 false, BSI_CONTINUE_LINKING
);
2326 /* If exceptions are enabled, wrap *STMT_P in a MUST_NOT_THROW catch
2327 handler. This prevents programs from violating the structured
2328 block semantics with throws. */
2331 maybe_catch_exception (tree
*stmt_p
)
2335 if (!flag_exceptions
)
2338 if (lang_protect_cleanup_actions
)
2339 t
= lang_protect_cleanup_actions ();
2341 t
= build_call_expr (built_in_decls
[BUILT_IN_TRAP
], 0);
2342 f
= build2 (EH_FILTER_EXPR
, void_type_node
, NULL
, NULL
);
2343 EH_FILTER_MUST_NOT_THROW (f
) = 1;
2344 gimplify_and_add (t
, &EH_FILTER_FAILURE (f
));
2346 t
= build2 (TRY_CATCH_EXPR
, void_type_node
, *stmt_p
, NULL
);
2347 append_to_statement_list (f
, &TREE_OPERAND (t
, 1));
2350 append_to_statement_list (t
, stmt_p
);
2353 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
2356 list2chain (tree list
)
2360 for (t
= list
; t
; t
= TREE_CHAIN (t
))
2362 tree var
= TREE_VALUE (t
);
2364 TREE_CHAIN (var
) = TREE_VALUE (TREE_CHAIN (t
));
2366 TREE_CHAIN (var
) = NULL_TREE
;
2369 return list
? TREE_VALUE (list
) : NULL_TREE
;
2373 /* Remove barriers in REGION->EXIT's block. Note that this is only
2374 valid for OMP_PARALLEL regions. Since the end of a parallel region
2375 is an implicit barrier, any workshare inside the OMP_PARALLEL that
2376 left a barrier at the end of the OMP_PARALLEL region can now be
2380 remove_exit_barrier (struct omp_region
*region
)
2382 block_stmt_iterator si
;
2383 basic_block exit_bb
;
2388 exit_bb
= region
->exit
;
2390 /* If the parallel region doesn't return, we don't have REGION->EXIT
2395 /* The last insn in the block will be the parallel's OMP_RETURN. The
2396 workshare's OMP_RETURN will be in a preceding block. The kinds of
2397 statements that can appear in between are extremely limited -- no
2398 memory operations at all. Here, we allow nothing at all, so the
2399 only thing we allow to precede this OMP_RETURN is a label. */
2400 si
= bsi_last (exit_bb
);
2401 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_RETURN
);
2403 if (!bsi_end_p (si
) && TREE_CODE (bsi_stmt (si
)) != LABEL_EXPR
)
2406 FOR_EACH_EDGE (e
, ei
, exit_bb
->preds
)
2408 si
= bsi_last (e
->src
);
2412 if (TREE_CODE (t
) == OMP_RETURN
)
2413 OMP_RETURN_NOWAIT (t
) = 1;
2418 remove_exit_barriers (struct omp_region
*region
)
2420 if (region
->type
== OMP_PARALLEL
)
2421 remove_exit_barrier (region
);
2425 region
= region
->inner
;
2426 remove_exit_barriers (region
);
2427 while (region
->next
)
2429 region
= region
->next
;
2430 remove_exit_barriers (region
);
2435 /* Expand the OpenMP parallel directive starting at REGION. */
2438 expand_omp_parallel (struct omp_region
*region
)
2440 basic_block entry_bb
, exit_bb
, new_bb
;
2441 struct function
*child_cfun
;
2442 tree child_fn
, block
, t
, ws_args
;
2443 block_stmt_iterator si
;
2447 entry_stmt
= last_stmt (region
->entry
);
2448 child_fn
= OMP_PARALLEL_FN (entry_stmt
);
2449 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
2451 entry_bb
= region
->entry
;
2452 exit_bb
= region
->exit
;
2454 if (is_combined_parallel (region
))
2455 ws_args
= region
->ws_args
;
2457 ws_args
= NULL_TREE
;
2459 if (child_cfun
->cfg
)
2461 /* Due to inlining, it may happen that we have already outlined
2462 the region, in which case all we need to do is make the
2463 sub-graph unreachable and emit the parallel call. */
2464 edge entry_succ_e
, exit_succ_e
;
2465 block_stmt_iterator si
;
2467 entry_succ_e
= single_succ_edge (entry_bb
);
2469 si
= bsi_last (entry_bb
);
2470 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_PARALLEL
);
2471 bsi_remove (&si
, true);
2476 exit_succ_e
= single_succ_edge (exit_bb
);
2477 make_edge (new_bb
, exit_succ_e
->dest
, EDGE_FALLTHRU
);
2479 remove_edge_and_dominated_blocks (entry_succ_e
);
2483 /* If the parallel region needs data sent from the parent
2484 function, then the very first statement (except possible
2485 tree profile counter updates) of the parallel body
2486 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
2487 &.OMP_DATA_O is passed as an argument to the child function,
2488 we need to replace it with the argument as seen by the child
2491 In most cases, this will end up being the identity assignment
2492 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
2493 a function call that has been inlined, the original PARM_DECL
2494 .OMP_DATA_I may have been converted into a different local
2495 variable. In which case, we need to keep the assignment. */
2496 if (OMP_PARALLEL_DATA_ARG (entry_stmt
))
2498 basic_block entry_succ_bb
= single_succ (entry_bb
);
2499 block_stmt_iterator si
;
2500 tree parcopy_stmt
= NULL_TREE
, arg
, narg
;
2502 for (si
= bsi_start (entry_succ_bb
); ; bsi_next (&si
))
2506 gcc_assert (!bsi_end_p (si
));
2507 stmt
= bsi_stmt (si
);
2508 if (TREE_CODE (stmt
) != GIMPLE_MODIFY_STMT
)
2511 arg
= GIMPLE_STMT_OPERAND (stmt
, 1);
2513 if (TREE_CODE (arg
) == ADDR_EXPR
2514 && TREE_OPERAND (arg
, 0)
2515 == OMP_PARALLEL_DATA_ARG (entry_stmt
))
2517 parcopy_stmt
= stmt
;
2522 gcc_assert (parcopy_stmt
!= NULL_TREE
);
2523 arg
= DECL_ARGUMENTS (child_fn
);
2525 if (!gimple_in_ssa_p (cfun
))
2527 if (GIMPLE_STMT_OPERAND (parcopy_stmt
, 0) == arg
)
2528 bsi_remove (&si
, true);
2530 GIMPLE_STMT_OPERAND (parcopy_stmt
, 1) = arg
;
2534 /* If we are in ssa form, we must load the value from the default
2535 definition of the argument. That should not be defined now,
2536 since the argument is not used uninitialized. */
2537 gcc_assert (gimple_default_def (cfun
, arg
) == NULL
);
2538 narg
= make_ssa_name (arg
, build_empty_stmt ());
2539 set_default_def (arg
, narg
);
2540 GIMPLE_STMT_OPERAND (parcopy_stmt
, 1) = narg
;
2541 update_stmt (parcopy_stmt
);
2545 /* Declare local variables needed in CHILD_CFUN. */
2546 block
= DECL_INITIAL (child_fn
);
2547 BLOCK_VARS (block
) = list2chain (child_cfun
->unexpanded_var_list
);
2548 DECL_SAVED_TREE (child_fn
) = bb_stmt_list (single_succ (entry_bb
));
2550 /* Reset DECL_CONTEXT on function arguments. */
2551 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= TREE_CHAIN (t
))
2552 DECL_CONTEXT (t
) = child_fn
;
2554 /* Split ENTRY_BB at OMP_PARALLEL so that it can be moved to the
2556 si
= bsi_last (entry_bb
);
2558 gcc_assert (t
&& TREE_CODE (t
) == OMP_PARALLEL
);
2559 bsi_remove (&si
, true);
2560 e
= split_block (entry_bb
, t
);
2562 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
2564 /* Convert OMP_RETURN into a RETURN_EXPR. */
2567 si
= bsi_last (exit_bb
);
2568 gcc_assert (!bsi_end_p (si
)
2569 && TREE_CODE (bsi_stmt (si
)) == OMP_RETURN
);
2570 t
= build1 (RETURN_EXPR
, void_type_node
, NULL
);
2571 bsi_insert_after (&si
, t
, BSI_SAME_STMT
);
2572 bsi_remove (&si
, true);
2575 /* Move the parallel region into CHILD_CFUN. */
2577 if (gimple_in_ssa_p (cfun
))
2579 push_cfun (child_cfun
);
2581 init_ssa_operands ();
2582 cfun
->gimple_df
->in_ssa_p
= true;
2585 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
);
2587 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
2589 /* Inform the callgraph about the new function. */
2590 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
2591 = cfun
->curr_properties
;
2592 cgraph_add_new_function (child_fn
, true);
2594 /* Fix the callgraph edges for child_cfun. Those for cfun will be
2595 fixed in a following pass. */
2596 push_cfun (child_cfun
);
2597 rebuild_cgraph_edges ();
2601 /* Emit a library call to launch the children threads. */
2602 expand_parallel_call (region
, new_bb
, entry_stmt
, ws_args
);
2603 update_ssa (TODO_update_ssa_only_virtuals
);
2607 /* A subroutine of expand_omp_for. Generate code for a parallel
2608 loop with any schedule. Given parameters:
2610 for (V = N1; V cond N2; V += STEP) BODY;
2612 where COND is "<" or ">", we generate pseudocode
2614 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
2615 if (more) goto L0; else goto L3;
2622 if (V cond iend) goto L1; else goto L2;
2624 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
2627 If this is a combined omp parallel loop, instead of the call to
2628 GOMP_loop_foo_start, we call GOMP_loop_foo_next. */
2631 expand_omp_for_generic (struct omp_region
*region
,
2632 struct omp_for_data
*fd
,
2633 enum built_in_function start_fn
,
2634 enum built_in_function next_fn
)
2636 tree type
, istart0
, iend0
, iend
, phi
;
2637 tree t
, vmain
, vback
;
2638 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
;
2639 basic_block l2_bb
= NULL
, l3_bb
= NULL
;
2640 block_stmt_iterator si
;
2641 bool in_combined_parallel
= is_combined_parallel (region
);
2642 bool broken_loop
= region
->cont
== NULL
;
2645 gcc_assert (!broken_loop
|| !in_combined_parallel
);
2647 type
= TREE_TYPE (fd
->v
);
2649 istart0
= create_tmp_var (long_integer_type_node
, ".istart0");
2650 iend0
= create_tmp_var (long_integer_type_node
, ".iend0");
2651 TREE_ADDRESSABLE (istart0
) = 1;
2652 TREE_ADDRESSABLE (iend0
) = 1;
2653 if (gimple_in_ssa_p (cfun
))
2655 add_referenced_var (istart0
);
2656 add_referenced_var (iend0
);
2659 entry_bb
= region
->entry
;
2660 cont_bb
= region
->cont
;
2661 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
2662 gcc_assert (broken_loop
2663 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
2664 l0_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
2665 l1_bb
= single_succ (l0_bb
);
2668 l2_bb
= create_empty_bb (cont_bb
);
2669 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l1_bb
);
2670 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
2674 l3_bb
= BRANCH_EDGE (entry_bb
)->dest
;
2675 exit_bb
= region
->exit
;
2677 si
= bsi_last (entry_bb
);
2678 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_FOR
);
2679 if (in_combined_parallel
)
2681 /* In a combined parallel loop, emit a call to
2682 GOMP_loop_foo_next. */
2683 t
= build_call_expr (built_in_decls
[next_fn
], 2,
2684 build_fold_addr_expr (istart0
),
2685 build_fold_addr_expr (iend0
));
2689 tree t0
, t1
, t2
, t3
, t4
;
2690 /* If this is not a combined parallel loop, emit a call to
2691 GOMP_loop_foo_start in ENTRY_BB. */
2692 t4
= build_fold_addr_expr (iend0
);
2693 t3
= build_fold_addr_expr (istart0
);
2694 t2
= fold_convert (long_integer_type_node
, fd
->step
);
2695 t1
= fold_convert (long_integer_type_node
, fd
->n2
);
2696 t0
= fold_convert (long_integer_type_node
, fd
->n1
);
2699 t
= fold_convert (long_integer_type_node
, fd
->chunk_size
);
2700 t
= build_call_expr (built_in_decls
[start_fn
], 6,
2701 t0
, t1
, t2
, t
, t3
, t4
);
2704 t
= build_call_expr (built_in_decls
[start_fn
], 5,
2705 t0
, t1
, t2
, t3
, t4
);
2707 t
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2708 true, BSI_SAME_STMT
);
2709 t
= build3 (COND_EXPR
, void_type_node
, t
, NULL_TREE
, NULL_TREE
);
2710 bsi_insert_after (&si
, t
, BSI_SAME_STMT
);
2712 /* V may be used outside of the loop (e.g., to handle lastprivate clause).
2713 If this is the case, its value is undefined if the loop is not entered
2714 at all. To handle this case, set its initial value to N1. */
2715 if (gimple_in_ssa_p (cfun
))
2717 e
= find_edge (entry_bb
, l3_bb
);
2718 for (phi
= phi_nodes (l3_bb
); phi
; phi
= PHI_CHAIN (phi
))
2719 if (PHI_ARG_DEF_FROM_EDGE (phi
, e
) == fd
->v
)
2720 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, e
), fd
->n1
);
2724 t
= build_gimple_modify_stmt (fd
->v
, fd
->n1
);
2725 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
2728 /* Remove the OMP_FOR statement. */
2729 bsi_remove (&si
, true);
2731 /* Iteration setup for sequential loop goes in L0_BB. */
2732 si
= bsi_start (l0_bb
);
2733 t
= fold_convert (type
, istart0
);
2734 t
= force_gimple_operand_bsi (&si
, t
, false, NULL_TREE
,
2735 false, BSI_CONTINUE_LINKING
);
2736 t
= build_gimple_modify_stmt (fd
->v
, t
);
2737 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
2738 if (gimple_in_ssa_p (cfun
))
2739 SSA_NAME_DEF_STMT (fd
->v
) = t
;
2741 t
= fold_convert (type
, iend0
);
2742 iend
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2743 false, BSI_CONTINUE_LINKING
);
2747 /* Code to control the increment and predicate for the sequential
2748 loop goes in the CONT_BB. */
2749 si
= bsi_last (cont_bb
);
2751 gcc_assert (TREE_CODE (t
) == OMP_CONTINUE
);
2752 vmain
= TREE_OPERAND (t
, 1);
2753 vback
= TREE_OPERAND (t
, 0);
2755 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->step
);
2756 t
= force_gimple_operand_bsi (&si
, t
, false, NULL_TREE
,
2757 true, BSI_SAME_STMT
);
2758 t
= build_gimple_modify_stmt (vback
, t
);
2759 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
2760 if (gimple_in_ssa_p (cfun
))
2761 SSA_NAME_DEF_STMT (vback
) = t
;
2763 t
= build2 (fd
->cond_code
, boolean_type_node
, vback
, iend
);
2764 t
= build3 (COND_EXPR
, void_type_node
, t
, NULL_TREE
, NULL_TREE
);
2765 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
2767 /* Remove OMP_CONTINUE. */
2768 bsi_remove (&si
, true);
2770 /* Emit code to get the next parallel iteration in L2_BB. */
2771 si
= bsi_start (l2_bb
);
2773 t
= build_call_expr (built_in_decls
[next_fn
], 2,
2774 build_fold_addr_expr (istart0
),
2775 build_fold_addr_expr (iend0
));
2776 t
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2777 false, BSI_CONTINUE_LINKING
);
2778 t
= build3 (COND_EXPR
, void_type_node
, t
, NULL_TREE
, NULL_TREE
);
2779 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
2782 /* Add the loop cleanup function. */
2783 si
= bsi_last (exit_bb
);
2784 if (OMP_RETURN_NOWAIT (bsi_stmt (si
)))
2785 t
= built_in_decls
[BUILT_IN_GOMP_LOOP_END_NOWAIT
];
2787 t
= built_in_decls
[BUILT_IN_GOMP_LOOP_END
];
2788 t
= build_call_expr (t
, 0);
2789 bsi_insert_after (&si
, t
, BSI_SAME_STMT
);
2790 bsi_remove (&si
, true);
2792 /* Connect the new blocks. */
2793 find_edge (entry_bb
, l0_bb
)->flags
= EDGE_TRUE_VALUE
;
2794 find_edge (entry_bb
, l3_bb
)->flags
= EDGE_FALSE_VALUE
;
2798 e
= find_edge (cont_bb
, l3_bb
);
2799 ne
= make_edge (l2_bb
, l3_bb
, EDGE_FALSE_VALUE
);
2801 for (phi
= phi_nodes (l3_bb
); phi
; phi
= PHI_CHAIN (phi
))
2802 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, ne
),
2803 PHI_ARG_DEF_FROM_EDGE (phi
, e
));
2806 find_edge (cont_bb
, l1_bb
)->flags
= EDGE_TRUE_VALUE
;
2807 make_edge (cont_bb
, l2_bb
, EDGE_FALSE_VALUE
);
2808 make_edge (l2_bb
, l0_bb
, EDGE_TRUE_VALUE
);
2810 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
,
2811 recompute_dominator (CDI_DOMINATORS
, l2_bb
));
2812 set_immediate_dominator (CDI_DOMINATORS
, l3_bb
,
2813 recompute_dominator (CDI_DOMINATORS
, l3_bb
));
2814 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
,
2815 recompute_dominator (CDI_DOMINATORS
, l0_bb
));
2816 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
,
2817 recompute_dominator (CDI_DOMINATORS
, l1_bb
));
2822 /* A subroutine of expand_omp_for. Generate code for a parallel
2823 loop with static schedule and no specified chunk size. Given
2826 for (V = N1; V cond N2; V += STEP) BODY;
2828 where COND is "<" or ">", we generate pseudocode
2834 n = (adj + N2 - N1) / STEP;
2836 q += (q * nthreads != n);
2838 e0 = min(s0 + q, n);
2840 if (s0 >= e0) goto L2; else goto L0;
2846 if (V cond e) goto L1;
2851 expand_omp_for_static_nochunk (struct omp_region
*region
,
2852 struct omp_for_data
*fd
)
2854 tree n
, q
, s0
, e0
, e
, t
, nthreads
, threadid
;
2855 tree type
, vmain
, vback
;
2856 basic_block entry_bb
, exit_bb
, seq_start_bb
, body_bb
, cont_bb
;
2858 block_stmt_iterator si
;
2860 type
= TREE_TYPE (fd
->v
);
2862 entry_bb
= region
->entry
;
2863 cont_bb
= region
->cont
;
2864 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
2865 gcc_assert (BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
2866 seq_start_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
2867 body_bb
= single_succ (seq_start_bb
);
2868 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
2869 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
2870 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
2871 exit_bb
= region
->exit
;
2873 /* Iteration space partitioning goes in ENTRY_BB. */
2874 si
= bsi_last (entry_bb
);
2875 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_FOR
);
2877 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
], 0);
2878 t
= fold_convert (type
, t
);
2879 nthreads
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2880 true, BSI_SAME_STMT
);
2882 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
2883 t
= fold_convert (type
, t
);
2884 threadid
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2885 true, BSI_SAME_STMT
);
2887 fd
->n1
= force_gimple_operand_bsi (&si
,
2888 fold_convert (type
, fd
->n1
),
2890 true, BSI_SAME_STMT
);
2892 fd
->n2
= force_gimple_operand_bsi (&si
,
2893 fold_convert (type
, fd
->n2
),
2895 true, BSI_SAME_STMT
);
2897 fd
->step
= force_gimple_operand_bsi (&si
,
2898 fold_convert (type
, fd
->step
),
2900 true, BSI_SAME_STMT
);
2902 t
= build_int_cst (type
, (fd
->cond_code
== LT_EXPR
? -1 : 1));
2903 t
= fold_build2 (PLUS_EXPR
, type
, fd
->step
, t
);
2904 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->n2
);
2905 t
= fold_build2 (MINUS_EXPR
, type
, t
, fd
->n1
);
2906 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, t
, fd
->step
);
2907 t
= fold_convert (type
, t
);
2908 n
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
, true, BSI_SAME_STMT
);
2910 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, n
, nthreads
);
2911 q
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
, true, BSI_SAME_STMT
);
2913 t
= fold_build2 (MULT_EXPR
, type
, q
, nthreads
);
2914 t
= fold_build2 (NE_EXPR
, type
, t
, n
);
2915 t
= fold_build2 (PLUS_EXPR
, type
, q
, t
);
2916 q
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
, true, BSI_SAME_STMT
);
2918 t
= build2 (MULT_EXPR
, type
, q
, threadid
);
2919 s0
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
, true, BSI_SAME_STMT
);
2921 t
= fold_build2 (PLUS_EXPR
, type
, s0
, q
);
2922 t
= fold_build2 (MIN_EXPR
, type
, t
, n
);
2923 e0
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
, true, BSI_SAME_STMT
);
2925 t
= fold_convert (type
, s0
);
2926 t
= fold_build2 (MULT_EXPR
, type
, t
, fd
->step
);
2927 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->n1
);
2928 t
= force_gimple_operand_bsi (&si
, t
, false, NULL_TREE
,
2929 true, BSI_SAME_STMT
);
2930 t
= build_gimple_modify_stmt (fd
->v
, t
);
2931 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
2932 if (gimple_in_ssa_p (cfun
))
2933 SSA_NAME_DEF_STMT (fd
->v
) = t
;
2935 t
= build2 (GE_EXPR
, boolean_type_node
, s0
, e0
);
2936 t
= build3 (COND_EXPR
, void_type_node
, t
, NULL_TREE
, NULL_TREE
);
2937 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
2939 /* Remove the OMP_FOR statement. */
2940 bsi_remove (&si
, true);
2942 /* Setup code for sequential iteration goes in SEQ_START_BB. */
2943 si
= bsi_start (seq_start_bb
);
2945 t
= fold_convert (type
, e0
);
2946 t
= fold_build2 (MULT_EXPR
, type
, t
, fd
->step
);
2947 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->n1
);
2948 e
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
2949 false, BSI_CONTINUE_LINKING
);
2951 /* The code controlling the sequential loop replaces the OMP_CONTINUE. */
2952 si
= bsi_last (cont_bb
);
2954 gcc_assert (TREE_CODE (t
) == OMP_CONTINUE
);
2955 vmain
= TREE_OPERAND (t
, 1);
2956 vback
= TREE_OPERAND (t
, 0);
2958 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->step
);
2959 t
= force_gimple_operand_bsi (&si
, t
, false, NULL_TREE
,
2960 true, BSI_SAME_STMT
);
2961 t
= build_gimple_modify_stmt (vback
, t
);
2962 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
2963 if (gimple_in_ssa_p (cfun
))
2964 SSA_NAME_DEF_STMT (vback
) = t
;
2966 t
= build2 (fd
->cond_code
, boolean_type_node
, vback
, e
);
2967 t
= build3 (COND_EXPR
, void_type_node
, t
, NULL_TREE
, NULL_TREE
);
2968 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
2970 /* Remove the OMP_CONTINUE statement. */
2971 bsi_remove (&si
, true);
2973 /* Replace the OMP_RETURN with a barrier, or nothing. */
2974 si
= bsi_last (exit_bb
);
2975 if (!OMP_RETURN_NOWAIT (bsi_stmt (si
)))
2976 force_gimple_operand_bsi (&si
, build_omp_barrier (), false, NULL_TREE
,
2977 false, BSI_SAME_STMT
);
2978 bsi_remove (&si
, true);
2980 /* Connect all the blocks. */
2981 find_edge (entry_bb
, seq_start_bb
)->flags
= EDGE_FALSE_VALUE
;
2982 find_edge (entry_bb
, fin_bb
)->flags
= EDGE_TRUE_VALUE
;
2984 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
2985 find_edge (cont_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
2987 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
, entry_bb
);
2988 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
2989 recompute_dominator (CDI_DOMINATORS
, body_bb
));
2990 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
2991 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
2995 /* A subroutine of expand_omp_for. Generate code for a parallel
2996 loop with static schedule and a specified chunk size. Given
2999 for (V = N1; V cond N2; V += STEP) BODY;
3001 where COND is "<" or ">", we generate pseudocode
3007 n = (adj + N2 - N1) / STEP;
3009 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
3010 here so that V is defined
3011 if the loop is not entered
3013 s0 = (trip * nthreads + threadid) * CHUNK;
3014 e0 = min(s0 + CHUNK, n);
3015 if (s0 < n) goto L1; else goto L4;
3022 if (V cond e) goto L2; else goto L3;
3030 expand_omp_for_static_chunk (struct omp_region
*region
, struct omp_for_data
*fd
)
3032 tree n
, s0
, e0
, e
, t
, phi
, nphi
, args
;
3033 tree trip_var
, trip_init
, trip_main
, trip_back
, nthreads
, threadid
;
3034 tree type
, cont
, v_main
, v_back
, v_extra
;
3035 basic_block entry_bb
, exit_bb
, body_bb
, seq_start_bb
, iter_part_bb
;
3036 basic_block trip_update_bb
, cont_bb
, fin_bb
;
3037 block_stmt_iterator si
;
3040 type
= TREE_TYPE (fd
->v
);
3042 entry_bb
= region
->entry
;
3043 se
= split_block (entry_bb
, last_stmt (entry_bb
));
3045 iter_part_bb
= se
->dest
;
3046 cont_bb
= region
->cont
;
3047 gcc_assert (EDGE_COUNT (iter_part_bb
->succs
) == 2);
3048 gcc_assert (BRANCH_EDGE (iter_part_bb
)->dest
3049 == FALLTHRU_EDGE (cont_bb
)->dest
);
3050 seq_start_bb
= split_edge (FALLTHRU_EDGE (iter_part_bb
));
3051 body_bb
= single_succ (seq_start_bb
);
3052 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
3053 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
3054 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
3055 trip_update_bb
= split_edge (FALLTHRU_EDGE (cont_bb
));
3056 exit_bb
= region
->exit
;
3058 /* Trip and adjustment setup goes in ENTRY_BB. */
3059 si
= bsi_last (entry_bb
);
3060 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_FOR
);
3062 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
], 0);
3063 t
= fold_convert (type
, t
);
3064 nthreads
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
3065 true, BSI_SAME_STMT
);
3067 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
3068 t
= fold_convert (type
, t
);
3069 threadid
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
3070 true, BSI_SAME_STMT
);
3072 fd
->n1
= force_gimple_operand_bsi (&si
, fold_convert (type
, fd
->n1
),
3074 true, BSI_SAME_STMT
);
3075 fd
->n2
= force_gimple_operand_bsi (&si
, fold_convert (type
, fd
->n2
),
3077 true, BSI_SAME_STMT
);
3078 fd
->step
= force_gimple_operand_bsi (&si
, fold_convert (type
, fd
->step
),
3080 true, BSI_SAME_STMT
);
3082 = force_gimple_operand_bsi (&si
, fold_convert (type
,
3085 true, BSI_SAME_STMT
);
3087 t
= build_int_cst (type
, (fd
->cond_code
== LT_EXPR
? -1 : 1));
3088 t
= fold_build2 (PLUS_EXPR
, type
, fd
->step
, t
);
3089 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->n2
);
3090 t
= fold_build2 (MINUS_EXPR
, type
, t
, fd
->n1
);
3091 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, t
, fd
->step
);
3092 t
= fold_convert (type
, t
);
3093 n
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
3094 true, BSI_SAME_STMT
);
3096 trip_var
= create_tmp_var (type
, ".trip");
3097 if (gimple_in_ssa_p (cfun
))
3099 add_referenced_var (trip_var
);
3100 trip_init
= make_ssa_name (trip_var
, NULL_TREE
);
3101 trip_main
= make_ssa_name (trip_var
, NULL_TREE
);
3102 trip_back
= make_ssa_name (trip_var
, NULL_TREE
);
3106 trip_init
= trip_var
;
3107 trip_main
= trip_var
;
3108 trip_back
= trip_var
;
3111 t
= build_gimple_modify_stmt (trip_init
, build_int_cst (type
, 0));
3112 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
3113 if (gimple_in_ssa_p (cfun
))
3114 SSA_NAME_DEF_STMT (trip_init
) = t
;
3116 t
= fold_build2 (MULT_EXPR
, type
, threadid
, fd
->chunk_size
);
3117 t
= fold_build2 (MULT_EXPR
, type
, t
, fd
->step
);
3118 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->n1
);
3119 v_extra
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
3120 true, BSI_SAME_STMT
);
3122 /* Remove the OMP_FOR. */
3123 bsi_remove (&si
, true);
3125 /* Iteration space partitioning goes in ITER_PART_BB. */
3126 si
= bsi_last (iter_part_bb
);
3128 t
= fold_build2 (MULT_EXPR
, type
, trip_main
, nthreads
);
3129 t
= fold_build2 (PLUS_EXPR
, type
, t
, threadid
);
3130 t
= fold_build2 (MULT_EXPR
, type
, t
, fd
->chunk_size
);
3131 s0
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
3132 false, BSI_CONTINUE_LINKING
);
3134 t
= fold_build2 (PLUS_EXPR
, type
, s0
, fd
->chunk_size
);
3135 t
= fold_build2 (MIN_EXPR
, type
, t
, n
);
3136 e0
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
3137 false, BSI_CONTINUE_LINKING
);
3139 t
= build2 (LT_EXPR
, boolean_type_node
, s0
, n
);
3140 t
= build3 (COND_EXPR
, void_type_node
, t
, NULL_TREE
, NULL_TREE
);
3141 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
3143 /* Setup code for sequential iteration goes in SEQ_START_BB. */
3144 si
= bsi_start (seq_start_bb
);
3146 t
= fold_convert (type
, s0
);
3147 t
= fold_build2 (MULT_EXPR
, type
, t
, fd
->step
);
3148 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->n1
);
3149 t
= force_gimple_operand_bsi (&si
, t
, false, NULL_TREE
,
3150 false, BSI_CONTINUE_LINKING
);
3151 t
= build_gimple_modify_stmt (fd
->v
, t
);
3152 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
3153 if (gimple_in_ssa_p (cfun
))
3154 SSA_NAME_DEF_STMT (fd
->v
) = t
;
3156 t
= fold_convert (type
, e0
);
3157 t
= fold_build2 (MULT_EXPR
, type
, t
, fd
->step
);
3158 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->n1
);
3159 e
= force_gimple_operand_bsi (&si
, t
, true, NULL_TREE
,
3160 false, BSI_CONTINUE_LINKING
);
3162 /* The code controlling the sequential loop goes in CONT_BB,
3163 replacing the OMP_CONTINUE. */
3164 si
= bsi_last (cont_bb
);
3165 cont
= bsi_stmt (si
);
3166 gcc_assert (TREE_CODE (cont
) == OMP_CONTINUE
);
3167 v_main
= TREE_OPERAND (cont
, 1);
3168 v_back
= TREE_OPERAND (cont
, 0);
3170 t
= build2 (PLUS_EXPR
, type
, v_main
, fd
->step
);
3171 t
= build_gimple_modify_stmt (v_back
, t
);
3172 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
3173 if (gimple_in_ssa_p (cfun
))
3174 SSA_NAME_DEF_STMT (v_back
) = t
;
3176 t
= build2 (fd
->cond_code
, boolean_type_node
, v_back
, e
);
3177 t
= build3 (COND_EXPR
, void_type_node
, t
, NULL_TREE
, NULL_TREE
);
3178 bsi_insert_before (&si
, t
, BSI_SAME_STMT
);
3180 /* Remove OMP_CONTINUE. */
3181 bsi_remove (&si
, true);
3183 /* Trip update code goes into TRIP_UPDATE_BB. */
3184 si
= bsi_start (trip_update_bb
);
3186 t
= build_int_cst (type
, 1);
3187 t
= build2 (PLUS_EXPR
, type
, trip_main
, t
);
3188 t
= build_gimple_modify_stmt (trip_back
, t
);
3189 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
3190 if (gimple_in_ssa_p (cfun
))
3191 SSA_NAME_DEF_STMT (trip_back
) = t
;
3193 /* Replace the OMP_RETURN with a barrier, or nothing. */
3194 si
= bsi_last (exit_bb
);
3195 if (!OMP_RETURN_NOWAIT (bsi_stmt (si
)))
3196 force_gimple_operand_bsi (&si
, build_omp_barrier (), false, NULL_TREE
,
3197 false, BSI_SAME_STMT
);
3198 bsi_remove (&si
, true);
3200 /* Connect the new blocks. */
3201 find_edge (iter_part_bb
, seq_start_bb
)->flags
= EDGE_TRUE_VALUE
;
3202 find_edge (iter_part_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
3204 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
3205 find_edge (cont_bb
, trip_update_bb
)->flags
= EDGE_FALSE_VALUE
;
3207 redirect_edge_and_branch (single_succ_edge (trip_update_bb
), iter_part_bb
);
3209 if (gimple_in_ssa_p (cfun
))
3211 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
3212 remove arguments of the phi nodes in fin_bb. We need to create
3213 appropriate phi nodes in iter_part_bb instead. */
3214 se
= single_pred_edge (fin_bb
);
3215 re
= single_succ_edge (trip_update_bb
);
3216 ene
= single_succ_edge (entry_bb
);
3218 args
= PENDING_STMT (re
);
3219 PENDING_STMT (re
) = NULL_TREE
;
3220 for (phi
= phi_nodes (fin_bb
);
3222 phi
= PHI_CHAIN (phi
), args
= TREE_CHAIN (args
))
3224 t
= PHI_RESULT (phi
);
3225 gcc_assert (t
== TREE_PURPOSE (args
));
3226 nphi
= create_phi_node (t
, iter_part_bb
);
3227 SSA_NAME_DEF_STMT (t
) = nphi
;
3229 t
= PHI_ARG_DEF_FROM_EDGE (phi
, se
);
3230 /* A special case -- fd->v is not yet computed in iter_part_bb, we
3231 need to use v_extra instead. */
3234 add_phi_arg (nphi
, t
, ene
);
3235 add_phi_arg (nphi
, TREE_VALUE (args
), re
);
3237 gcc_assert (!phi
&& !args
);
3238 while ((phi
= phi_nodes (fin_bb
)) != NULL_TREE
)
3239 remove_phi_node (phi
, NULL_TREE
, false);
3241 /* Make phi node for trip. */
3242 phi
= create_phi_node (trip_main
, iter_part_bb
);
3243 SSA_NAME_DEF_STMT (trip_main
) = phi
;
3244 add_phi_arg (phi
, trip_back
, single_succ_edge (trip_update_bb
));
3245 add_phi_arg (phi
, trip_init
, single_succ_edge (entry_bb
));
3248 set_immediate_dominator (CDI_DOMINATORS
, trip_update_bb
, cont_bb
);
3249 set_immediate_dominator (CDI_DOMINATORS
, iter_part_bb
,
3250 recompute_dominator (CDI_DOMINATORS
, iter_part_bb
));
3251 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
3252 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
3253 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
,
3254 recompute_dominator (CDI_DOMINATORS
, seq_start_bb
));
3255 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
3256 recompute_dominator (CDI_DOMINATORS
, body_bb
));
3260 /* Expand the OpenMP loop defined by REGION. */
3263 expand_omp_for (struct omp_region
*region
)
3265 struct omp_for_data fd
;
3267 extract_omp_for_data (last_stmt (region
->entry
), &fd
);
3268 region
->sched_kind
= fd
.sched_kind
;
3270 if (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
3272 && region
->cont
!= NULL
)
3274 if (fd
.chunk_size
== NULL
)
3275 expand_omp_for_static_nochunk (region
, &fd
);
3277 expand_omp_for_static_chunk (region
, &fd
);
3281 int fn_index
= fd
.sched_kind
+ fd
.have_ordered
* 4;
3282 int start_ix
= BUILT_IN_GOMP_LOOP_STATIC_START
+ fn_index
;
3283 int next_ix
= BUILT_IN_GOMP_LOOP_STATIC_NEXT
+ fn_index
;
3284 expand_omp_for_generic (region
, &fd
, start_ix
, next_ix
);
3287 update_ssa (TODO_update_ssa_only_virtuals
);
3291 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
3293 v = GOMP_sections_start (n);
3310 v = GOMP_sections_next ();
3315 If this is a combined parallel sections, replace the call to
3316 GOMP_sections_start with call to GOMP_sections_next. */
3319 expand_omp_sections (struct omp_region
*region
)
3321 tree label_vec
, l1
, l2
, t
, u
, sections_stmt
, vin
, vmain
, vnext
, cont
;
3322 unsigned i
, casei
, len
;
3323 basic_block entry_bb
, l0_bb
, l1_bb
, l2_bb
, default_bb
;
3324 block_stmt_iterator si
;
3325 struct omp_region
*inner
;
3326 bool exit_reachable
= region
->cont
!= NULL
;
3328 gcc_assert (exit_reachable
== (region
->exit
!= NULL
));
3329 entry_bb
= region
->entry
;
3330 l0_bb
= single_succ (entry_bb
);
3331 l1_bb
= region
->cont
;
3332 l2_bb
= region
->exit
;
3335 gcc_assert (single_pred (l2_bb
) == l0_bb
);
3336 default_bb
= create_empty_bb (l1_bb
->prev_bb
);
3337 l1
= tree_block_label (l1_bb
);
3338 l2
= tree_block_label (l2_bb
);
3342 default_bb
= create_empty_bb (l0_bb
);
3344 l2
= tree_block_label (default_bb
);
3347 /* We will build a switch() with enough cases for all the
3348 OMP_SECTION regions, a '0' case to handle the end of more work
3349 and a default case to abort if something goes wrong. */
3350 len
= EDGE_COUNT (l0_bb
->succs
);
3351 label_vec
= make_tree_vec (len
+ 1);
3353 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
3354 OMP_SECTIONS statement. */
3355 si
= bsi_last (entry_bb
);
3356 sections_stmt
= bsi_stmt (si
);
3357 gcc_assert (TREE_CODE (sections_stmt
) == OMP_SECTIONS
);
3358 vin
= OMP_SECTIONS_CONTROL (sections_stmt
);
3359 if (!is_combined_parallel (region
))
3361 /* If we are not inside a combined parallel+sections region,
3362 call GOMP_sections_start. */
3363 t
= build_int_cst (unsigned_type_node
,
3364 exit_reachable
? len
- 1 : len
);
3365 u
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_START
];
3366 t
= build_call_expr (u
, 1, t
);
3370 /* Otherwise, call GOMP_sections_next. */
3371 u
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_NEXT
];
3372 t
= build_call_expr (u
, 0);
3374 t
= build_gimple_modify_stmt (vin
, t
);
3375 bsi_insert_after (&si
, t
, BSI_SAME_STMT
);
3376 if (gimple_in_ssa_p (cfun
))
3377 SSA_NAME_DEF_STMT (vin
) = t
;
3378 bsi_remove (&si
, true);
3380 /* The switch() statement replacing OMP_SECTIONS_SWITCH goes in L0_BB. */
3381 si
= bsi_last (l0_bb
);
3382 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_SECTIONS_SWITCH
);
3385 cont
= last_stmt (l1_bb
);
3386 gcc_assert (TREE_CODE (cont
) == OMP_CONTINUE
);
3387 vmain
= TREE_OPERAND (cont
, 1);
3388 vnext
= TREE_OPERAND (cont
, 0);
3396 t
= build3 (SWITCH_EXPR
, void_type_node
, vmain
, NULL
, label_vec
);
3397 bsi_insert_after (&si
, t
, BSI_SAME_STMT
);
3398 bsi_remove (&si
, true);
3403 t
= build3 (CASE_LABEL_EXPR
, void_type_node
,
3404 build_int_cst (unsigned_type_node
, 0), NULL
, l2
);
3405 TREE_VEC_ELT (label_vec
, 0) = t
;
3409 /* Convert each OMP_SECTION into a CASE_LABEL_EXPR. */
3410 for (inner
= region
->inner
, casei
= 1;
3412 inner
= inner
->next
, i
++, casei
++)
3414 basic_block s_entry_bb
, s_exit_bb
;
3416 s_entry_bb
= inner
->entry
;
3417 s_exit_bb
= inner
->exit
;
3419 t
= tree_block_label (s_entry_bb
);
3420 u
= build_int_cst (unsigned_type_node
, casei
);
3421 u
= build3 (CASE_LABEL_EXPR
, void_type_node
, u
, NULL
, t
);
3422 TREE_VEC_ELT (label_vec
, i
) = u
;
3424 si
= bsi_last (s_entry_bb
);
3425 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_SECTION
);
3426 gcc_assert (i
< len
|| OMP_SECTION_LAST (bsi_stmt (si
)));
3427 bsi_remove (&si
, true);
3428 single_succ_edge (s_entry_bb
)->flags
= EDGE_FALLTHRU
;
3430 if (s_exit_bb
== NULL
)
3433 si
= bsi_last (s_exit_bb
);
3434 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_RETURN
);
3435 bsi_remove (&si
, true);
3437 single_succ_edge (s_exit_bb
)->flags
= EDGE_FALLTHRU
;
3440 /* Error handling code goes in DEFAULT_BB. */
3441 t
= tree_block_label (default_bb
);
3442 u
= build3 (CASE_LABEL_EXPR
, void_type_node
, NULL
, NULL
, t
);
3443 TREE_VEC_ELT (label_vec
, len
) = u
;
3444 make_edge (l0_bb
, default_bb
, 0);
3446 si
= bsi_start (default_bb
);
3447 t
= build_call_expr (built_in_decls
[BUILT_IN_TRAP
], 0);
3448 bsi_insert_after (&si
, t
, BSI_CONTINUE_LINKING
);
3452 /* Code to get the next section goes in L1_BB. */
3453 si
= bsi_last (l1_bb
);
3454 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_CONTINUE
);
3456 t
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_SECTIONS_NEXT
], 0);
3457 t
= build_gimple_modify_stmt (vnext
, t
);
3458 bsi_insert_after (&si
, t
, BSI_SAME_STMT
);
3459 if (gimple_in_ssa_p (cfun
))
3460 SSA_NAME_DEF_STMT (vnext
) = t
;
3461 bsi_remove (&si
, true);
3463 single_succ_edge (l1_bb
)->flags
= EDGE_FALLTHRU
;
3465 /* Cleanup function replaces OMP_RETURN in EXIT_BB. */
3466 si
= bsi_last (l2_bb
);
3467 if (OMP_RETURN_NOWAIT (bsi_stmt (si
)))
3468 t
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_END_NOWAIT
];
3470 t
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_END
];
3471 t
= build_call_expr (t
, 0);
3472 bsi_insert_after (&si
, t
, BSI_SAME_STMT
);
3473 bsi_remove (&si
, true);
3476 set_immediate_dominator (CDI_DOMINATORS
, default_bb
, l0_bb
);
3480 /* Expand code for an OpenMP single directive. We've already expanded
3481 much of the code, here we simply place the GOMP_barrier call. */
3484 expand_omp_single (struct omp_region
*region
)
3486 basic_block entry_bb
, exit_bb
;
3487 block_stmt_iterator si
;
3488 bool need_barrier
= false;
3490 entry_bb
= region
->entry
;
3491 exit_bb
= region
->exit
;
3493 si
= bsi_last (entry_bb
);
3494 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
3495 be removed. We need to ensure that the thread that entered the single
3496 does not exit before the data is copied out by the other threads. */
3497 if (find_omp_clause (OMP_SINGLE_CLAUSES (bsi_stmt (si
)),
3498 OMP_CLAUSE_COPYPRIVATE
))
3499 need_barrier
= true;
3500 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_SINGLE
);
3501 bsi_remove (&si
, true);
3502 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
3504 si
= bsi_last (exit_bb
);
3505 if (!OMP_RETURN_NOWAIT (bsi_stmt (si
)) || need_barrier
)
3506 force_gimple_operand_bsi (&si
, build_omp_barrier (), false, NULL_TREE
,
3507 false, BSI_SAME_STMT
);
3508 bsi_remove (&si
, true);
3509 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
3513 /* Generic expansion for OpenMP synchronization directives: master,
3514 ordered and critical. All we need to do here is remove the entry
3515 and exit markers for REGION. */
3518 expand_omp_synch (struct omp_region
*region
)
3520 basic_block entry_bb
, exit_bb
;
3521 block_stmt_iterator si
;
3523 entry_bb
= region
->entry
;
3524 exit_bb
= region
->exit
;
3526 si
= bsi_last (entry_bb
);
3527 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_SINGLE
3528 || TREE_CODE (bsi_stmt (si
)) == OMP_MASTER
3529 || TREE_CODE (bsi_stmt (si
)) == OMP_ORDERED
3530 || TREE_CODE (bsi_stmt (si
)) == OMP_CRITICAL
);
3531 bsi_remove (&si
, true);
3532 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
3536 si
= bsi_last (exit_bb
);
3537 gcc_assert (TREE_CODE (bsi_stmt (si
)) == OMP_RETURN
);
3538 bsi_remove (&si
, true);
3539 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
3544 /* Expand the parallel region tree rooted at REGION. Expansion
3545 proceeds in depth-first order. Innermost regions are expanded
3546 first. This way, parallel regions that require a new function to
3547 be created (e.g., OMP_PARALLEL) can be expanded without having any
3548 internal dependencies in their body. */
3551 expand_omp (struct omp_region
*region
)
3556 expand_omp (region
->inner
);
3558 switch (region
->type
)
3561 expand_omp_parallel (region
);
3565 expand_omp_for (region
);
3569 expand_omp_sections (region
);
3573 /* Individual omp sections are handled together with their
3574 parent OMP_SECTIONS region. */
3578 expand_omp_single (region
);
3584 expand_omp_synch (region
);
3591 region
= region
->next
;
3596 /* Helper for build_omp_regions. Scan the dominator tree starting at
3597 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
3598 true, the function ends once a single tree is built (otherwise, whole
3599 forest of OMP constructs may be built). */
3602 build_omp_regions_1 (basic_block bb
, struct omp_region
*parent
,
3605 block_stmt_iterator si
;
3610 if (!bsi_end_p (si
) && OMP_DIRECTIVE_P (bsi_stmt (si
)))
3612 struct omp_region
*region
;
3613 enum tree_code code
;
3615 stmt
= bsi_stmt (si
);
3616 code
= TREE_CODE (stmt
);
3618 if (code
== OMP_RETURN
)
3620 /* STMT is the return point out of region PARENT. Mark it
3621 as the exit point and make PARENT the immediately
3622 enclosing region. */
3623 gcc_assert (parent
);
3626 parent
= parent
->outer
;
3628 /* If REGION is a parallel region, determine whether it is
3629 a combined parallel+workshare region. */
3630 if (region
->type
== OMP_PARALLEL
)
3631 determine_parallel_type (region
);
3633 else if (code
== OMP_CONTINUE
)
3635 gcc_assert (parent
);
3638 else if (code
== OMP_SECTIONS_SWITCH
)
3640 /* OMP_SECTIONS_SWITCH is part of OMP_SECTIONS, and we do nothing for
3645 /* Otherwise, this directive becomes the parent for a new
3647 region
= new_omp_region (bb
, code
, parent
);
3652 if (single_tree
&& !parent
)
3655 for (son
= first_dom_son (CDI_DOMINATORS
, bb
);
3657 son
= next_dom_son (CDI_DOMINATORS
, son
))
3658 build_omp_regions_1 (son
, parent
, single_tree
);
3661 /* Builds the tree of OMP regions rooted at ROOT, storing it to
3665 build_omp_regions_root (basic_block root
)
3667 gcc_assert (root_omp_region
== NULL
);
3668 build_omp_regions_1 (root
, NULL
, true);
3669 gcc_assert (root_omp_region
!= NULL
);
3672 /* Expands omp construct (and its subconstructs) starting in HEAD. */
3675 omp_expand_local (basic_block head
)
3677 build_omp_regions_root (head
);
3678 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
3680 fprintf (dump_file
, "\nOMP region tree\n\n");
3681 dump_omp_region (dump_file
, root_omp_region
, 0);
3682 fprintf (dump_file
, "\n");
3685 remove_exit_barriers (root_omp_region
);
3686 expand_omp (root_omp_region
);
3688 free_omp_regions ();
3691 /* Scan the CFG and build a tree of OMP regions. Return the root of
3692 the OMP region tree. */
3695 build_omp_regions (void)
3697 gcc_assert (root_omp_region
== NULL
);
3698 calculate_dominance_info (CDI_DOMINATORS
);
3699 build_omp_regions_1 (ENTRY_BLOCK_PTR
, NULL
, false);
3703 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
3706 execute_expand_omp (void)
3708 build_omp_regions ();
3710 if (!root_omp_region
)
3715 fprintf (dump_file
, "\nOMP region tree\n\n");
3716 dump_omp_region (dump_file
, root_omp_region
, 0);
3717 fprintf (dump_file
, "\n");
3720 remove_exit_barriers (root_omp_region
);
3722 expand_omp (root_omp_region
);
3724 cleanup_tree_cfg ();
3726 free_omp_regions ();
3731 /* OMP expansion in SSA form. For testing purposes only. */
3734 gate_expand_omp_ssa (void)
3736 return flag_openmp_ssa
&& flag_openmp
!= 0 && errorcount
== 0;
3739 struct tree_opt_pass pass_expand_omp_ssa
=
3741 "ompexpssa", /* name */
3742 gate_expand_omp_ssa
, /* gate */
3743 execute_expand_omp
, /* execute */
3746 0, /* static_pass_number */
3748 PROP_gimple_any
, /* properties_required */
3749 PROP_gimple_lomp
, /* properties_provided */
3750 0, /* properties_destroyed */
3751 0, /* todo_flags_start */
3752 TODO_dump_func
, /* todo_flags_finish */
3756 /* OMP expansion -- the default pass, run before creation of SSA form. */
3759 gate_expand_omp (void)
3761 return ((!flag_openmp_ssa
|| !optimize
)
3762 && flag_openmp
!= 0 && errorcount
== 0);
3765 struct tree_opt_pass pass_expand_omp
=
3767 "ompexp", /* name */
3768 gate_expand_omp
, /* gate */
3769 execute_expand_omp
, /* execute */
3772 0, /* static_pass_number */
3774 PROP_gimple_any
, /* properties_required */
3775 PROP_gimple_lomp
, /* properties_provided */
3776 0, /* properties_destroyed */
3777 0, /* todo_flags_start */
3778 TODO_dump_func
, /* todo_flags_finish */
3782 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
3784 /* Lower the OpenMP sections directive in *STMT_P. */
3787 lower_omp_sections (tree
*stmt_p
, omp_context
*ctx
)
3789 tree new_stmt
, stmt
, body
, bind
, block
, ilist
, olist
, new_body
, control
;
3791 tree_stmt_iterator tsi
;
3796 push_gimplify_context ();
3800 lower_rec_input_clauses (OMP_SECTIONS_CLAUSES (stmt
), &ilist
, &dlist
, ctx
);
3802 tsi
= tsi_start (OMP_SECTIONS_BODY (stmt
));
3803 for (len
= 0; !tsi_end_p (tsi
); len
++, tsi_next (&tsi
))
3806 tsi
= tsi_start (OMP_SECTIONS_BODY (stmt
));
3807 body
= alloc_stmt_list ();
3808 for (i
= 0; i
< len
; i
++, tsi_next (&tsi
))
3811 tree sec_start
, sec_end
;
3813 sec_start
= tsi_stmt (tsi
);
3814 sctx
= maybe_lookup_ctx (sec_start
);
3817 append_to_statement_list (sec_start
, &body
);
3819 lower_omp (&OMP_SECTION_BODY (sec_start
), sctx
);
3820 append_to_statement_list (OMP_SECTION_BODY (sec_start
), &body
);
3821 OMP_SECTION_BODY (sec_start
) = NULL
;
3825 tree l
= alloc_stmt_list ();
3826 lower_lastprivate_clauses (OMP_SECTIONS_CLAUSES (stmt
), NULL
,
3828 append_to_statement_list (l
, &body
);
3829 OMP_SECTION_LAST (sec_start
) = 1;
3832 sec_end
= make_node (OMP_RETURN
);
3833 append_to_statement_list (sec_end
, &body
);
3836 block
= make_node (BLOCK
);
3837 bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, body
, block
);
3840 lower_reduction_clauses (OMP_SECTIONS_CLAUSES (stmt
), &olist
, ctx
);
3842 pop_gimplify_context (NULL_TREE
);
3843 record_vars_into (ctx
->block_vars
, ctx
->cb
.dst_fn
);
3845 new_stmt
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
3846 TREE_SIDE_EFFECTS (new_stmt
) = 1;
3848 new_body
= alloc_stmt_list ();
3849 append_to_statement_list (ilist
, &new_body
);
3850 append_to_statement_list (stmt
, &new_body
);
3851 append_to_statement_list (make_node (OMP_SECTIONS_SWITCH
), &new_body
);
3852 append_to_statement_list (bind
, &new_body
);
3854 control
= create_tmp_var (unsigned_type_node
, ".section");
3855 t
= build2 (OMP_CONTINUE
, void_type_node
, control
, control
);
3856 OMP_SECTIONS_CONTROL (stmt
) = control
;
3857 append_to_statement_list (t
, &new_body
);
3859 append_to_statement_list (olist
, &new_body
);
3860 append_to_statement_list (dlist
, &new_body
);
3862 maybe_catch_exception (&new_body
);
3864 t
= make_node (OMP_RETURN
);
3865 OMP_RETURN_NOWAIT (t
) = !!find_omp_clause (OMP_SECTIONS_CLAUSES (stmt
),
3867 append_to_statement_list (t
, &new_body
);
3869 BIND_EXPR_BODY (new_stmt
) = new_body
;
3870 OMP_SECTIONS_BODY (stmt
) = NULL
;
3876 /* A subroutine of lower_omp_single. Expand the simple form of
3877 an OMP_SINGLE, without a copyprivate clause:
3879 if (GOMP_single_start ())
3881 [ GOMP_barrier (); ] -> unless 'nowait' is present.
3883 FIXME. It may be better to delay expanding the logic of this until
3884 pass_expand_omp. The expanded logic may make the job more difficult
3885 to a synchronization analysis pass. */
3888 lower_omp_single_simple (tree single_stmt
, tree
*pre_p
)
3892 t
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_SINGLE_START
], 0);
3893 t
= build3 (COND_EXPR
, void_type_node
, t
,
3894 OMP_SINGLE_BODY (single_stmt
), NULL
);
3895 gimplify_and_add (t
, pre_p
);
3899 /* A subroutine of lower_omp_single. Expand the simple form of
3900 an OMP_SINGLE, with a copyprivate clause:
3902 #pragma omp single copyprivate (a, b, c)
3904 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
3907 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
3913 GOMP_single_copy_end (©out);
3924 FIXME. It may be better to delay expanding the logic of this until
3925 pass_expand_omp. The expanded logic may make the job more difficult
3926 to a synchronization analysis pass. */
3929 lower_omp_single_copy (tree single_stmt
, tree
*pre_p
, omp_context
*ctx
)
3931 tree ptr_type
, t
, l0
, l1
, l2
, copyin_seq
;
3933 ctx
->sender_decl
= create_tmp_var (ctx
->record_type
, ".omp_copy_o");
3935 ptr_type
= build_pointer_type (ctx
->record_type
);
3936 ctx
->receiver_decl
= create_tmp_var (ptr_type
, ".omp_copy_i");
3938 l0
= create_artificial_label ();
3939 l1
= create_artificial_label ();
3940 l2
= create_artificial_label ();
3942 t
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_SINGLE_COPY_START
], 0);
3943 t
= fold_convert (ptr_type
, t
);
3944 t
= build_gimple_modify_stmt (ctx
->receiver_decl
, t
);
3945 gimplify_and_add (t
, pre_p
);
3947 t
= build2 (EQ_EXPR
, boolean_type_node
, ctx
->receiver_decl
,
3948 build_int_cst (ptr_type
, 0));
3949 t
= build3 (COND_EXPR
, void_type_node
, t
,
3950 build_and_jump (&l0
), build_and_jump (&l1
));
3951 gimplify_and_add (t
, pre_p
);
3953 t
= build1 (LABEL_EXPR
, void_type_node
, l0
);
3954 gimplify_and_add (t
, pre_p
);
3956 append_to_statement_list (OMP_SINGLE_BODY (single_stmt
), pre_p
);
3959 lower_copyprivate_clauses (OMP_SINGLE_CLAUSES (single_stmt
), pre_p
,
3962 t
= build_fold_addr_expr (ctx
->sender_decl
);
3963 t
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_SINGLE_COPY_END
], 1, t
);
3964 gimplify_and_add (t
, pre_p
);
3966 t
= build_and_jump (&l2
);
3967 gimplify_and_add (t
, pre_p
);
3969 t
= build1 (LABEL_EXPR
, void_type_node
, l1
);
3970 gimplify_and_add (t
, pre_p
);
3972 append_to_statement_list (copyin_seq
, pre_p
);
3974 t
= build1 (LABEL_EXPR
, void_type_node
, l2
);
3975 gimplify_and_add (t
, pre_p
);
3979 /* Expand code for an OpenMP single directive. */
3982 lower_omp_single (tree
*stmt_p
, omp_context
*ctx
)
3984 tree t
, bind
, block
, single_stmt
= *stmt_p
, dlist
;
3986 push_gimplify_context ();
3988 block
= make_node (BLOCK
);
3989 *stmt_p
= bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, block
);
3990 TREE_SIDE_EFFECTS (bind
) = 1;
3992 lower_rec_input_clauses (OMP_SINGLE_CLAUSES (single_stmt
),
3993 &BIND_EXPR_BODY (bind
), &dlist
, ctx
);
3994 lower_omp (&OMP_SINGLE_BODY (single_stmt
), ctx
);
3996 append_to_statement_list (single_stmt
, &BIND_EXPR_BODY (bind
));
3998 if (ctx
->record_type
)
3999 lower_omp_single_copy (single_stmt
, &BIND_EXPR_BODY (bind
), ctx
);
4001 lower_omp_single_simple (single_stmt
, &BIND_EXPR_BODY (bind
));
4003 OMP_SINGLE_BODY (single_stmt
) = NULL
;
4005 append_to_statement_list (dlist
, &BIND_EXPR_BODY (bind
));
4007 maybe_catch_exception (&BIND_EXPR_BODY (bind
));
4009 t
= make_node (OMP_RETURN
);
4010 OMP_RETURN_NOWAIT (t
) = !!find_omp_clause (OMP_SINGLE_CLAUSES (single_stmt
),
4012 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
4014 pop_gimplify_context (bind
);
4016 BIND_EXPR_VARS (bind
) = chainon (BIND_EXPR_VARS (bind
), ctx
->block_vars
);
4017 BLOCK_VARS (block
) = BIND_EXPR_VARS (bind
);
4021 /* Expand code for an OpenMP master directive. */
4024 lower_omp_master (tree
*stmt_p
, omp_context
*ctx
)
4026 tree bind
, block
, stmt
= *stmt_p
, lab
= NULL
, x
;
4028 push_gimplify_context ();
4030 block
= make_node (BLOCK
);
4031 *stmt_p
= bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, block
);
4032 TREE_SIDE_EFFECTS (bind
) = 1;
4034 append_to_statement_list (stmt
, &BIND_EXPR_BODY (bind
));
4036 x
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
4037 x
= build2 (EQ_EXPR
, boolean_type_node
, x
, integer_zero_node
);
4038 x
= build3 (COND_EXPR
, void_type_node
, x
, NULL
, build_and_jump (&lab
));
4039 gimplify_and_add (x
, &BIND_EXPR_BODY (bind
));
4041 lower_omp (&OMP_MASTER_BODY (stmt
), ctx
);
4042 maybe_catch_exception (&OMP_MASTER_BODY (stmt
));
4043 append_to_statement_list (OMP_MASTER_BODY (stmt
), &BIND_EXPR_BODY (bind
));
4044 OMP_MASTER_BODY (stmt
) = NULL
;
4046 x
= build1 (LABEL_EXPR
, void_type_node
, lab
);
4047 gimplify_and_add (x
, &BIND_EXPR_BODY (bind
));
4049 x
= make_node (OMP_RETURN
);
4050 OMP_RETURN_NOWAIT (x
) = 1;
4051 append_to_statement_list (x
, &BIND_EXPR_BODY (bind
));
4053 pop_gimplify_context (bind
);
4055 BIND_EXPR_VARS (bind
) = chainon (BIND_EXPR_VARS (bind
), ctx
->block_vars
);
4056 BLOCK_VARS (block
) = BIND_EXPR_VARS (bind
);
4060 /* Expand code for an OpenMP ordered directive. */
4063 lower_omp_ordered (tree
*stmt_p
, omp_context
*ctx
)
4065 tree bind
, block
, stmt
= *stmt_p
, x
;
4067 push_gimplify_context ();
4069 block
= make_node (BLOCK
);
4070 *stmt_p
= bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, block
);
4071 TREE_SIDE_EFFECTS (bind
) = 1;
4073 append_to_statement_list (stmt
, &BIND_EXPR_BODY (bind
));
4075 x
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_ORDERED_START
], 0);
4076 gimplify_and_add (x
, &BIND_EXPR_BODY (bind
));
4078 lower_omp (&OMP_ORDERED_BODY (stmt
), ctx
);
4079 maybe_catch_exception (&OMP_ORDERED_BODY (stmt
));
4080 append_to_statement_list (OMP_ORDERED_BODY (stmt
), &BIND_EXPR_BODY (bind
));
4081 OMP_ORDERED_BODY (stmt
) = NULL
;
4083 x
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_ORDERED_END
], 0);
4084 gimplify_and_add (x
, &BIND_EXPR_BODY (bind
));
4086 x
= make_node (OMP_RETURN
);
4087 OMP_RETURN_NOWAIT (x
) = 1;
4088 append_to_statement_list (x
, &BIND_EXPR_BODY (bind
));
4090 pop_gimplify_context (bind
);
4092 BIND_EXPR_VARS (bind
) = chainon (BIND_EXPR_VARS (bind
), ctx
->block_vars
);
4093 BLOCK_VARS (block
) = BIND_EXPR_VARS (bind
);
4097 /* Gimplify an OMP_CRITICAL statement. This is a relatively simple
4098 substitution of a couple of function calls. But in the NAMED case,
4099 requires that languages coordinate a symbol name. It is therefore
4100 best put here in common code. */
4102 static GTY((param1_is (tree
), param2_is (tree
)))
4103 splay_tree critical_name_mutexes
;
4106 lower_omp_critical (tree
*stmt_p
, omp_context
*ctx
)
4108 tree bind
, block
, stmt
= *stmt_p
;
4109 tree t
, lock
, unlock
, name
;
4111 name
= OMP_CRITICAL_NAME (stmt
);
4117 if (!critical_name_mutexes
)
4118 critical_name_mutexes
4119 = splay_tree_new_ggc (splay_tree_compare_pointers
);
4121 n
= splay_tree_lookup (critical_name_mutexes
, (splay_tree_key
) name
);
4126 decl
= create_tmp_var_raw (ptr_type_node
, NULL
);
4128 new_str
= ACONCAT ((".gomp_critical_user_",
4129 IDENTIFIER_POINTER (name
), NULL
));
4130 DECL_NAME (decl
) = get_identifier (new_str
);
4131 TREE_PUBLIC (decl
) = 1;
4132 TREE_STATIC (decl
) = 1;
4133 DECL_COMMON (decl
) = 1;
4134 DECL_ARTIFICIAL (decl
) = 1;
4135 DECL_IGNORED_P (decl
) = 1;
4136 varpool_finalize_decl (decl
);
4138 splay_tree_insert (critical_name_mutexes
, (splay_tree_key
) name
,
4139 (splay_tree_value
) decl
);
4142 decl
= (tree
) n
->value
;
4144 lock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_NAME_START
];
4145 lock
= build_call_expr (lock
, 1, build_fold_addr_expr (decl
));
4147 unlock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_NAME_END
];
4148 unlock
= build_call_expr (unlock
, 1, build_fold_addr_expr (decl
));
4152 lock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_START
];
4153 lock
= build_call_expr (lock
, 0);
4155 unlock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_END
];
4156 unlock
= build_call_expr (unlock
, 0);
4159 push_gimplify_context ();
4161 block
= make_node (BLOCK
);
4162 *stmt_p
= bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, block
);
4163 TREE_SIDE_EFFECTS (bind
) = 1;
4165 append_to_statement_list (stmt
, &BIND_EXPR_BODY (bind
));
4167 gimplify_and_add (lock
, &BIND_EXPR_BODY (bind
));
4169 lower_omp (&OMP_CRITICAL_BODY (stmt
), ctx
);
4170 maybe_catch_exception (&OMP_CRITICAL_BODY (stmt
));
4171 append_to_statement_list (OMP_CRITICAL_BODY (stmt
), &BIND_EXPR_BODY (bind
));
4172 OMP_CRITICAL_BODY (stmt
) = NULL
;
4174 gimplify_and_add (unlock
, &BIND_EXPR_BODY (bind
));
4176 t
= make_node (OMP_RETURN
);
4177 OMP_RETURN_NOWAIT (t
) = 1;
4178 append_to_statement_list (t
, &BIND_EXPR_BODY (bind
));
4180 pop_gimplify_context (bind
);
4181 BIND_EXPR_VARS (bind
) = chainon (BIND_EXPR_VARS (bind
), ctx
->block_vars
);
4182 BLOCK_VARS (block
) = BIND_EXPR_VARS (bind
);
4186 /* A subroutine of lower_omp_for. Generate code to emit the predicate
4187 for a lastprivate clause. Given a loop control predicate of (V
4188 cond N2), we gate the clause on (!(V cond N2)). The lowered form
4189 is appended to *DLIST, iterator initialization is appended to
4193 lower_omp_for_lastprivate (struct omp_for_data
*fd
, tree
*body_p
,
4194 tree
*dlist
, struct omp_context
*ctx
)
4196 tree clauses
, cond
, stmts
, vinit
, t
;
4197 enum tree_code cond_code
;
4199 cond_code
= fd
->cond_code
;
4200 cond_code
= cond_code
== LT_EXPR
? GE_EXPR
: LE_EXPR
;
4202 /* When possible, use a strict equality expression. This can let VRP
4203 type optimizations deduce the value and remove a copy. */
4204 if (host_integerp (fd
->step
, 0))
4206 HOST_WIDE_INT step
= TREE_INT_CST_LOW (fd
->step
);
4207 if (step
== 1 || step
== -1)
4208 cond_code
= EQ_EXPR
;
4211 cond
= build2 (cond_code
, boolean_type_node
, fd
->v
, fd
->n2
);
4213 clauses
= OMP_FOR_CLAUSES (fd
->for_stmt
);
4215 lower_lastprivate_clauses (clauses
, cond
, &stmts
, ctx
);
4218 append_to_statement_list (stmts
, dlist
);
4220 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
4222 if (cond_code
== EQ_EXPR
4223 && host_integerp (fd
->n2
, 0)
4224 && ! integer_zerop (fd
->n2
))
4225 vinit
= build_int_cst (TREE_TYPE (fd
->v
), 0);
4227 /* Initialize the iterator variable, so that threads that don't execute
4228 any iterations don't execute the lastprivate clauses by accident. */
4229 t
= build_gimple_modify_stmt (fd
->v
, vinit
);
4230 gimplify_and_add (t
, body_p
);
4235 /* Lower code for an OpenMP loop directive. */
4238 lower_omp_for (tree
*stmt_p
, omp_context
*ctx
)
4240 tree t
, stmt
, ilist
, dlist
, new_stmt
, *body_p
, *rhs_p
;
4241 struct omp_for_data fd
;
4245 push_gimplify_context ();
4247 lower_omp (&OMP_FOR_PRE_BODY (stmt
), ctx
);
4248 lower_omp (&OMP_FOR_BODY (stmt
), ctx
);
4250 /* Move declaration of temporaries in the loop body before we make
4252 if (TREE_CODE (OMP_FOR_BODY (stmt
)) == BIND_EXPR
)
4253 record_vars_into (BIND_EXPR_VARS (OMP_FOR_BODY (stmt
)), ctx
->cb
.dst_fn
);
4255 new_stmt
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
4256 TREE_SIDE_EFFECTS (new_stmt
) = 1;
4257 body_p
= &BIND_EXPR_BODY (new_stmt
);
4259 /* The pre-body and input clauses go before the lowered OMP_FOR. */
4262 append_to_statement_list (OMP_FOR_PRE_BODY (stmt
), body_p
);
4263 lower_rec_input_clauses (OMP_FOR_CLAUSES (stmt
), body_p
, &dlist
, ctx
);
4265 /* Lower the header expressions. At this point, we can assume that
4266 the header is of the form:
4268 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
4270 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
4271 using the .omp_data_s mapping, if needed. */
4272 rhs_p
= &GIMPLE_STMT_OPERAND (OMP_FOR_INIT (stmt
), 1);
4273 if (!is_gimple_min_invariant (*rhs_p
))
4274 *rhs_p
= get_formal_tmp_var (*rhs_p
, body_p
);
4276 rhs_p
= &TREE_OPERAND (OMP_FOR_COND (stmt
), 1);
4277 if (!is_gimple_min_invariant (*rhs_p
))
4278 *rhs_p
= get_formal_tmp_var (*rhs_p
, body_p
);
4280 rhs_p
= &TREE_OPERAND (GIMPLE_STMT_OPERAND (OMP_FOR_INCR (stmt
), 1), 1);
4281 if (!is_gimple_min_invariant (*rhs_p
))
4282 *rhs_p
= get_formal_tmp_var (*rhs_p
, body_p
);
4284 /* Once lowered, extract the bounds and clauses. */
4285 extract_omp_for_data (stmt
, &fd
);
4287 lower_omp_for_lastprivate (&fd
, body_p
, &dlist
, ctx
);
4289 append_to_statement_list (stmt
, body_p
);
4291 append_to_statement_list (OMP_FOR_BODY (stmt
), body_p
);
4293 t
= build2 (OMP_CONTINUE
, void_type_node
, fd
.v
, fd
.v
);
4294 append_to_statement_list (t
, body_p
);
4296 /* After the loop, add exit clauses. */
4297 lower_reduction_clauses (OMP_FOR_CLAUSES (stmt
), body_p
, ctx
);
4298 append_to_statement_list (dlist
, body_p
);
4300 maybe_catch_exception (body_p
);
4302 /* Region exit marker goes at the end of the loop body. */
4303 t
= make_node (OMP_RETURN
);
4304 OMP_RETURN_NOWAIT (t
) = fd
.have_nowait
;
4305 append_to_statement_list (t
, body_p
);
4307 pop_gimplify_context (NULL_TREE
);
4308 record_vars_into (ctx
->block_vars
, ctx
->cb
.dst_fn
);
4310 OMP_FOR_BODY (stmt
) = NULL_TREE
;
4311 OMP_FOR_PRE_BODY (stmt
) = NULL_TREE
;
4315 /* Callback for walk_stmts. Check if *TP only contains OMP_FOR
4319 check_combined_parallel (tree
*tp
, int *walk_subtrees
, void *data
)
4321 struct walk_stmt_info
*wi
= data
;
4322 int *info
= wi
->info
;
4325 switch (TREE_CODE (*tp
))
4329 *info
= *info
== 0 ? 1 : -1;
4338 /* Lower the OpenMP parallel directive in *STMT_P. CTX holds context
4339 information for the directive. */
4342 lower_omp_parallel (tree
*stmt_p
, omp_context
*ctx
)
4344 tree clauses
, par_bind
, par_body
, new_body
, bind
;
4345 tree olist
, ilist
, par_olist
, par_ilist
;
4346 tree stmt
, child_fn
, t
;
4350 clauses
= OMP_PARALLEL_CLAUSES (stmt
);
4351 par_bind
= OMP_PARALLEL_BODY (stmt
);
4352 par_body
= BIND_EXPR_BODY (par_bind
);
4353 child_fn
= ctx
->cb
.dst_fn
;
4354 if (!OMP_PARALLEL_COMBINED (stmt
))
4356 struct walk_stmt_info wi
;
4359 memset (&wi
, 0, sizeof (wi
));
4360 wi
.callback
= check_combined_parallel
;
4363 walk_stmts (&wi
, &par_bind
);
4365 OMP_PARALLEL_COMBINED (stmt
) = 1;
4368 push_gimplify_context ();
4370 par_olist
= NULL_TREE
;
4371 par_ilist
= NULL_TREE
;
4372 lower_rec_input_clauses (clauses
, &par_ilist
, &par_olist
, ctx
);
4373 lower_omp (&par_body
, ctx
);
4374 lower_reduction_clauses (clauses
, &par_olist
, ctx
);
4376 /* Declare all the variables created by mapping and the variables
4377 declared in the scope of the parallel body. */
4378 record_vars_into (ctx
->block_vars
, child_fn
);
4379 record_vars_into (BIND_EXPR_VARS (par_bind
), child_fn
);
4381 if (ctx
->record_type
)
4383 ctx
->sender_decl
= create_tmp_var (ctx
->record_type
, ".omp_data_o");
4384 OMP_PARALLEL_DATA_ARG (stmt
) = ctx
->sender_decl
;
4389 lower_send_clauses (clauses
, &ilist
, &olist
, ctx
);
4390 lower_send_shared_vars (&ilist
, &olist
, ctx
);
4392 /* Once all the expansions are done, sequence all the different
4393 fragments inside OMP_PARALLEL_BODY. */
4394 bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
4395 append_to_statement_list (ilist
, &BIND_EXPR_BODY (bind
));
4397 new_body
= alloc_stmt_list ();
4399 if (ctx
->record_type
)
4401 t
= build_fold_addr_expr (ctx
->sender_decl
);
4402 /* fixup_child_record_type might have changed receiver_decl's type. */
4403 t
= fold_convert (TREE_TYPE (ctx
->receiver_decl
), t
);
4404 t
= build_gimple_modify_stmt (ctx
->receiver_decl
, t
);
4405 append_to_statement_list (t
, &new_body
);
4408 append_to_statement_list (par_ilist
, &new_body
);
4409 append_to_statement_list (par_body
, &new_body
);
4410 append_to_statement_list (par_olist
, &new_body
);
4411 maybe_catch_exception (&new_body
);
4412 t
= make_node (OMP_RETURN
);
4413 append_to_statement_list (t
, &new_body
);
4414 OMP_PARALLEL_BODY (stmt
) = new_body
;
4416 append_to_statement_list (stmt
, &BIND_EXPR_BODY (bind
));
4417 append_to_statement_list (olist
, &BIND_EXPR_BODY (bind
));
4421 pop_gimplify_context (NULL_TREE
);
4425 /* Pass *TP back through the gimplifier within the context determined by WI.
4426 This handles replacement of DECL_VALUE_EXPR, as well as adjusting the
4427 flags on ADDR_EXPR. */
4430 lower_regimplify (tree
*tp
, struct walk_stmt_info
*wi
)
4432 enum gimplify_status gs
;
4436 gs
= gimplify_expr (tp
, &pre
, NULL
, is_gimple_lvalue
, fb_lvalue
);
4437 else if (wi
->val_only
)
4438 gs
= gimplify_expr (tp
, &pre
, NULL
, is_gimple_val
, fb_rvalue
);
4440 gs
= gimplify_expr (tp
, &pre
, NULL
, is_gimple_formal_tmp_var
, fb_rvalue
);
4441 gcc_assert (gs
== GS_ALL_DONE
);
4444 tsi_link_before (&wi
->tsi
, pre
, TSI_SAME_STMT
);
4447 /* Copy EXP into a temporary. Insert the initialization statement before TSI. */
4450 init_tmp_var (tree exp
, tree_stmt_iterator
*tsi
)
4454 t
= create_tmp_var (TREE_TYPE (exp
), NULL
);
4455 DECL_GIMPLE_REG_P (t
) = 1;
4456 stmt
= build_gimple_modify_stmt (t
, exp
);
4457 SET_EXPR_LOCUS (stmt
, EXPR_LOCUS (tsi_stmt (*tsi
)));
4458 tsi_link_before (tsi
, stmt
, TSI_SAME_STMT
);
4463 /* Similarly, but copy from the temporary and insert the statement
4464 after the iterator. */
4467 save_tmp_var (tree exp
, tree_stmt_iterator
*tsi
)
4471 t
= create_tmp_var (TREE_TYPE (exp
), NULL
);
4472 DECL_GIMPLE_REG_P (t
) = 1;
4473 stmt
= build_gimple_modify_stmt (exp
, t
);
4474 SET_EXPR_LOCUS (stmt
, EXPR_LOCUS (tsi_stmt (*tsi
)));
4475 tsi_link_after (tsi
, stmt
, TSI_SAME_STMT
);
4480 /* Callback for walk_stmts. Lower the OpenMP directive pointed by TP. */
4483 lower_omp_1 (tree
*tp
, int *walk_subtrees
, void *data
)
4485 struct walk_stmt_info
*wi
= data
;
4486 omp_context
*ctx
= wi
->info
;
4489 /* If we have issued syntax errors, avoid doing any heavy lifting.
4490 Just replace the OpenMP directives with a NOP to avoid
4491 confusing RTL expansion. */
4492 if (errorcount
&& OMP_DIRECTIVE_P (*tp
))
4494 *tp
= build_empty_stmt ();
4499 switch (TREE_CODE (*tp
))
4502 ctx
= maybe_lookup_ctx (t
);
4503 lower_omp_parallel (tp
, ctx
);
4507 ctx
= maybe_lookup_ctx (t
);
4509 lower_omp_for (tp
, ctx
);
4513 ctx
= maybe_lookup_ctx (t
);
4515 lower_omp_sections (tp
, ctx
);
4519 ctx
= maybe_lookup_ctx (t
);
4521 lower_omp_single (tp
, ctx
);
4525 ctx
= maybe_lookup_ctx (t
);
4527 lower_omp_master (tp
, ctx
);
4531 ctx
= maybe_lookup_ctx (t
);
4533 lower_omp_ordered (tp
, ctx
);
4537 ctx
= maybe_lookup_ctx (t
);
4539 lower_omp_critical (tp
, ctx
);
4543 if (ctx
&& DECL_HAS_VALUE_EXPR_P (t
))
4545 lower_regimplify (&t
, wi
);
4549 t
= save_tmp_var (t
, &wi
->tsi
);
4551 t
= init_tmp_var (t
, &wi
->tsi
);
4559 lower_regimplify (tp
, wi
);
4563 case ARRAY_RANGE_REF
:
4567 case VIEW_CONVERT_EXPR
:
4569 lower_regimplify (tp
, wi
);
4576 wi
->val_only
= true;
4577 lower_regimplify (&TREE_OPERAND (t
, 0), wi
);
4582 if (!TYPE_P (t
) && !DECL_P (t
))
4591 lower_omp (tree
*stmt_p
, omp_context
*ctx
)
4593 struct walk_stmt_info wi
;
4595 memset (&wi
, 0, sizeof (wi
));
4596 wi
.callback
= lower_omp_1
;
4599 wi
.want_locations
= true;
4601 walk_stmts (&wi
, stmt_p
);
4604 /* Main entry point. */
4607 execute_lower_omp (void)
4609 all_contexts
= splay_tree_new (splay_tree_compare_pointers
, 0,
4610 delete_omp_context
);
4612 scan_omp (&DECL_SAVED_TREE (current_function_decl
), NULL
);
4613 gcc_assert (parallel_nesting_level
== 0);
4615 if (all_contexts
->root
)
4616 lower_omp (&DECL_SAVED_TREE (current_function_decl
), NULL
);
4620 splay_tree_delete (all_contexts
);
4621 all_contexts
= NULL
;
4627 gate_lower_omp (void)
4629 return flag_openmp
!= 0;
4632 struct tree_opt_pass pass_lower_omp
=
4634 "omplower", /* name */
4635 gate_lower_omp
, /* gate */
4636 execute_lower_omp
, /* execute */
4639 0, /* static_pass_number */
4641 PROP_gimple_any
, /* properties_required */
4642 PROP_gimple_lomp
, /* properties_provided */
4643 0, /* properties_destroyed */
4644 0, /* todo_flags_start */
4645 TODO_dump_func
, /* todo_flags_finish */
4649 /* The following is a utility to diagnose OpenMP structured block violations.
4650 It is not part of the "omplower" pass, as that's invoked too late. It
4651 should be invoked by the respective front ends after gimplification. */
4653 static splay_tree all_labels
;
4655 /* Check for mismatched contexts and generate an error if needed. Return
4656 true if an error is detected. */
4659 diagnose_sb_0 (tree
*stmt_p
, tree branch_ctx
, tree label_ctx
)
4663 if ((label_ctx
? TREE_VALUE (label_ctx
) : NULL
) == branch_ctx
)
4666 /* Try to avoid confusing the user by producing and error message
4667 with correct "exit" or "enter" verbage. We prefer "exit"
4668 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
4669 if (branch_ctx
== NULL
)
4675 if (TREE_VALUE (label_ctx
) == branch_ctx
)
4680 label_ctx
= TREE_CHAIN (label_ctx
);
4685 error ("invalid exit from OpenMP structured block");
4687 error ("invalid entry to OpenMP structured block");
4689 *stmt_p
= build_empty_stmt ();
4693 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
4694 where in the tree each label is found. */
4697 diagnose_sb_1 (tree
*tp
, int *walk_subtrees
, void *data
)
4699 struct walk_stmt_info
*wi
= data
;
4700 tree context
= (tree
) wi
->info
;
4705 switch (TREE_CODE (t
))
4710 walk_tree (&OMP_CLAUSES (t
), diagnose_sb_1
, wi
, NULL
);
4716 /* The minimal context here is just a tree of statements. */
4717 inner_context
= tree_cons (NULL
, t
, context
);
4718 wi
->info
= inner_context
;
4719 walk_stmts (wi
, &OMP_BODY (t
));
4724 walk_tree (&OMP_FOR_CLAUSES (t
), diagnose_sb_1
, wi
, NULL
);
4725 inner_context
= tree_cons (NULL
, t
, context
);
4726 wi
->info
= inner_context
;
4727 walk_tree (&OMP_FOR_INIT (t
), diagnose_sb_1
, wi
, NULL
);
4728 walk_tree (&OMP_FOR_COND (t
), diagnose_sb_1
, wi
, NULL
);
4729 walk_tree (&OMP_FOR_INCR (t
), diagnose_sb_1
, wi
, NULL
);
4730 walk_stmts (wi
, &OMP_FOR_PRE_BODY (t
));
4731 walk_stmts (wi
, &OMP_FOR_BODY (t
));
4736 splay_tree_insert (all_labels
, (splay_tree_key
) LABEL_EXPR_LABEL (t
),
4737 (splay_tree_value
) context
);
4747 /* Pass 2: Check each branch and see if its context differs from that of
4748 the destination label's context. */
4751 diagnose_sb_2 (tree
*tp
, int *walk_subtrees
, void *data
)
4753 struct walk_stmt_info
*wi
= data
;
4754 tree context
= (tree
) wi
->info
;
4759 switch (TREE_CODE (t
))
4764 walk_tree (&OMP_CLAUSES (t
), diagnose_sb_2
, wi
, NULL
);
4771 walk_stmts (wi
, &OMP_BODY (t
));
4776 walk_tree (&OMP_FOR_CLAUSES (t
), diagnose_sb_2
, wi
, NULL
);
4778 walk_tree (&OMP_FOR_INIT (t
), diagnose_sb_2
, wi
, NULL
);
4779 walk_tree (&OMP_FOR_COND (t
), diagnose_sb_2
, wi
, NULL
);
4780 walk_tree (&OMP_FOR_INCR (t
), diagnose_sb_2
, wi
, NULL
);
4781 walk_stmts (wi
, &OMP_FOR_PRE_BODY (t
));
4782 walk_stmts (wi
, &OMP_FOR_BODY (t
));
4788 tree lab
= GOTO_DESTINATION (t
);
4789 if (TREE_CODE (lab
) != LABEL_DECL
)
4792 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
4793 diagnose_sb_0 (tp
, context
, n
? (tree
) n
->value
: NULL_TREE
);
4799 tree vec
= SWITCH_LABELS (t
);
4800 int i
, len
= TREE_VEC_LENGTH (vec
);
4801 for (i
= 0; i
< len
; ++i
)
4803 tree lab
= CASE_LABEL (TREE_VEC_ELT (vec
, i
));
4804 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
4805 if (diagnose_sb_0 (tp
, context
, (tree
) n
->value
))
4812 diagnose_sb_0 (tp
, context
, NULL_TREE
);
4823 diagnose_omp_structured_block_errors (tree fndecl
)
4825 tree save_current
= current_function_decl
;
4826 struct walk_stmt_info wi
;
4828 current_function_decl
= fndecl
;
4830 all_labels
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
4832 memset (&wi
, 0, sizeof (wi
));
4833 wi
.callback
= diagnose_sb_1
;
4834 walk_stmts (&wi
, &DECL_SAVED_TREE (fndecl
));
4836 memset (&wi
, 0, sizeof (wi
));
4837 wi
.callback
= diagnose_sb_2
;
4838 wi
.want_locations
= true;
4839 wi
.want_return_expr
= true;
4840 walk_stmts (&wi
, &DECL_SAVED_TREE (fndecl
));
4842 splay_tree_delete (all_labels
);
4845 current_function_decl
= save_current
;
4848 #include "gt-omp-low.h"