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-2013 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"
31 #include "tree-iterator.h"
32 #include "tree-inline.h"
33 #include "langhooks.h"
34 #include "diagnostic-core.h"
35 #include "tree-flow.h"
39 #include "tree-pass.h"
42 #include "splay-tree.h"
47 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
48 phases. The first phase scans the function looking for OMP statements
49 and then for variables that must be replaced to satisfy data sharing
50 clauses. The second phase expands code for the constructs, as well as
51 re-gimplifying things when variables have been replaced with complex
54 Final code generation is done by pass_expand_omp. The flowgraph is
55 scanned for parallel regions which are then moved to a new
56 function, to be invoked by the thread library. */
58 /* Context structure. Used to store information about each parallel
59 directive in the code. */
61 typedef struct omp_context
63 /* This field must be at the beginning, as we do "inheritance": Some
64 callback functions for tree-inline.c (e.g., omp_copy_decl)
65 receive a copy_body_data pointer that is up-casted to an
66 omp_context pointer. */
69 /* The tree of contexts corresponding to the encountered constructs. */
70 struct omp_context
*outer
;
73 /* Map variables to fields in a structure that allows communication
74 between sending and receiving threads. */
80 /* These are used just by task contexts, if task firstprivate fn is
81 needed. srecord_type is used to communicate from the thread
82 that encountered the task construct to task firstprivate fn,
83 record_type is allocated by GOMP_task, initialized by task firstprivate
84 fn and passed to the task body fn. */
85 splay_tree sfield_map
;
88 /* A chain of variables to add to the top-level block surrounding the
89 construct. In the case of a parallel, this is in the child function. */
92 /* What to do with variables with implicitly determined sharing
94 enum omp_clause_default_kind default_kind
;
96 /* Nesting depth of this context. Used to beautify error messages re
97 invalid gotos. The outermost ctx is depth 1, with depth 0 being
98 reserved for the main body of the function. */
101 /* True if this parallel directive is nested within another. */
106 struct omp_for_data_loop
108 tree v
, n1
, n2
, step
;
109 enum tree_code cond_code
;
112 /* A structure describing the main elements of a parallel loop. */
116 struct omp_for_data_loop loop
;
121 bool have_nowait
, have_ordered
;
122 enum omp_clause_schedule_kind sched_kind
;
123 struct omp_for_data_loop
*loops
;
127 static splay_tree all_contexts
;
128 static int taskreg_nesting_level
;
129 struct omp_region
*root_omp_region
;
130 static bitmap task_shared_vars
;
131 static vec
<omp_context
*> taskreg_contexts
;
133 static void scan_omp (gimple_seq
*, omp_context
*);
134 static tree
scan_omp_1_op (tree
*, int *, void *);
136 #define WALK_SUBSTMTS \
140 case GIMPLE_EH_FILTER: \
141 case GIMPLE_TRANSACTION: \
142 /* The sub-statements for these should be walked. */ \
143 *handled_ops_p = false; \
146 /* Convenience function for calling scan_omp_1_op on tree operands. */
149 scan_omp_op (tree
*tp
, omp_context
*ctx
)
151 struct walk_stmt_info wi
;
153 memset (&wi
, 0, sizeof (wi
));
155 wi
.want_locations
= true;
157 return walk_tree (tp
, scan_omp_1_op
, &wi
, NULL
);
160 static void lower_omp (gimple_seq
*, omp_context
*);
161 static tree
lookup_decl_in_outer_ctx (tree
, omp_context
*);
162 static tree
maybe_lookup_decl_in_outer_ctx (tree
, omp_context
*);
164 /* Find an OpenMP clause of type KIND within CLAUSES. */
167 find_omp_clause (tree clauses
, enum omp_clause_code kind
)
169 for (; clauses
; clauses
= OMP_CLAUSE_CHAIN (clauses
))
170 if (OMP_CLAUSE_CODE (clauses
) == kind
)
176 /* Return true if CTX is for an omp parallel. */
179 is_parallel_ctx (omp_context
*ctx
)
181 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
;
185 /* Return true if CTX is for an omp task. */
188 is_task_ctx (omp_context
*ctx
)
190 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_TASK
;
194 /* Return true if CTX is for an omp parallel or omp task. */
197 is_taskreg_ctx (omp_context
*ctx
)
199 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
200 || gimple_code (ctx
->stmt
) == GIMPLE_OMP_TASK
;
204 /* Return true if REGION is a combined parallel+workshare region. */
207 is_combined_parallel (struct omp_region
*region
)
209 return region
->is_combined_parallel
;
213 /* Extract the header elements of parallel loop FOR_STMT and store
217 extract_omp_for_data (gimple for_stmt
, struct omp_for_data
*fd
,
218 struct omp_for_data_loop
*loops
)
220 tree t
, var
, *collapse_iter
, *collapse_count
;
221 tree count
= NULL_TREE
, iter_type
= long_integer_type_node
;
222 struct omp_for_data_loop
*loop
;
224 struct omp_for_data_loop dummy_loop
;
225 location_t loc
= gimple_location (for_stmt
);
227 fd
->for_stmt
= for_stmt
;
229 fd
->collapse
= gimple_omp_for_collapse (for_stmt
);
230 if (fd
->collapse
> 1)
233 fd
->loops
= &fd
->loop
;
235 fd
->have_nowait
= fd
->have_ordered
= false;
236 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
237 fd
->chunk_size
= NULL_TREE
;
238 collapse_iter
= NULL
;
239 collapse_count
= NULL
;
241 for (t
= gimple_omp_for_clauses (for_stmt
); t
; t
= OMP_CLAUSE_CHAIN (t
))
242 switch (OMP_CLAUSE_CODE (t
))
244 case OMP_CLAUSE_NOWAIT
:
245 fd
->have_nowait
= true;
247 case OMP_CLAUSE_ORDERED
:
248 fd
->have_ordered
= true;
250 case OMP_CLAUSE_SCHEDULE
:
251 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_KIND (t
);
252 fd
->chunk_size
= OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t
);
254 case OMP_CLAUSE_COLLAPSE
:
255 if (fd
->collapse
> 1)
257 collapse_iter
= &OMP_CLAUSE_COLLAPSE_ITERVAR (t
);
258 collapse_count
= &OMP_CLAUSE_COLLAPSE_COUNT (t
);
264 /* FIXME: for now map schedule(auto) to schedule(static).
265 There should be analysis to determine whether all iterations
266 are approximately the same amount of work (then schedule(static)
267 is best) or if it varies (then schedule(dynamic,N) is better). */
268 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_AUTO
)
270 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
271 gcc_assert (fd
->chunk_size
== NULL
);
273 gcc_assert (fd
->collapse
== 1 || collapse_iter
!= NULL
);
274 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
275 gcc_assert (fd
->chunk_size
== NULL
);
276 else if (fd
->chunk_size
== NULL
)
278 /* We only need to compute a default chunk size for ordered
279 static loops and dynamic loops. */
280 if (fd
->sched_kind
!= OMP_CLAUSE_SCHEDULE_STATIC
283 fd
->chunk_size
= (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
284 ? integer_zero_node
: integer_one_node
;
287 for (i
= 0; i
< fd
->collapse
; i
++)
289 if (fd
->collapse
== 1)
291 else if (loops
!= NULL
)
297 loop
->v
= gimple_omp_for_index (for_stmt
, i
);
298 gcc_assert (SSA_VAR_P (loop
->v
));
299 gcc_assert (TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
300 || TREE_CODE (TREE_TYPE (loop
->v
)) == POINTER_TYPE
);
301 var
= TREE_CODE (loop
->v
) == SSA_NAME
? SSA_NAME_VAR (loop
->v
) : loop
->v
;
302 loop
->n1
= gimple_omp_for_initial (for_stmt
, i
);
304 loop
->cond_code
= gimple_omp_for_cond (for_stmt
, i
);
305 loop
->n2
= gimple_omp_for_final (for_stmt
, i
);
306 switch (loop
->cond_code
)
312 if (POINTER_TYPE_P (TREE_TYPE (loop
->n2
)))
313 loop
->n2
= fold_build_pointer_plus_hwi_loc (loc
, loop
->n2
, 1);
315 loop
->n2
= fold_build2_loc (loc
,
316 PLUS_EXPR
, TREE_TYPE (loop
->n2
), loop
->n2
,
317 build_int_cst (TREE_TYPE (loop
->n2
), 1));
318 loop
->cond_code
= LT_EXPR
;
321 if (POINTER_TYPE_P (TREE_TYPE (loop
->n2
)))
322 loop
->n2
= fold_build_pointer_plus_hwi_loc (loc
, loop
->n2
, -1);
324 loop
->n2
= fold_build2_loc (loc
,
325 MINUS_EXPR
, TREE_TYPE (loop
->n2
), loop
->n2
,
326 build_int_cst (TREE_TYPE (loop
->n2
), 1));
327 loop
->cond_code
= GT_EXPR
;
333 t
= gimple_omp_for_incr (for_stmt
, i
);
334 gcc_assert (TREE_OPERAND (t
, 0) == var
);
335 switch (TREE_CODE (t
))
338 loop
->step
= TREE_OPERAND (t
, 1);
340 case POINTER_PLUS_EXPR
:
341 loop
->step
= fold_convert (ssizetype
, TREE_OPERAND (t
, 1));
344 loop
->step
= TREE_OPERAND (t
, 1);
345 loop
->step
= fold_build1_loc (loc
,
346 NEGATE_EXPR
, TREE_TYPE (loop
->step
),
353 if (iter_type
!= long_long_unsigned_type_node
)
355 if (POINTER_TYPE_P (TREE_TYPE (loop
->v
)))
356 iter_type
= long_long_unsigned_type_node
;
357 else if (TYPE_UNSIGNED (TREE_TYPE (loop
->v
))
358 && TYPE_PRECISION (TREE_TYPE (loop
->v
))
359 >= TYPE_PRECISION (iter_type
))
363 if (loop
->cond_code
== LT_EXPR
)
364 n
= fold_build2_loc (loc
,
365 PLUS_EXPR
, TREE_TYPE (loop
->v
),
366 loop
->n2
, loop
->step
);
369 if (TREE_CODE (n
) != INTEGER_CST
370 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type
), n
))
371 iter_type
= long_long_unsigned_type_node
;
373 else if (TYPE_PRECISION (TREE_TYPE (loop
->v
))
374 > TYPE_PRECISION (iter_type
))
378 if (loop
->cond_code
== LT_EXPR
)
381 n2
= fold_build2_loc (loc
,
382 PLUS_EXPR
, TREE_TYPE (loop
->v
),
383 loop
->n2
, loop
->step
);
387 n1
= fold_build2_loc (loc
,
388 MINUS_EXPR
, TREE_TYPE (loop
->v
),
389 loop
->n2
, loop
->step
);
392 if (TREE_CODE (n1
) != INTEGER_CST
393 || TREE_CODE (n2
) != INTEGER_CST
394 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type
), n1
)
395 || !tree_int_cst_lt (n2
, TYPE_MAX_VALUE (iter_type
)))
396 iter_type
= long_long_unsigned_type_node
;
400 if (collapse_count
&& *collapse_count
== NULL
)
402 t
= fold_binary (loop
->cond_code
, boolean_type_node
,
403 fold_convert (TREE_TYPE (loop
->v
), loop
->n1
),
404 fold_convert (TREE_TYPE (loop
->v
), loop
->n2
));
405 if (t
&& integer_zerop (t
))
406 count
= build_zero_cst (long_long_unsigned_type_node
);
407 else if ((i
== 0 || count
!= NULL_TREE
)
408 && TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
409 && TREE_CONSTANT (loop
->n1
)
410 && TREE_CONSTANT (loop
->n2
)
411 && TREE_CODE (loop
->step
) == INTEGER_CST
)
413 tree itype
= TREE_TYPE (loop
->v
);
415 if (POINTER_TYPE_P (itype
))
416 itype
= signed_type_for (itype
);
417 t
= build_int_cst (itype
, (loop
->cond_code
== LT_EXPR
? -1 : 1));
418 t
= fold_build2_loc (loc
,
420 fold_convert_loc (loc
, itype
, loop
->step
), t
);
421 t
= fold_build2_loc (loc
, PLUS_EXPR
, itype
, t
,
422 fold_convert_loc (loc
, itype
, loop
->n2
));
423 t
= fold_build2_loc (loc
, MINUS_EXPR
, itype
, t
,
424 fold_convert_loc (loc
, itype
, loop
->n1
));
425 if (TYPE_UNSIGNED (itype
) && loop
->cond_code
== GT_EXPR
)
426 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
,
427 fold_build1_loc (loc
, NEGATE_EXPR
, itype
, t
),
428 fold_build1_loc (loc
, NEGATE_EXPR
, itype
,
429 fold_convert_loc (loc
, itype
,
432 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
, t
,
433 fold_convert_loc (loc
, itype
, loop
->step
));
434 t
= fold_convert_loc (loc
, long_long_unsigned_type_node
, t
);
435 if (count
!= NULL_TREE
)
436 count
= fold_build2_loc (loc
,
437 MULT_EXPR
, long_long_unsigned_type_node
,
441 if (TREE_CODE (count
) != INTEGER_CST
)
444 else if (count
&& !integer_zerop (count
))
451 if (!tree_int_cst_lt (count
, TYPE_MAX_VALUE (long_integer_type_node
)))
452 iter_type
= long_long_unsigned_type_node
;
454 iter_type
= long_integer_type_node
;
456 else if (collapse_iter
&& *collapse_iter
!= NULL
)
457 iter_type
= TREE_TYPE (*collapse_iter
);
458 fd
->iter_type
= iter_type
;
459 if (collapse_iter
&& *collapse_iter
== NULL
)
460 *collapse_iter
= create_tmp_var (iter_type
, ".iter");
461 if (collapse_count
&& *collapse_count
== NULL
)
464 *collapse_count
= fold_convert_loc (loc
, iter_type
, count
);
466 *collapse_count
= create_tmp_var (iter_type
, ".count");
469 if (fd
->collapse
> 1)
471 fd
->loop
.v
= *collapse_iter
;
472 fd
->loop
.n1
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
473 fd
->loop
.n2
= *collapse_count
;
474 fd
->loop
.step
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 1);
475 fd
->loop
.cond_code
= LT_EXPR
;
480 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
481 is the immediate dominator of PAR_ENTRY_BB, return true if there
482 are no data dependencies that would prevent expanding the parallel
483 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
485 When expanding a combined parallel+workshare region, the call to
486 the child function may need additional arguments in the case of
487 GIMPLE_OMP_FOR regions. In some cases, these arguments are
488 computed out of variables passed in from the parent to the child
489 via 'struct .omp_data_s'. For instance:
491 #pragma omp parallel for schedule (guided, i * 4)
496 # BLOCK 2 (PAR_ENTRY_BB)
498 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
500 # BLOCK 3 (WS_ENTRY_BB)
501 .omp_data_i = &.omp_data_o;
502 D.1667 = .omp_data_i->i;
504 #pragma omp for schedule (guided, D.1598)
506 When we outline the parallel region, the call to the child function
507 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
508 that value is computed *after* the call site. So, in principle we
509 cannot do the transformation.
511 To see whether the code in WS_ENTRY_BB blocks the combined
512 parallel+workshare call, we collect all the variables used in the
513 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
514 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
517 FIXME. If we had the SSA form built at this point, we could merely
518 hoist the code in block 3 into block 2 and be done with it. But at
519 this point we don't have dataflow information and though we could
520 hack something up here, it is really not worth the aggravation. */
523 workshare_safe_to_combine_p (basic_block ws_entry_bb
)
525 struct omp_for_data fd
;
526 gimple ws_stmt
= last_stmt (ws_entry_bb
);
528 if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
531 gcc_assert (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
);
533 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
535 if (fd
.collapse
> 1 && TREE_CODE (fd
.loop
.n2
) != INTEGER_CST
)
537 if (fd
.iter_type
!= long_integer_type_node
)
540 /* FIXME. We give up too easily here. If any of these arguments
541 are not constants, they will likely involve variables that have
542 been mapped into fields of .omp_data_s for sharing with the child
543 function. With appropriate data flow, it would be possible to
545 if (!is_gimple_min_invariant (fd
.loop
.n1
)
546 || !is_gimple_min_invariant (fd
.loop
.n2
)
547 || !is_gimple_min_invariant (fd
.loop
.step
)
548 || (fd
.chunk_size
&& !is_gimple_min_invariant (fd
.chunk_size
)))
555 /* Collect additional arguments needed to emit a combined
556 parallel+workshare call. WS_STMT is the workshare directive being
559 static vec
<tree
, va_gc
> *
560 get_ws_args_for (gimple ws_stmt
)
563 location_t loc
= gimple_location (ws_stmt
);
564 vec
<tree
, va_gc
> *ws_args
;
566 if (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
)
568 struct omp_for_data fd
;
570 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
572 vec_alloc (ws_args
, 3 + (fd
.chunk_size
!= 0));
574 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.n1
);
575 ws_args
->quick_push (t
);
577 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.n2
);
578 ws_args
->quick_push (t
);
580 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.step
);
581 ws_args
->quick_push (t
);
585 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.chunk_size
);
586 ws_args
->quick_push (t
);
591 else if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
593 /* Number of sections is equal to the number of edges from the
594 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
595 the exit of the sections region. */
596 basic_block bb
= single_succ (gimple_bb (ws_stmt
));
597 t
= build_int_cst (unsigned_type_node
, EDGE_COUNT (bb
->succs
) - 1);
598 vec_alloc (ws_args
, 1);
599 ws_args
->quick_push (t
);
607 /* Discover whether REGION is a combined parallel+workshare region. */
610 determine_parallel_type (struct omp_region
*region
)
612 basic_block par_entry_bb
, par_exit_bb
;
613 basic_block ws_entry_bb
, ws_exit_bb
;
615 if (region
== NULL
|| region
->inner
== NULL
616 || region
->exit
== NULL
|| region
->inner
->exit
== NULL
617 || region
->inner
->cont
== NULL
)
620 /* We only support parallel+for and parallel+sections. */
621 if (region
->type
!= GIMPLE_OMP_PARALLEL
622 || (region
->inner
->type
!= GIMPLE_OMP_FOR
623 && region
->inner
->type
!= GIMPLE_OMP_SECTIONS
))
626 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
627 WS_EXIT_BB -> PAR_EXIT_BB. */
628 par_entry_bb
= region
->entry
;
629 par_exit_bb
= region
->exit
;
630 ws_entry_bb
= region
->inner
->entry
;
631 ws_exit_bb
= region
->inner
->exit
;
633 if (single_succ (par_entry_bb
) == ws_entry_bb
634 && single_succ (ws_exit_bb
) == par_exit_bb
635 && workshare_safe_to_combine_p (ws_entry_bb
)
636 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb
))
637 || (last_and_only_stmt (ws_entry_bb
)
638 && last_and_only_stmt (par_exit_bb
))))
640 gimple ws_stmt
= last_stmt (ws_entry_bb
);
642 if (region
->inner
->type
== GIMPLE_OMP_FOR
)
644 /* If this is a combined parallel loop, we need to determine
645 whether or not to use the combined library calls. There
646 are two cases where we do not apply the transformation:
647 static loops and any kind of ordered loop. In the first
648 case, we already open code the loop so there is no need
649 to do anything else. In the latter case, the combined
650 parallel loop call would still need extra synchronization
651 to implement ordered semantics, so there would not be any
652 gain in using the combined call. */
653 tree clauses
= gimple_omp_for_clauses (ws_stmt
);
654 tree c
= find_omp_clause (clauses
, OMP_CLAUSE_SCHEDULE
);
656 || OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_STATIC
657 || find_omp_clause (clauses
, OMP_CLAUSE_ORDERED
))
659 region
->is_combined_parallel
= false;
660 region
->inner
->is_combined_parallel
= false;
665 region
->is_combined_parallel
= true;
666 region
->inner
->is_combined_parallel
= true;
667 region
->ws_args
= get_ws_args_for (ws_stmt
);
672 /* Return true if EXPR is variable sized. */
675 is_variable_sized (const_tree expr
)
677 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr
)));
680 /* Return true if DECL is a reference type. */
683 is_reference (tree decl
)
685 return lang_hooks
.decls
.omp_privatize_by_reference (decl
);
688 /* Lookup variables in the decl or field splay trees. The "maybe" form
689 allows for the variable form to not have been entered, otherwise we
690 assert that the variable must have been entered. */
693 lookup_decl (tree var
, omp_context
*ctx
)
696 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
701 maybe_lookup_decl (const_tree var
, omp_context
*ctx
)
704 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
705 return n
? *n
: NULL_TREE
;
709 lookup_field (tree var
, omp_context
*ctx
)
712 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
713 return (tree
) n
->value
;
717 lookup_sfield (tree var
, omp_context
*ctx
)
720 n
= splay_tree_lookup (ctx
->sfield_map
721 ? ctx
->sfield_map
: ctx
->field_map
,
722 (splay_tree_key
) var
);
723 return (tree
) n
->value
;
727 maybe_lookup_field (tree var
, omp_context
*ctx
)
730 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
731 return n
? (tree
) n
->value
: NULL_TREE
;
734 /* Return true if DECL should be copied by pointer. SHARED_CTX is
735 the parallel context if DECL is to be shared. */
738 use_pointer_for_field (tree decl
, omp_context
*shared_ctx
)
740 if (AGGREGATE_TYPE_P (TREE_TYPE (decl
)))
743 /* We can only use copy-in/copy-out semantics for shared variables
744 when we know the value is not accessible from an outer scope. */
747 /* ??? Trivially accessible from anywhere. But why would we even
748 be passing an address in this case? Should we simply assert
749 this to be false, or should we have a cleanup pass that removes
750 these from the list of mappings? */
751 if (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
754 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
755 without analyzing the expression whether or not its location
756 is accessible to anyone else. In the case of nested parallel
757 regions it certainly may be. */
758 if (TREE_CODE (decl
) != RESULT_DECL
&& DECL_HAS_VALUE_EXPR_P (decl
))
761 /* Do not use copy-in/copy-out for variables that have their
763 if (TREE_ADDRESSABLE (decl
))
766 /* lower_send_shared_vars only uses copy-in, but not copy-out
768 if (TREE_READONLY (decl
)
769 || ((TREE_CODE (decl
) == RESULT_DECL
770 || TREE_CODE (decl
) == PARM_DECL
)
771 && DECL_BY_REFERENCE (decl
)))
774 /* Disallow copy-in/out in nested parallel if
775 decl is shared in outer parallel, otherwise
776 each thread could store the shared variable
777 in its own copy-in location, making the
778 variable no longer really shared. */
779 if (shared_ctx
->is_nested
)
783 for (up
= shared_ctx
->outer
; up
; up
= up
->outer
)
784 if (is_taskreg_ctx (up
) && maybe_lookup_decl (decl
, up
))
791 for (c
= gimple_omp_taskreg_clauses (up
->stmt
);
792 c
; c
= OMP_CLAUSE_CHAIN (c
))
793 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
794 && OMP_CLAUSE_DECL (c
) == decl
)
798 goto maybe_mark_addressable_and_ret
;
802 /* For tasks avoid using copy-in/out. As tasks can be
803 deferred or executed in different thread, when GOMP_task
804 returns, the task hasn't necessarily terminated. */
805 if (is_task_ctx (shared_ctx
))
808 maybe_mark_addressable_and_ret
:
809 outer
= maybe_lookup_decl_in_outer_ctx (decl
, shared_ctx
);
810 if (is_gimple_reg (outer
))
812 /* Taking address of OUTER in lower_send_shared_vars
813 might need regimplification of everything that uses the
815 if (!task_shared_vars
)
816 task_shared_vars
= BITMAP_ALLOC (NULL
);
817 bitmap_set_bit (task_shared_vars
, DECL_UID (outer
));
818 TREE_ADDRESSABLE (outer
) = 1;
827 /* Create a new VAR_DECL and copy information from VAR to it. */
830 copy_var_decl (tree var
, tree name
, tree type
)
832 tree copy
= build_decl (DECL_SOURCE_LOCATION (var
), VAR_DECL
, name
, type
);
834 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (var
);
835 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (var
);
836 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (var
);
837 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (var
);
838 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (var
);
839 DECL_CONTEXT (copy
) = DECL_CONTEXT (var
);
840 TREE_NO_WARNING (copy
) = TREE_NO_WARNING (var
);
841 TREE_USED (copy
) = 1;
842 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
847 /* Construct a new automatic decl similar to VAR. */
850 omp_copy_decl_2 (tree var
, tree name
, tree type
, omp_context
*ctx
)
852 tree copy
= copy_var_decl (var
, name
, type
);
854 DECL_CONTEXT (copy
) = current_function_decl
;
855 DECL_CHAIN (copy
) = ctx
->block_vars
;
856 ctx
->block_vars
= copy
;
862 omp_copy_decl_1 (tree var
, omp_context
*ctx
)
864 return omp_copy_decl_2 (var
, DECL_NAME (var
), TREE_TYPE (var
), ctx
);
867 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
870 omp_build_component_ref (tree obj
, tree field
)
872 tree ret
= build3 (COMPONENT_REF
, TREE_TYPE (field
), obj
, field
, NULL
);
873 if (TREE_THIS_VOLATILE (field
))
874 TREE_THIS_VOLATILE (ret
) |= 1;
875 if (TREE_READONLY (field
))
876 TREE_READONLY (ret
) |= 1;
880 /* Build tree nodes to access the field for VAR on the receiver side. */
883 build_receiver_ref (tree var
, bool by_ref
, omp_context
*ctx
)
885 tree x
, field
= lookup_field (var
, ctx
);
887 /* If the receiver record type was remapped in the child function,
888 remap the field into the new record type. */
889 x
= maybe_lookup_field (field
, ctx
);
893 x
= build_simple_mem_ref (ctx
->receiver_decl
);
894 x
= omp_build_component_ref (x
, field
);
896 x
= build_simple_mem_ref (x
);
901 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
902 of a parallel, this is a component reference; for workshare constructs
903 this is some variable. */
906 build_outer_var_ref (tree var
, omp_context
*ctx
)
910 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
, ctx
)))
912 else if (is_variable_sized (var
))
914 x
= TREE_OPERAND (DECL_VALUE_EXPR (var
), 0);
915 x
= build_outer_var_ref (x
, ctx
);
916 x
= build_simple_mem_ref (x
);
918 else if (is_taskreg_ctx (ctx
))
920 bool by_ref
= use_pointer_for_field (var
, NULL
);
921 x
= build_receiver_ref (var
, by_ref
, ctx
);
924 x
= lookup_decl (var
, ctx
->outer
);
925 else if (is_reference (var
))
926 /* This can happen with orphaned constructs. If var is reference, it is
927 possible it is shared and as such valid. */
932 if (is_reference (var
))
933 x
= build_simple_mem_ref (x
);
938 /* Build tree nodes to access the field for VAR on the sender side. */
941 build_sender_ref (tree var
, omp_context
*ctx
)
943 tree field
= lookup_sfield (var
, ctx
);
944 return omp_build_component_ref (ctx
->sender_decl
, field
);
947 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
950 install_var_field (tree var
, bool by_ref
, int mask
, omp_context
*ctx
)
952 tree field
, type
, sfield
= NULL_TREE
;
954 gcc_assert ((mask
& 1) == 0
955 || !splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
));
956 gcc_assert ((mask
& 2) == 0 || !ctx
->sfield_map
957 || !splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) var
));
959 type
= TREE_TYPE (var
);
961 type
= build_pointer_type (type
);
962 else if ((mask
& 3) == 1 && is_reference (var
))
963 type
= TREE_TYPE (type
);
965 field
= build_decl (DECL_SOURCE_LOCATION (var
),
966 FIELD_DECL
, DECL_NAME (var
), type
);
968 /* Remember what variable this field was created for. This does have a
969 side effect of making dwarf2out ignore this member, so for helpful
970 debugging we clear it later in delete_omp_context. */
971 DECL_ABSTRACT_ORIGIN (field
) = var
;
972 if (type
== TREE_TYPE (var
))
974 DECL_ALIGN (field
) = DECL_ALIGN (var
);
975 DECL_USER_ALIGN (field
) = DECL_USER_ALIGN (var
);
976 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (var
);
979 DECL_ALIGN (field
) = TYPE_ALIGN (type
);
983 insert_field_into_struct (ctx
->record_type
, field
);
984 if (ctx
->srecord_type
)
986 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
987 FIELD_DECL
, DECL_NAME (var
), type
);
988 DECL_ABSTRACT_ORIGIN (sfield
) = var
;
989 DECL_ALIGN (sfield
) = DECL_ALIGN (field
);
990 DECL_USER_ALIGN (sfield
) = DECL_USER_ALIGN (field
);
991 TREE_THIS_VOLATILE (sfield
) = TREE_THIS_VOLATILE (field
);
992 insert_field_into_struct (ctx
->srecord_type
, sfield
);
997 if (ctx
->srecord_type
== NULL_TREE
)
1001 ctx
->srecord_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1002 ctx
->sfield_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1003 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= TREE_CHAIN (t
))
1005 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
1006 FIELD_DECL
, DECL_NAME (t
), TREE_TYPE (t
));
1007 DECL_ABSTRACT_ORIGIN (sfield
) = DECL_ABSTRACT_ORIGIN (t
);
1008 insert_field_into_struct (ctx
->srecord_type
, sfield
);
1009 splay_tree_insert (ctx
->sfield_map
,
1010 (splay_tree_key
) DECL_ABSTRACT_ORIGIN (t
),
1011 (splay_tree_value
) sfield
);
1015 insert_field_into_struct ((mask
& 1) ? ctx
->record_type
1016 : ctx
->srecord_type
, field
);
1020 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) var
,
1021 (splay_tree_value
) field
);
1022 if ((mask
& 2) && ctx
->sfield_map
)
1023 splay_tree_insert (ctx
->sfield_map
, (splay_tree_key
) var
,
1024 (splay_tree_value
) sfield
);
1028 install_var_local (tree var
, omp_context
*ctx
)
1030 tree new_var
= omp_copy_decl_1 (var
, ctx
);
1031 insert_decl_map (&ctx
->cb
, var
, new_var
);
1035 /* Adjust the replacement for DECL in CTX for the new context. This means
1036 copying the DECL_VALUE_EXPR, and fixing up the type. */
1039 fixup_remapped_decl (tree decl
, omp_context
*ctx
, bool private_debug
)
1041 tree new_decl
, size
;
1043 new_decl
= lookup_decl (decl
, ctx
);
1045 TREE_TYPE (new_decl
) = remap_type (TREE_TYPE (decl
), &ctx
->cb
);
1047 if ((!TREE_CONSTANT (DECL_SIZE (new_decl
)) || private_debug
)
1048 && DECL_HAS_VALUE_EXPR_P (decl
))
1050 tree ve
= DECL_VALUE_EXPR (decl
);
1051 walk_tree (&ve
, copy_tree_body_r
, &ctx
->cb
, NULL
);
1052 SET_DECL_VALUE_EXPR (new_decl
, ve
);
1053 DECL_HAS_VALUE_EXPR_P (new_decl
) = 1;
1056 if (!TREE_CONSTANT (DECL_SIZE (new_decl
)))
1058 size
= remap_decl (DECL_SIZE (decl
), &ctx
->cb
);
1059 if (size
== error_mark_node
)
1060 size
= TYPE_SIZE (TREE_TYPE (new_decl
));
1061 DECL_SIZE (new_decl
) = size
;
1063 size
= remap_decl (DECL_SIZE_UNIT (decl
), &ctx
->cb
);
1064 if (size
== error_mark_node
)
1065 size
= TYPE_SIZE_UNIT (TREE_TYPE (new_decl
));
1066 DECL_SIZE_UNIT (new_decl
) = size
;
1070 /* The callback for remap_decl. Search all containing contexts for a
1071 mapping of the variable; this avoids having to duplicate the splay
1072 tree ahead of time. We know a mapping doesn't already exist in the
1073 given context. Create new mappings to implement default semantics. */
1076 omp_copy_decl (tree var
, copy_body_data
*cb
)
1078 omp_context
*ctx
= (omp_context
*) cb
;
1081 if (TREE_CODE (var
) == LABEL_DECL
)
1083 new_var
= create_artificial_label (DECL_SOURCE_LOCATION (var
));
1084 DECL_CONTEXT (new_var
) = current_function_decl
;
1085 insert_decl_map (&ctx
->cb
, var
, new_var
);
1089 while (!is_taskreg_ctx (ctx
))
1094 new_var
= maybe_lookup_decl (var
, ctx
);
1099 if (is_global_var (var
) || decl_function_context (var
) != ctx
->cb
.src_fn
)
1102 return error_mark_node
;
1106 /* Return the parallel region associated with STMT. */
1108 /* Debugging dumps for parallel regions. */
1109 void dump_omp_region (FILE *, struct omp_region
*, int);
1110 void debug_omp_region (struct omp_region
*);
1111 void debug_all_omp_regions (void);
1113 /* Dump the parallel region tree rooted at REGION. */
1116 dump_omp_region (FILE *file
, struct omp_region
*region
, int indent
)
1118 fprintf (file
, "%*sbb %d: %s\n", indent
, "", region
->entry
->index
,
1119 gimple_code_name
[region
->type
]);
1122 dump_omp_region (file
, region
->inner
, indent
+ 4);
1126 fprintf (file
, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent
, "",
1127 region
->cont
->index
);
1131 fprintf (file
, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent
, "",
1132 region
->exit
->index
);
1134 fprintf (file
, "%*s[no exit marker]\n", indent
, "");
1137 dump_omp_region (file
, region
->next
, indent
);
1141 debug_omp_region (struct omp_region
*region
)
1143 dump_omp_region (stderr
, region
, 0);
1147 debug_all_omp_regions (void)
1149 dump_omp_region (stderr
, root_omp_region
, 0);
1153 /* Create a new parallel region starting at STMT inside region PARENT. */
1156 new_omp_region (basic_block bb
, enum gimple_code type
,
1157 struct omp_region
*parent
)
1159 struct omp_region
*region
= XCNEW (struct omp_region
);
1161 region
->outer
= parent
;
1163 region
->type
= type
;
1167 /* This is a nested region. Add it to the list of inner
1168 regions in PARENT. */
1169 region
->next
= parent
->inner
;
1170 parent
->inner
= region
;
1174 /* This is a toplevel region. Add it to the list of toplevel
1175 regions in ROOT_OMP_REGION. */
1176 region
->next
= root_omp_region
;
1177 root_omp_region
= region
;
1183 /* Release the memory associated with the region tree rooted at REGION. */
1186 free_omp_region_1 (struct omp_region
*region
)
1188 struct omp_region
*i
, *n
;
1190 for (i
= region
->inner
; i
; i
= n
)
1193 free_omp_region_1 (i
);
1199 /* Release the memory for the entire omp region tree. */
1202 free_omp_regions (void)
1204 struct omp_region
*r
, *n
;
1205 for (r
= root_omp_region
; r
; r
= n
)
1208 free_omp_region_1 (r
);
1210 root_omp_region
= NULL
;
1214 /* Create a new context, with OUTER_CTX being the surrounding context. */
1216 static omp_context
*
1217 new_omp_context (gimple stmt
, omp_context
*outer_ctx
)
1219 omp_context
*ctx
= XCNEW (omp_context
);
1221 splay_tree_insert (all_contexts
, (splay_tree_key
) stmt
,
1222 (splay_tree_value
) ctx
);
1227 ctx
->outer
= outer_ctx
;
1228 ctx
->cb
= outer_ctx
->cb
;
1229 ctx
->cb
.block
= NULL
;
1230 ctx
->depth
= outer_ctx
->depth
+ 1;
1234 ctx
->cb
.src_fn
= current_function_decl
;
1235 ctx
->cb
.dst_fn
= current_function_decl
;
1236 ctx
->cb
.src_node
= cgraph_get_node (current_function_decl
);
1237 gcc_checking_assert (ctx
->cb
.src_node
);
1238 ctx
->cb
.dst_node
= ctx
->cb
.src_node
;
1239 ctx
->cb
.src_cfun
= cfun
;
1240 ctx
->cb
.copy_decl
= omp_copy_decl
;
1241 ctx
->cb
.eh_lp_nr
= 0;
1242 ctx
->cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
1246 ctx
->cb
.decl_map
= pointer_map_create ();
1251 static gimple_seq
maybe_catch_exception (gimple_seq
);
1253 /* Finalize task copyfn. */
1256 finalize_task_copyfn (gimple task_stmt
)
1258 struct function
*child_cfun
;
1260 gimple_seq seq
= NULL
, new_seq
;
1263 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
1264 if (child_fn
== NULL_TREE
)
1267 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
1269 /* Inform the callgraph about the new function. */
1270 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
1271 = cfun
->curr_properties
& ~PROP_loops
;
1273 push_cfun (child_cfun
);
1274 bind
= gimplify_body (child_fn
, false);
1275 gimple_seq_add_stmt (&seq
, bind
);
1276 new_seq
= maybe_catch_exception (seq
);
1279 bind
= gimple_build_bind (NULL
, new_seq
, NULL
);
1281 gimple_seq_add_stmt (&seq
, bind
);
1283 gimple_set_body (child_fn
, seq
);
1286 cgraph_add_new_function (child_fn
, false);
1289 /* Destroy a omp_context data structures. Called through the splay tree
1290 value delete callback. */
1293 delete_omp_context (splay_tree_value value
)
1295 omp_context
*ctx
= (omp_context
*) value
;
1297 pointer_map_destroy (ctx
->cb
.decl_map
);
1300 splay_tree_delete (ctx
->field_map
);
1301 if (ctx
->sfield_map
)
1302 splay_tree_delete (ctx
->sfield_map
);
1304 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1305 it produces corrupt debug information. */
1306 if (ctx
->record_type
)
1309 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= DECL_CHAIN (t
))
1310 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1312 if (ctx
->srecord_type
)
1315 for (t
= TYPE_FIELDS (ctx
->srecord_type
); t
; t
= DECL_CHAIN (t
))
1316 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1319 if (is_task_ctx (ctx
))
1320 finalize_task_copyfn (ctx
->stmt
);
1325 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1329 fixup_child_record_type (omp_context
*ctx
)
1331 tree f
, type
= ctx
->record_type
;
1333 /* ??? It isn't sufficient to just call remap_type here, because
1334 variably_modified_type_p doesn't work the way we expect for
1335 record types. Testing each field for whether it needs remapping
1336 and creating a new record by hand works, however. */
1337 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
1338 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
1342 tree name
, new_fields
= NULL
;
1344 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1345 name
= DECL_NAME (TYPE_NAME (ctx
->record_type
));
1346 name
= build_decl (DECL_SOURCE_LOCATION (ctx
->receiver_decl
),
1347 TYPE_DECL
, name
, type
);
1348 TYPE_NAME (type
) = name
;
1350 for (f
= TYPE_FIELDS (ctx
->record_type
); f
; f
= DECL_CHAIN (f
))
1352 tree new_f
= copy_node (f
);
1353 DECL_CONTEXT (new_f
) = type
;
1354 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &ctx
->cb
);
1355 DECL_CHAIN (new_f
) = new_fields
;
1356 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &ctx
->cb
, NULL
);
1357 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
,
1359 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
1363 /* Arrange to be able to look up the receiver field
1364 given the sender field. */
1365 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) f
,
1366 (splay_tree_value
) new_f
);
1368 TYPE_FIELDS (type
) = nreverse (new_fields
);
1372 TREE_TYPE (ctx
->receiver_decl
) = build_pointer_type (type
);
1375 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1376 specified by CLAUSES. */
1379 scan_sharing_clauses (tree clauses
, omp_context
*ctx
)
1382 bool scan_array_reductions
= false;
1384 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1388 switch (OMP_CLAUSE_CODE (c
))
1390 case OMP_CLAUSE_PRIVATE
:
1391 decl
= OMP_CLAUSE_DECL (c
);
1392 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
1394 else if (!is_variable_sized (decl
))
1395 install_var_local (decl
, ctx
);
1398 case OMP_CLAUSE_SHARED
:
1399 gcc_assert (is_taskreg_ctx (ctx
));
1400 decl
= OMP_CLAUSE_DECL (c
);
1401 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl
))
1402 || !is_variable_sized (decl
));
1403 /* Global variables don't need to be copied,
1404 the receiver side will use them directly. */
1405 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1407 by_ref
= use_pointer_for_field (decl
, ctx
);
1408 if (! TREE_READONLY (decl
)
1409 || TREE_ADDRESSABLE (decl
)
1411 || is_reference (decl
))
1413 install_var_field (decl
, by_ref
, 3, ctx
);
1414 install_var_local (decl
, ctx
);
1417 /* We don't need to copy const scalar vars back. */
1418 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_FIRSTPRIVATE
);
1421 case OMP_CLAUSE_LASTPRIVATE
:
1422 /* Let the corresponding firstprivate clause create
1424 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1428 case OMP_CLAUSE_FIRSTPRIVATE
:
1429 case OMP_CLAUSE_REDUCTION
:
1430 decl
= OMP_CLAUSE_DECL (c
);
1432 if (is_variable_sized (decl
))
1434 if (is_task_ctx (ctx
))
1435 install_var_field (decl
, false, 1, ctx
);
1438 else if (is_taskreg_ctx (ctx
))
1441 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
));
1442 by_ref
= use_pointer_for_field (decl
, NULL
);
1444 if (is_task_ctx (ctx
)
1445 && (global
|| by_ref
|| is_reference (decl
)))
1447 install_var_field (decl
, false, 1, ctx
);
1449 install_var_field (decl
, by_ref
, 2, ctx
);
1452 install_var_field (decl
, by_ref
, 3, ctx
);
1454 install_var_local (decl
, ctx
);
1457 case OMP_CLAUSE_COPYPRIVATE
:
1458 case OMP_CLAUSE_COPYIN
:
1459 decl
= OMP_CLAUSE_DECL (c
);
1460 by_ref
= use_pointer_for_field (decl
, NULL
);
1461 install_var_field (decl
, by_ref
, 3, ctx
);
1464 case OMP_CLAUSE_DEFAULT
:
1465 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
1468 case OMP_CLAUSE_FINAL
:
1470 case OMP_CLAUSE_NUM_THREADS
:
1471 case OMP_CLAUSE_SCHEDULE
:
1473 scan_omp_op (&OMP_CLAUSE_OPERAND (c
, 0), ctx
->outer
);
1476 case OMP_CLAUSE_NOWAIT
:
1477 case OMP_CLAUSE_ORDERED
:
1478 case OMP_CLAUSE_COLLAPSE
:
1479 case OMP_CLAUSE_UNTIED
:
1480 case OMP_CLAUSE_MERGEABLE
:
1488 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1490 switch (OMP_CLAUSE_CODE (c
))
1492 case OMP_CLAUSE_LASTPRIVATE
:
1493 /* Let the corresponding firstprivate clause create
1495 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1496 scan_array_reductions
= true;
1497 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1501 case OMP_CLAUSE_PRIVATE
:
1502 case OMP_CLAUSE_FIRSTPRIVATE
:
1503 case OMP_CLAUSE_REDUCTION
:
1504 decl
= OMP_CLAUSE_DECL (c
);
1505 if (is_variable_sized (decl
))
1506 install_var_local (decl
, ctx
);
1507 fixup_remapped_decl (decl
, ctx
,
1508 OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_PRIVATE
1509 && OMP_CLAUSE_PRIVATE_DEBUG (c
));
1510 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1511 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1512 scan_array_reductions
= true;
1515 case OMP_CLAUSE_SHARED
:
1516 decl
= OMP_CLAUSE_DECL (c
);
1517 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1518 fixup_remapped_decl (decl
, ctx
, false);
1521 case OMP_CLAUSE_COPYPRIVATE
:
1522 case OMP_CLAUSE_COPYIN
:
1523 case OMP_CLAUSE_DEFAULT
:
1525 case OMP_CLAUSE_NUM_THREADS
:
1526 case OMP_CLAUSE_SCHEDULE
:
1527 case OMP_CLAUSE_NOWAIT
:
1528 case OMP_CLAUSE_ORDERED
:
1529 case OMP_CLAUSE_COLLAPSE
:
1530 case OMP_CLAUSE_UNTIED
:
1531 case OMP_CLAUSE_FINAL
:
1532 case OMP_CLAUSE_MERGEABLE
:
1540 if (scan_array_reductions
)
1541 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1542 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1543 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1545 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
1546 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
1548 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
1549 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1550 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
1553 /* Create a new name for omp child function. Returns an identifier. */
1555 static GTY(()) unsigned int tmp_ompfn_id_num
;
1558 create_omp_child_function_name (bool task_copy
)
1560 return (clone_function_name (current_function_decl
,
1561 task_copy
? "_omp_cpyfn" : "_omp_fn"));
1564 /* Build a decl for the omp child function. It'll not contain a body
1565 yet, just the bare decl. */
1568 create_omp_child_function (omp_context
*ctx
, bool task_copy
)
1570 tree decl
, type
, name
, t
;
1572 name
= create_omp_child_function_name (task_copy
);
1574 type
= build_function_type_list (void_type_node
, ptr_type_node
,
1575 ptr_type_node
, NULL_TREE
);
1577 type
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
1579 decl
= build_decl (gimple_location (ctx
->stmt
),
1580 FUNCTION_DECL
, name
, type
);
1583 ctx
->cb
.dst_fn
= decl
;
1585 gimple_omp_task_set_copy_fn (ctx
->stmt
, decl
);
1587 TREE_STATIC (decl
) = 1;
1588 TREE_USED (decl
) = 1;
1589 DECL_ARTIFICIAL (decl
) = 1;
1590 DECL_IGNORED_P (decl
) = 0;
1591 TREE_PUBLIC (decl
) = 0;
1592 DECL_UNINLINABLE (decl
) = 1;
1593 DECL_EXTERNAL (decl
) = 0;
1594 DECL_CONTEXT (decl
) = NULL_TREE
;
1595 DECL_INITIAL (decl
) = make_node (BLOCK
);
1597 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1598 RESULT_DECL
, NULL_TREE
, void_type_node
);
1599 DECL_ARTIFICIAL (t
) = 1;
1600 DECL_IGNORED_P (t
) = 1;
1601 DECL_CONTEXT (t
) = decl
;
1602 DECL_RESULT (decl
) = t
;
1604 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1605 PARM_DECL
, get_identifier (".omp_data_i"), ptr_type_node
);
1606 DECL_ARTIFICIAL (t
) = 1;
1607 DECL_NAMELESS (t
) = 1;
1608 DECL_ARG_TYPE (t
) = ptr_type_node
;
1609 DECL_CONTEXT (t
) = current_function_decl
;
1611 DECL_ARGUMENTS (decl
) = t
;
1613 ctx
->receiver_decl
= t
;
1616 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1617 PARM_DECL
, get_identifier (".omp_data_o"),
1619 DECL_ARTIFICIAL (t
) = 1;
1620 DECL_NAMELESS (t
) = 1;
1621 DECL_ARG_TYPE (t
) = ptr_type_node
;
1622 DECL_CONTEXT (t
) = current_function_decl
;
1624 TREE_ADDRESSABLE (t
) = 1;
1625 DECL_CHAIN (t
) = DECL_ARGUMENTS (decl
);
1626 DECL_ARGUMENTS (decl
) = t
;
1629 /* Allocate memory for the function structure. The call to
1630 allocate_struct_function clobbers CFUN, so we need to restore
1632 push_struct_function (decl
);
1633 cfun
->function_end_locus
= gimple_location (ctx
->stmt
);
1638 /* Scan an OpenMP parallel directive. */
1641 scan_omp_parallel (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1645 gimple stmt
= gsi_stmt (*gsi
);
1647 /* Ignore parallel directives with empty bodies, unless there
1648 are copyin clauses. */
1650 && empty_body_p (gimple_omp_body (stmt
))
1651 && find_omp_clause (gimple_omp_parallel_clauses (stmt
),
1652 OMP_CLAUSE_COPYIN
) == NULL
)
1654 gsi_replace (gsi
, gimple_build_nop (), false);
1658 ctx
= new_omp_context (stmt
, outer_ctx
);
1659 taskreg_contexts
.safe_push (ctx
);
1660 if (taskreg_nesting_level
> 1)
1661 ctx
->is_nested
= true;
1662 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1663 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1664 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1665 name
= create_tmp_var_name (".omp_data_s");
1666 name
= build_decl (gimple_location (stmt
),
1667 TYPE_DECL
, name
, ctx
->record_type
);
1668 DECL_ARTIFICIAL (name
) = 1;
1669 DECL_NAMELESS (name
) = 1;
1670 TYPE_NAME (ctx
->record_type
) = name
;
1671 create_omp_child_function (ctx
, false);
1672 gimple_omp_parallel_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
1674 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt
), ctx
);
1675 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1677 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1678 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1681 /* Scan an OpenMP task directive. */
1684 scan_omp_task (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1688 gimple stmt
= gsi_stmt (*gsi
);
1690 /* Ignore task directives with empty bodies. */
1692 && empty_body_p (gimple_omp_body (stmt
)))
1694 gsi_replace (gsi
, gimple_build_nop (), false);
1698 ctx
= new_omp_context (stmt
, outer_ctx
);
1699 taskreg_contexts
.safe_push (ctx
);
1700 if (taskreg_nesting_level
> 1)
1701 ctx
->is_nested
= true;
1702 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1703 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1704 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1705 name
= create_tmp_var_name (".omp_data_s");
1706 name
= build_decl (gimple_location (stmt
),
1707 TYPE_DECL
, name
, ctx
->record_type
);
1708 DECL_ARTIFICIAL (name
) = 1;
1709 DECL_NAMELESS (name
) = 1;
1710 TYPE_NAME (ctx
->record_type
) = name
;
1711 create_omp_child_function (ctx
, false);
1712 gimple_omp_task_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
1714 scan_sharing_clauses (gimple_omp_task_clauses (stmt
), ctx
);
1716 if (ctx
->srecord_type
)
1718 name
= create_tmp_var_name (".omp_data_a");
1719 name
= build_decl (gimple_location (stmt
),
1720 TYPE_DECL
, name
, ctx
->srecord_type
);
1721 DECL_ARTIFICIAL (name
) = 1;
1722 DECL_NAMELESS (name
) = 1;
1723 TYPE_NAME (ctx
->srecord_type
) = name
;
1724 create_omp_child_function (ctx
, true);
1727 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1729 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1731 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1732 t
= build_int_cst (long_integer_type_node
, 0);
1733 gimple_omp_task_set_arg_size (stmt
, t
);
1734 t
= build_int_cst (long_integer_type_node
, 1);
1735 gimple_omp_task_set_arg_align (stmt
, t
);
1740 /* If any decls have been made addressable during scan_omp,
1741 adjust their fields if needed, and layout record types
1742 of parallel/task constructs. */
1745 finish_taskreg_scan (omp_context
*ctx
)
1747 if (ctx
->record_type
== NULL_TREE
)
1750 /* If any task_shared_vars were needed, verify all
1751 OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK}
1752 statements if use_pointer_for_field hasn't changed
1753 because of that. If it did, update field types now. */
1754 if (task_shared_vars
)
1758 for (c
= gimple_omp_taskreg_clauses (ctx
->stmt
);
1759 c
; c
= OMP_CLAUSE_CHAIN (c
))
1760 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
)
1762 tree decl
= OMP_CLAUSE_DECL (c
);
1764 /* Global variables don't need to be copied,
1765 the receiver side will use them directly. */
1766 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1768 if (!bitmap_bit_p (task_shared_vars
, DECL_UID (decl
))
1769 || !use_pointer_for_field (decl
, ctx
))
1771 tree field
= lookup_field (decl
, ctx
);
1772 if (TREE_CODE (TREE_TYPE (field
)) == POINTER_TYPE
1773 && TREE_TYPE (TREE_TYPE (field
)) == TREE_TYPE (decl
))
1775 TREE_TYPE (field
) = build_pointer_type (TREE_TYPE (decl
));
1776 TREE_THIS_VOLATILE (field
) = 0;
1777 DECL_USER_ALIGN (field
) = 0;
1778 DECL_ALIGN (field
) = TYPE_ALIGN (TREE_TYPE (field
));
1779 if (TYPE_ALIGN (ctx
->record_type
) < DECL_ALIGN (field
))
1780 TYPE_ALIGN (ctx
->record_type
) = DECL_ALIGN (field
);
1781 if (ctx
->srecord_type
)
1783 tree sfield
= lookup_sfield (decl
, ctx
);
1784 TREE_TYPE (sfield
) = TREE_TYPE (field
);
1785 TREE_THIS_VOLATILE (sfield
) = 0;
1786 DECL_USER_ALIGN (sfield
) = 0;
1787 DECL_ALIGN (sfield
) = DECL_ALIGN (field
);
1788 if (TYPE_ALIGN (ctx
->srecord_type
) < DECL_ALIGN (sfield
))
1789 TYPE_ALIGN (ctx
->srecord_type
) = DECL_ALIGN (sfield
);
1794 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
)
1796 layout_type (ctx
->record_type
);
1797 fixup_child_record_type (ctx
);
1801 location_t loc
= gimple_location (ctx
->stmt
);
1802 tree
*p
, vla_fields
= NULL_TREE
, *q
= &vla_fields
;
1803 /* Move VLA fields to the end. */
1804 p
= &TYPE_FIELDS (ctx
->record_type
);
1806 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p
))
1807 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p
))))
1810 *p
= TREE_CHAIN (*p
);
1811 TREE_CHAIN (*q
) = NULL_TREE
;
1812 q
= &TREE_CHAIN (*q
);
1815 p
= &DECL_CHAIN (*p
);
1817 layout_type (ctx
->record_type
);
1818 fixup_child_record_type (ctx
);
1819 if (ctx
->srecord_type
)
1820 layout_type (ctx
->srecord_type
);
1821 tree t
= fold_convert_loc (loc
, long_integer_type_node
,
1822 TYPE_SIZE_UNIT (ctx
->record_type
));
1823 gimple_omp_task_set_arg_size (ctx
->stmt
, t
);
1824 t
= build_int_cst (long_integer_type_node
,
1825 TYPE_ALIGN_UNIT (ctx
->record_type
));
1826 gimple_omp_task_set_arg_align (ctx
->stmt
, t
);
1831 /* Scan an OpenMP loop directive. */
1834 scan_omp_for (gimple stmt
, omp_context
*outer_ctx
)
1839 ctx
= new_omp_context (stmt
, outer_ctx
);
1841 scan_sharing_clauses (gimple_omp_for_clauses (stmt
), ctx
);
1843 scan_omp (gimple_omp_for_pre_body_ptr (stmt
), ctx
);
1844 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
1846 scan_omp_op (gimple_omp_for_index_ptr (stmt
, i
), ctx
);
1847 scan_omp_op (gimple_omp_for_initial_ptr (stmt
, i
), ctx
);
1848 scan_omp_op (gimple_omp_for_final_ptr (stmt
, i
), ctx
);
1849 scan_omp_op (gimple_omp_for_incr_ptr (stmt
, i
), ctx
);
1851 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1854 /* Scan an OpenMP sections directive. */
1857 scan_omp_sections (gimple stmt
, omp_context
*outer_ctx
)
1861 ctx
= new_omp_context (stmt
, outer_ctx
);
1862 scan_sharing_clauses (gimple_omp_sections_clauses (stmt
), ctx
);
1863 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1866 /* Scan an OpenMP single directive. */
1869 scan_omp_single (gimple stmt
, omp_context
*outer_ctx
)
1874 ctx
= new_omp_context (stmt
, outer_ctx
);
1875 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1876 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1877 name
= create_tmp_var_name (".omp_copy_s");
1878 name
= build_decl (gimple_location (stmt
),
1879 TYPE_DECL
, name
, ctx
->record_type
);
1880 TYPE_NAME (ctx
->record_type
) = name
;
1882 scan_sharing_clauses (gimple_omp_single_clauses (stmt
), ctx
);
1883 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1885 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1886 ctx
->record_type
= NULL
;
1888 layout_type (ctx
->record_type
);
1892 /* Check OpenMP nesting restrictions. */
1894 check_omp_nesting_restrictions (gimple stmt
, omp_context
*ctx
)
1896 switch (gimple_code (stmt
))
1898 case GIMPLE_OMP_FOR
:
1899 case GIMPLE_OMP_SECTIONS
:
1900 case GIMPLE_OMP_SINGLE
:
1902 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1903 switch (gimple_code (ctx
->stmt
))
1905 case GIMPLE_OMP_FOR
:
1906 case GIMPLE_OMP_SECTIONS
:
1907 case GIMPLE_OMP_SINGLE
:
1908 case GIMPLE_OMP_ORDERED
:
1909 case GIMPLE_OMP_MASTER
:
1910 case GIMPLE_OMP_TASK
:
1911 if (is_gimple_call (stmt
))
1913 error_at (gimple_location (stmt
),
1914 "barrier region may not be closely nested inside "
1915 "of work-sharing, critical, ordered, master or "
1916 "explicit task region");
1919 error_at (gimple_location (stmt
),
1920 "work-sharing region may not be closely nested inside "
1921 "of work-sharing, critical, ordered, master or explicit "
1924 case GIMPLE_OMP_PARALLEL
:
1930 case GIMPLE_OMP_MASTER
:
1931 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1932 switch (gimple_code (ctx
->stmt
))
1934 case GIMPLE_OMP_FOR
:
1935 case GIMPLE_OMP_SECTIONS
:
1936 case GIMPLE_OMP_SINGLE
:
1937 case GIMPLE_OMP_TASK
:
1938 error_at (gimple_location (stmt
),
1939 "master region may not be closely nested inside "
1940 "of work-sharing or explicit task region");
1942 case GIMPLE_OMP_PARALLEL
:
1948 case GIMPLE_OMP_ORDERED
:
1949 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1950 switch (gimple_code (ctx
->stmt
))
1952 case GIMPLE_OMP_CRITICAL
:
1953 case GIMPLE_OMP_TASK
:
1954 error_at (gimple_location (stmt
),
1955 "ordered region may not be closely nested inside "
1956 "of critical or explicit task region");
1958 case GIMPLE_OMP_FOR
:
1959 if (find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
1960 OMP_CLAUSE_ORDERED
) == NULL
)
1962 error_at (gimple_location (stmt
),
1963 "ordered region must be closely nested inside "
1964 "a loop region with an ordered clause");
1968 case GIMPLE_OMP_PARALLEL
:
1974 case GIMPLE_OMP_CRITICAL
:
1975 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1976 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_CRITICAL
1977 && (gimple_omp_critical_name (stmt
)
1978 == gimple_omp_critical_name (ctx
->stmt
)))
1980 error_at (gimple_location (stmt
),
1981 "critical region may not be nested inside a critical "
1982 "region with the same name");
1993 /* Helper function scan_omp.
1995 Callback for walk_tree or operators in walk_gimple_stmt used to
1996 scan for OpenMP directives in TP. */
1999 scan_omp_1_op (tree
*tp
, int *walk_subtrees
, void *data
)
2001 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
2002 omp_context
*ctx
= (omp_context
*) wi
->info
;
2005 switch (TREE_CODE (t
))
2012 *tp
= remap_decl (t
, &ctx
->cb
);
2016 if (ctx
&& TYPE_P (t
))
2017 *tp
= remap_type (t
, &ctx
->cb
);
2018 else if (!DECL_P (t
))
2023 tree tem
= remap_type (TREE_TYPE (t
), &ctx
->cb
);
2024 if (tem
!= TREE_TYPE (t
))
2026 if (TREE_CODE (t
) == INTEGER_CST
)
2027 *tp
= build_int_cst_wide (tem
,
2028 TREE_INT_CST_LOW (t
),
2029 TREE_INT_CST_HIGH (t
));
2031 TREE_TYPE (t
) = tem
;
2042 /* Helper function for scan_omp.
2044 Callback for walk_gimple_stmt used to scan for OpenMP directives in
2045 the current statement in GSI. */
2048 scan_omp_1_stmt (gimple_stmt_iterator
*gsi
, bool *handled_ops_p
,
2049 struct walk_stmt_info
*wi
)
2051 gimple stmt
= gsi_stmt (*gsi
);
2052 omp_context
*ctx
= (omp_context
*) wi
->info
;
2054 if (gimple_has_location (stmt
))
2055 input_location
= gimple_location (stmt
);
2057 /* Check the OpenMP nesting restrictions. */
2060 bool remove
= false;
2061 if (is_gimple_omp (stmt
))
2062 remove
= !check_omp_nesting_restrictions (stmt
, ctx
);
2063 else if (is_gimple_call (stmt
))
2065 tree fndecl
= gimple_call_fndecl (stmt
);
2066 if (fndecl
&& DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
2067 && DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_GOMP_BARRIER
)
2068 remove
= !check_omp_nesting_restrictions (stmt
, ctx
);
2072 stmt
= gimple_build_nop ();
2073 gsi_replace (gsi
, stmt
, false);
2077 *handled_ops_p
= true;
2079 switch (gimple_code (stmt
))
2081 case GIMPLE_OMP_PARALLEL
:
2082 taskreg_nesting_level
++;
2083 scan_omp_parallel (gsi
, ctx
);
2084 taskreg_nesting_level
--;
2087 case GIMPLE_OMP_TASK
:
2088 taskreg_nesting_level
++;
2089 scan_omp_task (gsi
, ctx
);
2090 taskreg_nesting_level
--;
2093 case GIMPLE_OMP_FOR
:
2094 scan_omp_for (stmt
, ctx
);
2097 case GIMPLE_OMP_SECTIONS
:
2098 scan_omp_sections (stmt
, ctx
);
2101 case GIMPLE_OMP_SINGLE
:
2102 scan_omp_single (stmt
, ctx
);
2105 case GIMPLE_OMP_SECTION
:
2106 case GIMPLE_OMP_MASTER
:
2107 case GIMPLE_OMP_ORDERED
:
2108 case GIMPLE_OMP_CRITICAL
:
2109 ctx
= new_omp_context (stmt
, ctx
);
2110 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2117 *handled_ops_p
= false;
2119 for (var
= gimple_bind_vars (stmt
); var
; var
= DECL_CHAIN (var
))
2120 insert_decl_map (&ctx
->cb
, var
, var
);
2124 *handled_ops_p
= false;
2132 /* Scan all the statements starting at the current statement. CTX
2133 contains context information about the OpenMP directives and
2134 clauses found during the scan. */
2137 scan_omp (gimple_seq
*body_p
, omp_context
*ctx
)
2139 location_t saved_location
;
2140 struct walk_stmt_info wi
;
2142 memset (&wi
, 0, sizeof (wi
));
2144 wi
.want_locations
= true;
2146 saved_location
= input_location
;
2147 walk_gimple_seq_mod (body_p
, scan_omp_1_stmt
, scan_omp_1_op
, &wi
);
2148 input_location
= saved_location
;
2151 /* Re-gimplification and code generation routines. */
2153 /* Build a call to GOMP_barrier. */
2156 build_omp_barrier (void)
2158 return build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_BARRIER
), 0);
2161 /* If a context was created for STMT when it was scanned, return it. */
2163 static omp_context
*
2164 maybe_lookup_ctx (gimple stmt
)
2167 n
= splay_tree_lookup (all_contexts
, (splay_tree_key
) stmt
);
2168 return n
? (omp_context
*) n
->value
: NULL
;
2172 /* Find the mapping for DECL in CTX or the immediately enclosing
2173 context that has a mapping for DECL.
2175 If CTX is a nested parallel directive, we may have to use the decl
2176 mappings created in CTX's parent context. Suppose that we have the
2177 following parallel nesting (variable UIDs showed for clarity):
2180 #omp parallel shared(iD.1562) -> outer parallel
2181 iD.1562 = iD.1562 + 1;
2183 #omp parallel shared (iD.1562) -> inner parallel
2184 iD.1562 = iD.1562 - 1;
2186 Each parallel structure will create a distinct .omp_data_s structure
2187 for copying iD.1562 in/out of the directive:
2189 outer parallel .omp_data_s.1.i -> iD.1562
2190 inner parallel .omp_data_s.2.i -> iD.1562
2192 A shared variable mapping will produce a copy-out operation before
2193 the parallel directive and a copy-in operation after it. So, in
2194 this case we would have:
2197 .omp_data_o.1.i = iD.1562;
2198 #omp parallel shared(iD.1562) -> outer parallel
2199 .omp_data_i.1 = &.omp_data_o.1
2200 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2202 .omp_data_o.2.i = iD.1562; -> **
2203 #omp parallel shared(iD.1562) -> inner parallel
2204 .omp_data_i.2 = &.omp_data_o.2
2205 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2208 ** This is a problem. The symbol iD.1562 cannot be referenced
2209 inside the body of the outer parallel region. But since we are
2210 emitting this copy operation while expanding the inner parallel
2211 directive, we need to access the CTX structure of the outer
2212 parallel directive to get the correct mapping:
2214 .omp_data_o.2.i = .omp_data_i.1->i
2216 Since there may be other workshare or parallel directives enclosing
2217 the parallel directive, it may be necessary to walk up the context
2218 parent chain. This is not a problem in general because nested
2219 parallelism happens only rarely. */
2222 lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2227 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2228 t
= maybe_lookup_decl (decl
, up
);
2230 gcc_assert (!ctx
->is_nested
|| t
|| is_global_var (decl
));
2232 return t
? t
: decl
;
2236 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2237 in outer contexts. */
2240 maybe_lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2245 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2246 t
= maybe_lookup_decl (decl
, up
);
2248 return t
? t
: decl
;
2252 /* Construct the initialization value for reduction CLAUSE. */
2255 omp_reduction_init (tree clause
, tree type
)
2257 location_t loc
= OMP_CLAUSE_LOCATION (clause
);
2258 switch (OMP_CLAUSE_REDUCTION_CODE (clause
))
2265 case TRUTH_ORIF_EXPR
:
2266 case TRUTH_XOR_EXPR
:
2268 return build_zero_cst (type
);
2271 case TRUTH_AND_EXPR
:
2272 case TRUTH_ANDIF_EXPR
:
2274 return fold_convert_loc (loc
, type
, integer_one_node
);
2277 return fold_convert_loc (loc
, type
, integer_minus_one_node
);
2280 if (SCALAR_FLOAT_TYPE_P (type
))
2282 REAL_VALUE_TYPE max
, min
;
2283 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2286 real_arithmetic (&min
, NEGATE_EXPR
, &max
, NULL
);
2289 real_maxval (&min
, 1, TYPE_MODE (type
));
2290 return build_real (type
, min
);
2294 gcc_assert (INTEGRAL_TYPE_P (type
));
2295 return TYPE_MIN_VALUE (type
);
2299 if (SCALAR_FLOAT_TYPE_P (type
))
2301 REAL_VALUE_TYPE max
;
2302 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2305 real_maxval (&max
, 0, TYPE_MODE (type
));
2306 return build_real (type
, max
);
2310 gcc_assert (INTEGRAL_TYPE_P (type
));
2311 return TYPE_MAX_VALUE (type
);
2319 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2320 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2321 private variables. Initialization statements go in ILIST, while calls
2322 to destructors go in DLIST. */
2325 lower_rec_input_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*dlist
,
2328 tree c
, dtor
, copyin_seq
, x
, ptr
;
2329 bool copyin_by_ref
= false;
2330 bool lastprivate_firstprivate
= false;
2335 /* Do all the fixed sized types in the first pass, and the variable sized
2336 types in the second pass. This makes sure that the scalar arguments to
2337 the variable sized types are processed before we use them in the
2338 variable sized operations. */
2339 for (pass
= 0; pass
< 2; ++pass
)
2341 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2343 enum omp_clause_code c_kind
= OMP_CLAUSE_CODE (c
);
2346 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2350 case OMP_CLAUSE_PRIVATE
:
2351 if (OMP_CLAUSE_PRIVATE_DEBUG (c
))
2354 case OMP_CLAUSE_SHARED
:
2355 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c
), ctx
) == NULL
)
2357 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c
)));
2360 case OMP_CLAUSE_FIRSTPRIVATE
:
2361 case OMP_CLAUSE_COPYIN
:
2362 case OMP_CLAUSE_REDUCTION
:
2364 case OMP_CLAUSE_LASTPRIVATE
:
2365 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2367 lastprivate_firstprivate
= true;
2376 new_var
= var
= OMP_CLAUSE_DECL (c
);
2377 if (c_kind
!= OMP_CLAUSE_COPYIN
)
2378 new_var
= lookup_decl (var
, ctx
);
2380 if (c_kind
== OMP_CLAUSE_SHARED
|| c_kind
== OMP_CLAUSE_COPYIN
)
2385 else if (is_variable_sized (var
))
2387 /* For variable sized types, we need to allocate the
2388 actual storage here. Call alloca and store the
2389 result in the pointer decl that we created elsewhere. */
2393 if (c_kind
!= OMP_CLAUSE_FIRSTPRIVATE
|| !is_task_ctx (ctx
))
2398 ptr
= DECL_VALUE_EXPR (new_var
);
2399 gcc_assert (TREE_CODE (ptr
) == INDIRECT_REF
);
2400 ptr
= TREE_OPERAND (ptr
, 0);
2401 gcc_assert (DECL_P (ptr
));
2402 x
= TYPE_SIZE_UNIT (TREE_TYPE (new_var
));
2404 /* void *tmp = __builtin_alloca */
2405 atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA
);
2406 stmt
= gimple_build_call (atmp
, 1, x
);
2407 tmp
= create_tmp_var_raw (ptr_type_node
, NULL
);
2408 gimple_add_tmp_var (tmp
);
2409 gimple_call_set_lhs (stmt
, tmp
);
2411 gimple_seq_add_stmt (ilist
, stmt
);
2413 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ptr
), tmp
);
2414 gimplify_assign (ptr
, x
, ilist
);
2417 else if (is_reference (var
))
2419 /* For references that are being privatized for Fortran,
2420 allocate new backing storage for the new pointer
2421 variable. This allows us to avoid changing all the
2422 code that expects a pointer to something that expects
2423 a direct variable. Note that this doesn't apply to
2424 C++, since reference types are disallowed in data
2425 sharing clauses there, except for NRV optimized
2430 x
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var
)));
2431 if (c_kind
== OMP_CLAUSE_FIRSTPRIVATE
&& is_task_ctx (ctx
))
2433 x
= build_receiver_ref (var
, false, ctx
);
2434 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2436 else if (TREE_CONSTANT (x
))
2438 const char *name
= NULL
;
2439 if (DECL_NAME (var
))
2440 name
= IDENTIFIER_POINTER (DECL_NAME (new_var
));
2442 x
= create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var
)),
2444 gimple_add_tmp_var (x
);
2445 TREE_ADDRESSABLE (x
) = 1;
2446 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2450 tree atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA
);
2451 x
= build_call_expr_loc (clause_loc
, atmp
, 1, x
);
2454 x
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), x
);
2455 gimplify_assign (new_var
, x
, ilist
);
2457 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
2459 else if (c_kind
== OMP_CLAUSE_REDUCTION
2460 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2468 switch (OMP_CLAUSE_CODE (c
))
2470 case OMP_CLAUSE_SHARED
:
2471 /* Shared global vars are just accessed directly. */
2472 if (is_global_var (new_var
))
2474 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2475 needs to be delayed until after fixup_child_record_type so
2476 that we get the correct type during the dereference. */
2477 by_ref
= use_pointer_for_field (var
, ctx
);
2478 x
= build_receiver_ref (var
, by_ref
, ctx
);
2479 SET_DECL_VALUE_EXPR (new_var
, x
);
2480 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2482 /* ??? If VAR is not passed by reference, and the variable
2483 hasn't been initialized yet, then we'll get a warning for
2484 the store into the omp_data_s structure. Ideally, we'd be
2485 able to notice this and not store anything at all, but
2486 we're generating code too early. Suppress the warning. */
2488 TREE_NO_WARNING (var
) = 1;
2491 case OMP_CLAUSE_LASTPRIVATE
:
2492 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2496 case OMP_CLAUSE_PRIVATE
:
2497 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_PRIVATE
)
2498 x
= build_outer_var_ref (var
, ctx
);
2499 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
2501 if (is_task_ctx (ctx
))
2502 x
= build_receiver_ref (var
, false, ctx
);
2504 x
= build_outer_var_ref (var
, ctx
);
2508 x
= lang_hooks
.decls
.omp_clause_default_ctor (c
, new_var
, x
);
2510 gimplify_and_add (x
, ilist
);
2514 x
= lang_hooks
.decls
.omp_clause_dtor (c
, new_var
);
2517 gimple_seq tseq
= NULL
;
2520 gimplify_stmt (&dtor
, &tseq
);
2521 gimple_seq_add_seq (dlist
, tseq
);
2525 case OMP_CLAUSE_FIRSTPRIVATE
:
2526 if (is_task_ctx (ctx
))
2528 if (is_reference (var
) || is_variable_sized (var
))
2530 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
,
2532 || use_pointer_for_field (var
, NULL
))
2534 x
= build_receiver_ref (var
, false, ctx
);
2535 SET_DECL_VALUE_EXPR (new_var
, x
);
2536 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2540 x
= build_outer_var_ref (var
, ctx
);
2541 x
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, new_var
, x
);
2542 gimplify_and_add (x
, ilist
);
2546 case OMP_CLAUSE_COPYIN
:
2547 by_ref
= use_pointer_for_field (var
, NULL
);
2548 x
= build_receiver_ref (var
, by_ref
, ctx
);
2549 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, x
);
2550 append_to_statement_list (x
, ©in_seq
);
2551 copyin_by_ref
|= by_ref
;
2554 case OMP_CLAUSE_REDUCTION
:
2555 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2557 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
2558 x
= build_outer_var_ref (var
, ctx
);
2560 if (is_reference (var
))
2561 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2562 SET_DECL_VALUE_EXPR (placeholder
, x
);
2563 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
2564 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
2565 gimple_seq_add_seq (ilist
,
2566 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
2567 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
2568 DECL_HAS_VALUE_EXPR_P (placeholder
) = 0;
2572 x
= omp_reduction_init (c
, TREE_TYPE (new_var
));
2573 gcc_assert (TREE_CODE (TREE_TYPE (new_var
)) != ARRAY_TYPE
);
2574 gimplify_assign (new_var
, x
, ilist
);
2584 /* The copyin sequence is not to be executed by the main thread, since
2585 that would result in self-copies. Perhaps not visible to scalars,
2586 but it certainly is to C++ operator=. */
2589 x
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
),
2591 x
= build2 (NE_EXPR
, boolean_type_node
, x
,
2592 build_int_cst (TREE_TYPE (x
), 0));
2593 x
= build3 (COND_EXPR
, void_type_node
, x
, copyin_seq
, NULL
);
2594 gimplify_and_add (x
, ilist
);
2597 /* If any copyin variable is passed by reference, we must ensure the
2598 master thread doesn't modify it before it is copied over in all
2599 threads. Similarly for variables in both firstprivate and
2600 lastprivate clauses we need to ensure the lastprivate copying
2601 happens after firstprivate copying in all threads. */
2602 if (copyin_by_ref
|| lastprivate_firstprivate
)
2603 gimplify_and_add (build_omp_barrier (), ilist
);
2607 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2608 both parallel and workshare constructs. PREDICATE may be NULL if it's
2612 lower_lastprivate_clauses (tree clauses
, tree predicate
, gimple_seq
*stmt_list
,
2615 tree x
, c
, label
= NULL
;
2616 bool par_clauses
= false;
2618 /* Early exit if there are no lastprivate clauses. */
2619 clauses
= find_omp_clause (clauses
, OMP_CLAUSE_LASTPRIVATE
);
2620 if (clauses
== NULL
)
2622 /* If this was a workshare clause, see if it had been combined
2623 with its parallel. In that case, look for the clauses on the
2624 parallel statement itself. */
2625 if (is_parallel_ctx (ctx
))
2629 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
2632 clauses
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
2633 OMP_CLAUSE_LASTPRIVATE
);
2634 if (clauses
== NULL
)
2642 tree label_true
, arm1
, arm2
;
2644 label
= create_artificial_label (UNKNOWN_LOCATION
);
2645 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
2646 arm1
= TREE_OPERAND (predicate
, 0);
2647 arm2
= TREE_OPERAND (predicate
, 1);
2648 gimplify_expr (&arm1
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
2649 gimplify_expr (&arm2
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
2650 stmt
= gimple_build_cond (TREE_CODE (predicate
), arm1
, arm2
,
2652 gimple_seq_add_stmt (stmt_list
, stmt
);
2653 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label_true
));
2656 for (c
= clauses
; c
;)
2659 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2661 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
2663 var
= OMP_CLAUSE_DECL (c
);
2664 new_var
= lookup_decl (var
, ctx
);
2666 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
2668 lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
2669 gimple_seq_add_seq (stmt_list
,
2670 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
2672 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) = NULL
;
2674 x
= build_outer_var_ref (var
, ctx
);
2675 if (is_reference (var
))
2676 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
2677 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, x
, new_var
);
2678 gimplify_and_add (x
, stmt_list
);
2680 c
= OMP_CLAUSE_CHAIN (c
);
2681 if (c
== NULL
&& !par_clauses
)
2683 /* If this was a workshare clause, see if it had been combined
2684 with its parallel. In that case, continue looking for the
2685 clauses also on the parallel statement itself. */
2686 if (is_parallel_ctx (ctx
))
2690 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
2693 c
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
2694 OMP_CLAUSE_LASTPRIVATE
);
2700 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label
));
2704 /* Generate code to implement the REDUCTION clauses. */
2707 lower_reduction_clauses (tree clauses
, gimple_seq
*stmt_seqp
, omp_context
*ctx
)
2709 gimple_seq sub_seq
= NULL
;
2714 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2715 update in that case, otherwise use a lock. */
2716 for (c
= clauses
; c
&& count
< 2; c
= OMP_CLAUSE_CHAIN (c
))
2717 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
2719 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2721 /* Never use OMP_ATOMIC for array reductions. */
2731 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2733 tree var
, ref
, new_var
;
2734 enum tree_code code
;
2735 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2737 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
)
2740 var
= OMP_CLAUSE_DECL (c
);
2741 new_var
= lookup_decl (var
, ctx
);
2742 if (is_reference (var
))
2743 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
2744 ref
= build_outer_var_ref (var
, ctx
);
2745 code
= OMP_CLAUSE_REDUCTION_CODE (c
);
2747 /* reduction(-:var) sums up the partial results, so it acts
2748 identically to reduction(+:var). */
2749 if (code
== MINUS_EXPR
)
2754 tree addr
= build_fold_addr_expr_loc (clause_loc
, ref
);
2756 addr
= save_expr (addr
);
2757 ref
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (addr
)), addr
);
2758 x
= fold_build2_loc (clause_loc
, code
, TREE_TYPE (ref
), ref
, new_var
);
2759 x
= build2 (OMP_ATOMIC
, void_type_node
, addr
, x
);
2760 gimplify_and_add (x
, stmt_seqp
);
2764 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2766 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
2768 if (is_reference (var
))
2769 ref
= build_fold_addr_expr_loc (clause_loc
, ref
);
2770 SET_DECL_VALUE_EXPR (placeholder
, ref
);
2771 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
2772 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
2773 gimple_seq_add_seq (&sub_seq
, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
2774 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
2775 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
) = NULL
;
2779 x
= build2 (code
, TREE_TYPE (ref
), ref
, new_var
);
2780 ref
= build_outer_var_ref (var
, ctx
);
2781 gimplify_assign (ref
, x
, &sub_seq
);
2785 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START
),
2787 gimple_seq_add_stmt (stmt_seqp
, stmt
);
2789 gimple_seq_add_seq (stmt_seqp
, sub_seq
);
2791 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END
),
2793 gimple_seq_add_stmt (stmt_seqp
, stmt
);
2797 /* Generate code to implement the COPYPRIVATE clauses. */
2800 lower_copyprivate_clauses (tree clauses
, gimple_seq
*slist
, gimple_seq
*rlist
,
2805 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2807 tree var
, new_var
, ref
, x
;
2809 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2811 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYPRIVATE
)
2814 var
= OMP_CLAUSE_DECL (c
);
2815 by_ref
= use_pointer_for_field (var
, NULL
);
2817 ref
= build_sender_ref (var
, ctx
);
2818 x
= new_var
= lookup_decl_in_outer_ctx (var
, ctx
);
2821 x
= build_fold_addr_expr_loc (clause_loc
, new_var
);
2822 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ref
), x
);
2824 gimplify_assign (ref
, x
, slist
);
2826 ref
= build_receiver_ref (var
, false, ctx
);
2829 ref
= fold_convert_loc (clause_loc
,
2830 build_pointer_type (TREE_TYPE (new_var
)),
2832 ref
= build_fold_indirect_ref_loc (clause_loc
, ref
);
2834 if (is_reference (var
))
2836 ref
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), ref
);
2837 ref
= build_simple_mem_ref_loc (clause_loc
, ref
);
2838 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
2840 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, ref
);
2841 gimplify_and_add (x
, rlist
);
2846 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2847 and REDUCTION from the sender (aka parent) side. */
2850 lower_send_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*olist
,
2855 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2857 tree val
, ref
, x
, var
;
2858 bool by_ref
, do_in
= false, do_out
= false;
2859 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2861 switch (OMP_CLAUSE_CODE (c
))
2863 case OMP_CLAUSE_PRIVATE
:
2864 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
2867 case OMP_CLAUSE_FIRSTPRIVATE
:
2868 case OMP_CLAUSE_COPYIN
:
2869 case OMP_CLAUSE_LASTPRIVATE
:
2870 case OMP_CLAUSE_REDUCTION
:
2876 val
= OMP_CLAUSE_DECL (c
);
2877 var
= lookup_decl_in_outer_ctx (val
, ctx
);
2879 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYIN
2880 && is_global_var (var
))
2882 if (is_variable_sized (val
))
2884 by_ref
= use_pointer_for_field (val
, NULL
);
2886 switch (OMP_CLAUSE_CODE (c
))
2888 case OMP_CLAUSE_PRIVATE
:
2889 case OMP_CLAUSE_FIRSTPRIVATE
:
2890 case OMP_CLAUSE_COPYIN
:
2894 case OMP_CLAUSE_LASTPRIVATE
:
2895 if (by_ref
|| is_reference (val
))
2897 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2904 if (lang_hooks
.decls
.omp_private_outer_ref (val
))
2909 case OMP_CLAUSE_REDUCTION
:
2911 do_out
= !(by_ref
|| is_reference (val
));
2920 ref
= build_sender_ref (val
, ctx
);
2921 x
= by_ref
? build_fold_addr_expr_loc (clause_loc
, var
) : var
;
2922 gimplify_assign (ref
, x
, ilist
);
2923 if (is_task_ctx (ctx
))
2924 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref
, 1)) = NULL
;
2929 ref
= build_sender_ref (val
, ctx
);
2930 gimplify_assign (var
, ref
, olist
);
2935 /* Generate code to implement SHARED from the sender (aka parent)
2936 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2937 list things that got automatically shared. */
2940 lower_send_shared_vars (gimple_seq
*ilist
, gimple_seq
*olist
, omp_context
*ctx
)
2942 tree var
, ovar
, nvar
, f
, x
, record_type
;
2944 if (ctx
->record_type
== NULL
)
2947 record_type
= ctx
->srecord_type
? ctx
->srecord_type
: ctx
->record_type
;
2948 for (f
= TYPE_FIELDS (record_type
); f
; f
= DECL_CHAIN (f
))
2950 ovar
= DECL_ABSTRACT_ORIGIN (f
);
2951 nvar
= maybe_lookup_decl (ovar
, ctx
);
2952 if (!nvar
|| !DECL_HAS_VALUE_EXPR_P (nvar
))
2955 /* If CTX is a nested parallel directive. Find the immediately
2956 enclosing parallel or workshare construct that contains a
2957 mapping for OVAR. */
2958 var
= lookup_decl_in_outer_ctx (ovar
, ctx
);
2960 if (use_pointer_for_field (ovar
, ctx
))
2962 x
= build_sender_ref (ovar
, ctx
);
2963 var
= build_fold_addr_expr (var
);
2964 gimplify_assign (x
, var
, ilist
);
2968 x
= build_sender_ref (ovar
, ctx
);
2969 gimplify_assign (x
, var
, ilist
);
2971 if (!TREE_READONLY (var
)
2972 /* We don't need to receive a new reference to a result
2973 or parm decl. In fact we may not store to it as we will
2974 invalidate any pending RSO and generate wrong gimple
2976 && !((TREE_CODE (var
) == RESULT_DECL
2977 || TREE_CODE (var
) == PARM_DECL
)
2978 && DECL_BY_REFERENCE (var
)))
2980 x
= build_sender_ref (ovar
, ctx
);
2981 gimplify_assign (var
, x
, olist
);
2988 /* A convenience function to build an empty GIMPLE_COND with just the
2992 gimple_build_cond_empty (tree cond
)
2994 enum tree_code pred_code
;
2997 gimple_cond_get_ops_from_tree (cond
, &pred_code
, &lhs
, &rhs
);
2998 return gimple_build_cond (pred_code
, lhs
, rhs
, NULL_TREE
, NULL_TREE
);
3002 /* Build the function calls to GOMP_parallel_start etc to actually
3003 generate the parallel operation. REGION is the parallel region
3004 being expanded. BB is the block where to insert the code. WS_ARGS
3005 will be set if this is a call to a combined parallel+workshare
3006 construct, it contains the list of additional arguments needed by
3007 the workshare construct. */
3010 expand_parallel_call (struct omp_region
*region
, basic_block bb
,
3011 gimple entry_stmt
, vec
<tree
, va_gc
> *ws_args
)
3013 tree t
, t1
, t2
, val
, cond
, c
, clauses
;
3014 gimple_stmt_iterator gsi
;
3016 enum built_in_function start_ix
;
3018 location_t clause_loc
;
3019 vec
<tree
, va_gc
> *args
;
3021 clauses
= gimple_omp_parallel_clauses (entry_stmt
);
3023 /* Determine what flavor of GOMP_parallel_start we will be
3025 start_ix
= BUILT_IN_GOMP_PARALLEL_START
;
3026 if (is_combined_parallel (region
))
3028 switch (region
->inner
->type
)
3030 case GIMPLE_OMP_FOR
:
3031 gcc_assert (region
->inner
->sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
3032 start_ix2
= ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
3033 + (region
->inner
->sched_kind
3034 == OMP_CLAUSE_SCHEDULE_RUNTIME
3035 ? 3 : region
->inner
->sched_kind
));
3036 start_ix
= (enum built_in_function
)start_ix2
;
3038 case GIMPLE_OMP_SECTIONS
:
3039 start_ix
= BUILT_IN_GOMP_PARALLEL_SECTIONS_START
;
3046 /* By default, the value of NUM_THREADS is zero (selected at run time)
3047 and there is no conditional. */
3049 val
= build_int_cst (unsigned_type_node
, 0);
3051 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
3053 cond
= OMP_CLAUSE_IF_EXPR (c
);
3055 c
= find_omp_clause (clauses
, OMP_CLAUSE_NUM_THREADS
);
3058 val
= OMP_CLAUSE_NUM_THREADS_EXPR (c
);
3059 clause_loc
= OMP_CLAUSE_LOCATION (c
);
3062 clause_loc
= gimple_location (entry_stmt
);
3064 /* Ensure 'val' is of the correct type. */
3065 val
= fold_convert_loc (clause_loc
, unsigned_type_node
, val
);
3067 /* If we found the clause 'if (cond)', build either
3068 (cond != 0) or (cond ? val : 1u). */
3071 gimple_stmt_iterator gsi
;
3073 cond
= gimple_boolify (cond
);
3075 if (integer_zerop (val
))
3076 val
= fold_build2_loc (clause_loc
,
3077 EQ_EXPR
, unsigned_type_node
, cond
,
3078 build_int_cst (TREE_TYPE (cond
), 0));
3081 basic_block cond_bb
, then_bb
, else_bb
;
3082 edge e
, e_then
, e_else
;
3083 tree tmp_then
, tmp_else
, tmp_join
, tmp_var
;
3085 tmp_var
= create_tmp_var (TREE_TYPE (val
), NULL
);
3086 if (gimple_in_ssa_p (cfun
))
3088 tmp_then
= make_ssa_name (tmp_var
, NULL
);
3089 tmp_else
= make_ssa_name (tmp_var
, NULL
);
3090 tmp_join
= make_ssa_name (tmp_var
, NULL
);
3099 e
= split_block (bb
, NULL
);
3104 then_bb
= create_empty_bb (cond_bb
);
3105 else_bb
= create_empty_bb (then_bb
);
3106 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
3107 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
3109 stmt
= gimple_build_cond_empty (cond
);
3110 gsi
= gsi_start_bb (cond_bb
);
3111 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3113 gsi
= gsi_start_bb (then_bb
);
3114 stmt
= gimple_build_assign (tmp_then
, val
);
3115 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3117 gsi
= gsi_start_bb (else_bb
);
3118 stmt
= gimple_build_assign
3119 (tmp_else
, build_int_cst (unsigned_type_node
, 1));
3120 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3122 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
3123 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
3124 e_then
= make_edge (then_bb
, bb
, EDGE_FALLTHRU
);
3125 e_else
= make_edge (else_bb
, bb
, EDGE_FALLTHRU
);
3127 if (gimple_in_ssa_p (cfun
))
3129 gimple phi
= create_phi_node (tmp_join
, bb
);
3130 add_phi_arg (phi
, tmp_then
, e_then
, UNKNOWN_LOCATION
);
3131 add_phi_arg (phi
, tmp_else
, e_else
, UNKNOWN_LOCATION
);
3137 gsi
= gsi_start_bb (bb
);
3138 val
= force_gimple_operand_gsi (&gsi
, val
, true, NULL_TREE
,
3139 false, GSI_CONTINUE_LINKING
);
3142 gsi
= gsi_last_bb (bb
);
3143 t
= gimple_omp_parallel_data_arg (entry_stmt
);
3145 t1
= null_pointer_node
;
3147 t1
= build_fold_addr_expr (t
);
3148 t2
= build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt
));
3150 vec_alloc (args
, 3 + vec_safe_length (ws_args
));
3151 args
->quick_push (t2
);
3152 args
->quick_push (t1
);
3153 args
->quick_push (val
);
3155 args
->splice (*ws_args
);
3157 t
= build_call_expr_loc_vec (UNKNOWN_LOCATION
,
3158 builtin_decl_explicit (start_ix
), args
);
3160 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3161 false, GSI_CONTINUE_LINKING
);
3163 t
= gimple_omp_parallel_data_arg (entry_stmt
);
3165 t
= null_pointer_node
;
3167 t
= build_fold_addr_expr (t
);
3168 t
= build_call_expr_loc (gimple_location (entry_stmt
),
3169 gimple_omp_parallel_child_fn (entry_stmt
), 1, t
);
3170 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3171 false, GSI_CONTINUE_LINKING
);
3173 t
= build_call_expr_loc (gimple_location (entry_stmt
),
3174 builtin_decl_explicit (BUILT_IN_GOMP_PARALLEL_END
),
3176 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3177 false, GSI_CONTINUE_LINKING
);
3181 /* Build the function call to GOMP_task to actually
3182 generate the task operation. BB is the block where to insert the code. */
3185 expand_task_call (basic_block bb
, gimple entry_stmt
)
3187 tree t
, t1
, t2
, t3
, flags
, cond
, c
, c2
, clauses
;
3188 gimple_stmt_iterator gsi
;
3189 location_t loc
= gimple_location (entry_stmt
);
3191 clauses
= gimple_omp_task_clauses (entry_stmt
);
3193 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
3195 cond
= gimple_boolify (OMP_CLAUSE_IF_EXPR (c
));
3197 cond
= boolean_true_node
;
3199 c
= find_omp_clause (clauses
, OMP_CLAUSE_UNTIED
);
3200 c2
= find_omp_clause (clauses
, OMP_CLAUSE_MERGEABLE
);
3201 flags
= build_int_cst (unsigned_type_node
,
3202 (c
? 1 : 0) + (c2
? 4 : 0));
3204 c
= find_omp_clause (clauses
, OMP_CLAUSE_FINAL
);
3207 c
= gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c
));
3208 c
= fold_build3_loc (loc
, COND_EXPR
, unsigned_type_node
, c
,
3209 build_int_cst (unsigned_type_node
, 2),
3210 build_int_cst (unsigned_type_node
, 0));
3211 flags
= fold_build2_loc (loc
, PLUS_EXPR
, unsigned_type_node
, flags
, c
);
3214 gsi
= gsi_last_bb (bb
);
3215 t
= gimple_omp_task_data_arg (entry_stmt
);
3217 t2
= null_pointer_node
;
3219 t2
= build_fold_addr_expr_loc (loc
, t
);
3220 t1
= build_fold_addr_expr_loc (loc
, gimple_omp_task_child_fn (entry_stmt
));
3221 t
= gimple_omp_task_copy_fn (entry_stmt
);
3223 t3
= null_pointer_node
;
3225 t3
= build_fold_addr_expr_loc (loc
, t
);
3227 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK
),
3229 gimple_omp_task_arg_size (entry_stmt
),
3230 gimple_omp_task_arg_align (entry_stmt
), cond
, flags
);
3232 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3233 false, GSI_CONTINUE_LINKING
);
3237 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3238 catch handler and return it. This prevents programs from violating the
3239 structured block semantics with throws. */
3242 maybe_catch_exception (gimple_seq body
)
3247 if (!flag_exceptions
)
3250 if (lang_hooks
.eh_protect_cleanup_actions
!= NULL
)
3251 decl
= lang_hooks
.eh_protect_cleanup_actions ();
3253 decl
= builtin_decl_explicit (BUILT_IN_TRAP
);
3255 g
= gimple_build_eh_must_not_throw (decl
);
3256 g
= gimple_build_try (body
, gimple_seq_alloc_with_stmt (g
),
3259 return gimple_seq_alloc_with_stmt (g
);
3262 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3265 vec2chain (vec
<tree
, va_gc
> *v
)
3267 tree chain
= NULL_TREE
, t
;
3270 FOR_EACH_VEC_SAFE_ELT_REVERSE (v
, ix
, t
)
3272 DECL_CHAIN (t
) = chain
;
3280 /* Remove barriers in REGION->EXIT's block. Note that this is only
3281 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3282 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3283 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3287 remove_exit_barrier (struct omp_region
*region
)
3289 gimple_stmt_iterator gsi
;
3290 basic_block exit_bb
;
3294 int any_addressable_vars
= -1;
3296 exit_bb
= region
->exit
;
3298 /* If the parallel region doesn't return, we don't have REGION->EXIT
3303 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3304 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3305 statements that can appear in between are extremely limited -- no
3306 memory operations at all. Here, we allow nothing at all, so the
3307 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3308 gsi
= gsi_last_bb (exit_bb
);
3309 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
3311 if (!gsi_end_p (gsi
) && gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
3314 FOR_EACH_EDGE (e
, ei
, exit_bb
->preds
)
3316 gsi
= gsi_last_bb (e
->src
);
3317 if (gsi_end_p (gsi
))
3319 stmt
= gsi_stmt (gsi
);
3320 if (gimple_code (stmt
) == GIMPLE_OMP_RETURN
3321 && !gimple_omp_return_nowait_p (stmt
))
3323 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3324 in many cases. If there could be tasks queued, the barrier
3325 might be needed to let the tasks run before some local
3326 variable of the parallel that the task uses as shared
3327 runs out of scope. The task can be spawned either
3328 from within current function (this would be easy to check)
3329 or from some function it calls and gets passed an address
3330 of such a variable. */
3331 if (any_addressable_vars
< 0)
3333 gimple parallel_stmt
= last_stmt (region
->entry
);
3334 tree child_fun
= gimple_omp_parallel_child_fn (parallel_stmt
);
3335 tree local_decls
, block
, decl
;
3338 any_addressable_vars
= 0;
3339 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun
), ix
, decl
)
3340 if (TREE_ADDRESSABLE (decl
))
3342 any_addressable_vars
= 1;
3345 for (block
= gimple_block (stmt
);
3346 !any_addressable_vars
3348 && TREE_CODE (block
) == BLOCK
;
3349 block
= BLOCK_SUPERCONTEXT (block
))
3351 for (local_decls
= BLOCK_VARS (block
);
3353 local_decls
= DECL_CHAIN (local_decls
))
3354 if (TREE_ADDRESSABLE (local_decls
))
3356 any_addressable_vars
= 1;
3359 if (block
== gimple_block (parallel_stmt
))
3363 if (!any_addressable_vars
)
3364 gimple_omp_return_set_nowait (stmt
);
3370 remove_exit_barriers (struct omp_region
*region
)
3372 if (region
->type
== GIMPLE_OMP_PARALLEL
)
3373 remove_exit_barrier (region
);
3377 region
= region
->inner
;
3378 remove_exit_barriers (region
);
3379 while (region
->next
)
3381 region
= region
->next
;
3382 remove_exit_barriers (region
);
3387 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3388 calls. These can't be declared as const functions, but
3389 within one parallel body they are constant, so they can be
3390 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3391 which are declared const. Similarly for task body, except
3392 that in untied task omp_get_thread_num () can change at any task
3393 scheduling point. */
3396 optimize_omp_library_calls (gimple entry_stmt
)
3399 gimple_stmt_iterator gsi
;
3400 tree thr_num_tree
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
3401 tree thr_num_id
= DECL_ASSEMBLER_NAME (thr_num_tree
);
3402 tree num_thr_tree
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
3403 tree num_thr_id
= DECL_ASSEMBLER_NAME (num_thr_tree
);
3404 bool untied_task
= (gimple_code (entry_stmt
) == GIMPLE_OMP_TASK
3405 && find_omp_clause (gimple_omp_task_clauses (entry_stmt
),
3406 OMP_CLAUSE_UNTIED
) != NULL
);
3409 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3411 gimple call
= gsi_stmt (gsi
);
3414 if (is_gimple_call (call
)
3415 && (decl
= gimple_call_fndecl (call
))
3416 && DECL_EXTERNAL (decl
)
3417 && TREE_PUBLIC (decl
)
3418 && DECL_INITIAL (decl
) == NULL
)
3422 if (DECL_NAME (decl
) == thr_num_id
)
3424 /* In #pragma omp task untied omp_get_thread_num () can change
3425 during the execution of the task region. */
3428 built_in
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
3430 else if (DECL_NAME (decl
) == num_thr_id
)
3431 built_in
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
3435 if (DECL_ASSEMBLER_NAME (decl
) != DECL_ASSEMBLER_NAME (built_in
)
3436 || gimple_call_num_args (call
) != 0)
3439 if (flag_exceptions
&& !TREE_NOTHROW (decl
))
3442 if (TREE_CODE (TREE_TYPE (decl
)) != FUNCTION_TYPE
3443 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl
)),
3444 TREE_TYPE (TREE_TYPE (built_in
))))
3447 gimple_call_set_fndecl (call
, built_in
);
3452 /* Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be
3456 expand_omp_regimplify_p (tree
*tp
, int *walk_subtrees
, void *)
3460 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
3461 if (TREE_CODE (t
) == VAR_DECL
&& DECL_HAS_VALUE_EXPR_P (t
))
3464 if (TREE_CODE (t
) == ADDR_EXPR
)
3465 recompute_tree_invariant_for_addr_expr (t
);
3467 *walk_subtrees
= !TYPE_P (t
) && !DECL_P (t
);
3471 /* Expand the OpenMP parallel or task directive starting at REGION. */
3474 expand_omp_taskreg (struct omp_region
*region
)
3476 basic_block entry_bb
, exit_bb
, new_bb
;
3477 struct function
*child_cfun
;
3478 tree child_fn
, block
, t
;
3479 gimple_stmt_iterator gsi
;
3480 gimple entry_stmt
, stmt
;
3482 vec
<tree
, va_gc
> *ws_args
;
3484 entry_stmt
= last_stmt (region
->entry
);
3485 child_fn
= gimple_omp_taskreg_child_fn (entry_stmt
);
3486 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
3488 entry_bb
= region
->entry
;
3489 exit_bb
= region
->exit
;
3491 if (is_combined_parallel (region
))
3492 ws_args
= region
->ws_args
;
3496 if (child_cfun
->cfg
)
3498 /* Due to inlining, it may happen that we have already outlined
3499 the region, in which case all we need to do is make the
3500 sub-graph unreachable and emit the parallel call. */
3501 edge entry_succ_e
, exit_succ_e
;
3502 gimple_stmt_iterator gsi
;
3504 entry_succ_e
= single_succ_edge (entry_bb
);
3506 gsi
= gsi_last_bb (entry_bb
);
3507 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_PARALLEL
3508 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_TASK
);
3509 gsi_remove (&gsi
, true);
3514 exit_succ_e
= single_succ_edge (exit_bb
);
3515 make_edge (new_bb
, exit_succ_e
->dest
, EDGE_FALLTHRU
);
3517 remove_edge_and_dominated_blocks (entry_succ_e
);
3521 unsigned srcidx
, dstidx
, num
;
3523 /* If the parallel region needs data sent from the parent
3524 function, then the very first statement (except possible
3525 tree profile counter updates) of the parallel body
3526 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3527 &.OMP_DATA_O is passed as an argument to the child function,
3528 we need to replace it with the argument as seen by the child
3531 In most cases, this will end up being the identity assignment
3532 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3533 a function call that has been inlined, the original PARM_DECL
3534 .OMP_DATA_I may have been converted into a different local
3535 variable. In which case, we need to keep the assignment. */
3536 if (gimple_omp_taskreg_data_arg (entry_stmt
))
3538 basic_block entry_succ_bb
= single_succ (entry_bb
);
3539 gimple_stmt_iterator gsi
;
3541 gimple parcopy_stmt
= NULL
;
3543 for (gsi
= gsi_start_bb (entry_succ_bb
); ; gsi_next (&gsi
))
3547 gcc_assert (!gsi_end_p (gsi
));
3548 stmt
= gsi_stmt (gsi
);
3549 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
3552 if (gimple_num_ops (stmt
) == 2)
3554 tree arg
= gimple_assign_rhs1 (stmt
);
3556 /* We're ignore the subcode because we're
3557 effectively doing a STRIP_NOPS. */
3559 if (TREE_CODE (arg
) == ADDR_EXPR
3560 && TREE_OPERAND (arg
, 0)
3561 == gimple_omp_taskreg_data_arg (entry_stmt
))
3563 parcopy_stmt
= stmt
;
3569 gcc_assert (parcopy_stmt
!= NULL
);
3570 arg
= DECL_ARGUMENTS (child_fn
);
3572 if (!gimple_in_ssa_p (cfun
))
3574 if (gimple_assign_lhs (parcopy_stmt
) == arg
)
3575 gsi_remove (&gsi
, true);
3578 /* ?? Is setting the subcode really necessary ?? */
3579 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (arg
));
3580 gimple_assign_set_rhs1 (parcopy_stmt
, arg
);
3585 /* If we are in ssa form, we must load the value from the default
3586 definition of the argument. That should not be defined now,
3587 since the argument is not used uninitialized. */
3588 gcc_assert (ssa_default_def (cfun
, arg
) == NULL
);
3589 narg
= make_ssa_name (arg
, gimple_build_nop ());
3590 set_ssa_default_def (cfun
, arg
, narg
);
3591 /* ?? Is setting the subcode really necessary ?? */
3592 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (narg
));
3593 gimple_assign_set_rhs1 (parcopy_stmt
, narg
);
3594 update_stmt (parcopy_stmt
);
3598 /* Declare local variables needed in CHILD_CFUN. */
3599 block
= DECL_INITIAL (child_fn
);
3600 BLOCK_VARS (block
) = vec2chain (child_cfun
->local_decls
);
3601 /* The gimplifier could record temporaries in parallel/task block
3602 rather than in containing function's local_decls chain,
3603 which would mean cgraph missed finalizing them. Do it now. */
3604 for (t
= BLOCK_VARS (block
); t
; t
= DECL_CHAIN (t
))
3605 if (TREE_CODE (t
) == VAR_DECL
3607 && !DECL_EXTERNAL (t
))
3608 varpool_finalize_decl (t
);
3609 DECL_SAVED_TREE (child_fn
) = NULL
;
3610 /* We'll create a CFG for child_fn, so no gimple body is needed. */
3611 gimple_set_body (child_fn
, NULL
);
3612 TREE_USED (block
) = 1;
3614 /* Reset DECL_CONTEXT on function arguments. */
3615 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
3616 DECL_CONTEXT (t
) = child_fn
;
3618 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3619 so that it can be moved to the child function. */
3620 gsi
= gsi_last_bb (entry_bb
);
3621 stmt
= gsi_stmt (gsi
);
3622 gcc_assert (stmt
&& (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
3623 || gimple_code (stmt
) == GIMPLE_OMP_TASK
));
3624 gsi_remove (&gsi
, true);
3625 e
= split_block (entry_bb
, stmt
);
3627 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
3629 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3632 gsi
= gsi_last_bb (exit_bb
);
3633 gcc_assert (!gsi_end_p (gsi
)
3634 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
3635 stmt
= gimple_build_return (NULL
);
3636 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
3637 gsi_remove (&gsi
, true);
3640 /* Move the parallel region into CHILD_CFUN. */
3642 if (gimple_in_ssa_p (cfun
))
3644 init_tree_ssa (child_cfun
);
3645 init_ssa_operands (child_cfun
);
3646 child_cfun
->gimple_df
->in_ssa_p
= true;
3650 block
= gimple_block (entry_stmt
);
3652 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
, block
);
3654 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
3656 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3657 num
= vec_safe_length (child_cfun
->local_decls
);
3658 for (srcidx
= 0, dstidx
= 0; srcidx
< num
; srcidx
++)
3660 t
= (*child_cfun
->local_decls
)[srcidx
];
3661 if (DECL_CONTEXT (t
) == cfun
->decl
)
3663 if (srcidx
!= dstidx
)
3664 (*child_cfun
->local_decls
)[dstidx
] = t
;
3668 vec_safe_truncate (child_cfun
->local_decls
, dstidx
);
3670 /* Inform the callgraph about the new function. */
3671 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
3672 = cfun
->curr_properties
& ~PROP_loops
;
3673 cgraph_add_new_function (child_fn
, true);
3675 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3676 fixed in a following pass. */
3677 push_cfun (child_cfun
);
3679 optimize_omp_library_calls (entry_stmt
);
3680 rebuild_cgraph_edges ();
3682 /* Some EH regions might become dead, see PR34608. If
3683 pass_cleanup_cfg isn't the first pass to happen with the
3684 new child, these dead EH edges might cause problems.
3685 Clean them up now. */
3686 if (flag_exceptions
)
3689 bool changed
= false;
3692 changed
|= gimple_purge_dead_eh_edges (bb
);
3694 cleanup_tree_cfg ();
3696 if (gimple_in_ssa_p (cfun
))
3697 update_ssa (TODO_update_ssa
);
3701 /* Emit a library call to launch the children threads. */
3702 if (gimple_code (entry_stmt
) == GIMPLE_OMP_PARALLEL
)
3703 expand_parallel_call (region
, new_bb
, entry_stmt
, ws_args
);
3705 expand_task_call (new_bb
, entry_stmt
);
3706 if (gimple_in_ssa_p (cfun
))
3707 update_ssa (TODO_update_ssa_only_virtuals
);
3711 /* A subroutine of expand_omp_for. Generate code for a parallel
3712 loop with any schedule. Given parameters:
3714 for (V = N1; V cond N2; V += STEP) BODY;
3716 where COND is "<" or ">", we generate pseudocode
3718 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3719 if (more) goto L0; else goto L3;
3726 if (V cond iend) goto L1; else goto L2;
3728 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3731 If this is a combined omp parallel loop, instead of the call to
3732 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3734 For collapsed loops, given parameters:
3736 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3737 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3738 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3741 we generate pseudocode
3743 if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
3748 count3 = (adj + N32 - N31) / STEP3;
3749 if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
3754 count2 = (adj + N22 - N21) / STEP2;
3755 if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
3760 count1 = (adj + N12 - N11) / STEP1;
3761 count = count1 * count2 * count3;
3766 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3767 if (more) goto L0; else goto L3;
3771 V3 = N31 + (T % count3) * STEP3;
3773 V2 = N21 + (T % count2) * STEP2;
3775 V1 = N11 + T * STEP1;
3780 if (V < iend) goto L10; else goto L2;
3783 if (V3 cond3 N32) goto L1; else goto L11;
3787 if (V2 cond2 N22) goto L1; else goto L12;
3793 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3799 expand_omp_for_generic (struct omp_region
*region
,
3800 struct omp_for_data
*fd
,
3801 enum built_in_function start_fn
,
3802 enum built_in_function next_fn
)
3804 tree type
, istart0
, iend0
, iend
;
3805 tree t
, vmain
, vback
, bias
= NULL_TREE
;
3806 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
, collapse_bb
;
3807 basic_block l2_bb
= NULL
, l3_bb
= NULL
;
3808 gimple_stmt_iterator gsi
;
3810 bool in_combined_parallel
= is_combined_parallel (region
);
3811 bool broken_loop
= region
->cont
== NULL
;
3813 tree
*counts
= NULL
;
3816 gcc_assert (!broken_loop
|| !in_combined_parallel
);
3817 gcc_assert (fd
->iter_type
== long_integer_type_node
3818 || !in_combined_parallel
);
3820 type
= TREE_TYPE (fd
->loop
.v
);
3821 istart0
= create_tmp_var (fd
->iter_type
, ".istart0");
3822 iend0
= create_tmp_var (fd
->iter_type
, ".iend0");
3823 TREE_ADDRESSABLE (istart0
) = 1;
3824 TREE_ADDRESSABLE (iend0
) = 1;
3826 /* See if we need to bias by LLONG_MIN. */
3827 if (fd
->iter_type
== long_long_unsigned_type_node
3828 && TREE_CODE (type
) == INTEGER_TYPE
3829 && !TYPE_UNSIGNED (type
))
3833 if (fd
->loop
.cond_code
== LT_EXPR
)
3836 n2
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
3840 n1
= fold_build2 (MINUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
3843 if (TREE_CODE (n1
) != INTEGER_CST
3844 || TREE_CODE (n2
) != INTEGER_CST
3845 || ((tree_int_cst_sgn (n1
) < 0) ^ (tree_int_cst_sgn (n2
) < 0)))
3846 bias
= fold_convert (fd
->iter_type
, TYPE_MIN_VALUE (type
));
3849 entry_bb
= region
->entry
;
3850 cont_bb
= region
->cont
;
3852 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
3853 gcc_assert (broken_loop
3854 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
3855 l0_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
3856 l1_bb
= single_succ (l0_bb
);
3859 l2_bb
= create_empty_bb (cont_bb
);
3860 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l1_bb
);
3861 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
3865 l3_bb
= BRANCH_EDGE (entry_bb
)->dest
;
3866 exit_bb
= region
->exit
;
3868 gsi
= gsi_last_bb (entry_bb
);
3870 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
3871 if (fd
->collapse
> 1)
3873 basic_block zero_iter_bb
= NULL
;
3874 int first_zero_iter
= -1;
3876 /* collapsed loops need work for expansion in SSA form. */
3877 gcc_assert (!gimple_in_ssa_p (cfun
));
3878 counts
= (tree
*) alloca (fd
->collapse
* sizeof (tree
));
3879 for (i
= 0; i
< fd
->collapse
; i
++)
3881 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
3883 if (SSA_VAR_P (fd
->loop
.n2
)
3884 && ((t
= fold_binary (fd
->loops
[i
].cond_code
, boolean_type_node
,
3885 fold_convert (itype
, fd
->loops
[i
].n1
),
3886 fold_convert (itype
, fd
->loops
[i
].n2
)))
3887 == NULL_TREE
|| !integer_onep (t
)))
3890 n1
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n1
));
3891 n1
= force_gimple_operand_gsi (&gsi
, n1
, true, NULL_TREE
,
3892 true, GSI_SAME_STMT
);
3893 n2
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
3894 n2
= force_gimple_operand_gsi (&gsi
, n2
, true, NULL_TREE
,
3895 true, GSI_SAME_STMT
);
3896 stmt
= gimple_build_cond (fd
->loops
[i
].cond_code
, n1
, n2
,
3897 NULL_TREE
, NULL_TREE
);
3898 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3899 if (walk_tree (gimple_cond_lhs_ptr (stmt
),
3900 expand_omp_regimplify_p
, NULL
, NULL
)
3901 || walk_tree (gimple_cond_rhs_ptr (stmt
),
3902 expand_omp_regimplify_p
, NULL
, NULL
))
3904 gsi
= gsi_for_stmt (stmt
);
3905 gimple_regimplify_operands (stmt
, &gsi
);
3907 e
= split_block (entry_bb
, stmt
);
3908 if (zero_iter_bb
== NULL
)
3910 first_zero_iter
= i
;
3911 zero_iter_bb
= create_empty_bb (entry_bb
);
3913 add_bb_to_loop (zero_iter_bb
, entry_bb
->loop_father
);
3914 gsi
= gsi_after_labels (zero_iter_bb
);
3915 stmt
= gimple_build_assign (fd
->loop
.n2
,
3916 build_zero_cst (type
));
3917 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3918 set_immediate_dominator (CDI_DOMINATORS
, zero_iter_bb
,
3921 ne
= make_edge (entry_bb
, zero_iter_bb
, EDGE_FALSE_VALUE
);
3922 ne
->probability
= REG_BR_PROB_BASE
/ 2000 - 1;
3923 e
->flags
= EDGE_TRUE_VALUE
;
3924 e
->probability
= REG_BR_PROB_BASE
- ne
->probability
;
3926 gsi
= gsi_last_bb (entry_bb
);
3928 if (POINTER_TYPE_P (itype
))
3929 itype
= signed_type_for (itype
);
3930 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
== LT_EXPR
3932 t
= fold_build2 (PLUS_EXPR
, itype
,
3933 fold_convert (itype
, fd
->loops
[i
].step
), t
);
3934 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
3935 fold_convert (itype
, fd
->loops
[i
].n2
));
3936 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
3937 fold_convert (itype
, fd
->loops
[i
].n1
));
3938 if (TYPE_UNSIGNED (itype
) && fd
->loops
[i
].cond_code
== GT_EXPR
)
3939 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
3940 fold_build1 (NEGATE_EXPR
, itype
, t
),
3941 fold_build1 (NEGATE_EXPR
, itype
,
3942 fold_convert (itype
,
3943 fd
->loops
[i
].step
)));
3945 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
,
3946 fold_convert (itype
, fd
->loops
[i
].step
));
3947 t
= fold_convert (type
, t
);
3948 if (TREE_CODE (t
) == INTEGER_CST
)
3952 counts
[i
] = create_tmp_reg (type
, ".count");
3953 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3954 true, GSI_SAME_STMT
);
3955 stmt
= gimple_build_assign (counts
[i
], t
);
3956 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3958 if (SSA_VAR_P (fd
->loop
.n2
))
3964 t
= fold_build2 (MULT_EXPR
, type
, fd
->loop
.n2
, counts
[i
]);
3965 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3966 true, GSI_SAME_STMT
);
3968 stmt
= gimple_build_assign (fd
->loop
.n2
, t
);
3969 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3974 /* Some counts[i] vars might be uninitialized if
3975 some loop has zero iterations. But the body shouldn't
3976 be executed in that case, so just avoid uninit warnings. */
3977 for (i
= first_zero_iter
; i
< fd
->collapse
; i
++)
3978 if (SSA_VAR_P (counts
[i
]))
3979 TREE_NO_WARNING (counts
[i
]) = 1;
3981 e
= split_block (entry_bb
, gsi_stmt (gsi
));
3983 make_edge (zero_iter_bb
, entry_bb
, EDGE_FALLTHRU
);
3984 gsi
= gsi_last_bb (entry_bb
);
3985 set_immediate_dominator (CDI_DOMINATORS
, entry_bb
,
3986 get_immediate_dominator (CDI_DOMINATORS
,
3990 if (in_combined_parallel
)
3992 /* In a combined parallel loop, emit a call to
3993 GOMP_loop_foo_next. */
3994 t
= build_call_expr (builtin_decl_explicit (next_fn
), 2,
3995 build_fold_addr_expr (istart0
),
3996 build_fold_addr_expr (iend0
));
4000 tree t0
, t1
, t2
, t3
, t4
;
4001 /* If this is not a combined parallel loop, emit a call to
4002 GOMP_loop_foo_start in ENTRY_BB. */
4003 t4
= build_fold_addr_expr (iend0
);
4004 t3
= build_fold_addr_expr (istart0
);
4005 t2
= fold_convert (fd
->iter_type
, fd
->loop
.step
);
4006 if (POINTER_TYPE_P (type
)
4007 && TYPE_PRECISION (type
) != TYPE_PRECISION (fd
->iter_type
))
4009 /* Avoid casting pointers to integer of a different size. */
4010 tree itype
= signed_type_for (type
);
4011 t1
= fold_convert (fd
->iter_type
, fold_convert (itype
, fd
->loop
.n2
));
4012 t0
= fold_convert (fd
->iter_type
, fold_convert (itype
, fd
->loop
.n1
));
4016 t1
= fold_convert (fd
->iter_type
, fd
->loop
.n2
);
4017 t0
= fold_convert (fd
->iter_type
, fd
->loop
.n1
);
4021 t1
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t1
, bias
);
4022 t0
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t0
, bias
);
4024 if (fd
->iter_type
== long_integer_type_node
)
4028 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
4029 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4030 6, t0
, t1
, t2
, t
, t3
, t4
);
4033 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4034 5, t0
, t1
, t2
, t3
, t4
);
4042 /* The GOMP_loop_ull_*start functions have additional boolean
4043 argument, true for < loops and false for > loops.
4044 In Fortran, the C bool type can be different from
4045 boolean_type_node. */
4046 bfn_decl
= builtin_decl_explicit (start_fn
);
4047 c_bool_type
= TREE_TYPE (TREE_TYPE (bfn_decl
));
4048 t5
= build_int_cst (c_bool_type
,
4049 fd
->loop
.cond_code
== LT_EXPR
? 1 : 0);
4052 tree bfn_decl
= builtin_decl_explicit (start_fn
);
4053 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
4054 t
= build_call_expr (bfn_decl
, 7, t5
, t0
, t1
, t2
, t
, t3
, t4
);
4057 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4058 6, t5
, t0
, t1
, t2
, t3
, t4
);
4061 if (TREE_TYPE (t
) != boolean_type_node
)
4062 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
4063 t
, build_int_cst (TREE_TYPE (t
), 0));
4064 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4065 true, GSI_SAME_STMT
);
4066 gsi_insert_after (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4068 /* Remove the GIMPLE_OMP_FOR statement. */
4069 gsi_remove (&gsi
, true);
4071 /* Iteration setup for sequential loop goes in L0_BB. */
4072 gsi
= gsi_start_bb (l0_bb
);
4075 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
4076 if (POINTER_TYPE_P (type
))
4077 t
= fold_convert (signed_type_for (type
), t
);
4078 t
= fold_convert (type
, t
);
4079 t
= force_gimple_operand_gsi (&gsi
, t
,
4081 && TREE_ADDRESSABLE (fd
->loop
.v
),
4082 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
4083 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4084 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4088 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
4089 if (POINTER_TYPE_P (type
))
4090 t
= fold_convert (signed_type_for (type
), t
);
4091 t
= fold_convert (type
, t
);
4092 iend
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4093 false, GSI_CONTINUE_LINKING
);
4094 if (fd
->collapse
> 1)
4096 tree tem
= create_tmp_reg (type
, ".tem");
4097 stmt
= gimple_build_assign (tem
, fd
->loop
.v
);
4098 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4099 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
4101 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
), itype
;
4103 if (POINTER_TYPE_P (vtype
))
4104 itype
= signed_type_for (vtype
);
4105 t
= fold_build2 (TRUNC_MOD_EXPR
, type
, tem
, counts
[i
]);
4106 t
= fold_convert (itype
, t
);
4107 t
= fold_build2 (MULT_EXPR
, itype
, t
,
4108 fold_convert (itype
, fd
->loops
[i
].step
));
4109 if (POINTER_TYPE_P (vtype
))
4110 t
= fold_build_pointer_plus (fd
->loops
[i
].n1
, t
);
4112 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[i
].n1
, t
);
4113 t
= force_gimple_operand_gsi (&gsi
, t
,
4114 DECL_P (fd
->loops
[i
].v
)
4115 && TREE_ADDRESSABLE (fd
->loops
[i
].v
),
4117 GSI_CONTINUE_LINKING
);
4118 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
4119 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4122 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, tem
, counts
[i
]);
4123 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4124 false, GSI_CONTINUE_LINKING
);
4125 stmt
= gimple_build_assign (tem
, t
);
4126 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4133 /* Code to control the increment and predicate for the sequential
4134 loop goes in the CONT_BB. */
4135 gsi
= gsi_last_bb (cont_bb
);
4136 stmt
= gsi_stmt (gsi
);
4137 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4138 vmain
= gimple_omp_continue_control_use (stmt
);
4139 vback
= gimple_omp_continue_control_def (stmt
);
4141 if (POINTER_TYPE_P (type
))
4142 t
= fold_build_pointer_plus (vmain
, fd
->loop
.step
);
4144 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
4145 t
= force_gimple_operand_gsi (&gsi
, t
,
4146 DECL_P (vback
) && TREE_ADDRESSABLE (vback
),
4147 NULL_TREE
, true, GSI_SAME_STMT
);
4148 stmt
= gimple_build_assign (vback
, t
);
4149 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4151 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
4152 DECL_P (vback
) && TREE_ADDRESSABLE (vback
) ? t
: vback
,
4154 stmt
= gimple_build_cond_empty (t
);
4155 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4157 /* Remove GIMPLE_OMP_CONTINUE. */
4158 gsi_remove (&gsi
, true);
4160 if (fd
->collapse
> 1)
4162 basic_block last_bb
, bb
;
4165 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
4167 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
);
4169 bb
= create_empty_bb (last_bb
);
4170 gsi
= gsi_start_bb (bb
);
4172 if (i
< fd
->collapse
- 1)
4174 e
= make_edge (last_bb
, bb
, EDGE_FALSE_VALUE
);
4175 e
->probability
= REG_BR_PROB_BASE
/ 8;
4177 t
= fd
->loops
[i
+ 1].n1
;
4178 t
= force_gimple_operand_gsi (&gsi
, t
,
4179 DECL_P (fd
->loops
[i
+ 1].v
)
4181 (fd
->loops
[i
+ 1].v
),
4183 GSI_CONTINUE_LINKING
);
4184 stmt
= gimple_build_assign (fd
->loops
[i
+ 1].v
, t
);
4185 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4190 set_immediate_dominator (CDI_DOMINATORS
, bb
, last_bb
);
4192 if (POINTER_TYPE_P (vtype
))
4193 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, fd
->loops
[i
].step
);
4195 t
= fold_build2 (PLUS_EXPR
, vtype
, fd
->loops
[i
].v
,
4197 t
= force_gimple_operand_gsi (&gsi
, t
,
4198 DECL_P (fd
->loops
[i
].v
)
4199 && TREE_ADDRESSABLE (fd
->loops
[i
].v
),
4201 GSI_CONTINUE_LINKING
);
4202 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
4203 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4207 t
= fd
->loops
[i
].n2
;
4208 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4209 false, GSI_CONTINUE_LINKING
);
4210 tree v
= fd
->loops
[i
].v
;
4211 if (DECL_P (v
) && TREE_ADDRESSABLE (v
))
4212 v
= force_gimple_operand_gsi (&gsi
, v
, true, NULL_TREE
,
4213 false, GSI_CONTINUE_LINKING
);
4214 t
= fold_build2 (fd
->loops
[i
].cond_code
, boolean_type_node
,
4216 stmt
= gimple_build_cond_empty (t
);
4217 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4218 e
= make_edge (bb
, l1_bb
, EDGE_TRUE_VALUE
);
4219 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
4222 make_edge (bb
, l1_bb
, EDGE_FALLTHRU
);
4227 /* Emit code to get the next parallel iteration in L2_BB. */
4228 gsi
= gsi_start_bb (l2_bb
);
4230 t
= build_call_expr (builtin_decl_explicit (next_fn
), 2,
4231 build_fold_addr_expr (istart0
),
4232 build_fold_addr_expr (iend0
));
4233 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4234 false, GSI_CONTINUE_LINKING
);
4235 if (TREE_TYPE (t
) != boolean_type_node
)
4236 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
4237 t
, build_int_cst (TREE_TYPE (t
), 0));
4238 stmt
= gimple_build_cond_empty (t
);
4239 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4242 /* Add the loop cleanup function. */
4243 gsi
= gsi_last_bb (exit_bb
);
4244 if (gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4245 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT
);
4247 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END
);
4248 stmt
= gimple_build_call (t
, 0);
4249 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
4250 gsi_remove (&gsi
, true);
4252 /* Connect the new blocks. */
4253 find_edge (entry_bb
, l0_bb
)->flags
= EDGE_TRUE_VALUE
;
4254 find_edge (entry_bb
, l3_bb
)->flags
= EDGE_FALSE_VALUE
;
4260 e
= find_edge (cont_bb
, l3_bb
);
4261 ne
= make_edge (l2_bb
, l3_bb
, EDGE_FALSE_VALUE
);
4263 phis
= phi_nodes (l3_bb
);
4264 for (gsi
= gsi_start (phis
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4266 gimple phi
= gsi_stmt (gsi
);
4267 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, ne
),
4268 PHI_ARG_DEF_FROM_EDGE (phi
, e
));
4272 make_edge (cont_bb
, l2_bb
, EDGE_FALSE_VALUE
);
4273 if (fd
->collapse
> 1)
4275 e
= find_edge (cont_bb
, l1_bb
);
4277 e
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
4281 e
= find_edge (cont_bb
, l1_bb
);
4282 e
->flags
= EDGE_TRUE_VALUE
;
4284 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
4285 find_edge (cont_bb
, l2_bb
)->probability
= REG_BR_PROB_BASE
/ 8;
4286 make_edge (l2_bb
, l0_bb
, EDGE_TRUE_VALUE
);
4288 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
,
4289 recompute_dominator (CDI_DOMINATORS
, l2_bb
));
4290 set_immediate_dominator (CDI_DOMINATORS
, l3_bb
,
4291 recompute_dominator (CDI_DOMINATORS
, l3_bb
));
4292 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
,
4293 recompute_dominator (CDI_DOMINATORS
, l0_bb
));
4294 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
,
4295 recompute_dominator (CDI_DOMINATORS
, l1_bb
));
4300 /* A subroutine of expand_omp_for. Generate code for a parallel
4301 loop with static schedule and no specified chunk size. Given
4304 for (V = N1; V cond N2; V += STEP) BODY;
4306 where COND is "<" or ">", we generate pseudocode
4308 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
4313 if ((__typeof (V)) -1 > 0 && cond is >)
4314 n = -(adj + N2 - N1) / -STEP;
4316 n = (adj + N2 - N1) / STEP;
4319 if (threadid < tt) goto L3; else goto L4;
4324 s0 = q * threadid + tt;
4327 if (s0 >= e0) goto L2; else goto L0;
4333 if (V cond e) goto L1;
4338 expand_omp_for_static_nochunk (struct omp_region
*region
,
4339 struct omp_for_data
*fd
)
4341 tree n
, q
, s0
, e0
, e
, t
, tt
, nthreads
, threadid
;
4342 tree type
, itype
, vmain
, vback
;
4343 basic_block entry_bb
, second_bb
, third_bb
, exit_bb
, seq_start_bb
;
4344 basic_block body_bb
, cont_bb
;
4346 gimple_stmt_iterator gsi
;
4350 itype
= type
= TREE_TYPE (fd
->loop
.v
);
4351 if (POINTER_TYPE_P (type
))
4352 itype
= signed_type_for (type
);
4354 entry_bb
= region
->entry
;
4355 cont_bb
= region
->cont
;
4356 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
4357 gcc_assert (BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
4358 seq_start_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
4359 body_bb
= single_succ (seq_start_bb
);
4360 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
4361 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
4362 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
4363 exit_bb
= region
->exit
;
4365 /* Iteration space partitioning goes in ENTRY_BB. */
4366 gsi
= gsi_last_bb (entry_bb
);
4367 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4369 t
= fold_binary (fd
->loop
.cond_code
, boolean_type_node
,
4370 fold_convert (type
, fd
->loop
.n1
),
4371 fold_convert (type
, fd
->loop
.n2
));
4372 if (TYPE_UNSIGNED (type
)
4373 && (t
== NULL_TREE
|| !integer_onep (t
)))
4376 n1
= fold_convert (type
, unshare_expr (fd
->loop
.n1
));
4377 n1
= force_gimple_operand_gsi (&gsi
, n1
, true, NULL_TREE
,
4378 true, GSI_SAME_STMT
);
4379 n2
= fold_convert (type
, unshare_expr (fd
->loop
.n2
));
4380 n2
= force_gimple_operand_gsi (&gsi
, n2
, true, NULL_TREE
,
4381 true, GSI_SAME_STMT
);
4382 stmt
= gimple_build_cond (fd
->loop
.cond_code
, n1
, n2
,
4383 NULL_TREE
, NULL_TREE
);
4384 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4385 if (walk_tree (gimple_cond_lhs_ptr (stmt
),
4386 expand_omp_regimplify_p
, NULL
, NULL
)
4387 || walk_tree (gimple_cond_rhs_ptr (stmt
),
4388 expand_omp_regimplify_p
, NULL
, NULL
))
4390 gsi
= gsi_for_stmt (stmt
);
4391 gimple_regimplify_operands (stmt
, &gsi
);
4393 ep
= split_block (entry_bb
, stmt
);
4394 ep
->flags
= EDGE_TRUE_VALUE
;
4395 entry_bb
= ep
->dest
;
4396 ep
->probability
= REG_BR_PROB_BASE
- (REG_BR_PROB_BASE
/ 2000 - 1);
4397 ep
= make_edge (ep
->src
, fin_bb
, EDGE_FALSE_VALUE
);
4398 ep
->probability
= REG_BR_PROB_BASE
/ 2000 - 1;
4399 if (gimple_in_ssa_p (cfun
))
4401 int dest_idx
= find_edge (entry_bb
, fin_bb
)->dest_idx
;
4402 for (gsi
= gsi_start_phis (fin_bb
);
4403 !gsi_end_p (gsi
); gsi_next (&gsi
))
4405 gimple phi
= gsi_stmt (gsi
);
4406 add_phi_arg (phi
, gimple_phi_arg_def (phi
, dest_idx
),
4407 ep
, UNKNOWN_LOCATION
);
4410 gsi
= gsi_last_bb (entry_bb
);
4413 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
), 0);
4414 t
= fold_convert (itype
, t
);
4415 nthreads
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4416 true, GSI_SAME_STMT
);
4418 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
), 0);
4419 t
= fold_convert (itype
, t
);
4420 threadid
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4421 true, GSI_SAME_STMT
);
4424 = force_gimple_operand_gsi (&gsi
, fold_convert (type
, fd
->loop
.n1
),
4425 true, NULL_TREE
, true, GSI_SAME_STMT
);
4427 = force_gimple_operand_gsi (&gsi
, fold_convert (itype
, fd
->loop
.n2
),
4428 true, NULL_TREE
, true, GSI_SAME_STMT
);
4430 = force_gimple_operand_gsi (&gsi
, fold_convert (itype
, fd
->loop
.step
),
4431 true, NULL_TREE
, true, GSI_SAME_STMT
);
4433 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
4434 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loop
.step
, t
);
4435 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fd
->loop
.n2
);
4436 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, fd
->loop
.n1
));
4437 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
4438 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4439 fold_build1 (NEGATE_EXPR
, itype
, t
),
4440 fold_build1 (NEGATE_EXPR
, itype
, fd
->loop
.step
));
4442 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, fd
->loop
.step
);
4443 t
= fold_convert (itype
, t
);
4444 n
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4446 q
= create_tmp_reg (itype
, "q");
4447 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, n
, nthreads
);
4448 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, true, GSI_SAME_STMT
);
4449 gsi_insert_before (&gsi
, gimple_build_assign (q
, t
), GSI_SAME_STMT
);
4451 tt
= create_tmp_reg (itype
, "tt");
4452 t
= fold_build2 (TRUNC_MOD_EXPR
, itype
, n
, nthreads
);
4453 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, true, GSI_SAME_STMT
);
4454 gsi_insert_before (&gsi
, gimple_build_assign (tt
, t
), GSI_SAME_STMT
);
4456 t
= build2 (LT_EXPR
, boolean_type_node
, threadid
, tt
);
4457 stmt
= gimple_build_cond_empty (t
);
4458 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4460 second_bb
= split_block (entry_bb
, stmt
)->dest
;
4461 gsi
= gsi_last_bb (second_bb
);
4462 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4464 gsi_insert_before (&gsi
, gimple_build_assign (tt
, build_int_cst (itype
, 0)),
4466 stmt
= gimple_build_assign_with_ops (PLUS_EXPR
, q
, q
,
4467 build_int_cst (itype
, 1));
4468 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4470 third_bb
= split_block (second_bb
, stmt
)->dest
;
4471 gsi
= gsi_last_bb (third_bb
);
4472 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4474 t
= build2 (MULT_EXPR
, itype
, q
, threadid
);
4475 t
= build2 (PLUS_EXPR
, itype
, t
, tt
);
4476 s0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4478 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, q
);
4479 e0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4481 t
= build2 (GE_EXPR
, boolean_type_node
, s0
, e0
);
4482 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4484 /* Remove the GIMPLE_OMP_FOR statement. */
4485 gsi_remove (&gsi
, true);
4487 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4488 gsi
= gsi_start_bb (seq_start_bb
);
4490 t
= fold_convert (itype
, s0
);
4491 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4492 if (POINTER_TYPE_P (type
))
4493 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4495 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4496 t
= force_gimple_operand_gsi (&gsi
, t
,
4498 && TREE_ADDRESSABLE (fd
->loop
.v
),
4499 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
4500 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4501 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4503 t
= fold_convert (itype
, e0
);
4504 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4505 if (POINTER_TYPE_P (type
))
4506 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4508 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4509 e
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4510 false, GSI_CONTINUE_LINKING
);
4512 /* The code controlling the sequential loop replaces the
4513 GIMPLE_OMP_CONTINUE. */
4514 gsi
= gsi_last_bb (cont_bb
);
4515 stmt
= gsi_stmt (gsi
);
4516 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4517 vmain
= gimple_omp_continue_control_use (stmt
);
4518 vback
= gimple_omp_continue_control_def (stmt
);
4520 if (POINTER_TYPE_P (type
))
4521 t
= fold_build_pointer_plus (vmain
, fd
->loop
.step
);
4523 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
4524 t
= force_gimple_operand_gsi (&gsi
, t
,
4525 DECL_P (vback
) && TREE_ADDRESSABLE (vback
),
4526 NULL_TREE
, true, GSI_SAME_STMT
);
4527 stmt
= gimple_build_assign (vback
, t
);
4528 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4530 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
4531 DECL_P (vback
) && TREE_ADDRESSABLE (vback
) ? t
: vback
, e
);
4532 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4534 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4535 gsi_remove (&gsi
, true);
4537 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4538 gsi
= gsi_last_bb (exit_bb
);
4539 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4540 force_gimple_operand_gsi (&gsi
, build_omp_barrier (), false, NULL_TREE
,
4541 false, GSI_SAME_STMT
);
4542 gsi_remove (&gsi
, true);
4544 /* Connect all the blocks. */
4545 ep
= make_edge (entry_bb
, third_bb
, EDGE_FALSE_VALUE
);
4546 ep
->probability
= REG_BR_PROB_BASE
/ 4 * 3;
4547 ep
= find_edge (entry_bb
, second_bb
);
4548 ep
->flags
= EDGE_TRUE_VALUE
;
4549 ep
->probability
= REG_BR_PROB_BASE
/ 4;
4550 find_edge (third_bb
, seq_start_bb
)->flags
= EDGE_FALSE_VALUE
;
4551 find_edge (third_bb
, fin_bb
)->flags
= EDGE_TRUE_VALUE
;
4553 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
4554 find_edge (cont_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
4556 set_immediate_dominator (CDI_DOMINATORS
, second_bb
, entry_bb
);
4557 set_immediate_dominator (CDI_DOMINATORS
, third_bb
, entry_bb
);
4558 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
, third_bb
);
4559 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
4560 recompute_dominator (CDI_DOMINATORS
, body_bb
));
4561 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
4562 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
4566 /* A subroutine of expand_omp_for. Generate code for a parallel
4567 loop with static schedule and a specified chunk size. Given
4570 for (V = N1; V cond N2; V += STEP) BODY;
4572 where COND is "<" or ">", we generate pseudocode
4574 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
4579 if ((__typeof (V)) -1 > 0 && cond is >)
4580 n = -(adj + N2 - N1) / -STEP;
4582 n = (adj + N2 - N1) / STEP;
4584 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4585 here so that V is defined
4586 if the loop is not entered
4588 s0 = (trip * nthreads + threadid) * CHUNK;
4589 e0 = min(s0 + CHUNK, n);
4590 if (s0 < n) goto L1; else goto L4;
4597 if (V cond e) goto L2; else goto L3;
4605 expand_omp_for_static_chunk (struct omp_region
*region
, struct omp_for_data
*fd
)
4607 tree n
, s0
, e0
, e
, t
;
4608 tree trip_var
, trip_init
, trip_main
, trip_back
, nthreads
, threadid
;
4609 tree type
, itype
, v_main
, v_back
, v_extra
;
4610 basic_block entry_bb
, exit_bb
, body_bb
, seq_start_bb
, iter_part_bb
;
4611 basic_block trip_update_bb
, cont_bb
, fin_bb
;
4612 gimple_stmt_iterator si
;
4616 itype
= type
= TREE_TYPE (fd
->loop
.v
);
4617 if (POINTER_TYPE_P (type
))
4618 itype
= signed_type_for (type
);
4620 entry_bb
= region
->entry
;
4621 se
= split_block (entry_bb
, last_stmt (entry_bb
));
4623 iter_part_bb
= se
->dest
;
4624 cont_bb
= region
->cont
;
4625 gcc_assert (EDGE_COUNT (iter_part_bb
->succs
) == 2);
4626 gcc_assert (BRANCH_EDGE (iter_part_bb
)->dest
4627 == FALLTHRU_EDGE (cont_bb
)->dest
);
4628 seq_start_bb
= split_edge (FALLTHRU_EDGE (iter_part_bb
));
4629 body_bb
= single_succ (seq_start_bb
);
4630 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
4631 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
4632 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
4633 trip_update_bb
= split_edge (FALLTHRU_EDGE (cont_bb
));
4634 exit_bb
= region
->exit
;
4636 /* Trip and adjustment setup goes in ENTRY_BB. */
4637 si
= gsi_last_bb (entry_bb
);
4638 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_FOR
);
4640 t
= fold_binary (fd
->loop
.cond_code
, boolean_type_node
,
4641 fold_convert (type
, fd
->loop
.n1
),
4642 fold_convert (type
, fd
->loop
.n2
));
4643 if (TYPE_UNSIGNED (type
)
4644 && (t
== NULL_TREE
|| !integer_onep (t
)))
4647 n1
= fold_convert (type
, unshare_expr (fd
->loop
.n1
));
4648 n1
= force_gimple_operand_gsi (&si
, n1
, true, NULL_TREE
,
4649 true, GSI_SAME_STMT
);
4650 n2
= fold_convert (type
, unshare_expr (fd
->loop
.n2
));
4651 n2
= force_gimple_operand_gsi (&si
, n2
, true, NULL_TREE
,
4652 true, GSI_SAME_STMT
);
4653 stmt
= gimple_build_cond (fd
->loop
.cond_code
, n1
, n2
,
4654 NULL_TREE
, NULL_TREE
);
4655 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4656 if (walk_tree (gimple_cond_lhs_ptr (stmt
),
4657 expand_omp_regimplify_p
, NULL
, NULL
)
4658 || walk_tree (gimple_cond_rhs_ptr (stmt
),
4659 expand_omp_regimplify_p
, NULL
, NULL
))
4661 si
= gsi_for_stmt (stmt
);
4662 gimple_regimplify_operands (stmt
, &si
);
4664 se
= split_block (entry_bb
, stmt
);
4665 se
->flags
= EDGE_TRUE_VALUE
;
4666 entry_bb
= se
->dest
;
4667 se
->probability
= REG_BR_PROB_BASE
- (REG_BR_PROB_BASE
/ 2000 - 1);
4668 se
= make_edge (se
->src
, fin_bb
, EDGE_FALSE_VALUE
);
4669 se
->probability
= REG_BR_PROB_BASE
/ 2000 - 1;
4670 if (gimple_in_ssa_p (cfun
))
4672 int dest_idx
= find_edge (entry_bb
, fin_bb
)->dest_idx
;
4673 for (si
= gsi_start_phis (fin_bb
);
4674 !gsi_end_p (si
); gsi_next (&si
))
4676 gimple phi
= gsi_stmt (si
);
4677 add_phi_arg (phi
, gimple_phi_arg_def (phi
, dest_idx
),
4678 se
, UNKNOWN_LOCATION
);
4681 si
= gsi_last_bb (entry_bb
);
4684 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
), 0);
4685 t
= fold_convert (itype
, t
);
4686 nthreads
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4687 true, GSI_SAME_STMT
);
4689 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
), 0);
4690 t
= fold_convert (itype
, t
);
4691 threadid
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4692 true, GSI_SAME_STMT
);
4695 = force_gimple_operand_gsi (&si
, fold_convert (type
, fd
->loop
.n1
),
4696 true, NULL_TREE
, true, GSI_SAME_STMT
);
4698 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->loop
.n2
),
4699 true, NULL_TREE
, true, GSI_SAME_STMT
);
4701 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->loop
.step
),
4702 true, NULL_TREE
, true, GSI_SAME_STMT
);
4704 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->chunk_size
),
4705 true, NULL_TREE
, true, GSI_SAME_STMT
);
4707 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
4708 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loop
.step
, t
);
4709 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fd
->loop
.n2
);
4710 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, fd
->loop
.n1
));
4711 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
4712 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4713 fold_build1 (NEGATE_EXPR
, itype
, t
),
4714 fold_build1 (NEGATE_EXPR
, itype
, fd
->loop
.step
));
4716 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, fd
->loop
.step
);
4717 t
= fold_convert (itype
, t
);
4718 n
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4719 true, GSI_SAME_STMT
);
4721 trip_var
= create_tmp_reg (itype
, ".trip");
4722 if (gimple_in_ssa_p (cfun
))
4724 trip_init
= make_ssa_name (trip_var
, NULL
);
4725 trip_main
= make_ssa_name (trip_var
, NULL
);
4726 trip_back
= make_ssa_name (trip_var
, NULL
);
4730 trip_init
= trip_var
;
4731 trip_main
= trip_var
;
4732 trip_back
= trip_var
;
4735 stmt
= gimple_build_assign (trip_init
, build_int_cst (itype
, 0));
4736 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4738 t
= fold_build2 (MULT_EXPR
, itype
, threadid
, fd
->chunk_size
);
4739 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4740 if (POINTER_TYPE_P (type
))
4741 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4743 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4744 v_extra
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4745 true, GSI_SAME_STMT
);
4747 /* Remove the GIMPLE_OMP_FOR. */
4748 gsi_remove (&si
, true);
4750 /* Iteration space partitioning goes in ITER_PART_BB. */
4751 si
= gsi_last_bb (iter_part_bb
);
4753 t
= fold_build2 (MULT_EXPR
, itype
, trip_main
, nthreads
);
4754 t
= fold_build2 (PLUS_EXPR
, itype
, t
, threadid
);
4755 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->chunk_size
);
4756 s0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4757 false, GSI_CONTINUE_LINKING
);
4759 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, fd
->chunk_size
);
4760 t
= fold_build2 (MIN_EXPR
, itype
, t
, n
);
4761 e0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4762 false, GSI_CONTINUE_LINKING
);
4764 t
= build2 (LT_EXPR
, boolean_type_node
, s0
, n
);
4765 gsi_insert_after (&si
, gimple_build_cond_empty (t
), GSI_CONTINUE_LINKING
);
4767 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4768 si
= gsi_start_bb (seq_start_bb
);
4770 t
= fold_convert (itype
, s0
);
4771 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4772 if (POINTER_TYPE_P (type
))
4773 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4775 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4776 t
= force_gimple_operand_gsi (&si
, t
,
4778 && TREE_ADDRESSABLE (fd
->loop
.v
),
4779 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
4780 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4781 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4783 t
= fold_convert (itype
, e0
);
4784 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4785 if (POINTER_TYPE_P (type
))
4786 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4788 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4789 e
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4790 false, GSI_CONTINUE_LINKING
);
4792 /* The code controlling the sequential loop goes in CONT_BB,
4793 replacing the GIMPLE_OMP_CONTINUE. */
4794 si
= gsi_last_bb (cont_bb
);
4795 stmt
= gsi_stmt (si
);
4796 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4797 v_main
= gimple_omp_continue_control_use (stmt
);
4798 v_back
= gimple_omp_continue_control_def (stmt
);
4800 if (POINTER_TYPE_P (type
))
4801 t
= fold_build_pointer_plus (v_main
, fd
->loop
.step
);
4803 t
= fold_build2 (PLUS_EXPR
, type
, v_main
, fd
->loop
.step
);
4804 if (DECL_P (v_back
) && TREE_ADDRESSABLE (v_back
))
4805 t
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4806 true, GSI_SAME_STMT
);
4807 stmt
= gimple_build_assign (v_back
, t
);
4808 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4810 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
4811 DECL_P (v_back
) && TREE_ADDRESSABLE (v_back
)
4813 gsi_insert_before (&si
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4815 /* Remove GIMPLE_OMP_CONTINUE. */
4816 gsi_remove (&si
, true);
4818 /* Trip update code goes into TRIP_UPDATE_BB. */
4819 si
= gsi_start_bb (trip_update_bb
);
4821 t
= build_int_cst (itype
, 1);
4822 t
= build2 (PLUS_EXPR
, itype
, trip_main
, t
);
4823 stmt
= gimple_build_assign (trip_back
, t
);
4824 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4826 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4827 si
= gsi_last_bb (exit_bb
);
4828 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)))
4829 force_gimple_operand_gsi (&si
, build_omp_barrier (), false, NULL_TREE
,
4830 false, GSI_SAME_STMT
);
4831 gsi_remove (&si
, true);
4833 /* Connect the new blocks. */
4834 find_edge (iter_part_bb
, seq_start_bb
)->flags
= EDGE_TRUE_VALUE
;
4835 find_edge (iter_part_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
4837 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
4838 find_edge (cont_bb
, trip_update_bb
)->flags
= EDGE_FALSE_VALUE
;
4840 redirect_edge_and_branch (single_succ_edge (trip_update_bb
), iter_part_bb
);
4842 if (gimple_in_ssa_p (cfun
))
4844 gimple_stmt_iterator psi
;
4847 edge_var_map_vector
*head
;
4851 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4852 remove arguments of the phi nodes in fin_bb. We need to create
4853 appropriate phi nodes in iter_part_bb instead. */
4854 se
= single_pred_edge (fin_bb
);
4855 re
= single_succ_edge (trip_update_bb
);
4856 head
= redirect_edge_var_map_vector (re
);
4857 ene
= single_succ_edge (entry_bb
);
4859 psi
= gsi_start_phis (fin_bb
);
4860 for (i
= 0; !gsi_end_p (psi
) && head
->iterate (i
, &vm
);
4861 gsi_next (&psi
), ++i
)
4864 source_location locus
;
4866 phi
= gsi_stmt (psi
);
4867 t
= gimple_phi_result (phi
);
4868 gcc_assert (t
== redirect_edge_var_map_result (vm
));
4869 nphi
= create_phi_node (t
, iter_part_bb
);
4871 t
= PHI_ARG_DEF_FROM_EDGE (phi
, se
);
4872 locus
= gimple_phi_arg_location_from_edge (phi
, se
);
4874 /* A special case -- fd->loop.v is not yet computed in
4875 iter_part_bb, we need to use v_extra instead. */
4876 if (t
== fd
->loop
.v
)
4878 add_phi_arg (nphi
, t
, ene
, locus
);
4879 locus
= redirect_edge_var_map_location (vm
);
4880 add_phi_arg (nphi
, redirect_edge_var_map_def (vm
), re
, locus
);
4882 gcc_assert (!gsi_end_p (psi
) && i
== head
->length ());
4883 redirect_edge_var_map_clear (re
);
4886 psi
= gsi_start_phis (fin_bb
);
4887 if (gsi_end_p (psi
))
4889 remove_phi_node (&psi
, false);
4892 /* Make phi node for trip. */
4893 phi
= create_phi_node (trip_main
, iter_part_bb
);
4894 add_phi_arg (phi
, trip_back
, single_succ_edge (trip_update_bb
),
4896 add_phi_arg (phi
, trip_init
, single_succ_edge (entry_bb
),
4900 set_immediate_dominator (CDI_DOMINATORS
, trip_update_bb
, cont_bb
);
4901 set_immediate_dominator (CDI_DOMINATORS
, iter_part_bb
,
4902 recompute_dominator (CDI_DOMINATORS
, iter_part_bb
));
4903 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
4904 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
4905 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
,
4906 recompute_dominator (CDI_DOMINATORS
, seq_start_bb
));
4907 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
4908 recompute_dominator (CDI_DOMINATORS
, body_bb
));
4912 /* Expand the OpenMP loop defined by REGION. */
4915 expand_omp_for (struct omp_region
*region
)
4917 struct omp_for_data fd
;
4918 struct omp_for_data_loop
*loops
;
4921 = (struct omp_for_data_loop
*)
4922 alloca (gimple_omp_for_collapse (last_stmt (region
->entry
))
4923 * sizeof (struct omp_for_data_loop
));
4924 extract_omp_for_data (last_stmt (region
->entry
), &fd
, loops
);
4925 region
->sched_kind
= fd
.sched_kind
;
4927 gcc_assert (EDGE_COUNT (region
->entry
->succs
) == 2);
4928 BRANCH_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
4929 FALLTHRU_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
4932 gcc_assert (EDGE_COUNT (region
->cont
->succs
) == 2);
4933 BRANCH_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
4934 FALLTHRU_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
4937 if (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
4940 && region
->cont
!= NULL
)
4942 if (fd
.chunk_size
== NULL
)
4943 expand_omp_for_static_nochunk (region
, &fd
);
4945 expand_omp_for_static_chunk (region
, &fd
);
4949 int fn_index
, start_ix
, next_ix
;
4951 if (fd
.chunk_size
== NULL
4952 && fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
4953 fd
.chunk_size
= integer_zero_node
;
4954 gcc_assert (fd
.sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
4955 fn_index
= (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
4956 ? 3 : fd
.sched_kind
;
4957 fn_index
+= fd
.have_ordered
* 4;
4958 start_ix
= ((int)BUILT_IN_GOMP_LOOP_STATIC_START
) + fn_index
;
4959 next_ix
= ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT
) + fn_index
;
4960 if (fd
.iter_type
== long_long_unsigned_type_node
)
4962 start_ix
+= ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4963 - (int)BUILT_IN_GOMP_LOOP_STATIC_START
);
4964 next_ix
+= ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4965 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT
);
4967 expand_omp_for_generic (region
, &fd
, (enum built_in_function
) start_ix
,
4968 (enum built_in_function
) next_ix
);
4971 if (gimple_in_ssa_p (cfun
))
4972 update_ssa (TODO_update_ssa_only_virtuals
);
4976 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4978 v = GOMP_sections_start (n);
4995 v = GOMP_sections_next ();
5000 If this is a combined parallel sections, replace the call to
5001 GOMP_sections_start with call to GOMP_sections_next. */
5004 expand_omp_sections (struct omp_region
*region
)
5006 tree t
, u
, vin
= NULL
, vmain
, vnext
, l2
;
5007 vec
<tree
> label_vec
;
5009 basic_block entry_bb
, l0_bb
, l1_bb
, l2_bb
, default_bb
;
5010 gimple_stmt_iterator si
, switch_si
;
5011 gimple sections_stmt
, stmt
, cont
;
5014 struct omp_region
*inner
;
5016 bool exit_reachable
= region
->cont
!= NULL
;
5018 gcc_assert (region
->exit
!= NULL
);
5019 entry_bb
= region
->entry
;
5020 l0_bb
= single_succ (entry_bb
);
5021 l1_bb
= region
->cont
;
5022 l2_bb
= region
->exit
;
5023 if (single_pred_p (l2_bb
) && single_pred (l2_bb
) == l0_bb
)
5024 l2
= gimple_block_label (l2_bb
);
5027 /* This can happen if there are reductions. */
5028 len
= EDGE_COUNT (l0_bb
->succs
);
5029 gcc_assert (len
> 0);
5030 e
= EDGE_SUCC (l0_bb
, len
- 1);
5031 si
= gsi_last_bb (e
->dest
);
5034 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
5035 l2
= gimple_block_label (e
->dest
);
5037 FOR_EACH_EDGE (e
, ei
, l0_bb
->succs
)
5039 si
= gsi_last_bb (e
->dest
);
5041 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
5043 l2
= gimple_block_label (e
->dest
);
5049 default_bb
= create_empty_bb (l1_bb
->prev_bb
);
5051 default_bb
= create_empty_bb (l0_bb
);
5053 /* We will build a switch() with enough cases for all the
5054 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
5055 and a default case to abort if something goes wrong. */
5056 len
= EDGE_COUNT (l0_bb
->succs
);
5058 /* Use vec::quick_push on label_vec throughout, since we know the size
5060 label_vec
.create (len
);
5062 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
5063 GIMPLE_OMP_SECTIONS statement. */
5064 si
= gsi_last_bb (entry_bb
);
5065 sections_stmt
= gsi_stmt (si
);
5066 gcc_assert (gimple_code (sections_stmt
) == GIMPLE_OMP_SECTIONS
);
5067 vin
= gimple_omp_sections_control (sections_stmt
);
5068 if (!is_combined_parallel (region
))
5070 /* If we are not inside a combined parallel+sections region,
5071 call GOMP_sections_start. */
5072 t
= build_int_cst (unsigned_type_node
, len
- 1);
5073 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START
);
5074 stmt
= gimple_build_call (u
, 1, t
);
5078 /* Otherwise, call GOMP_sections_next. */
5079 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT
);
5080 stmt
= gimple_build_call (u
, 0);
5082 gimple_call_set_lhs (stmt
, vin
);
5083 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
5084 gsi_remove (&si
, true);
5086 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
5088 switch_si
= gsi_last_bb (l0_bb
);
5089 gcc_assert (gimple_code (gsi_stmt (switch_si
)) == GIMPLE_OMP_SECTIONS_SWITCH
);
5092 cont
= last_stmt (l1_bb
);
5093 gcc_assert (gimple_code (cont
) == GIMPLE_OMP_CONTINUE
);
5094 vmain
= gimple_omp_continue_control_use (cont
);
5095 vnext
= gimple_omp_continue_control_def (cont
);
5103 t
= build_case_label (build_int_cst (unsigned_type_node
, 0), NULL
, l2
);
5104 label_vec
.quick_push (t
);
5107 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
5108 for (inner
= region
->inner
, casei
= 1;
5110 inner
= inner
->next
, i
++, casei
++)
5112 basic_block s_entry_bb
, s_exit_bb
;
5114 /* Skip optional reduction region. */
5115 if (inner
->type
== GIMPLE_OMP_ATOMIC_LOAD
)
5122 s_entry_bb
= inner
->entry
;
5123 s_exit_bb
= inner
->exit
;
5125 t
= gimple_block_label (s_entry_bb
);
5126 u
= build_int_cst (unsigned_type_node
, casei
);
5127 u
= build_case_label (u
, NULL
, t
);
5128 label_vec
.quick_push (u
);
5130 si
= gsi_last_bb (s_entry_bb
);
5131 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SECTION
);
5132 gcc_assert (i
< len
|| gimple_omp_section_last_p (gsi_stmt (si
)));
5133 gsi_remove (&si
, true);
5134 single_succ_edge (s_entry_bb
)->flags
= EDGE_FALLTHRU
;
5136 if (s_exit_bb
== NULL
)
5139 si
= gsi_last_bb (s_exit_bb
);
5140 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
5141 gsi_remove (&si
, true);
5143 single_succ_edge (s_exit_bb
)->flags
= EDGE_FALLTHRU
;
5146 /* Error handling code goes in DEFAULT_BB. */
5147 t
= gimple_block_label (default_bb
);
5148 u
= build_case_label (NULL
, NULL
, t
);
5149 make_edge (l0_bb
, default_bb
, 0);
5151 stmt
= gimple_build_switch (vmain
, u
, label_vec
);
5152 gsi_insert_after (&switch_si
, stmt
, GSI_SAME_STMT
);
5153 gsi_remove (&switch_si
, true);
5154 label_vec
.release ();
5156 si
= gsi_start_bb (default_bb
);
5157 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
5158 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
5164 /* Code to get the next section goes in L1_BB. */
5165 si
= gsi_last_bb (l1_bb
);
5166 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CONTINUE
);
5168 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT
);
5169 stmt
= gimple_build_call (bfn_decl
, 0);
5170 gimple_call_set_lhs (stmt
, vnext
);
5171 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
5172 gsi_remove (&si
, true);
5174 single_succ_edge (l1_bb
)->flags
= EDGE_FALLTHRU
;
5177 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
5178 si
= gsi_last_bb (l2_bb
);
5179 if (gimple_omp_return_nowait_p (gsi_stmt (si
)))
5180 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT
);
5182 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END
);
5183 stmt
= gimple_build_call (t
, 0);
5184 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
5185 gsi_remove (&si
, true);
5187 set_immediate_dominator (CDI_DOMINATORS
, default_bb
, l0_bb
);
5191 /* Expand code for an OpenMP single directive. We've already expanded
5192 much of the code, here we simply place the GOMP_barrier call. */
5195 expand_omp_single (struct omp_region
*region
)
5197 basic_block entry_bb
, exit_bb
;
5198 gimple_stmt_iterator si
;
5199 bool need_barrier
= false;
5201 entry_bb
= region
->entry
;
5202 exit_bb
= region
->exit
;
5204 si
= gsi_last_bb (entry_bb
);
5205 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
5206 be removed. We need to ensure that the thread that entered the single
5207 does not exit before the data is copied out by the other threads. */
5208 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si
)),
5209 OMP_CLAUSE_COPYPRIVATE
))
5210 need_barrier
= true;
5211 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
);
5212 gsi_remove (&si
, true);
5213 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
5215 si
= gsi_last_bb (exit_bb
);
5216 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)) || need_barrier
)
5217 force_gimple_operand_gsi (&si
, build_omp_barrier (), false, NULL_TREE
,
5218 false, GSI_SAME_STMT
);
5219 gsi_remove (&si
, true);
5220 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
5224 /* Generic expansion for OpenMP synchronization directives: master,
5225 ordered and critical. All we need to do here is remove the entry
5226 and exit markers for REGION. */
5229 expand_omp_synch (struct omp_region
*region
)
5231 basic_block entry_bb
, exit_bb
;
5232 gimple_stmt_iterator si
;
5234 entry_bb
= region
->entry
;
5235 exit_bb
= region
->exit
;
5237 si
= gsi_last_bb (entry_bb
);
5238 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
5239 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_MASTER
5240 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ORDERED
5241 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CRITICAL
);
5242 gsi_remove (&si
, true);
5243 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
5247 si
= gsi_last_bb (exit_bb
);
5248 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
5249 gsi_remove (&si
, true);
5250 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
5254 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5255 operation as a normal volatile load. */
5258 expand_omp_atomic_load (basic_block load_bb
, tree addr
,
5259 tree loaded_val
, int index
)
5261 enum built_in_function tmpbase
;
5262 gimple_stmt_iterator gsi
;
5263 basic_block store_bb
;
5266 tree decl
, call
, type
, itype
;
5268 gsi
= gsi_last_bb (load_bb
);
5269 stmt
= gsi_stmt (gsi
);
5270 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_LOAD
);
5271 loc
= gimple_location (stmt
);
5273 /* ??? If the target does not implement atomic_load_optab[mode], and mode
5274 is smaller than word size, then expand_atomic_load assumes that the load
5275 is atomic. We could avoid the builtin entirely in this case. */
5277 tmpbase
= (enum built_in_function
) (BUILT_IN_ATOMIC_LOAD_N
+ index
+ 1);
5278 decl
= builtin_decl_explicit (tmpbase
);
5279 if (decl
== NULL_TREE
)
5282 type
= TREE_TYPE (loaded_val
);
5283 itype
= TREE_TYPE (TREE_TYPE (decl
));
5285 call
= build_call_expr_loc (loc
, decl
, 2, addr
,
5286 build_int_cst (NULL
, MEMMODEL_RELAXED
));
5287 if (!useless_type_conversion_p (type
, itype
))
5288 call
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, type
, call
);
5289 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, loaded_val
, call
);
5291 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5292 gsi_remove (&gsi
, true);
5294 store_bb
= single_succ (load_bb
);
5295 gsi
= gsi_last_bb (store_bb
);
5296 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
5297 gsi_remove (&gsi
, true);
5299 if (gimple_in_ssa_p (cfun
))
5300 update_ssa (TODO_update_ssa_no_phi
);
5305 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5306 operation as a normal volatile store. */
5309 expand_omp_atomic_store (basic_block load_bb
, tree addr
,
5310 tree loaded_val
, tree stored_val
, int index
)
5312 enum built_in_function tmpbase
;
5313 gimple_stmt_iterator gsi
;
5314 basic_block store_bb
= single_succ (load_bb
);
5317 tree decl
, call
, type
, itype
;
5318 enum machine_mode imode
;
5321 gsi
= gsi_last_bb (load_bb
);
5322 stmt
= gsi_stmt (gsi
);
5323 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_LOAD
);
5325 /* If the load value is needed, then this isn't a store but an exchange. */
5326 exchange
= gimple_omp_atomic_need_value_p (stmt
);
5328 gsi
= gsi_last_bb (store_bb
);
5329 stmt
= gsi_stmt (gsi
);
5330 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_STORE
);
5331 loc
= gimple_location (stmt
);
5333 /* ??? If the target does not implement atomic_store_optab[mode], and mode
5334 is smaller than word size, then expand_atomic_store assumes that the store
5335 is atomic. We could avoid the builtin entirely in this case. */
5337 tmpbase
= (exchange
? BUILT_IN_ATOMIC_EXCHANGE_N
: BUILT_IN_ATOMIC_STORE_N
);
5338 tmpbase
= (enum built_in_function
) ((int) tmpbase
+ index
+ 1);
5339 decl
= builtin_decl_explicit (tmpbase
);
5340 if (decl
== NULL_TREE
)
5343 type
= TREE_TYPE (stored_val
);
5345 /* Dig out the type of the function's second argument. */
5346 itype
= TREE_TYPE (decl
);
5347 itype
= TYPE_ARG_TYPES (itype
);
5348 itype
= TREE_CHAIN (itype
);
5349 itype
= TREE_VALUE (itype
);
5350 imode
= TYPE_MODE (itype
);
5352 if (exchange
&& !can_atomic_exchange_p (imode
, true))
5355 if (!useless_type_conversion_p (itype
, type
))
5356 stored_val
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, itype
, stored_val
);
5357 call
= build_call_expr_loc (loc
, decl
, 3, addr
, stored_val
,
5358 build_int_cst (NULL
, MEMMODEL_RELAXED
));
5361 if (!useless_type_conversion_p (type
, itype
))
5362 call
= build1_loc (loc
, VIEW_CONVERT_EXPR
, type
, call
);
5363 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, loaded_val
, call
);
5366 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5367 gsi_remove (&gsi
, true);
5369 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
5370 gsi
= gsi_last_bb (load_bb
);
5371 gsi_remove (&gsi
, true);
5373 if (gimple_in_ssa_p (cfun
))
5374 update_ssa (TODO_update_ssa_no_phi
);
5379 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5380 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
5381 size of the data type, and thus usable to find the index of the builtin
5382 decl. Returns false if the expression is not of the proper form. */
5385 expand_omp_atomic_fetch_op (basic_block load_bb
,
5386 tree addr
, tree loaded_val
,
5387 tree stored_val
, int index
)
5389 enum built_in_function oldbase
, newbase
, tmpbase
;
5390 tree decl
, itype
, call
;
5392 basic_block store_bb
= single_succ (load_bb
);
5393 gimple_stmt_iterator gsi
;
5396 enum tree_code code
;
5397 bool need_old
, need_new
;
5398 enum machine_mode imode
;
5400 /* We expect to find the following sequences:
5403 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5406 val = tmp OP something; (or: something OP tmp)
5407 GIMPLE_OMP_STORE (val)
5409 ???FIXME: Allow a more flexible sequence.
5410 Perhaps use data flow to pick the statements.
5414 gsi
= gsi_after_labels (store_bb
);
5415 stmt
= gsi_stmt (gsi
);
5416 loc
= gimple_location (stmt
);
5417 if (!is_gimple_assign (stmt
))
5420 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_OMP_ATOMIC_STORE
)
5422 need_new
= gimple_omp_atomic_need_value_p (gsi_stmt (gsi
));
5423 need_old
= gimple_omp_atomic_need_value_p (last_stmt (load_bb
));
5424 gcc_checking_assert (!need_old
|| !need_new
);
5426 if (!operand_equal_p (gimple_assign_lhs (stmt
), stored_val
, 0))
5429 /* Check for one of the supported fetch-op operations. */
5430 code
= gimple_assign_rhs_code (stmt
);
5434 case POINTER_PLUS_EXPR
:
5435 oldbase
= BUILT_IN_ATOMIC_FETCH_ADD_N
;
5436 newbase
= BUILT_IN_ATOMIC_ADD_FETCH_N
;
5439 oldbase
= BUILT_IN_ATOMIC_FETCH_SUB_N
;
5440 newbase
= BUILT_IN_ATOMIC_SUB_FETCH_N
;
5443 oldbase
= BUILT_IN_ATOMIC_FETCH_AND_N
;
5444 newbase
= BUILT_IN_ATOMIC_AND_FETCH_N
;
5447 oldbase
= BUILT_IN_ATOMIC_FETCH_OR_N
;
5448 newbase
= BUILT_IN_ATOMIC_OR_FETCH_N
;
5451 oldbase
= BUILT_IN_ATOMIC_FETCH_XOR_N
;
5452 newbase
= BUILT_IN_ATOMIC_XOR_FETCH_N
;
5458 /* Make sure the expression is of the proper form. */
5459 if (operand_equal_p (gimple_assign_rhs1 (stmt
), loaded_val
, 0))
5460 rhs
= gimple_assign_rhs2 (stmt
);
5461 else if (commutative_tree_code (gimple_assign_rhs_code (stmt
))
5462 && operand_equal_p (gimple_assign_rhs2 (stmt
), loaded_val
, 0))
5463 rhs
= gimple_assign_rhs1 (stmt
);
5467 tmpbase
= ((enum built_in_function
)
5468 ((need_new
? newbase
: oldbase
) + index
+ 1));
5469 decl
= builtin_decl_explicit (tmpbase
);
5470 if (decl
== NULL_TREE
)
5472 itype
= TREE_TYPE (TREE_TYPE (decl
));
5473 imode
= TYPE_MODE (itype
);
5475 /* We could test all of the various optabs involved, but the fact of the
5476 matter is that (with the exception of i486 vs i586 and xadd) all targets
5477 that support any atomic operaton optab also implements compare-and-swap.
5478 Let optabs.c take care of expanding any compare-and-swap loop. */
5479 if (!can_compare_and_swap_p (imode
, true))
5482 gsi
= gsi_last_bb (load_bb
);
5483 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5485 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5486 It only requires that the operation happen atomically. Thus we can
5487 use the RELAXED memory model. */
5488 call
= build_call_expr_loc (loc
, decl
, 3, addr
,
5489 fold_convert_loc (loc
, itype
, rhs
),
5490 build_int_cst (NULL
, MEMMODEL_RELAXED
));
5492 if (need_old
|| need_new
)
5494 lhs
= need_old
? loaded_val
: stored_val
;
5495 call
= fold_convert_loc (loc
, TREE_TYPE (lhs
), call
);
5496 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, lhs
, call
);
5499 call
= fold_convert_loc (loc
, void_type_node
, call
);
5500 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5501 gsi_remove (&gsi
, true);
5503 gsi
= gsi_last_bb (store_bb
);
5504 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
5505 gsi_remove (&gsi
, true);
5506 gsi
= gsi_last_bb (store_bb
);
5507 gsi_remove (&gsi
, true);
5509 if (gimple_in_ssa_p (cfun
))
5510 update_ssa (TODO_update_ssa_no_phi
);
5515 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5519 newval = rhs; // with oldval replacing *addr in rhs
5520 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5521 if (oldval != newval)
5524 INDEX is log2 of the size of the data type, and thus usable to find the
5525 index of the builtin decl. */
5528 expand_omp_atomic_pipeline (basic_block load_bb
, basic_block store_bb
,
5529 tree addr
, tree loaded_val
, tree stored_val
,
5532 tree loadedi
, storedi
, initial
, new_storedi
, old_vali
;
5533 tree type
, itype
, cmpxchg
, iaddr
;
5534 gimple_stmt_iterator si
;
5535 basic_block loop_header
= single_succ (load_bb
);
5538 enum built_in_function fncode
;
5540 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5541 order to use the RELAXED memory model effectively. */
5542 fncode
= (enum built_in_function
)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5544 cmpxchg
= builtin_decl_explicit (fncode
);
5545 if (cmpxchg
== NULL_TREE
)
5547 type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
5548 itype
= TREE_TYPE (TREE_TYPE (cmpxchg
));
5550 if (!can_compare_and_swap_p (TYPE_MODE (itype
), true))
5553 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5554 si
= gsi_last_bb (load_bb
);
5555 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5557 /* For floating-point values, we'll need to view-convert them to integers
5558 so that we can perform the atomic compare and swap. Simplify the
5559 following code by always setting up the "i"ntegral variables. */
5560 if (!INTEGRAL_TYPE_P (type
) && !POINTER_TYPE_P (type
))
5564 iaddr
= create_tmp_reg (build_pointer_type_for_mode (itype
, ptr_mode
,
5567 = force_gimple_operand_gsi (&si
,
5568 fold_convert (TREE_TYPE (iaddr
), addr
),
5569 false, NULL_TREE
, true, GSI_SAME_STMT
);
5570 stmt
= gimple_build_assign (iaddr
, iaddr_val
);
5571 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5572 loadedi
= create_tmp_var (itype
, NULL
);
5573 if (gimple_in_ssa_p (cfun
))
5574 loadedi
= make_ssa_name (loadedi
, NULL
);
5579 loadedi
= loaded_val
;
5583 = force_gimple_operand_gsi (&si
,
5584 build2 (MEM_REF
, TREE_TYPE (TREE_TYPE (iaddr
)),
5586 build_int_cst (TREE_TYPE (iaddr
), 0)),
5587 true, NULL_TREE
, true, GSI_SAME_STMT
);
5589 /* Move the value to the LOADEDI temporary. */
5590 if (gimple_in_ssa_p (cfun
))
5592 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header
)));
5593 phi
= create_phi_node (loadedi
, loop_header
);
5594 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, single_succ_edge (load_bb
)),
5598 gsi_insert_before (&si
,
5599 gimple_build_assign (loadedi
, initial
),
5601 if (loadedi
!= loaded_val
)
5603 gimple_stmt_iterator gsi2
;
5606 x
= build1 (VIEW_CONVERT_EXPR
, type
, loadedi
);
5607 gsi2
= gsi_start_bb (loop_header
);
5608 if (gimple_in_ssa_p (cfun
))
5611 x
= force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
5612 true, GSI_SAME_STMT
);
5613 stmt
= gimple_build_assign (loaded_val
, x
);
5614 gsi_insert_before (&gsi2
, stmt
, GSI_SAME_STMT
);
5618 x
= build2 (MODIFY_EXPR
, TREE_TYPE (loaded_val
), loaded_val
, x
);
5619 force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
5620 true, GSI_SAME_STMT
);
5623 gsi_remove (&si
, true);
5625 si
= gsi_last_bb (store_bb
);
5626 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
5629 storedi
= stored_val
;
5632 force_gimple_operand_gsi (&si
,
5633 build1 (VIEW_CONVERT_EXPR
, itype
,
5634 stored_val
), true, NULL_TREE
, true,
5637 /* Build the compare&swap statement. */
5638 new_storedi
= build_call_expr (cmpxchg
, 3, iaddr
, loadedi
, storedi
);
5639 new_storedi
= force_gimple_operand_gsi (&si
,
5640 fold_convert (TREE_TYPE (loadedi
),
5643 true, GSI_SAME_STMT
);
5645 if (gimple_in_ssa_p (cfun
))
5649 old_vali
= create_tmp_var (TREE_TYPE (loadedi
), NULL
);
5650 stmt
= gimple_build_assign (old_vali
, loadedi
);
5651 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5653 stmt
= gimple_build_assign (loadedi
, new_storedi
);
5654 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5657 /* Note that we always perform the comparison as an integer, even for
5658 floating point. This allows the atomic operation to properly
5659 succeed even with NaNs and -0.0. */
5660 stmt
= gimple_build_cond_empty
5661 (build2 (NE_EXPR
, boolean_type_node
,
5662 new_storedi
, old_vali
));
5663 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5666 e
= single_succ_edge (store_bb
);
5667 e
->flags
&= ~EDGE_FALLTHRU
;
5668 e
->flags
|= EDGE_FALSE_VALUE
;
5670 e
= make_edge (store_bb
, loop_header
, EDGE_TRUE_VALUE
);
5672 /* Copy the new value to loadedi (we already did that before the condition
5673 if we are not in SSA). */
5674 if (gimple_in_ssa_p (cfun
))
5676 phi
= gimple_seq_first_stmt (phi_nodes (loop_header
));
5677 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, e
), new_storedi
);
5680 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5681 gsi_remove (&si
, true);
5683 if (gimple_in_ssa_p (cfun
))
5684 update_ssa (TODO_update_ssa_no_phi
);
5689 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5691 GOMP_atomic_start ();
5695 The result is not globally atomic, but works so long as all parallel
5696 references are within #pragma omp atomic directives. According to
5697 responses received from omp@openmp.org, appears to be within spec.
5698 Which makes sense, since that's how several other compilers handle
5699 this situation as well.
5700 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5701 expanding. STORED_VAL is the operand of the matching
5702 GIMPLE_OMP_ATOMIC_STORE.
5705 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5709 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
5714 expand_omp_atomic_mutex (basic_block load_bb
, basic_block store_bb
,
5715 tree addr
, tree loaded_val
, tree stored_val
)
5717 gimple_stmt_iterator si
;
5721 si
= gsi_last_bb (load_bb
);
5722 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5724 t
= builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START
);
5725 t
= build_call_expr (t
, 0);
5726 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5728 stmt
= gimple_build_assign (loaded_val
, build_simple_mem_ref (addr
));
5729 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5730 gsi_remove (&si
, true);
5732 si
= gsi_last_bb (store_bb
);
5733 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
5735 stmt
= gimple_build_assign (build_simple_mem_ref (unshare_expr (addr
)),
5737 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5739 t
= builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END
);
5740 t
= build_call_expr (t
, 0);
5741 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5742 gsi_remove (&si
, true);
5744 if (gimple_in_ssa_p (cfun
))
5745 update_ssa (TODO_update_ssa_no_phi
);
5749 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5750 using expand_omp_atomic_fetch_op. If it failed, we try to
5751 call expand_omp_atomic_pipeline, and if it fails too, the
5752 ultimate fallback is wrapping the operation in a mutex
5753 (expand_omp_atomic_mutex). REGION is the atomic region built
5754 by build_omp_regions_1(). */
5757 expand_omp_atomic (struct omp_region
*region
)
5759 basic_block load_bb
= region
->entry
, store_bb
= region
->exit
;
5760 gimple load
= last_stmt (load_bb
), store
= last_stmt (store_bb
);
5761 tree loaded_val
= gimple_omp_atomic_load_lhs (load
);
5762 tree addr
= gimple_omp_atomic_load_rhs (load
);
5763 tree stored_val
= gimple_omp_atomic_store_val (store
);
5764 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
5765 HOST_WIDE_INT index
;
5767 /* Make sure the type is one of the supported sizes. */
5768 index
= tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
5769 index
= exact_log2 (index
);
5770 if (index
>= 0 && index
<= 4)
5772 unsigned int align
= TYPE_ALIGN_UNIT (type
);
5774 /* __sync builtins require strict data alignment. */
5775 if (exact_log2 (align
) >= index
)
5778 if (loaded_val
== stored_val
5779 && (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_INT
5780 || GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
)
5781 && GET_MODE_BITSIZE (TYPE_MODE (type
)) <= BITS_PER_WORD
5782 && expand_omp_atomic_load (load_bb
, addr
, loaded_val
, index
))
5786 if ((GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_INT
5787 || GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
)
5788 && GET_MODE_BITSIZE (TYPE_MODE (type
)) <= BITS_PER_WORD
5789 && store_bb
== single_succ (load_bb
)
5790 && first_stmt (store_bb
) == store
5791 && expand_omp_atomic_store (load_bb
, addr
, loaded_val
,
5795 /* When possible, use specialized atomic update functions. */
5796 if ((INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
))
5797 && store_bb
== single_succ (load_bb
)
5798 && expand_omp_atomic_fetch_op (load_bb
, addr
,
5799 loaded_val
, stored_val
, index
))
5802 /* If we don't have specialized __sync builtins, try and implement
5803 as a compare and swap loop. */
5804 if (expand_omp_atomic_pipeline (load_bb
, store_bb
, addr
,
5805 loaded_val
, stored_val
, index
))
5810 /* The ultimate fallback is wrapping the operation in a mutex. */
5811 expand_omp_atomic_mutex (load_bb
, store_bb
, addr
, loaded_val
, stored_val
);
5815 /* Expand the parallel region tree rooted at REGION. Expansion
5816 proceeds in depth-first order. Innermost regions are expanded
5817 first. This way, parallel regions that require a new function to
5818 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5819 internal dependencies in their body. */
5822 expand_omp (struct omp_region
*region
)
5826 location_t saved_location
;
5828 /* First, determine whether this is a combined parallel+workshare
5830 if (region
->type
== GIMPLE_OMP_PARALLEL
)
5831 determine_parallel_type (region
);
5834 expand_omp (region
->inner
);
5836 saved_location
= input_location
;
5837 if (gimple_has_location (last_stmt (region
->entry
)))
5838 input_location
= gimple_location (last_stmt (region
->entry
));
5840 switch (region
->type
)
5842 case GIMPLE_OMP_PARALLEL
:
5843 case GIMPLE_OMP_TASK
:
5844 expand_omp_taskreg (region
);
5847 case GIMPLE_OMP_FOR
:
5848 expand_omp_for (region
);
5851 case GIMPLE_OMP_SECTIONS
:
5852 expand_omp_sections (region
);
5855 case GIMPLE_OMP_SECTION
:
5856 /* Individual omp sections are handled together with their
5857 parent GIMPLE_OMP_SECTIONS region. */
5860 case GIMPLE_OMP_SINGLE
:
5861 expand_omp_single (region
);
5864 case GIMPLE_OMP_MASTER
:
5865 case GIMPLE_OMP_ORDERED
:
5866 case GIMPLE_OMP_CRITICAL
:
5867 expand_omp_synch (region
);
5870 case GIMPLE_OMP_ATOMIC_LOAD
:
5871 expand_omp_atomic (region
);
5878 input_location
= saved_location
;
5879 region
= region
->next
;
5884 /* Helper for build_omp_regions. Scan the dominator tree starting at
5885 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5886 true, the function ends once a single tree is built (otherwise, whole
5887 forest of OMP constructs may be built). */
5890 build_omp_regions_1 (basic_block bb
, struct omp_region
*parent
,
5893 gimple_stmt_iterator gsi
;
5897 gsi
= gsi_last_bb (bb
);
5898 if (!gsi_end_p (gsi
) && is_gimple_omp (gsi_stmt (gsi
)))
5900 struct omp_region
*region
;
5901 enum gimple_code code
;
5903 stmt
= gsi_stmt (gsi
);
5904 code
= gimple_code (stmt
);
5905 if (code
== GIMPLE_OMP_RETURN
)
5907 /* STMT is the return point out of region PARENT. Mark it
5908 as the exit point and make PARENT the immediately
5909 enclosing region. */
5910 gcc_assert (parent
);
5913 parent
= parent
->outer
;
5915 else if (code
== GIMPLE_OMP_ATOMIC_STORE
)
5917 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5918 GIMPLE_OMP_RETURN, but matches with
5919 GIMPLE_OMP_ATOMIC_LOAD. */
5920 gcc_assert (parent
);
5921 gcc_assert (parent
->type
== GIMPLE_OMP_ATOMIC_LOAD
);
5924 parent
= parent
->outer
;
5927 else if (code
== GIMPLE_OMP_CONTINUE
)
5929 gcc_assert (parent
);
5932 else if (code
== GIMPLE_OMP_SECTIONS_SWITCH
)
5934 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5935 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5940 /* Otherwise, this directive becomes the parent for a new
5942 region
= new_omp_region (bb
, code
, parent
);
5947 if (single_tree
&& !parent
)
5950 for (son
= first_dom_son (CDI_DOMINATORS
, bb
);
5952 son
= next_dom_son (CDI_DOMINATORS
, son
))
5953 build_omp_regions_1 (son
, parent
, single_tree
);
5956 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5960 build_omp_regions_root (basic_block root
)
5962 gcc_assert (root_omp_region
== NULL
);
5963 build_omp_regions_1 (root
, NULL
, true);
5964 gcc_assert (root_omp_region
!= NULL
);
5967 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5970 omp_expand_local (basic_block head
)
5972 build_omp_regions_root (head
);
5973 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5975 fprintf (dump_file
, "\nOMP region tree\n\n");
5976 dump_omp_region (dump_file
, root_omp_region
, 0);
5977 fprintf (dump_file
, "\n");
5980 remove_exit_barriers (root_omp_region
);
5981 expand_omp (root_omp_region
);
5983 free_omp_regions ();
5986 /* Scan the CFG and build a tree of OMP regions. Return the root of
5987 the OMP region tree. */
5990 build_omp_regions (void)
5992 gcc_assert (root_omp_region
== NULL
);
5993 calculate_dominance_info (CDI_DOMINATORS
);
5994 build_omp_regions_1 (ENTRY_BLOCK_PTR
, NULL
, false);
5997 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
6000 execute_expand_omp (void)
6002 build_omp_regions ();
6004 if (!root_omp_region
)
6009 fprintf (dump_file
, "\nOMP region tree\n\n");
6010 dump_omp_region (dump_file
, root_omp_region
, 0);
6011 fprintf (dump_file
, "\n");
6014 remove_exit_barriers (root_omp_region
);
6016 expand_omp (root_omp_region
);
6018 cleanup_tree_cfg ();
6020 free_omp_regions ();
6025 /* OMP expansion -- the default pass, run before creation of SSA form. */
6028 gate_expand_omp (void)
6030 return (flag_openmp
!= 0 && !seen_error ());
6033 struct gimple_opt_pass pass_expand_omp
=
6037 "ompexp", /* name */
6038 OPTGROUP_NONE
, /* optinfo_flags */
6039 gate_expand_omp
, /* gate */
6040 execute_expand_omp
, /* execute */
6043 0, /* static_pass_number */
6044 TV_NONE
, /* tv_id */
6045 PROP_gimple_any
, /* properties_required */
6046 0, /* properties_provided */
6047 0, /* properties_destroyed */
6048 0, /* todo_flags_start */
6049 0 /* todo_flags_finish */
6053 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
6055 /* Lower the OpenMP sections directive in the current statement in GSI_P.
6056 CTX is the enclosing OMP context for the current statement. */
6059 lower_omp_sections (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6061 tree block
, control
;
6062 gimple_stmt_iterator tgsi
;
6063 gimple stmt
, new_stmt
, bind
, t
;
6064 gimple_seq ilist
, dlist
, olist
, new_body
;
6065 struct gimplify_ctx gctx
;
6067 stmt
= gsi_stmt (*gsi_p
);
6069 push_gimplify_context (&gctx
);
6073 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt
),
6074 &ilist
, &dlist
, ctx
);
6076 new_body
= gimple_omp_body (stmt
);
6077 gimple_omp_set_body (stmt
, NULL
);
6078 tgsi
= gsi_start (new_body
);
6079 for (; !gsi_end_p (tgsi
); gsi_next (&tgsi
))
6084 sec_start
= gsi_stmt (tgsi
);
6085 sctx
= maybe_lookup_ctx (sec_start
);
6088 lower_omp (gimple_omp_body_ptr (sec_start
), sctx
);
6089 gsi_insert_seq_after (&tgsi
, gimple_omp_body (sec_start
),
6090 GSI_CONTINUE_LINKING
);
6091 gimple_omp_set_body (sec_start
, NULL
);
6093 if (gsi_one_before_end_p (tgsi
))
6095 gimple_seq l
= NULL
;
6096 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt
), NULL
,
6098 gsi_insert_seq_after (&tgsi
, l
, GSI_CONTINUE_LINKING
);
6099 gimple_omp_section_set_last (sec_start
);
6102 gsi_insert_after (&tgsi
, gimple_build_omp_return (false),
6103 GSI_CONTINUE_LINKING
);
6106 block
= make_node (BLOCK
);
6107 bind
= gimple_build_bind (NULL
, new_body
, block
);
6110 lower_reduction_clauses (gimple_omp_sections_clauses (stmt
), &olist
, ctx
);
6112 block
= make_node (BLOCK
);
6113 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
6114 gsi_replace (gsi_p
, new_stmt
, true);
6116 pop_gimplify_context (new_stmt
);
6117 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
6118 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
6119 if (BLOCK_VARS (block
))
6120 TREE_USED (block
) = 1;
6123 gimple_seq_add_seq (&new_body
, ilist
);
6124 gimple_seq_add_stmt (&new_body
, stmt
);
6125 gimple_seq_add_stmt (&new_body
, gimple_build_omp_sections_switch ());
6126 gimple_seq_add_stmt (&new_body
, bind
);
6128 control
= create_tmp_var (unsigned_type_node
, ".section");
6129 t
= gimple_build_omp_continue (control
, control
);
6130 gimple_omp_sections_set_control (stmt
, control
);
6131 gimple_seq_add_stmt (&new_body
, t
);
6133 gimple_seq_add_seq (&new_body
, olist
);
6134 gimple_seq_add_seq (&new_body
, dlist
);
6136 new_body
= maybe_catch_exception (new_body
);
6138 t
= gimple_build_omp_return
6139 (!!find_omp_clause (gimple_omp_sections_clauses (stmt
),
6140 OMP_CLAUSE_NOWAIT
));
6141 gimple_seq_add_stmt (&new_body
, t
);
6143 gimple_bind_set_body (new_stmt
, new_body
);
6147 /* A subroutine of lower_omp_single. Expand the simple form of
6148 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
6150 if (GOMP_single_start ())
6152 [ GOMP_barrier (); ] -> unless 'nowait' is present.
6154 FIXME. It may be better to delay expanding the logic of this until
6155 pass_expand_omp. The expanded logic may make the job more difficult
6156 to a synchronization analysis pass. */
6159 lower_omp_single_simple (gimple single_stmt
, gimple_seq
*pre_p
)
6161 location_t loc
= gimple_location (single_stmt
);
6162 tree tlabel
= create_artificial_label (loc
);
6163 tree flabel
= create_artificial_label (loc
);
6167 decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START
);
6168 lhs
= create_tmp_var (TREE_TYPE (TREE_TYPE (decl
)), NULL
);
6169 call
= gimple_build_call (decl
, 0);
6170 gimple_call_set_lhs (call
, lhs
);
6171 gimple_seq_add_stmt (pre_p
, call
);
6173 cond
= gimple_build_cond (EQ_EXPR
, lhs
,
6174 fold_convert_loc (loc
, TREE_TYPE (lhs
),
6177 gimple_seq_add_stmt (pre_p
, cond
);
6178 gimple_seq_add_stmt (pre_p
, gimple_build_label (tlabel
));
6179 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
6180 gimple_seq_add_stmt (pre_p
, gimple_build_label (flabel
));
6184 /* A subroutine of lower_omp_single. Expand the simple form of
6185 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
6187 #pragma omp single copyprivate (a, b, c)
6189 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
6192 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
6198 GOMP_single_copy_end (©out);
6209 FIXME. It may be better to delay expanding the logic of this until
6210 pass_expand_omp. The expanded logic may make the job more difficult
6211 to a synchronization analysis pass. */
6214 lower_omp_single_copy (gimple single_stmt
, gimple_seq
*pre_p
, omp_context
*ctx
)
6216 tree ptr_type
, t
, l0
, l1
, l2
, bfn_decl
;
6217 gimple_seq copyin_seq
;
6218 location_t loc
= gimple_location (single_stmt
);
6220 ctx
->sender_decl
= create_tmp_var (ctx
->record_type
, ".omp_copy_o");
6222 ptr_type
= build_pointer_type (ctx
->record_type
);
6223 ctx
->receiver_decl
= create_tmp_var (ptr_type
, ".omp_copy_i");
6225 l0
= create_artificial_label (loc
);
6226 l1
= create_artificial_label (loc
);
6227 l2
= create_artificial_label (loc
);
6229 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START
);
6230 t
= build_call_expr_loc (loc
, bfn_decl
, 0);
6231 t
= fold_convert_loc (loc
, ptr_type
, t
);
6232 gimplify_assign (ctx
->receiver_decl
, t
, pre_p
);
6234 t
= build2 (EQ_EXPR
, boolean_type_node
, ctx
->receiver_decl
,
6235 build_int_cst (ptr_type
, 0));
6236 t
= build3 (COND_EXPR
, void_type_node
, t
,
6237 build_and_jump (&l0
), build_and_jump (&l1
));
6238 gimplify_and_add (t
, pre_p
);
6240 gimple_seq_add_stmt (pre_p
, gimple_build_label (l0
));
6242 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
6245 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt
), pre_p
,
6248 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
6249 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END
);
6250 t
= build_call_expr_loc (loc
, bfn_decl
, 1, t
);
6251 gimplify_and_add (t
, pre_p
);
6253 t
= build_and_jump (&l2
);
6254 gimplify_and_add (t
, pre_p
);
6256 gimple_seq_add_stmt (pre_p
, gimple_build_label (l1
));
6258 gimple_seq_add_seq (pre_p
, copyin_seq
);
6260 gimple_seq_add_stmt (pre_p
, gimple_build_label (l2
));
6264 /* Expand code for an OpenMP single directive. */
6267 lower_omp_single (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6270 gimple t
, bind
, single_stmt
= gsi_stmt (*gsi_p
);
6271 gimple_seq bind_body
, dlist
;
6272 struct gimplify_ctx gctx
;
6274 push_gimplify_context (&gctx
);
6276 block
= make_node (BLOCK
);
6277 bind
= gimple_build_bind (NULL
, NULL
, block
);
6278 gsi_replace (gsi_p
, bind
, true);
6281 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt
),
6282 &bind_body
, &dlist
, ctx
);
6283 lower_omp (gimple_omp_body_ptr (single_stmt
), ctx
);
6285 gimple_seq_add_stmt (&bind_body
, single_stmt
);
6287 if (ctx
->record_type
)
6288 lower_omp_single_copy (single_stmt
, &bind_body
, ctx
);
6290 lower_omp_single_simple (single_stmt
, &bind_body
);
6292 gimple_omp_set_body (single_stmt
, NULL
);
6294 gimple_seq_add_seq (&bind_body
, dlist
);
6296 bind_body
= maybe_catch_exception (bind_body
);
6298 t
= gimple_build_omp_return
6299 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt
),
6300 OMP_CLAUSE_NOWAIT
));
6301 gimple_seq_add_stmt (&bind_body
, t
);
6302 gimple_bind_set_body (bind
, bind_body
);
6304 pop_gimplify_context (bind
);
6306 gimple_bind_append_vars (bind
, ctx
->block_vars
);
6307 BLOCK_VARS (block
) = ctx
->block_vars
;
6308 if (BLOCK_VARS (block
))
6309 TREE_USED (block
) = 1;
6313 /* Expand code for an OpenMP master directive. */
6316 lower_omp_master (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6318 tree block
, lab
= NULL
, x
, bfn_decl
;
6319 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
6320 location_t loc
= gimple_location (stmt
);
6322 struct gimplify_ctx gctx
;
6324 push_gimplify_context (&gctx
);
6326 block
= make_node (BLOCK
);
6327 bind
= gimple_build_bind (NULL
, NULL
, block
);
6328 gsi_replace (gsi_p
, bind
, true);
6329 gimple_bind_add_stmt (bind
, stmt
);
6331 bfn_decl
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
6332 x
= build_call_expr_loc (loc
, bfn_decl
, 0);
6333 x
= build2 (EQ_EXPR
, boolean_type_node
, x
, integer_zero_node
);
6334 x
= build3 (COND_EXPR
, void_type_node
, x
, NULL
, build_and_jump (&lab
));
6336 gimplify_and_add (x
, &tseq
);
6337 gimple_bind_add_seq (bind
, tseq
);
6339 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
6340 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
6341 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
6342 gimple_omp_set_body (stmt
, NULL
);
6344 gimple_bind_add_stmt (bind
, gimple_build_label (lab
));
6346 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
6348 pop_gimplify_context (bind
);
6350 gimple_bind_append_vars (bind
, ctx
->block_vars
);
6351 BLOCK_VARS (block
) = ctx
->block_vars
;
6355 /* Expand code for an OpenMP ordered directive. */
6358 lower_omp_ordered (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6361 gimple stmt
= gsi_stmt (*gsi_p
), bind
, x
;
6362 struct gimplify_ctx gctx
;
6364 push_gimplify_context (&gctx
);
6366 block
= make_node (BLOCK
);
6367 bind
= gimple_build_bind (NULL
, NULL
, block
);
6368 gsi_replace (gsi_p
, bind
, true);
6369 gimple_bind_add_stmt (bind
, stmt
);
6371 x
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START
),
6373 gimple_bind_add_stmt (bind
, x
);
6375 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
6376 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
6377 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
6378 gimple_omp_set_body (stmt
, NULL
);
6380 x
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END
), 0);
6381 gimple_bind_add_stmt (bind
, x
);
6383 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
6385 pop_gimplify_context (bind
);
6387 gimple_bind_append_vars (bind
, ctx
->block_vars
);
6388 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
6392 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
6393 substitution of a couple of function calls. But in the NAMED case,
6394 requires that languages coordinate a symbol name. It is therefore
6395 best put here in common code. */
6397 static GTY((param1_is (tree
), param2_is (tree
)))
6398 splay_tree critical_name_mutexes
;
6401 lower_omp_critical (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6404 tree name
, lock
, unlock
;
6405 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
6406 location_t loc
= gimple_location (stmt
);
6408 struct gimplify_ctx gctx
;
6410 name
= gimple_omp_critical_name (stmt
);
6416 if (!critical_name_mutexes
)
6417 critical_name_mutexes
6418 = splay_tree_new_ggc (splay_tree_compare_pointers
,
6419 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s
,
6420 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s
);
6422 n
= splay_tree_lookup (critical_name_mutexes
, (splay_tree_key
) name
);
6427 decl
= create_tmp_var_raw (ptr_type_node
, NULL
);
6429 new_str
= ACONCAT ((".gomp_critical_user_",
6430 IDENTIFIER_POINTER (name
), NULL
));
6431 DECL_NAME (decl
) = get_identifier (new_str
);
6432 TREE_PUBLIC (decl
) = 1;
6433 TREE_STATIC (decl
) = 1;
6434 DECL_COMMON (decl
) = 1;
6435 DECL_ARTIFICIAL (decl
) = 1;
6436 DECL_IGNORED_P (decl
) = 1;
6437 varpool_finalize_decl (decl
);
6439 splay_tree_insert (critical_name_mutexes
, (splay_tree_key
) name
,
6440 (splay_tree_value
) decl
);
6443 decl
= (tree
) n
->value
;
6445 lock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START
);
6446 lock
= build_call_expr_loc (loc
, lock
, 1, build_fold_addr_expr_loc (loc
, decl
));
6448 unlock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END
);
6449 unlock
= build_call_expr_loc (loc
, unlock
, 1,
6450 build_fold_addr_expr_loc (loc
, decl
));
6454 lock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START
);
6455 lock
= build_call_expr_loc (loc
, lock
, 0);
6457 unlock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END
);
6458 unlock
= build_call_expr_loc (loc
, unlock
, 0);
6461 push_gimplify_context (&gctx
);
6463 block
= make_node (BLOCK
);
6464 bind
= gimple_build_bind (NULL
, NULL
, block
);
6465 gsi_replace (gsi_p
, bind
, true);
6466 gimple_bind_add_stmt (bind
, stmt
);
6468 tbody
= gimple_bind_body (bind
);
6469 gimplify_and_add (lock
, &tbody
);
6470 gimple_bind_set_body (bind
, tbody
);
6472 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
6473 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
6474 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
6475 gimple_omp_set_body (stmt
, NULL
);
6477 tbody
= gimple_bind_body (bind
);
6478 gimplify_and_add (unlock
, &tbody
);
6479 gimple_bind_set_body (bind
, tbody
);
6481 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
6483 pop_gimplify_context (bind
);
6484 gimple_bind_append_vars (bind
, ctx
->block_vars
);
6485 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
6489 /* A subroutine of lower_omp_for. Generate code to emit the predicate
6490 for a lastprivate clause. Given a loop control predicate of (V
6491 cond N2), we gate the clause on (!(V cond N2)). The lowered form
6492 is appended to *DLIST, iterator initialization is appended to
6496 lower_omp_for_lastprivate (struct omp_for_data
*fd
, gimple_seq
*body_p
,
6497 gimple_seq
*dlist
, struct omp_context
*ctx
)
6499 tree clauses
, cond
, vinit
;
6500 enum tree_code cond_code
;
6503 cond_code
= fd
->loop
.cond_code
;
6504 cond_code
= cond_code
== LT_EXPR
? GE_EXPR
: LE_EXPR
;
6506 /* When possible, use a strict equality expression. This can let VRP
6507 type optimizations deduce the value and remove a copy. */
6508 if (host_integerp (fd
->loop
.step
, 0))
6510 HOST_WIDE_INT step
= TREE_INT_CST_LOW (fd
->loop
.step
);
6511 if (step
== 1 || step
== -1)
6512 cond_code
= EQ_EXPR
;
6515 cond
= build2 (cond_code
, boolean_type_node
, fd
->loop
.v
, fd
->loop
.n2
);
6517 clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
6519 lower_lastprivate_clauses (clauses
, cond
, &stmts
, ctx
);
6520 if (!gimple_seq_empty_p (stmts
))
6522 gimple_seq_add_seq (&stmts
, *dlist
);
6525 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6526 vinit
= fd
->loop
.n1
;
6527 if (cond_code
== EQ_EXPR
6528 && host_integerp (fd
->loop
.n2
, 0)
6529 && ! integer_zerop (fd
->loop
.n2
))
6530 vinit
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
6532 /* Initialize the iterator variable, so that threads that don't execute
6533 any iterations don't execute the lastprivate clauses by accident. */
6534 gimplify_assign (fd
->loop
.v
, vinit
, body_p
);
6539 /* Lower code for an OpenMP loop directive. */
6542 lower_omp_for (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6545 struct omp_for_data fd
;
6546 gimple stmt
= gsi_stmt (*gsi_p
), new_stmt
;
6547 gimple_seq omp_for_body
, body
, dlist
;
6549 struct gimplify_ctx gctx
;
6551 push_gimplify_context (&gctx
);
6553 lower_omp (gimple_omp_for_pre_body_ptr (stmt
), ctx
);
6554 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
6556 block
= make_node (BLOCK
);
6557 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
6558 /* Replace at gsi right away, so that 'stmt' is no member
6559 of a sequence anymore as we're going to add to to a different
6561 gsi_replace (gsi_p
, new_stmt
, true);
6563 /* Move declaration of temporaries in the loop body before we make
6565 omp_for_body
= gimple_omp_body (stmt
);
6566 if (!gimple_seq_empty_p (omp_for_body
)
6567 && gimple_code (gimple_seq_first_stmt (omp_for_body
)) == GIMPLE_BIND
)
6569 tree vars
= gimple_bind_vars (gimple_seq_first_stmt (omp_for_body
));
6570 gimple_bind_append_vars (new_stmt
, vars
);
6573 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6576 lower_rec_input_clauses (gimple_omp_for_clauses (stmt
), &body
, &dlist
, ctx
);
6577 gimple_seq_add_seq (&body
, gimple_omp_for_pre_body (stmt
));
6579 /* Lower the header expressions. At this point, we can assume that
6580 the header is of the form:
6582 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6584 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6585 using the .omp_data_s mapping, if needed. */
6586 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
6588 rhs_p
= gimple_omp_for_initial_ptr (stmt
, i
);
6589 if (!is_gimple_min_invariant (*rhs_p
))
6590 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6592 rhs_p
= gimple_omp_for_final_ptr (stmt
, i
);
6593 if (!is_gimple_min_invariant (*rhs_p
))
6594 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6596 rhs_p
= &TREE_OPERAND (gimple_omp_for_incr (stmt
, i
), 1);
6597 if (!is_gimple_min_invariant (*rhs_p
))
6598 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6601 /* Once lowered, extract the bounds and clauses. */
6602 extract_omp_for_data (stmt
, &fd
, NULL
);
6604 lower_omp_for_lastprivate (&fd
, &body
, &dlist
, ctx
);
6606 gimple_seq_add_stmt (&body
, stmt
);
6607 gimple_seq_add_seq (&body
, gimple_omp_body (stmt
));
6609 gimple_seq_add_stmt (&body
, gimple_build_omp_continue (fd
.loop
.v
,
6612 /* After the loop, add exit clauses. */
6613 lower_reduction_clauses (gimple_omp_for_clauses (stmt
), &body
, ctx
);
6614 gimple_seq_add_seq (&body
, dlist
);
6616 body
= maybe_catch_exception (body
);
6618 /* Region exit marker goes at the end of the loop body. */
6619 gimple_seq_add_stmt (&body
, gimple_build_omp_return (fd
.have_nowait
));
6621 pop_gimplify_context (new_stmt
);
6623 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
6624 BLOCK_VARS (block
) = gimple_bind_vars (new_stmt
);
6625 if (BLOCK_VARS (block
))
6626 TREE_USED (block
) = 1;
6628 gimple_bind_set_body (new_stmt
, body
);
6629 gimple_omp_set_body (stmt
, NULL
);
6630 gimple_omp_for_set_pre_body (stmt
, NULL
);
6633 /* Callback for walk_stmts. Check if the current statement only contains
6634 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6637 check_combined_parallel (gimple_stmt_iterator
*gsi_p
,
6638 bool *handled_ops_p
,
6639 struct walk_stmt_info
*wi
)
6641 int *info
= (int *) wi
->info
;
6642 gimple stmt
= gsi_stmt (*gsi_p
);
6644 *handled_ops_p
= true;
6645 switch (gimple_code (stmt
))
6649 case GIMPLE_OMP_FOR
:
6650 case GIMPLE_OMP_SECTIONS
:
6651 *info
= *info
== 0 ? 1 : -1;
6660 struct omp_taskcopy_context
6662 /* This field must be at the beginning, as we do "inheritance": Some
6663 callback functions for tree-inline.c (e.g., omp_copy_decl)
6664 receive a copy_body_data pointer that is up-casted to an
6665 omp_context pointer. */
6671 task_copyfn_copy_decl (tree var
, copy_body_data
*cb
)
6673 struct omp_taskcopy_context
*tcctx
= (struct omp_taskcopy_context
*) cb
;
6675 if (splay_tree_lookup (tcctx
->ctx
->sfield_map
, (splay_tree_key
) var
))
6676 return create_tmp_var (TREE_TYPE (var
), NULL
);
6682 task_copyfn_remap_type (struct omp_taskcopy_context
*tcctx
, tree orig_type
)
6684 tree name
, new_fields
= NULL
, type
, f
;
6686 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6687 name
= DECL_NAME (TYPE_NAME (orig_type
));
6688 name
= build_decl (gimple_location (tcctx
->ctx
->stmt
),
6689 TYPE_DECL
, name
, type
);
6690 TYPE_NAME (type
) = name
;
6692 for (f
= TYPE_FIELDS (orig_type
); f
; f
= TREE_CHAIN (f
))
6694 tree new_f
= copy_node (f
);
6695 DECL_CONTEXT (new_f
) = type
;
6696 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &tcctx
->cb
);
6697 TREE_CHAIN (new_f
) = new_fields
;
6698 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
6699 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
6700 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
6703 *pointer_map_insert (tcctx
->cb
.decl_map
, f
) = new_f
;
6705 TYPE_FIELDS (type
) = nreverse (new_fields
);
6710 /* Create task copyfn. */
6713 create_task_copyfn (gimple task_stmt
, omp_context
*ctx
)
6715 struct function
*child_cfun
;
6716 tree child_fn
, t
, c
, src
, dst
, f
, sf
, arg
, sarg
, decl
;
6717 tree record_type
, srecord_type
, bind
, list
;
6718 bool record_needs_remap
= false, srecord_needs_remap
= false;
6720 struct omp_taskcopy_context tcctx
;
6721 struct gimplify_ctx gctx
;
6722 location_t loc
= gimple_location (task_stmt
);
6724 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
6725 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
6726 gcc_assert (child_cfun
->cfg
== NULL
);
6727 DECL_SAVED_TREE (child_fn
) = alloc_stmt_list ();
6729 /* Reset DECL_CONTEXT on function arguments. */
6730 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
6731 DECL_CONTEXT (t
) = child_fn
;
6733 /* Populate the function. */
6734 push_gimplify_context (&gctx
);
6735 push_cfun (child_cfun
);
6737 bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
6738 TREE_SIDE_EFFECTS (bind
) = 1;
6740 DECL_SAVED_TREE (child_fn
) = bind
;
6741 DECL_SOURCE_LOCATION (child_fn
) = gimple_location (task_stmt
);
6743 /* Remap src and dst argument types if needed. */
6744 record_type
= ctx
->record_type
;
6745 srecord_type
= ctx
->srecord_type
;
6746 for (f
= TYPE_FIELDS (record_type
); f
; f
= DECL_CHAIN (f
))
6747 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
6749 record_needs_remap
= true;
6752 for (f
= TYPE_FIELDS (srecord_type
); f
; f
= DECL_CHAIN (f
))
6753 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
6755 srecord_needs_remap
= true;
6759 if (record_needs_remap
|| srecord_needs_remap
)
6761 memset (&tcctx
, '\0', sizeof (tcctx
));
6762 tcctx
.cb
.src_fn
= ctx
->cb
.src_fn
;
6763 tcctx
.cb
.dst_fn
= child_fn
;
6764 tcctx
.cb
.src_node
= cgraph_get_node (tcctx
.cb
.src_fn
);
6765 gcc_checking_assert (tcctx
.cb
.src_node
);
6766 tcctx
.cb
.dst_node
= tcctx
.cb
.src_node
;
6767 tcctx
.cb
.src_cfun
= ctx
->cb
.src_cfun
;
6768 tcctx
.cb
.copy_decl
= task_copyfn_copy_decl
;
6769 tcctx
.cb
.eh_lp_nr
= 0;
6770 tcctx
.cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
6771 tcctx
.cb
.decl_map
= pointer_map_create ();
6774 if (record_needs_remap
)
6775 record_type
= task_copyfn_remap_type (&tcctx
, record_type
);
6776 if (srecord_needs_remap
)
6777 srecord_type
= task_copyfn_remap_type (&tcctx
, srecord_type
);
6780 tcctx
.cb
.decl_map
= NULL
;
6782 arg
= DECL_ARGUMENTS (child_fn
);
6783 TREE_TYPE (arg
) = build_pointer_type (record_type
);
6784 sarg
= DECL_CHAIN (arg
);
6785 TREE_TYPE (sarg
) = build_pointer_type (srecord_type
);
6787 /* First pass: initialize temporaries used in record_type and srecord_type
6788 sizes and field offsets. */
6789 if (tcctx
.cb
.decl_map
)
6790 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6791 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
6795 decl
= OMP_CLAUSE_DECL (c
);
6796 p
= (tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, decl
);
6799 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6800 sf
= (tree
) n
->value
;
6801 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6802 src
= build_simple_mem_ref_loc (loc
, sarg
);
6803 src
= omp_build_component_ref (src
, sf
);
6804 t
= build2 (MODIFY_EXPR
, TREE_TYPE (*p
), *p
, src
);
6805 append_to_statement_list (t
, &list
);
6808 /* Second pass: copy shared var pointers and copy construct non-VLA
6809 firstprivate vars. */
6810 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6811 switch (OMP_CLAUSE_CODE (c
))
6813 case OMP_CLAUSE_SHARED
:
6814 decl
= OMP_CLAUSE_DECL (c
);
6815 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6818 f
= (tree
) n
->value
;
6819 if (tcctx
.cb
.decl_map
)
6820 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6821 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6822 sf
= (tree
) n
->value
;
6823 if (tcctx
.cb
.decl_map
)
6824 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6825 src
= build_simple_mem_ref_loc (loc
, sarg
);
6826 src
= omp_build_component_ref (src
, sf
);
6827 dst
= build_simple_mem_ref_loc (loc
, arg
);
6828 dst
= omp_build_component_ref (dst
, f
);
6829 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
6830 append_to_statement_list (t
, &list
);
6832 case OMP_CLAUSE_FIRSTPRIVATE
:
6833 decl
= OMP_CLAUSE_DECL (c
);
6834 if (is_variable_sized (decl
))
6836 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6839 f
= (tree
) n
->value
;
6840 if (tcctx
.cb
.decl_map
)
6841 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6842 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6845 sf
= (tree
) n
->value
;
6846 if (tcctx
.cb
.decl_map
)
6847 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6848 src
= build_simple_mem_ref_loc (loc
, sarg
);
6849 src
= omp_build_component_ref (src
, sf
);
6850 if (use_pointer_for_field (decl
, NULL
) || is_reference (decl
))
6851 src
= build_simple_mem_ref_loc (loc
, src
);
6855 dst
= build_simple_mem_ref_loc (loc
, arg
);
6856 dst
= omp_build_component_ref (dst
, f
);
6857 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
6858 append_to_statement_list (t
, &list
);
6860 case OMP_CLAUSE_PRIVATE
:
6861 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
6863 decl
= OMP_CLAUSE_DECL (c
);
6864 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6865 f
= (tree
) n
->value
;
6866 if (tcctx
.cb
.decl_map
)
6867 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6868 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6871 sf
= (tree
) n
->value
;
6872 if (tcctx
.cb
.decl_map
)
6873 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6874 src
= build_simple_mem_ref_loc (loc
, sarg
);
6875 src
= omp_build_component_ref (src
, sf
);
6876 if (use_pointer_for_field (decl
, NULL
))
6877 src
= build_simple_mem_ref_loc (loc
, src
);
6881 dst
= build_simple_mem_ref_loc (loc
, arg
);
6882 dst
= omp_build_component_ref (dst
, f
);
6883 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
6884 append_to_statement_list (t
, &list
);
6890 /* Last pass: handle VLA firstprivates. */
6891 if (tcctx
.cb
.decl_map
)
6892 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6893 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
6897 decl
= OMP_CLAUSE_DECL (c
);
6898 if (!is_variable_sized (decl
))
6900 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6903 f
= (tree
) n
->value
;
6904 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6905 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl
));
6906 ind
= DECL_VALUE_EXPR (decl
);
6907 gcc_assert (TREE_CODE (ind
) == INDIRECT_REF
);
6908 gcc_assert (DECL_P (TREE_OPERAND (ind
, 0)));
6909 n
= splay_tree_lookup (ctx
->sfield_map
,
6910 (splay_tree_key
) TREE_OPERAND (ind
, 0));
6911 sf
= (tree
) n
->value
;
6912 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6913 src
= build_simple_mem_ref_loc (loc
, sarg
);
6914 src
= omp_build_component_ref (src
, sf
);
6915 src
= build_simple_mem_ref_loc (loc
, src
);
6916 dst
= build_simple_mem_ref_loc (loc
, arg
);
6917 dst
= omp_build_component_ref (dst
, f
);
6918 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
6919 append_to_statement_list (t
, &list
);
6920 n
= splay_tree_lookup (ctx
->field_map
,
6921 (splay_tree_key
) TREE_OPERAND (ind
, 0));
6922 df
= (tree
) n
->value
;
6923 df
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, df
);
6924 ptr
= build_simple_mem_ref_loc (loc
, arg
);
6925 ptr
= omp_build_component_ref (ptr
, df
);
6926 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ptr
), ptr
,
6927 build_fold_addr_expr_loc (loc
, dst
));
6928 append_to_statement_list (t
, &list
);
6931 t
= build1 (RETURN_EXPR
, void_type_node
, NULL
);
6932 append_to_statement_list (t
, &list
);
6934 if (tcctx
.cb
.decl_map
)
6935 pointer_map_destroy (tcctx
.cb
.decl_map
);
6936 pop_gimplify_context (NULL
);
6937 BIND_EXPR_BODY (bind
) = list
;
6941 /* Lower the OpenMP parallel or task directive in the current statement
6942 in GSI_P. CTX holds context information for the directive. */
6945 lower_omp_taskreg (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6949 gimple stmt
= gsi_stmt (*gsi_p
);
6950 gimple par_bind
, bind
;
6951 gimple_seq par_body
, olist
, ilist
, par_olist
, par_ilist
, new_body
;
6952 struct gimplify_ctx gctx
;
6953 location_t loc
= gimple_location (stmt
);
6955 clauses
= gimple_omp_taskreg_clauses (stmt
);
6956 par_bind
= gimple_seq_first_stmt (gimple_omp_body (stmt
));
6957 par_body
= gimple_bind_body (par_bind
);
6958 child_fn
= ctx
->cb
.dst_fn
;
6959 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
6960 && !gimple_omp_parallel_combined_p (stmt
))
6962 struct walk_stmt_info wi
;
6965 memset (&wi
, 0, sizeof (wi
));
6968 walk_gimple_seq (par_body
, check_combined_parallel
, NULL
, &wi
);
6970 gimple_omp_parallel_set_combined_p (stmt
, true);
6972 if (ctx
->srecord_type
)
6973 create_task_copyfn (stmt
, ctx
);
6975 push_gimplify_context (&gctx
);
6979 lower_rec_input_clauses (clauses
, &par_ilist
, &par_olist
, ctx
);
6980 lower_omp (&par_body
, ctx
);
6981 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
)
6982 lower_reduction_clauses (clauses
, &par_olist
, ctx
);
6984 /* Declare all the variables created by mapping and the variables
6985 declared in the scope of the parallel body. */
6986 record_vars_into (ctx
->block_vars
, child_fn
);
6987 record_vars_into (gimple_bind_vars (par_bind
), child_fn
);
6989 if (ctx
->record_type
)
6992 = create_tmp_var (ctx
->srecord_type
? ctx
->srecord_type
6993 : ctx
->record_type
, ".omp_data_o");
6994 DECL_NAMELESS (ctx
->sender_decl
) = 1;
6995 TREE_ADDRESSABLE (ctx
->sender_decl
) = 1;
6996 gimple_omp_taskreg_set_data_arg (stmt
, ctx
->sender_decl
);
7001 lower_send_clauses (clauses
, &ilist
, &olist
, ctx
);
7002 lower_send_shared_vars (&ilist
, &olist
, ctx
);
7004 /* Once all the expansions are done, sequence all the different
7005 fragments inside gimple_omp_body. */
7009 if (ctx
->record_type
)
7011 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
7012 /* fixup_child_record_type might have changed receiver_decl's type. */
7013 t
= fold_convert_loc (loc
, TREE_TYPE (ctx
->receiver_decl
), t
);
7014 gimple_seq_add_stmt (&new_body
,
7015 gimple_build_assign (ctx
->receiver_decl
, t
));
7018 gimple_seq_add_seq (&new_body
, par_ilist
);
7019 gimple_seq_add_seq (&new_body
, par_body
);
7020 gimple_seq_add_seq (&new_body
, par_olist
);
7021 new_body
= maybe_catch_exception (new_body
);
7022 gimple_seq_add_stmt (&new_body
, gimple_build_omp_return (false));
7023 gimple_omp_set_body (stmt
, new_body
);
7025 bind
= gimple_build_bind (NULL
, NULL
, gimple_bind_block (par_bind
));
7026 gsi_replace (gsi_p
, bind
, true);
7027 gimple_bind_add_seq (bind
, ilist
);
7028 gimple_bind_add_stmt (bind
, stmt
);
7029 gimple_bind_add_seq (bind
, olist
);
7031 pop_gimplify_context (NULL
);
7034 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
7035 regimplified. If DATA is non-NULL, lower_omp_1 is outside
7036 of OpenMP context, but with task_shared_vars set. */
7039 lower_omp_regimplify_p (tree
*tp
, int *walk_subtrees
,
7044 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
7045 if (TREE_CODE (t
) == VAR_DECL
&& data
== NULL
&& DECL_HAS_VALUE_EXPR_P (t
))
7048 if (task_shared_vars
7050 && bitmap_bit_p (task_shared_vars
, DECL_UID (t
)))
7053 /* If a global variable has been privatized, TREE_CONSTANT on
7054 ADDR_EXPR might be wrong. */
7055 if (data
== NULL
&& TREE_CODE (t
) == ADDR_EXPR
)
7056 recompute_tree_invariant_for_addr_expr (t
);
7058 *walk_subtrees
= !TYPE_P (t
) && !DECL_P (t
);
7063 lower_omp_1 (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
7065 gimple stmt
= gsi_stmt (*gsi_p
);
7066 struct walk_stmt_info wi
;
7068 if (gimple_has_location (stmt
))
7069 input_location
= gimple_location (stmt
);
7071 if (task_shared_vars
)
7072 memset (&wi
, '\0', sizeof (wi
));
7074 /* If we have issued syntax errors, avoid doing any heavy lifting.
7075 Just replace the OpenMP directives with a NOP to avoid
7076 confusing RTL expansion. */
7077 if (seen_error () && is_gimple_omp (stmt
))
7079 gsi_replace (gsi_p
, gimple_build_nop (), true);
7083 switch (gimple_code (stmt
))
7086 if ((ctx
|| task_shared_vars
)
7087 && (walk_tree (gimple_cond_lhs_ptr (stmt
), lower_omp_regimplify_p
,
7088 ctx
? NULL
: &wi
, NULL
)
7089 || walk_tree (gimple_cond_rhs_ptr (stmt
), lower_omp_regimplify_p
,
7090 ctx
? NULL
: &wi
, NULL
)))
7091 gimple_regimplify_operands (stmt
, gsi_p
);
7094 lower_omp (gimple_catch_handler_ptr (stmt
), ctx
);
7096 case GIMPLE_EH_FILTER
:
7097 lower_omp (gimple_eh_filter_failure_ptr (stmt
), ctx
);
7100 lower_omp (gimple_try_eval_ptr (stmt
), ctx
);
7101 lower_omp (gimple_try_cleanup_ptr (stmt
), ctx
);
7103 case GIMPLE_TRANSACTION
:
7104 lower_omp (gimple_transaction_body_ptr (stmt
), ctx
);
7107 lower_omp (gimple_bind_body_ptr (stmt
), ctx
);
7109 case GIMPLE_OMP_PARALLEL
:
7110 case GIMPLE_OMP_TASK
:
7111 ctx
= maybe_lookup_ctx (stmt
);
7112 lower_omp_taskreg (gsi_p
, ctx
);
7114 case GIMPLE_OMP_FOR
:
7115 ctx
= maybe_lookup_ctx (stmt
);
7117 lower_omp_for (gsi_p
, ctx
);
7119 case GIMPLE_OMP_SECTIONS
:
7120 ctx
= maybe_lookup_ctx (stmt
);
7122 lower_omp_sections (gsi_p
, ctx
);
7124 case GIMPLE_OMP_SINGLE
:
7125 ctx
= maybe_lookup_ctx (stmt
);
7127 lower_omp_single (gsi_p
, ctx
);
7129 case GIMPLE_OMP_MASTER
:
7130 ctx
= maybe_lookup_ctx (stmt
);
7132 lower_omp_master (gsi_p
, ctx
);
7134 case GIMPLE_OMP_ORDERED
:
7135 ctx
= maybe_lookup_ctx (stmt
);
7137 lower_omp_ordered (gsi_p
, ctx
);
7139 case GIMPLE_OMP_CRITICAL
:
7140 ctx
= maybe_lookup_ctx (stmt
);
7142 lower_omp_critical (gsi_p
, ctx
);
7144 case GIMPLE_OMP_ATOMIC_LOAD
:
7145 if ((ctx
|| task_shared_vars
)
7146 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt
),
7147 lower_omp_regimplify_p
, ctx
? NULL
: &wi
, NULL
))
7148 gimple_regimplify_operands (stmt
, gsi_p
);
7151 if ((ctx
|| task_shared_vars
)
7152 && walk_gimple_op (stmt
, lower_omp_regimplify_p
,
7154 gimple_regimplify_operands (stmt
, gsi_p
);
7160 lower_omp (gimple_seq
*body
, omp_context
*ctx
)
7162 location_t saved_location
= input_location
;
7163 gimple_stmt_iterator gsi
;
7164 for (gsi
= gsi_start (*body
); !gsi_end_p (gsi
); gsi_next (&gsi
))
7165 lower_omp_1 (&gsi
, ctx
);
7166 input_location
= saved_location
;
7169 /* Main entry point. */
7172 execute_lower_omp (void)
7178 /* This pass always runs, to provide PROP_gimple_lomp.
7179 But there is nothing to do unless -fopenmp is given. */
7180 if (flag_openmp
== 0)
7183 all_contexts
= splay_tree_new (splay_tree_compare_pointers
, 0,
7184 delete_omp_context
);
7186 body
= gimple_body (current_function_decl
);
7187 scan_omp (&body
, NULL
);
7188 gcc_assert (taskreg_nesting_level
== 0);
7189 FOR_EACH_VEC_ELT (taskreg_contexts
, i
, ctx
)
7190 finish_taskreg_scan (ctx
);
7191 taskreg_contexts
.release ();
7193 if (all_contexts
->root
)
7195 struct gimplify_ctx gctx
;
7197 if (task_shared_vars
)
7198 push_gimplify_context (&gctx
);
7199 lower_omp (&body
, NULL
);
7200 if (task_shared_vars
)
7201 pop_gimplify_context (NULL
);
7206 splay_tree_delete (all_contexts
);
7207 all_contexts
= NULL
;
7209 BITMAP_FREE (task_shared_vars
);
7213 struct gimple_opt_pass pass_lower_omp
=
7217 "omplower", /* name */
7218 OPTGROUP_NONE
, /* optinfo_flags */
7220 execute_lower_omp
, /* execute */
7223 0, /* static_pass_number */
7224 TV_NONE
, /* tv_id */
7225 PROP_gimple_any
, /* properties_required */
7226 PROP_gimple_lomp
, /* properties_provided */
7227 0, /* properties_destroyed */
7228 0, /* todo_flags_start */
7229 0 /* todo_flags_finish */
7233 /* The following is a utility to diagnose OpenMP structured block violations.
7234 It is not part of the "omplower" pass, as that's invoked too late. It
7235 should be invoked by the respective front ends after gimplification. */
7237 static splay_tree all_labels
;
7239 /* Check for mismatched contexts and generate an error if needed. Return
7240 true if an error is detected. */
7243 diagnose_sb_0 (gimple_stmt_iterator
*gsi_p
,
7244 gimple branch_ctx
, gimple label_ctx
)
7246 if (label_ctx
== branch_ctx
)
7251 Previously we kept track of the label's entire context in diagnose_sb_[12]
7252 so we could traverse it and issue a correct "exit" or "enter" error
7253 message upon a structured block violation.
7255 We built the context by building a list with tree_cons'ing, but there is
7256 no easy counterpart in gimple tuples. It seems like far too much work
7257 for issuing exit/enter error messages. If someone really misses the
7258 distinct error message... patches welcome.
7262 /* Try to avoid confusing the user by producing and error message
7263 with correct "exit" or "enter" verbiage. We prefer "exit"
7264 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
7265 if (branch_ctx
== NULL
)
7271 if (TREE_VALUE (label_ctx
) == branch_ctx
)
7276 label_ctx
= TREE_CHAIN (label_ctx
);
7281 error ("invalid exit from OpenMP structured block");
7283 error ("invalid entry to OpenMP structured block");
7286 /* If it's obvious we have an invalid entry, be specific about the error. */
7287 if (branch_ctx
== NULL
)
7288 error ("invalid entry to OpenMP structured block");
7290 /* Otherwise, be vague and lazy, but efficient. */
7291 error ("invalid branch to/from an OpenMP structured block");
7293 gsi_replace (gsi_p
, gimple_build_nop (), false);
7297 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7298 where each label is found. */
7301 diagnose_sb_1 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
7302 struct walk_stmt_info
*wi
)
7304 gimple context
= (gimple
) wi
->info
;
7305 gimple inner_context
;
7306 gimple stmt
= gsi_stmt (*gsi_p
);
7308 *handled_ops_p
= true;
7310 switch (gimple_code (stmt
))
7314 case GIMPLE_OMP_PARALLEL
:
7315 case GIMPLE_OMP_TASK
:
7316 case GIMPLE_OMP_SECTIONS
:
7317 case GIMPLE_OMP_SINGLE
:
7318 case GIMPLE_OMP_SECTION
:
7319 case GIMPLE_OMP_MASTER
:
7320 case GIMPLE_OMP_ORDERED
:
7321 case GIMPLE_OMP_CRITICAL
:
7322 /* The minimal context here is just the current OMP construct. */
7323 inner_context
= stmt
;
7324 wi
->info
= inner_context
;
7325 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
7329 case GIMPLE_OMP_FOR
:
7330 inner_context
= stmt
;
7331 wi
->info
= inner_context
;
7332 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7334 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
7335 diagnose_sb_1
, NULL
, wi
);
7336 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
7341 splay_tree_insert (all_labels
, (splay_tree_key
) gimple_label_label (stmt
),
7342 (splay_tree_value
) context
);
7352 /* Pass 2: Check each branch and see if its context differs from that of
7353 the destination label's context. */
7356 diagnose_sb_2 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
7357 struct walk_stmt_info
*wi
)
7359 gimple context
= (gimple
) wi
->info
;
7361 gimple stmt
= gsi_stmt (*gsi_p
);
7363 *handled_ops_p
= true;
7365 switch (gimple_code (stmt
))
7369 case GIMPLE_OMP_PARALLEL
:
7370 case GIMPLE_OMP_TASK
:
7371 case GIMPLE_OMP_SECTIONS
:
7372 case GIMPLE_OMP_SINGLE
:
7373 case GIMPLE_OMP_SECTION
:
7374 case GIMPLE_OMP_MASTER
:
7375 case GIMPLE_OMP_ORDERED
:
7376 case GIMPLE_OMP_CRITICAL
:
7378 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt
), diagnose_sb_2
, NULL
, wi
);
7382 case GIMPLE_OMP_FOR
:
7384 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7386 walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt
),
7387 diagnose_sb_2
, NULL
, wi
);
7388 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt
), diagnose_sb_2
, NULL
, wi
);
7394 tree lab
= gimple_cond_true_label (stmt
);
7397 n
= splay_tree_lookup (all_labels
,
7398 (splay_tree_key
) lab
);
7399 diagnose_sb_0 (gsi_p
, context
,
7400 n
? (gimple
) n
->value
: NULL
);
7402 lab
= gimple_cond_false_label (stmt
);
7405 n
= splay_tree_lookup (all_labels
,
7406 (splay_tree_key
) lab
);
7407 diagnose_sb_0 (gsi_p
, context
,
7408 n
? (gimple
) n
->value
: NULL
);
7415 tree lab
= gimple_goto_dest (stmt
);
7416 if (TREE_CODE (lab
) != LABEL_DECL
)
7419 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
7420 diagnose_sb_0 (gsi_p
, context
, n
? (gimple
) n
->value
: NULL
);
7427 for (i
= 0; i
< gimple_switch_num_labels (stmt
); ++i
)
7429 tree lab
= CASE_LABEL (gimple_switch_label (stmt
, i
));
7430 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
7431 if (n
&& diagnose_sb_0 (gsi_p
, context
, (gimple
) n
->value
))
7438 diagnose_sb_0 (gsi_p
, context
, NULL
);
7449 diagnose_omp_structured_block_errors (void)
7451 struct walk_stmt_info wi
;
7452 gimple_seq body
= gimple_body (current_function_decl
);
7454 all_labels
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
7456 memset (&wi
, 0, sizeof (wi
));
7457 walk_gimple_seq (body
, diagnose_sb_1
, NULL
, &wi
);
7459 memset (&wi
, 0, sizeof (wi
));
7460 wi
.want_locations
= true;
7461 walk_gimple_seq_mod (&body
, diagnose_sb_2
, NULL
, &wi
);
7463 gimple_set_body (current_function_decl
, body
);
7465 splay_tree_delete (all_labels
);
7472 gate_diagnose_omp_blocks (void)
7474 return flag_openmp
!= 0;
7477 struct gimple_opt_pass pass_diagnose_omp_blocks
=
7481 "*diagnose_omp_blocks", /* name */
7482 OPTGROUP_NONE
, /* optinfo_flags */
7483 gate_diagnose_omp_blocks
, /* gate */
7484 diagnose_omp_structured_block_errors
, /* execute */
7487 0, /* static_pass_number */
7488 TV_NONE
, /* tv_id */
7489 PROP_gimple_any
, /* properties_required */
7490 0, /* properties_provided */
7491 0, /* properties_destroyed */
7492 0, /* todo_flags_start */
7493 0, /* todo_flags_finish */
7497 #include "gt-omp-low.h"