1 /* Lowering pass for OpenMP directives. Converts OpenMP directives
2 into explicit calls to the runtime library (libgomp) and data
3 marshalling to implement data sharing and copying clauses.
4 Contributed by Diego Novillo <dnovillo@redhat.com>
6 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
7 Free Software Foundation, Inc.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
27 #include "coretypes.h"
32 #include "tree-iterator.h"
33 #include "tree-inline.h"
34 #include "langhooks.h"
35 #include "diagnostic-core.h"
36 #include "tree-flow.h"
40 #include "tree-pass.h"
43 #include "splay-tree.h"
48 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
49 phases. The first phase scans the function looking for OMP statements
50 and then for variables that must be replaced to satisfy data sharing
51 clauses. The second phase expands code for the constructs, as well as
52 re-gimplifying things when variables have been replaced with complex
55 Final code generation is done by pass_expand_omp. The flowgraph is
56 scanned for parallel regions which are then moved to a new
57 function, to be invoked by the thread library. */
59 /* Context structure. Used to store information about each parallel
60 directive in the code. */
62 typedef struct omp_context
64 /* This field must be at the beginning, as we do "inheritance": Some
65 callback functions for tree-inline.c (e.g., omp_copy_decl)
66 receive a copy_body_data pointer that is up-casted to an
67 omp_context pointer. */
70 /* The tree of contexts corresponding to the encountered constructs. */
71 struct omp_context
*outer
;
74 /* Map variables to fields in a structure that allows communication
75 between sending and receiving threads. */
81 /* These are used just by task contexts, if task firstprivate fn is
82 needed. srecord_type is used to communicate from the thread
83 that encountered the task construct to task firstprivate fn,
84 record_type is allocated by GOMP_task, initialized by task firstprivate
85 fn and passed to the task body fn. */
86 splay_tree sfield_map
;
89 /* A chain of variables to add to the top-level block surrounding the
90 construct. In the case of a parallel, this is in the child function. */
93 /* What to do with variables with implicitly determined sharing
95 enum omp_clause_default_kind default_kind
;
97 /* Nesting depth of this context. Used to beautify error messages re
98 invalid gotos. The outermost ctx is depth 1, with depth 0 being
99 reserved for the main body of the function. */
102 /* True if this parallel directive is nested within another. */
107 struct omp_for_data_loop
109 tree v
, n1
, n2
, step
;
110 enum tree_code cond_code
;
113 /* A structure describing the main elements of a parallel loop. */
117 struct omp_for_data_loop loop
;
122 bool have_nowait
, have_ordered
;
123 enum omp_clause_schedule_kind sched_kind
;
124 struct omp_for_data_loop
*loops
;
128 static splay_tree all_contexts
;
129 static int taskreg_nesting_level
;
130 struct omp_region
*root_omp_region
;
131 static bitmap task_shared_vars
;
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 if ((i
== 0 || count
!= NULL_TREE
)
403 && TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
404 && TREE_CONSTANT (loop
->n1
)
405 && TREE_CONSTANT (loop
->n2
)
406 && TREE_CODE (loop
->step
) == INTEGER_CST
)
408 tree itype
= TREE_TYPE (loop
->v
);
410 if (POINTER_TYPE_P (itype
))
411 itype
= signed_type_for (itype
);
412 t
= build_int_cst (itype
, (loop
->cond_code
== LT_EXPR
? -1 : 1));
413 t
= fold_build2_loc (loc
,
415 fold_convert_loc (loc
, itype
, loop
->step
), t
);
416 t
= fold_build2_loc (loc
, PLUS_EXPR
, itype
, t
,
417 fold_convert_loc (loc
, itype
, loop
->n2
));
418 t
= fold_build2_loc (loc
, MINUS_EXPR
, itype
, t
,
419 fold_convert_loc (loc
, itype
, loop
->n1
));
420 if (TYPE_UNSIGNED (itype
) && loop
->cond_code
== GT_EXPR
)
421 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
,
422 fold_build1_loc (loc
, NEGATE_EXPR
, itype
, t
),
423 fold_build1_loc (loc
, NEGATE_EXPR
, itype
,
424 fold_convert_loc (loc
, itype
,
427 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
, t
,
428 fold_convert_loc (loc
, itype
, loop
->step
));
429 t
= fold_convert_loc (loc
, long_long_unsigned_type_node
, t
);
430 if (count
!= NULL_TREE
)
431 count
= fold_build2_loc (loc
,
432 MULT_EXPR
, long_long_unsigned_type_node
,
436 if (TREE_CODE (count
) != INTEGER_CST
)
446 if (!tree_int_cst_lt (count
, TYPE_MAX_VALUE (long_integer_type_node
)))
447 iter_type
= long_long_unsigned_type_node
;
449 iter_type
= long_integer_type_node
;
451 else if (collapse_iter
&& *collapse_iter
!= NULL
)
452 iter_type
= TREE_TYPE (*collapse_iter
);
453 fd
->iter_type
= iter_type
;
454 if (collapse_iter
&& *collapse_iter
== NULL
)
455 *collapse_iter
= create_tmp_var (iter_type
, ".iter");
456 if (collapse_count
&& *collapse_count
== NULL
)
459 *collapse_count
= fold_convert_loc (loc
, iter_type
, count
);
461 *collapse_count
= create_tmp_var (iter_type
, ".count");
464 if (fd
->collapse
> 1)
466 fd
->loop
.v
= *collapse_iter
;
467 fd
->loop
.n1
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
468 fd
->loop
.n2
= *collapse_count
;
469 fd
->loop
.step
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 1);
470 fd
->loop
.cond_code
= LT_EXPR
;
475 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
476 is the immediate dominator of PAR_ENTRY_BB, return true if there
477 are no data dependencies that would prevent expanding the parallel
478 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
480 When expanding a combined parallel+workshare region, the call to
481 the child function may need additional arguments in the case of
482 GIMPLE_OMP_FOR regions. In some cases, these arguments are
483 computed out of variables passed in from the parent to the child
484 via 'struct .omp_data_s'. For instance:
486 #pragma omp parallel for schedule (guided, i * 4)
491 # BLOCK 2 (PAR_ENTRY_BB)
493 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
495 # BLOCK 3 (WS_ENTRY_BB)
496 .omp_data_i = &.omp_data_o;
497 D.1667 = .omp_data_i->i;
499 #pragma omp for schedule (guided, D.1598)
501 When we outline the parallel region, the call to the child function
502 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
503 that value is computed *after* the call site. So, in principle we
504 cannot do the transformation.
506 To see whether the code in WS_ENTRY_BB blocks the combined
507 parallel+workshare call, we collect all the variables used in the
508 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
509 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
512 FIXME. If we had the SSA form built at this point, we could merely
513 hoist the code in block 3 into block 2 and be done with it. But at
514 this point we don't have dataflow information and though we could
515 hack something up here, it is really not worth the aggravation. */
518 workshare_safe_to_combine_p (basic_block ws_entry_bb
)
520 struct omp_for_data fd
;
521 gimple ws_stmt
= last_stmt (ws_entry_bb
);
523 if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
526 gcc_assert (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
);
528 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
530 if (fd
.collapse
> 1 && TREE_CODE (fd
.loop
.n2
) != INTEGER_CST
)
532 if (fd
.iter_type
!= long_integer_type_node
)
535 /* FIXME. We give up too easily here. If any of these arguments
536 are not constants, they will likely involve variables that have
537 been mapped into fields of .omp_data_s for sharing with the child
538 function. With appropriate data flow, it would be possible to
540 if (!is_gimple_min_invariant (fd
.loop
.n1
)
541 || !is_gimple_min_invariant (fd
.loop
.n2
)
542 || !is_gimple_min_invariant (fd
.loop
.step
)
543 || (fd
.chunk_size
&& !is_gimple_min_invariant (fd
.chunk_size
)))
550 /* Collect additional arguments needed to emit a combined
551 parallel+workshare call. WS_STMT is the workshare directive being
554 static VEC(tree
,gc
) *
555 get_ws_args_for (gimple ws_stmt
)
558 location_t loc
= gimple_location (ws_stmt
);
559 VEC(tree
,gc
) *ws_args
;
561 if (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
)
563 struct omp_for_data fd
;
565 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
567 ws_args
= VEC_alloc (tree
, gc
, 3 + (fd
.chunk_size
!= 0));
569 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.n1
);
570 VEC_quick_push (tree
, ws_args
, t
);
572 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.n2
);
573 VEC_quick_push (tree
, ws_args
, t
);
575 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.step
);
576 VEC_quick_push (tree
, ws_args
, t
);
580 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.chunk_size
);
581 VEC_quick_push (tree
, ws_args
, t
);
586 else if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
588 /* Number of sections is equal to the number of edges from the
589 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
590 the exit of the sections region. */
591 basic_block bb
= single_succ (gimple_bb (ws_stmt
));
592 t
= build_int_cst (unsigned_type_node
, EDGE_COUNT (bb
->succs
) - 1);
593 ws_args
= VEC_alloc (tree
, gc
, 1);
594 VEC_quick_push (tree
, ws_args
, t
);
602 /* Discover whether REGION is a combined parallel+workshare region. */
605 determine_parallel_type (struct omp_region
*region
)
607 basic_block par_entry_bb
, par_exit_bb
;
608 basic_block ws_entry_bb
, ws_exit_bb
;
610 if (region
== NULL
|| region
->inner
== NULL
611 || region
->exit
== NULL
|| region
->inner
->exit
== NULL
612 || region
->inner
->cont
== NULL
)
615 /* We only support parallel+for and parallel+sections. */
616 if (region
->type
!= GIMPLE_OMP_PARALLEL
617 || (region
->inner
->type
!= GIMPLE_OMP_FOR
618 && region
->inner
->type
!= GIMPLE_OMP_SECTIONS
))
621 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
622 WS_EXIT_BB -> PAR_EXIT_BB. */
623 par_entry_bb
= region
->entry
;
624 par_exit_bb
= region
->exit
;
625 ws_entry_bb
= region
->inner
->entry
;
626 ws_exit_bb
= region
->inner
->exit
;
628 if (single_succ (par_entry_bb
) == ws_entry_bb
629 && single_succ (ws_exit_bb
) == par_exit_bb
630 && workshare_safe_to_combine_p (ws_entry_bb
)
631 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb
))
632 || (last_and_only_stmt (ws_entry_bb
)
633 && last_and_only_stmt (par_exit_bb
))))
635 gimple ws_stmt
= last_stmt (ws_entry_bb
);
637 if (region
->inner
->type
== GIMPLE_OMP_FOR
)
639 /* If this is a combined parallel loop, we need to determine
640 whether or not to use the combined library calls. There
641 are two cases where we do not apply the transformation:
642 static loops and any kind of ordered loop. In the first
643 case, we already open code the loop so there is no need
644 to do anything else. In the latter case, the combined
645 parallel loop call would still need extra synchronization
646 to implement ordered semantics, so there would not be any
647 gain in using the combined call. */
648 tree clauses
= gimple_omp_for_clauses (ws_stmt
);
649 tree c
= find_omp_clause (clauses
, OMP_CLAUSE_SCHEDULE
);
651 || OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_STATIC
652 || find_omp_clause (clauses
, OMP_CLAUSE_ORDERED
))
654 region
->is_combined_parallel
= false;
655 region
->inner
->is_combined_parallel
= false;
660 region
->is_combined_parallel
= true;
661 region
->inner
->is_combined_parallel
= true;
662 region
->ws_args
= get_ws_args_for (ws_stmt
);
667 /* Return true if EXPR is variable sized. */
670 is_variable_sized (const_tree expr
)
672 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr
)));
675 /* Return true if DECL is a reference type. */
678 is_reference (tree decl
)
680 return lang_hooks
.decls
.omp_privatize_by_reference (decl
);
683 /* Lookup variables in the decl or field splay trees. The "maybe" form
684 allows for the variable form to not have been entered, otherwise we
685 assert that the variable must have been entered. */
688 lookup_decl (tree var
, omp_context
*ctx
)
691 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
696 maybe_lookup_decl (const_tree var
, omp_context
*ctx
)
699 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
700 return n
? *n
: NULL_TREE
;
704 lookup_field (tree var
, omp_context
*ctx
)
707 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
708 return (tree
) n
->value
;
712 lookup_sfield (tree var
, omp_context
*ctx
)
715 n
= splay_tree_lookup (ctx
->sfield_map
716 ? ctx
->sfield_map
: ctx
->field_map
,
717 (splay_tree_key
) var
);
718 return (tree
) n
->value
;
722 maybe_lookup_field (tree var
, omp_context
*ctx
)
725 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
726 return n
? (tree
) n
->value
: NULL_TREE
;
729 /* Return true if DECL should be copied by pointer. SHARED_CTX is
730 the parallel context if DECL is to be shared. */
733 use_pointer_for_field (tree decl
, omp_context
*shared_ctx
)
735 if (AGGREGATE_TYPE_P (TREE_TYPE (decl
)))
738 /* We can only use copy-in/copy-out semantics for shared variables
739 when we know the value is not accessible from an outer scope. */
742 /* ??? Trivially accessible from anywhere. But why would we even
743 be passing an address in this case? Should we simply assert
744 this to be false, or should we have a cleanup pass that removes
745 these from the list of mappings? */
746 if (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
749 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
750 without analyzing the expression whether or not its location
751 is accessible to anyone else. In the case of nested parallel
752 regions it certainly may be. */
753 if (TREE_CODE (decl
) != RESULT_DECL
&& DECL_HAS_VALUE_EXPR_P (decl
))
756 /* Do not use copy-in/copy-out for variables that have their
758 if (TREE_ADDRESSABLE (decl
))
761 /* Disallow copy-in/out in nested parallel if
762 decl is shared in outer parallel, otherwise
763 each thread could store the shared variable
764 in its own copy-in location, making the
765 variable no longer really shared. */
766 if (!TREE_READONLY (decl
) && shared_ctx
->is_nested
)
770 for (up
= shared_ctx
->outer
; up
; up
= up
->outer
)
771 if (is_taskreg_ctx (up
) && maybe_lookup_decl (decl
, up
))
778 for (c
= gimple_omp_taskreg_clauses (up
->stmt
);
779 c
; c
= OMP_CLAUSE_CHAIN (c
))
780 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
781 && OMP_CLAUSE_DECL (c
) == decl
)
785 goto maybe_mark_addressable_and_ret
;
789 /* For tasks avoid using copy-in/out, unless they are readonly
790 (in which case just copy-in is used). As tasks can be
791 deferred or executed in different thread, when GOMP_task
792 returns, the task hasn't necessarily terminated. */
793 if (!TREE_READONLY (decl
) && is_task_ctx (shared_ctx
))
796 maybe_mark_addressable_and_ret
:
797 outer
= maybe_lookup_decl_in_outer_ctx (decl
, shared_ctx
);
798 if (is_gimple_reg (outer
))
800 /* Taking address of OUTER in lower_send_shared_vars
801 might need regimplification of everything that uses the
803 if (!task_shared_vars
)
804 task_shared_vars
= BITMAP_ALLOC (NULL
);
805 bitmap_set_bit (task_shared_vars
, DECL_UID (outer
));
806 TREE_ADDRESSABLE (outer
) = 1;
815 /* Create a new VAR_DECL and copy information from VAR to it. */
818 copy_var_decl (tree var
, tree name
, tree type
)
820 tree copy
= build_decl (DECL_SOURCE_LOCATION (var
), VAR_DECL
, name
, type
);
822 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (var
);
823 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (var
);
824 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (var
);
825 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (var
);
826 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (var
);
827 DECL_CONTEXT (copy
) = DECL_CONTEXT (var
);
828 TREE_USED (copy
) = 1;
829 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
834 /* Construct a new automatic decl similar to VAR. */
837 omp_copy_decl_2 (tree var
, tree name
, tree type
, omp_context
*ctx
)
839 tree copy
= copy_var_decl (var
, name
, type
);
841 DECL_CONTEXT (copy
) = current_function_decl
;
842 DECL_CHAIN (copy
) = ctx
->block_vars
;
843 ctx
->block_vars
= copy
;
849 omp_copy_decl_1 (tree var
, omp_context
*ctx
)
851 return omp_copy_decl_2 (var
, DECL_NAME (var
), TREE_TYPE (var
), ctx
);
854 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
857 omp_build_component_ref (tree obj
, tree field
)
859 tree ret
= build3 (COMPONENT_REF
, TREE_TYPE (field
), obj
, field
, NULL
);
860 if (TREE_THIS_VOLATILE (field
))
861 TREE_THIS_VOLATILE (ret
) |= 1;
862 if (TREE_READONLY (field
))
863 TREE_READONLY (ret
) |= 1;
867 /* Build tree nodes to access the field for VAR on the receiver side. */
870 build_receiver_ref (tree var
, bool by_ref
, omp_context
*ctx
)
872 tree x
, field
= lookup_field (var
, ctx
);
874 /* If the receiver record type was remapped in the child function,
875 remap the field into the new record type. */
876 x
= maybe_lookup_field (field
, ctx
);
880 x
= build_simple_mem_ref (ctx
->receiver_decl
);
881 x
= omp_build_component_ref (x
, field
);
883 x
= build_simple_mem_ref (x
);
888 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
889 of a parallel, this is a component reference; for workshare constructs
890 this is some variable. */
893 build_outer_var_ref (tree var
, omp_context
*ctx
)
897 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
, ctx
)))
899 else if (is_variable_sized (var
))
901 x
= TREE_OPERAND (DECL_VALUE_EXPR (var
), 0);
902 x
= build_outer_var_ref (x
, ctx
);
903 x
= build_simple_mem_ref (x
);
905 else if (is_taskreg_ctx (ctx
))
907 bool by_ref
= use_pointer_for_field (var
, NULL
);
908 x
= build_receiver_ref (var
, by_ref
, ctx
);
911 x
= lookup_decl (var
, ctx
->outer
);
912 else if (is_reference (var
))
913 /* This can happen with orphaned constructs. If var is reference, it is
914 possible it is shared and as such valid. */
919 if (is_reference (var
))
920 x
= build_simple_mem_ref (x
);
925 /* Build tree nodes to access the field for VAR on the sender side. */
928 build_sender_ref (tree var
, omp_context
*ctx
)
930 tree field
= lookup_sfield (var
, ctx
);
931 return omp_build_component_ref (ctx
->sender_decl
, field
);
934 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
937 install_var_field (tree var
, bool by_ref
, int mask
, omp_context
*ctx
)
939 tree field
, type
, sfield
= NULL_TREE
;
941 gcc_assert ((mask
& 1) == 0
942 || !splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
));
943 gcc_assert ((mask
& 2) == 0 || !ctx
->sfield_map
944 || !splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) var
));
946 type
= TREE_TYPE (var
);
948 type
= build_pointer_type (type
);
949 else if ((mask
& 3) == 1 && is_reference (var
))
950 type
= TREE_TYPE (type
);
952 field
= build_decl (DECL_SOURCE_LOCATION (var
),
953 FIELD_DECL
, DECL_NAME (var
), type
);
955 /* Remember what variable this field was created for. This does have a
956 side effect of making dwarf2out ignore this member, so for helpful
957 debugging we clear it later in delete_omp_context. */
958 DECL_ABSTRACT_ORIGIN (field
) = var
;
959 if (type
== TREE_TYPE (var
))
961 DECL_ALIGN (field
) = DECL_ALIGN (var
);
962 DECL_USER_ALIGN (field
) = DECL_USER_ALIGN (var
);
963 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (var
);
966 DECL_ALIGN (field
) = TYPE_ALIGN (type
);
970 insert_field_into_struct (ctx
->record_type
, field
);
971 if (ctx
->srecord_type
)
973 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
974 FIELD_DECL
, DECL_NAME (var
), type
);
975 DECL_ABSTRACT_ORIGIN (sfield
) = var
;
976 DECL_ALIGN (sfield
) = DECL_ALIGN (field
);
977 DECL_USER_ALIGN (sfield
) = DECL_USER_ALIGN (field
);
978 TREE_THIS_VOLATILE (sfield
) = TREE_THIS_VOLATILE (field
);
979 insert_field_into_struct (ctx
->srecord_type
, sfield
);
984 if (ctx
->srecord_type
== NULL_TREE
)
988 ctx
->srecord_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
989 ctx
->sfield_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
990 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= TREE_CHAIN (t
))
992 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
993 FIELD_DECL
, DECL_NAME (t
), TREE_TYPE (t
));
994 DECL_ABSTRACT_ORIGIN (sfield
) = DECL_ABSTRACT_ORIGIN (t
);
995 insert_field_into_struct (ctx
->srecord_type
, sfield
);
996 splay_tree_insert (ctx
->sfield_map
,
997 (splay_tree_key
) DECL_ABSTRACT_ORIGIN (t
),
998 (splay_tree_value
) sfield
);
1002 insert_field_into_struct ((mask
& 1) ? ctx
->record_type
1003 : ctx
->srecord_type
, field
);
1007 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) var
,
1008 (splay_tree_value
) field
);
1009 if ((mask
& 2) && ctx
->sfield_map
)
1010 splay_tree_insert (ctx
->sfield_map
, (splay_tree_key
) var
,
1011 (splay_tree_value
) sfield
);
1015 install_var_local (tree var
, omp_context
*ctx
)
1017 tree new_var
= omp_copy_decl_1 (var
, ctx
);
1018 insert_decl_map (&ctx
->cb
, var
, new_var
);
1022 /* Adjust the replacement for DECL in CTX for the new context. This means
1023 copying the DECL_VALUE_EXPR, and fixing up the type. */
1026 fixup_remapped_decl (tree decl
, omp_context
*ctx
, bool private_debug
)
1028 tree new_decl
, size
;
1030 new_decl
= lookup_decl (decl
, ctx
);
1032 TREE_TYPE (new_decl
) = remap_type (TREE_TYPE (decl
), &ctx
->cb
);
1034 if ((!TREE_CONSTANT (DECL_SIZE (new_decl
)) || private_debug
)
1035 && DECL_HAS_VALUE_EXPR_P (decl
))
1037 tree ve
= DECL_VALUE_EXPR (decl
);
1038 walk_tree (&ve
, copy_tree_body_r
, &ctx
->cb
, NULL
);
1039 SET_DECL_VALUE_EXPR (new_decl
, ve
);
1040 DECL_HAS_VALUE_EXPR_P (new_decl
) = 1;
1043 if (!TREE_CONSTANT (DECL_SIZE (new_decl
)))
1045 size
= remap_decl (DECL_SIZE (decl
), &ctx
->cb
);
1046 if (size
== error_mark_node
)
1047 size
= TYPE_SIZE (TREE_TYPE (new_decl
));
1048 DECL_SIZE (new_decl
) = size
;
1050 size
= remap_decl (DECL_SIZE_UNIT (decl
), &ctx
->cb
);
1051 if (size
== error_mark_node
)
1052 size
= TYPE_SIZE_UNIT (TREE_TYPE (new_decl
));
1053 DECL_SIZE_UNIT (new_decl
) = size
;
1057 /* The callback for remap_decl. Search all containing contexts for a
1058 mapping of the variable; this avoids having to duplicate the splay
1059 tree ahead of time. We know a mapping doesn't already exist in the
1060 given context. Create new mappings to implement default semantics. */
1063 omp_copy_decl (tree var
, copy_body_data
*cb
)
1065 omp_context
*ctx
= (omp_context
*) cb
;
1068 if (TREE_CODE (var
) == LABEL_DECL
)
1070 new_var
= create_artificial_label (DECL_SOURCE_LOCATION (var
));
1071 DECL_CONTEXT (new_var
) = current_function_decl
;
1072 insert_decl_map (&ctx
->cb
, var
, new_var
);
1076 while (!is_taskreg_ctx (ctx
))
1081 new_var
= maybe_lookup_decl (var
, ctx
);
1086 if (is_global_var (var
) || decl_function_context (var
) != ctx
->cb
.src_fn
)
1089 return error_mark_node
;
1093 /* Return the parallel region associated with STMT. */
1095 /* Debugging dumps for parallel regions. */
1096 void dump_omp_region (FILE *, struct omp_region
*, int);
1097 void debug_omp_region (struct omp_region
*);
1098 void debug_all_omp_regions (void);
1100 /* Dump the parallel region tree rooted at REGION. */
1103 dump_omp_region (FILE *file
, struct omp_region
*region
, int indent
)
1105 fprintf (file
, "%*sbb %d: %s\n", indent
, "", region
->entry
->index
,
1106 gimple_code_name
[region
->type
]);
1109 dump_omp_region (file
, region
->inner
, indent
+ 4);
1113 fprintf (file
, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent
, "",
1114 region
->cont
->index
);
1118 fprintf (file
, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent
, "",
1119 region
->exit
->index
);
1121 fprintf (file
, "%*s[no exit marker]\n", indent
, "");
1124 dump_omp_region (file
, region
->next
, indent
);
1128 debug_omp_region (struct omp_region
*region
)
1130 dump_omp_region (stderr
, region
, 0);
1134 debug_all_omp_regions (void)
1136 dump_omp_region (stderr
, root_omp_region
, 0);
1140 /* Create a new parallel region starting at STMT inside region PARENT. */
1143 new_omp_region (basic_block bb
, enum gimple_code type
,
1144 struct omp_region
*parent
)
1146 struct omp_region
*region
= XCNEW (struct omp_region
);
1148 region
->outer
= parent
;
1150 region
->type
= type
;
1154 /* This is a nested region. Add it to the list of inner
1155 regions in PARENT. */
1156 region
->next
= parent
->inner
;
1157 parent
->inner
= region
;
1161 /* This is a toplevel region. Add it to the list of toplevel
1162 regions in ROOT_OMP_REGION. */
1163 region
->next
= root_omp_region
;
1164 root_omp_region
= region
;
1170 /* Release the memory associated with the region tree rooted at REGION. */
1173 free_omp_region_1 (struct omp_region
*region
)
1175 struct omp_region
*i
, *n
;
1177 for (i
= region
->inner
; i
; i
= n
)
1180 free_omp_region_1 (i
);
1186 /* Release the memory for the entire omp region tree. */
1189 free_omp_regions (void)
1191 struct omp_region
*r
, *n
;
1192 for (r
= root_omp_region
; r
; r
= n
)
1195 free_omp_region_1 (r
);
1197 root_omp_region
= NULL
;
1201 /* Create a new context, with OUTER_CTX being the surrounding context. */
1203 static omp_context
*
1204 new_omp_context (gimple stmt
, omp_context
*outer_ctx
)
1206 omp_context
*ctx
= XCNEW (omp_context
);
1208 splay_tree_insert (all_contexts
, (splay_tree_key
) stmt
,
1209 (splay_tree_value
) ctx
);
1214 ctx
->outer
= outer_ctx
;
1215 ctx
->cb
= outer_ctx
->cb
;
1216 ctx
->cb
.block
= NULL
;
1217 ctx
->depth
= outer_ctx
->depth
+ 1;
1221 ctx
->cb
.src_fn
= current_function_decl
;
1222 ctx
->cb
.dst_fn
= current_function_decl
;
1223 ctx
->cb
.src_node
= cgraph_get_node (current_function_decl
);
1224 gcc_checking_assert (ctx
->cb
.src_node
);
1225 ctx
->cb
.dst_node
= ctx
->cb
.src_node
;
1226 ctx
->cb
.src_cfun
= cfun
;
1227 ctx
->cb
.copy_decl
= omp_copy_decl
;
1228 ctx
->cb
.eh_lp_nr
= 0;
1229 ctx
->cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
1233 ctx
->cb
.decl_map
= pointer_map_create ();
1238 static gimple_seq
maybe_catch_exception (gimple_seq
);
1240 /* Finalize task copyfn. */
1243 finalize_task_copyfn (gimple task_stmt
)
1245 struct function
*child_cfun
;
1246 tree child_fn
, old_fn
;
1247 gimple_seq seq
= NULL
, new_seq
;
1250 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
1251 if (child_fn
== NULL_TREE
)
1254 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
1256 /* Inform the callgraph about the new function. */
1257 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
1258 = cfun
->curr_properties
& ~PROP_loops
;
1260 old_fn
= current_function_decl
;
1261 push_cfun (child_cfun
);
1262 current_function_decl
= child_fn
;
1263 bind
= gimplify_body (child_fn
, false);
1264 gimple_seq_add_stmt (&seq
, bind
);
1265 new_seq
= maybe_catch_exception (seq
);
1268 bind
= gimple_build_bind (NULL
, new_seq
, NULL
);
1270 gimple_seq_add_stmt (&seq
, bind
);
1272 gimple_set_body (child_fn
, seq
);
1274 current_function_decl
= old_fn
;
1276 cgraph_add_new_function (child_fn
, false);
1279 /* Destroy a omp_context data structures. Called through the splay tree
1280 value delete callback. */
1283 delete_omp_context (splay_tree_value value
)
1285 omp_context
*ctx
= (omp_context
*) value
;
1287 pointer_map_destroy (ctx
->cb
.decl_map
);
1290 splay_tree_delete (ctx
->field_map
);
1291 if (ctx
->sfield_map
)
1292 splay_tree_delete (ctx
->sfield_map
);
1294 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1295 it produces corrupt debug information. */
1296 if (ctx
->record_type
)
1299 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= DECL_CHAIN (t
))
1300 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1302 if (ctx
->srecord_type
)
1305 for (t
= TYPE_FIELDS (ctx
->srecord_type
); t
; t
= DECL_CHAIN (t
))
1306 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1309 if (is_task_ctx (ctx
))
1310 finalize_task_copyfn (ctx
->stmt
);
1315 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1319 fixup_child_record_type (omp_context
*ctx
)
1321 tree f
, type
= ctx
->record_type
;
1323 /* ??? It isn't sufficient to just call remap_type here, because
1324 variably_modified_type_p doesn't work the way we expect for
1325 record types. Testing each field for whether it needs remapping
1326 and creating a new record by hand works, however. */
1327 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
1328 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
1332 tree name
, new_fields
= NULL
;
1334 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1335 name
= DECL_NAME (TYPE_NAME (ctx
->record_type
));
1336 name
= build_decl (DECL_SOURCE_LOCATION (ctx
->receiver_decl
),
1337 TYPE_DECL
, name
, type
);
1338 TYPE_NAME (type
) = name
;
1340 for (f
= TYPE_FIELDS (ctx
->record_type
); f
; f
= DECL_CHAIN (f
))
1342 tree new_f
= copy_node (f
);
1343 DECL_CONTEXT (new_f
) = type
;
1344 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &ctx
->cb
);
1345 DECL_CHAIN (new_f
) = new_fields
;
1346 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &ctx
->cb
, NULL
);
1347 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
,
1349 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
1353 /* Arrange to be able to look up the receiver field
1354 given the sender field. */
1355 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) f
,
1356 (splay_tree_value
) new_f
);
1358 TYPE_FIELDS (type
) = nreverse (new_fields
);
1362 TREE_TYPE (ctx
->receiver_decl
) = build_pointer_type (type
);
1365 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1366 specified by CLAUSES. */
1369 scan_sharing_clauses (tree clauses
, omp_context
*ctx
)
1372 bool scan_array_reductions
= false;
1374 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1378 switch (OMP_CLAUSE_CODE (c
))
1380 case OMP_CLAUSE_PRIVATE
:
1381 decl
= OMP_CLAUSE_DECL (c
);
1382 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
1384 else if (!is_variable_sized (decl
))
1385 install_var_local (decl
, ctx
);
1388 case OMP_CLAUSE_SHARED
:
1389 gcc_assert (is_taskreg_ctx (ctx
));
1390 decl
= OMP_CLAUSE_DECL (c
);
1391 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl
))
1392 || !is_variable_sized (decl
));
1393 /* Global variables don't need to be copied,
1394 the receiver side will use them directly. */
1395 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1397 by_ref
= use_pointer_for_field (decl
, ctx
);
1398 if (! TREE_READONLY (decl
)
1399 || TREE_ADDRESSABLE (decl
)
1401 || is_reference (decl
))
1403 install_var_field (decl
, by_ref
, 3, ctx
);
1404 install_var_local (decl
, ctx
);
1407 /* We don't need to copy const scalar vars back. */
1408 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_FIRSTPRIVATE
);
1411 case OMP_CLAUSE_LASTPRIVATE
:
1412 /* Let the corresponding firstprivate clause create
1414 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1418 case OMP_CLAUSE_FIRSTPRIVATE
:
1419 case OMP_CLAUSE_REDUCTION
:
1420 decl
= OMP_CLAUSE_DECL (c
);
1422 if (is_variable_sized (decl
))
1424 if (is_task_ctx (ctx
))
1425 install_var_field (decl
, false, 1, ctx
);
1428 else if (is_taskreg_ctx (ctx
))
1431 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
));
1432 by_ref
= use_pointer_for_field (decl
, NULL
);
1434 if (is_task_ctx (ctx
)
1435 && (global
|| by_ref
|| is_reference (decl
)))
1437 install_var_field (decl
, false, 1, ctx
);
1439 install_var_field (decl
, by_ref
, 2, ctx
);
1442 install_var_field (decl
, by_ref
, 3, ctx
);
1444 install_var_local (decl
, ctx
);
1447 case OMP_CLAUSE_COPYPRIVATE
:
1448 case OMP_CLAUSE_COPYIN
:
1449 decl
= OMP_CLAUSE_DECL (c
);
1450 by_ref
= use_pointer_for_field (decl
, NULL
);
1451 install_var_field (decl
, by_ref
, 3, ctx
);
1454 case OMP_CLAUSE_DEFAULT
:
1455 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
1458 case OMP_CLAUSE_FINAL
:
1460 case OMP_CLAUSE_NUM_THREADS
:
1461 case OMP_CLAUSE_SCHEDULE
:
1463 scan_omp_op (&OMP_CLAUSE_OPERAND (c
, 0), ctx
->outer
);
1466 case OMP_CLAUSE_NOWAIT
:
1467 case OMP_CLAUSE_ORDERED
:
1468 case OMP_CLAUSE_COLLAPSE
:
1469 case OMP_CLAUSE_UNTIED
:
1470 case OMP_CLAUSE_MERGEABLE
:
1478 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1480 switch (OMP_CLAUSE_CODE (c
))
1482 case OMP_CLAUSE_LASTPRIVATE
:
1483 /* Let the corresponding firstprivate clause create
1485 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1486 scan_array_reductions
= true;
1487 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1491 case OMP_CLAUSE_PRIVATE
:
1492 case OMP_CLAUSE_FIRSTPRIVATE
:
1493 case OMP_CLAUSE_REDUCTION
:
1494 decl
= OMP_CLAUSE_DECL (c
);
1495 if (is_variable_sized (decl
))
1496 install_var_local (decl
, ctx
);
1497 fixup_remapped_decl (decl
, ctx
,
1498 OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_PRIVATE
1499 && OMP_CLAUSE_PRIVATE_DEBUG (c
));
1500 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1501 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1502 scan_array_reductions
= true;
1505 case OMP_CLAUSE_SHARED
:
1506 decl
= OMP_CLAUSE_DECL (c
);
1507 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1508 fixup_remapped_decl (decl
, ctx
, false);
1511 case OMP_CLAUSE_COPYPRIVATE
:
1512 case OMP_CLAUSE_COPYIN
:
1513 case OMP_CLAUSE_DEFAULT
:
1515 case OMP_CLAUSE_NUM_THREADS
:
1516 case OMP_CLAUSE_SCHEDULE
:
1517 case OMP_CLAUSE_NOWAIT
:
1518 case OMP_CLAUSE_ORDERED
:
1519 case OMP_CLAUSE_COLLAPSE
:
1520 case OMP_CLAUSE_UNTIED
:
1521 case OMP_CLAUSE_FINAL
:
1522 case OMP_CLAUSE_MERGEABLE
:
1530 if (scan_array_reductions
)
1531 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1532 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1533 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1535 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
1536 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
1538 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
1539 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1540 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
1543 /* Create a new name for omp child function. Returns an identifier. */
1545 static GTY(()) unsigned int tmp_ompfn_id_num
;
1548 create_omp_child_function_name (bool task_copy
)
1550 return (clone_function_name (current_function_decl
,
1551 task_copy
? "_omp_cpyfn" : "_omp_fn"));
1554 /* Build a decl for the omp child function. It'll not contain a body
1555 yet, just the bare decl. */
1558 create_omp_child_function (omp_context
*ctx
, bool task_copy
)
1560 tree decl
, type
, name
, t
;
1562 name
= create_omp_child_function_name (task_copy
);
1564 type
= build_function_type_list (void_type_node
, ptr_type_node
,
1565 ptr_type_node
, NULL_TREE
);
1567 type
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
1569 decl
= build_decl (gimple_location (ctx
->stmt
),
1570 FUNCTION_DECL
, name
, type
);
1573 ctx
->cb
.dst_fn
= decl
;
1575 gimple_omp_task_set_copy_fn (ctx
->stmt
, decl
);
1577 TREE_STATIC (decl
) = 1;
1578 TREE_USED (decl
) = 1;
1579 DECL_ARTIFICIAL (decl
) = 1;
1580 DECL_NAMELESS (decl
) = 1;
1581 DECL_IGNORED_P (decl
) = 0;
1582 TREE_PUBLIC (decl
) = 0;
1583 DECL_UNINLINABLE (decl
) = 1;
1584 DECL_EXTERNAL (decl
) = 0;
1585 DECL_CONTEXT (decl
) = NULL_TREE
;
1586 DECL_INITIAL (decl
) = make_node (BLOCK
);
1588 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1589 RESULT_DECL
, NULL_TREE
, void_type_node
);
1590 DECL_ARTIFICIAL (t
) = 1;
1591 DECL_IGNORED_P (t
) = 1;
1592 DECL_CONTEXT (t
) = decl
;
1593 DECL_RESULT (decl
) = t
;
1595 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1596 PARM_DECL
, get_identifier (".omp_data_i"), ptr_type_node
);
1597 DECL_ARTIFICIAL (t
) = 1;
1598 DECL_NAMELESS (t
) = 1;
1599 DECL_ARG_TYPE (t
) = ptr_type_node
;
1600 DECL_CONTEXT (t
) = current_function_decl
;
1602 DECL_ARGUMENTS (decl
) = t
;
1604 ctx
->receiver_decl
= t
;
1607 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1608 PARM_DECL
, get_identifier (".omp_data_o"),
1610 DECL_ARTIFICIAL (t
) = 1;
1611 DECL_NAMELESS (t
) = 1;
1612 DECL_ARG_TYPE (t
) = ptr_type_node
;
1613 DECL_CONTEXT (t
) = current_function_decl
;
1615 TREE_ADDRESSABLE (t
) = 1;
1616 DECL_CHAIN (t
) = DECL_ARGUMENTS (decl
);
1617 DECL_ARGUMENTS (decl
) = t
;
1620 /* Allocate memory for the function structure. The call to
1621 allocate_struct_function clobbers CFUN, so we need to restore
1623 push_struct_function (decl
);
1624 cfun
->function_end_locus
= gimple_location (ctx
->stmt
);
1629 /* Scan an OpenMP parallel directive. */
1632 scan_omp_parallel (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1636 gimple stmt
= gsi_stmt (*gsi
);
1638 /* Ignore parallel directives with empty bodies, unless there
1639 are copyin clauses. */
1641 && empty_body_p (gimple_omp_body (stmt
))
1642 && find_omp_clause (gimple_omp_parallel_clauses (stmt
),
1643 OMP_CLAUSE_COPYIN
) == NULL
)
1645 gsi_replace (gsi
, gimple_build_nop (), false);
1649 ctx
= new_omp_context (stmt
, outer_ctx
);
1650 if (taskreg_nesting_level
> 1)
1651 ctx
->is_nested
= true;
1652 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1653 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1654 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1655 name
= create_tmp_var_name (".omp_data_s");
1656 name
= build_decl (gimple_location (stmt
),
1657 TYPE_DECL
, name
, ctx
->record_type
);
1658 DECL_ARTIFICIAL (name
) = 1;
1659 DECL_NAMELESS (name
) = 1;
1660 TYPE_NAME (ctx
->record_type
) = name
;
1661 create_omp_child_function (ctx
, false);
1662 gimple_omp_parallel_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
1664 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt
), ctx
);
1665 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1667 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1668 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1671 layout_type (ctx
->record_type
);
1672 fixup_child_record_type (ctx
);
1676 /* Scan an OpenMP task directive. */
1679 scan_omp_task (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1683 gimple stmt
= gsi_stmt (*gsi
);
1684 location_t loc
= gimple_location (stmt
);
1686 /* Ignore task directives with empty bodies. */
1688 && empty_body_p (gimple_omp_body (stmt
)))
1690 gsi_replace (gsi
, gimple_build_nop (), false);
1694 ctx
= new_omp_context (stmt
, outer_ctx
);
1695 if (taskreg_nesting_level
> 1)
1696 ctx
->is_nested
= true;
1697 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1698 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1699 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1700 name
= create_tmp_var_name (".omp_data_s");
1701 name
= build_decl (gimple_location (stmt
),
1702 TYPE_DECL
, name
, ctx
->record_type
);
1703 DECL_ARTIFICIAL (name
) = 1;
1704 DECL_NAMELESS (name
) = 1;
1705 TYPE_NAME (ctx
->record_type
) = name
;
1706 create_omp_child_function (ctx
, false);
1707 gimple_omp_task_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
1709 scan_sharing_clauses (gimple_omp_task_clauses (stmt
), ctx
);
1711 if (ctx
->srecord_type
)
1713 name
= create_tmp_var_name (".omp_data_a");
1714 name
= build_decl (gimple_location (stmt
),
1715 TYPE_DECL
, name
, ctx
->srecord_type
);
1716 DECL_ARTIFICIAL (name
) = 1;
1717 DECL_NAMELESS (name
) = 1;
1718 TYPE_NAME (ctx
->srecord_type
) = name
;
1719 create_omp_child_function (ctx
, true);
1722 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1724 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1726 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1727 t
= build_int_cst (long_integer_type_node
, 0);
1728 gimple_omp_task_set_arg_size (stmt
, t
);
1729 t
= build_int_cst (long_integer_type_node
, 1);
1730 gimple_omp_task_set_arg_align (stmt
, t
);
1734 tree
*p
, vla_fields
= NULL_TREE
, *q
= &vla_fields
;
1735 /* Move VLA fields to the end. */
1736 p
= &TYPE_FIELDS (ctx
->record_type
);
1738 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p
))
1739 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p
))))
1742 *p
= TREE_CHAIN (*p
);
1743 TREE_CHAIN (*q
) = NULL_TREE
;
1744 q
= &TREE_CHAIN (*q
);
1747 p
= &DECL_CHAIN (*p
);
1749 layout_type (ctx
->record_type
);
1750 fixup_child_record_type (ctx
);
1751 if (ctx
->srecord_type
)
1752 layout_type (ctx
->srecord_type
);
1753 t
= fold_convert_loc (loc
, long_integer_type_node
,
1754 TYPE_SIZE_UNIT (ctx
->record_type
));
1755 gimple_omp_task_set_arg_size (stmt
, t
);
1756 t
= build_int_cst (long_integer_type_node
,
1757 TYPE_ALIGN_UNIT (ctx
->record_type
));
1758 gimple_omp_task_set_arg_align (stmt
, t
);
1763 /* Scan an OpenMP loop directive. */
1766 scan_omp_for (gimple stmt
, omp_context
*outer_ctx
)
1771 ctx
= new_omp_context (stmt
, outer_ctx
);
1773 scan_sharing_clauses (gimple_omp_for_clauses (stmt
), ctx
);
1775 scan_omp (gimple_omp_for_pre_body_ptr (stmt
), ctx
);
1776 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
1778 scan_omp_op (gimple_omp_for_index_ptr (stmt
, i
), ctx
);
1779 scan_omp_op (gimple_omp_for_initial_ptr (stmt
, i
), ctx
);
1780 scan_omp_op (gimple_omp_for_final_ptr (stmt
, i
), ctx
);
1781 scan_omp_op (gimple_omp_for_incr_ptr (stmt
, i
), ctx
);
1783 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1786 /* Scan an OpenMP sections directive. */
1789 scan_omp_sections (gimple stmt
, omp_context
*outer_ctx
)
1793 ctx
= new_omp_context (stmt
, outer_ctx
);
1794 scan_sharing_clauses (gimple_omp_sections_clauses (stmt
), ctx
);
1795 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1798 /* Scan an OpenMP single directive. */
1801 scan_omp_single (gimple stmt
, omp_context
*outer_ctx
)
1806 ctx
= new_omp_context (stmt
, outer_ctx
);
1807 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1808 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1809 name
= create_tmp_var_name (".omp_copy_s");
1810 name
= build_decl (gimple_location (stmt
),
1811 TYPE_DECL
, name
, ctx
->record_type
);
1812 TYPE_NAME (ctx
->record_type
) = name
;
1814 scan_sharing_clauses (gimple_omp_single_clauses (stmt
), ctx
);
1815 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
1817 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1818 ctx
->record_type
= NULL
;
1820 layout_type (ctx
->record_type
);
1824 /* Check OpenMP nesting restrictions. */
1826 check_omp_nesting_restrictions (gimple stmt
, omp_context
*ctx
)
1828 switch (gimple_code (stmt
))
1830 case GIMPLE_OMP_FOR
:
1831 case GIMPLE_OMP_SECTIONS
:
1832 case GIMPLE_OMP_SINGLE
:
1834 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1835 switch (gimple_code (ctx
->stmt
))
1837 case GIMPLE_OMP_FOR
:
1838 case GIMPLE_OMP_SECTIONS
:
1839 case GIMPLE_OMP_SINGLE
:
1840 case GIMPLE_OMP_ORDERED
:
1841 case GIMPLE_OMP_MASTER
:
1842 case GIMPLE_OMP_TASK
:
1843 if (is_gimple_call (stmt
))
1845 error_at (gimple_location (stmt
),
1846 "barrier region may not be closely nested inside "
1847 "of work-sharing, critical, ordered, master or "
1848 "explicit task region");
1851 error_at (gimple_location (stmt
),
1852 "work-sharing region may not be closely nested inside "
1853 "of work-sharing, critical, ordered, master or explicit "
1856 case GIMPLE_OMP_PARALLEL
:
1862 case GIMPLE_OMP_MASTER
:
1863 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1864 switch (gimple_code (ctx
->stmt
))
1866 case GIMPLE_OMP_FOR
:
1867 case GIMPLE_OMP_SECTIONS
:
1868 case GIMPLE_OMP_SINGLE
:
1869 case GIMPLE_OMP_TASK
:
1870 error_at (gimple_location (stmt
),
1871 "master region may not be closely nested inside "
1872 "of work-sharing or explicit task region");
1874 case GIMPLE_OMP_PARALLEL
:
1880 case GIMPLE_OMP_ORDERED
:
1881 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1882 switch (gimple_code (ctx
->stmt
))
1884 case GIMPLE_OMP_CRITICAL
:
1885 case GIMPLE_OMP_TASK
:
1886 error_at (gimple_location (stmt
),
1887 "ordered region may not be closely nested inside "
1888 "of critical or explicit task region");
1890 case GIMPLE_OMP_FOR
:
1891 if (find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
1892 OMP_CLAUSE_ORDERED
) == NULL
)
1894 error_at (gimple_location (stmt
),
1895 "ordered region must be closely nested inside "
1896 "a loop region with an ordered clause");
1900 case GIMPLE_OMP_PARALLEL
:
1906 case GIMPLE_OMP_CRITICAL
:
1907 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1908 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_CRITICAL
1909 && (gimple_omp_critical_name (stmt
)
1910 == gimple_omp_critical_name (ctx
->stmt
)))
1912 error_at (gimple_location (stmt
),
1913 "critical region may not be nested inside a critical "
1914 "region with the same name");
1925 /* Helper function scan_omp.
1927 Callback for walk_tree or operators in walk_gimple_stmt used to
1928 scan for OpenMP directives in TP. */
1931 scan_omp_1_op (tree
*tp
, int *walk_subtrees
, void *data
)
1933 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
1934 omp_context
*ctx
= (omp_context
*) wi
->info
;
1937 switch (TREE_CODE (t
))
1944 *tp
= remap_decl (t
, &ctx
->cb
);
1948 if (ctx
&& TYPE_P (t
))
1949 *tp
= remap_type (t
, &ctx
->cb
);
1950 else if (!DECL_P (t
))
1955 tree tem
= remap_type (TREE_TYPE (t
), &ctx
->cb
);
1956 if (tem
!= TREE_TYPE (t
))
1958 if (TREE_CODE (t
) == INTEGER_CST
)
1959 *tp
= build_int_cst_wide (tem
,
1960 TREE_INT_CST_LOW (t
),
1961 TREE_INT_CST_HIGH (t
));
1963 TREE_TYPE (t
) = tem
;
1974 /* Helper function for scan_omp.
1976 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1977 the current statement in GSI. */
1980 scan_omp_1_stmt (gimple_stmt_iterator
*gsi
, bool *handled_ops_p
,
1981 struct walk_stmt_info
*wi
)
1983 gimple stmt
= gsi_stmt (*gsi
);
1984 omp_context
*ctx
= (omp_context
*) wi
->info
;
1986 if (gimple_has_location (stmt
))
1987 input_location
= gimple_location (stmt
);
1989 /* Check the OpenMP nesting restrictions. */
1992 bool remove
= false;
1993 if (is_gimple_omp (stmt
))
1994 remove
= !check_omp_nesting_restrictions (stmt
, ctx
);
1995 else if (is_gimple_call (stmt
))
1997 tree fndecl
= gimple_call_fndecl (stmt
);
1998 if (fndecl
&& DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
1999 && DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_GOMP_BARRIER
)
2000 remove
= !check_omp_nesting_restrictions (stmt
, ctx
);
2004 stmt
= gimple_build_nop ();
2005 gsi_replace (gsi
, stmt
, false);
2009 *handled_ops_p
= true;
2011 switch (gimple_code (stmt
))
2013 case GIMPLE_OMP_PARALLEL
:
2014 taskreg_nesting_level
++;
2015 scan_omp_parallel (gsi
, ctx
);
2016 taskreg_nesting_level
--;
2019 case GIMPLE_OMP_TASK
:
2020 taskreg_nesting_level
++;
2021 scan_omp_task (gsi
, ctx
);
2022 taskreg_nesting_level
--;
2025 case GIMPLE_OMP_FOR
:
2026 scan_omp_for (stmt
, ctx
);
2029 case GIMPLE_OMP_SECTIONS
:
2030 scan_omp_sections (stmt
, ctx
);
2033 case GIMPLE_OMP_SINGLE
:
2034 scan_omp_single (stmt
, ctx
);
2037 case GIMPLE_OMP_SECTION
:
2038 case GIMPLE_OMP_MASTER
:
2039 case GIMPLE_OMP_ORDERED
:
2040 case GIMPLE_OMP_CRITICAL
:
2041 ctx
= new_omp_context (stmt
, ctx
);
2042 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2049 *handled_ops_p
= false;
2051 for (var
= gimple_bind_vars (stmt
); var
; var
= DECL_CHAIN (var
))
2052 insert_decl_map (&ctx
->cb
, var
, var
);
2056 *handled_ops_p
= false;
2064 /* Scan all the statements starting at the current statement. CTX
2065 contains context information about the OpenMP directives and
2066 clauses found during the scan. */
2069 scan_omp (gimple_seq
*body_p
, omp_context
*ctx
)
2071 location_t saved_location
;
2072 struct walk_stmt_info wi
;
2074 memset (&wi
, 0, sizeof (wi
));
2076 wi
.want_locations
= true;
2078 saved_location
= input_location
;
2079 walk_gimple_seq_mod (body_p
, scan_omp_1_stmt
, scan_omp_1_op
, &wi
);
2080 input_location
= saved_location
;
2083 /* Re-gimplification and code generation routines. */
2085 /* Build a call to GOMP_barrier. */
2088 build_omp_barrier (void)
2090 return build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_BARRIER
), 0);
2093 /* If a context was created for STMT when it was scanned, return it. */
2095 static omp_context
*
2096 maybe_lookup_ctx (gimple stmt
)
2099 n
= splay_tree_lookup (all_contexts
, (splay_tree_key
) stmt
);
2100 return n
? (omp_context
*) n
->value
: NULL
;
2104 /* Find the mapping for DECL in CTX or the immediately enclosing
2105 context that has a mapping for DECL.
2107 If CTX is a nested parallel directive, we may have to use the decl
2108 mappings created in CTX's parent context. Suppose that we have the
2109 following parallel nesting (variable UIDs showed for clarity):
2112 #omp parallel shared(iD.1562) -> outer parallel
2113 iD.1562 = iD.1562 + 1;
2115 #omp parallel shared (iD.1562) -> inner parallel
2116 iD.1562 = iD.1562 - 1;
2118 Each parallel structure will create a distinct .omp_data_s structure
2119 for copying iD.1562 in/out of the directive:
2121 outer parallel .omp_data_s.1.i -> iD.1562
2122 inner parallel .omp_data_s.2.i -> iD.1562
2124 A shared variable mapping will produce a copy-out operation before
2125 the parallel directive and a copy-in operation after it. So, in
2126 this case we would have:
2129 .omp_data_o.1.i = iD.1562;
2130 #omp parallel shared(iD.1562) -> outer parallel
2131 .omp_data_i.1 = &.omp_data_o.1
2132 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2134 .omp_data_o.2.i = iD.1562; -> **
2135 #omp parallel shared(iD.1562) -> inner parallel
2136 .omp_data_i.2 = &.omp_data_o.2
2137 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2140 ** This is a problem. The symbol iD.1562 cannot be referenced
2141 inside the body of the outer parallel region. But since we are
2142 emitting this copy operation while expanding the inner parallel
2143 directive, we need to access the CTX structure of the outer
2144 parallel directive to get the correct mapping:
2146 .omp_data_o.2.i = .omp_data_i.1->i
2148 Since there may be other workshare or parallel directives enclosing
2149 the parallel directive, it may be necessary to walk up the context
2150 parent chain. This is not a problem in general because nested
2151 parallelism happens only rarely. */
2154 lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2159 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2160 t
= maybe_lookup_decl (decl
, up
);
2162 gcc_assert (!ctx
->is_nested
|| t
|| is_global_var (decl
));
2164 return t
? t
: decl
;
2168 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2169 in outer contexts. */
2172 maybe_lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2177 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2178 t
= maybe_lookup_decl (decl
, up
);
2180 return t
? t
: decl
;
2184 /* Construct the initialization value for reduction CLAUSE. */
2187 omp_reduction_init (tree clause
, tree type
)
2189 location_t loc
= OMP_CLAUSE_LOCATION (clause
);
2190 switch (OMP_CLAUSE_REDUCTION_CODE (clause
))
2197 case TRUTH_ORIF_EXPR
:
2198 case TRUTH_XOR_EXPR
:
2200 return build_zero_cst (type
);
2203 case TRUTH_AND_EXPR
:
2204 case TRUTH_ANDIF_EXPR
:
2206 return fold_convert_loc (loc
, type
, integer_one_node
);
2209 return fold_convert_loc (loc
, type
, integer_minus_one_node
);
2212 if (SCALAR_FLOAT_TYPE_P (type
))
2214 REAL_VALUE_TYPE max
, min
;
2215 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2218 real_arithmetic (&min
, NEGATE_EXPR
, &max
, NULL
);
2221 real_maxval (&min
, 1, TYPE_MODE (type
));
2222 return build_real (type
, min
);
2226 gcc_assert (INTEGRAL_TYPE_P (type
));
2227 return TYPE_MIN_VALUE (type
);
2231 if (SCALAR_FLOAT_TYPE_P (type
))
2233 REAL_VALUE_TYPE max
;
2234 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2237 real_maxval (&max
, 0, TYPE_MODE (type
));
2238 return build_real (type
, max
);
2242 gcc_assert (INTEGRAL_TYPE_P (type
));
2243 return TYPE_MAX_VALUE (type
);
2251 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2252 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2253 private variables. Initialization statements go in ILIST, while calls
2254 to destructors go in DLIST. */
2257 lower_rec_input_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*dlist
,
2260 tree c
, dtor
, copyin_seq
, x
, ptr
;
2261 bool copyin_by_ref
= false;
2262 bool lastprivate_firstprivate
= false;
2267 /* Do all the fixed sized types in the first pass, and the variable sized
2268 types in the second pass. This makes sure that the scalar arguments to
2269 the variable sized types are processed before we use them in the
2270 variable sized operations. */
2271 for (pass
= 0; pass
< 2; ++pass
)
2273 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2275 enum omp_clause_code c_kind
= OMP_CLAUSE_CODE (c
);
2278 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2282 case OMP_CLAUSE_PRIVATE
:
2283 if (OMP_CLAUSE_PRIVATE_DEBUG (c
))
2286 case OMP_CLAUSE_SHARED
:
2287 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c
), ctx
) == NULL
)
2289 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c
)));
2292 case OMP_CLAUSE_FIRSTPRIVATE
:
2293 case OMP_CLAUSE_COPYIN
:
2294 case OMP_CLAUSE_REDUCTION
:
2296 case OMP_CLAUSE_LASTPRIVATE
:
2297 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2299 lastprivate_firstprivate
= true;
2308 new_var
= var
= OMP_CLAUSE_DECL (c
);
2309 if (c_kind
!= OMP_CLAUSE_COPYIN
)
2310 new_var
= lookup_decl (var
, ctx
);
2312 if (c_kind
== OMP_CLAUSE_SHARED
|| c_kind
== OMP_CLAUSE_COPYIN
)
2317 else if (is_variable_sized (var
))
2319 /* For variable sized types, we need to allocate the
2320 actual storage here. Call alloca and store the
2321 result in the pointer decl that we created elsewhere. */
2325 if (c_kind
!= OMP_CLAUSE_FIRSTPRIVATE
|| !is_task_ctx (ctx
))
2330 ptr
= DECL_VALUE_EXPR (new_var
);
2331 gcc_assert (TREE_CODE (ptr
) == INDIRECT_REF
);
2332 ptr
= TREE_OPERAND (ptr
, 0);
2333 gcc_assert (DECL_P (ptr
));
2334 x
= TYPE_SIZE_UNIT (TREE_TYPE (new_var
));
2336 /* void *tmp = __builtin_alloca */
2337 atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA
);
2338 stmt
= gimple_build_call (atmp
, 1, x
);
2339 tmp
= create_tmp_var_raw (ptr_type_node
, NULL
);
2340 gimple_add_tmp_var (tmp
);
2341 gimple_call_set_lhs (stmt
, tmp
);
2343 gimple_seq_add_stmt (ilist
, stmt
);
2345 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ptr
), tmp
);
2346 gimplify_assign (ptr
, x
, ilist
);
2349 else if (is_reference (var
))
2351 /* For references that are being privatized for Fortran,
2352 allocate new backing storage for the new pointer
2353 variable. This allows us to avoid changing all the
2354 code that expects a pointer to something that expects
2355 a direct variable. Note that this doesn't apply to
2356 C++, since reference types are disallowed in data
2357 sharing clauses there, except for NRV optimized
2362 x
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var
)));
2363 if (c_kind
== OMP_CLAUSE_FIRSTPRIVATE
&& is_task_ctx (ctx
))
2365 x
= build_receiver_ref (var
, false, ctx
);
2366 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2368 else if (TREE_CONSTANT (x
))
2370 const char *name
= NULL
;
2371 if (DECL_NAME (var
))
2372 name
= IDENTIFIER_POINTER (DECL_NAME (new_var
));
2374 x
= create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var
)),
2376 gimple_add_tmp_var (x
);
2377 TREE_ADDRESSABLE (x
) = 1;
2378 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2382 tree atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA
);
2383 x
= build_call_expr_loc (clause_loc
, atmp
, 1, x
);
2386 x
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), x
);
2387 gimplify_assign (new_var
, x
, ilist
);
2389 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
2391 else if (c_kind
== OMP_CLAUSE_REDUCTION
2392 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2400 switch (OMP_CLAUSE_CODE (c
))
2402 case OMP_CLAUSE_SHARED
:
2403 /* Shared global vars are just accessed directly. */
2404 if (is_global_var (new_var
))
2406 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2407 needs to be delayed until after fixup_child_record_type so
2408 that we get the correct type during the dereference. */
2409 by_ref
= use_pointer_for_field (var
, ctx
);
2410 x
= build_receiver_ref (var
, by_ref
, ctx
);
2411 SET_DECL_VALUE_EXPR (new_var
, x
);
2412 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2414 /* ??? If VAR is not passed by reference, and the variable
2415 hasn't been initialized yet, then we'll get a warning for
2416 the store into the omp_data_s structure. Ideally, we'd be
2417 able to notice this and not store anything at all, but
2418 we're generating code too early. Suppress the warning. */
2420 TREE_NO_WARNING (var
) = 1;
2423 case OMP_CLAUSE_LASTPRIVATE
:
2424 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2428 case OMP_CLAUSE_PRIVATE
:
2429 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_PRIVATE
)
2430 x
= build_outer_var_ref (var
, ctx
);
2431 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
2433 if (is_task_ctx (ctx
))
2434 x
= build_receiver_ref (var
, false, ctx
);
2436 x
= build_outer_var_ref (var
, ctx
);
2440 x
= lang_hooks
.decls
.omp_clause_default_ctor (c
, new_var
, x
);
2442 gimplify_and_add (x
, ilist
);
2446 x
= lang_hooks
.decls
.omp_clause_dtor (c
, new_var
);
2449 gimple_seq tseq
= NULL
;
2452 gimplify_stmt (&dtor
, &tseq
);
2453 gimple_seq_add_seq (dlist
, tseq
);
2457 case OMP_CLAUSE_FIRSTPRIVATE
:
2458 if (is_task_ctx (ctx
))
2460 if (is_reference (var
) || is_variable_sized (var
))
2462 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
,
2464 || use_pointer_for_field (var
, NULL
))
2466 x
= build_receiver_ref (var
, false, ctx
);
2467 SET_DECL_VALUE_EXPR (new_var
, x
);
2468 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2472 x
= build_outer_var_ref (var
, ctx
);
2473 x
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, new_var
, x
);
2474 gimplify_and_add (x
, ilist
);
2478 case OMP_CLAUSE_COPYIN
:
2479 by_ref
= use_pointer_for_field (var
, NULL
);
2480 x
= build_receiver_ref (var
, by_ref
, ctx
);
2481 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, x
);
2482 append_to_statement_list (x
, ©in_seq
);
2483 copyin_by_ref
|= by_ref
;
2486 case OMP_CLAUSE_REDUCTION
:
2487 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2489 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
2490 x
= build_outer_var_ref (var
, ctx
);
2492 if (is_reference (var
))
2493 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2494 SET_DECL_VALUE_EXPR (placeholder
, x
);
2495 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
2496 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
2497 gimple_seq_add_seq (ilist
,
2498 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
2499 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
2500 DECL_HAS_VALUE_EXPR_P (placeholder
) = 0;
2504 x
= omp_reduction_init (c
, TREE_TYPE (new_var
));
2505 gcc_assert (TREE_CODE (TREE_TYPE (new_var
)) != ARRAY_TYPE
);
2506 gimplify_assign (new_var
, x
, ilist
);
2516 /* The copyin sequence is not to be executed by the main thread, since
2517 that would result in self-copies. Perhaps not visible to scalars,
2518 but it certainly is to C++ operator=. */
2521 x
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
),
2523 x
= build2 (NE_EXPR
, boolean_type_node
, x
,
2524 build_int_cst (TREE_TYPE (x
), 0));
2525 x
= build3 (COND_EXPR
, void_type_node
, x
, copyin_seq
, NULL
);
2526 gimplify_and_add (x
, ilist
);
2529 /* If any copyin variable is passed by reference, we must ensure the
2530 master thread doesn't modify it before it is copied over in all
2531 threads. Similarly for variables in both firstprivate and
2532 lastprivate clauses we need to ensure the lastprivate copying
2533 happens after firstprivate copying in all threads. */
2534 if (copyin_by_ref
|| lastprivate_firstprivate
)
2535 gimplify_and_add (build_omp_barrier (), ilist
);
2539 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2540 both parallel and workshare constructs. PREDICATE may be NULL if it's
2544 lower_lastprivate_clauses (tree clauses
, tree predicate
, gimple_seq
*stmt_list
,
2547 tree x
, c
, label
= NULL
;
2548 bool par_clauses
= false;
2550 /* Early exit if there are no lastprivate clauses. */
2551 clauses
= find_omp_clause (clauses
, OMP_CLAUSE_LASTPRIVATE
);
2552 if (clauses
== NULL
)
2554 /* If this was a workshare clause, see if it had been combined
2555 with its parallel. In that case, look for the clauses on the
2556 parallel statement itself. */
2557 if (is_parallel_ctx (ctx
))
2561 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
2564 clauses
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
2565 OMP_CLAUSE_LASTPRIVATE
);
2566 if (clauses
== NULL
)
2574 tree label_true
, arm1
, arm2
;
2576 label
= create_artificial_label (UNKNOWN_LOCATION
);
2577 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
2578 arm1
= TREE_OPERAND (predicate
, 0);
2579 arm2
= TREE_OPERAND (predicate
, 1);
2580 gimplify_expr (&arm1
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
2581 gimplify_expr (&arm2
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
2582 stmt
= gimple_build_cond (TREE_CODE (predicate
), arm1
, arm2
,
2584 gimple_seq_add_stmt (stmt_list
, stmt
);
2585 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label_true
));
2588 for (c
= clauses
; c
;)
2591 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2593 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
2595 var
= OMP_CLAUSE_DECL (c
);
2596 new_var
= lookup_decl (var
, ctx
);
2598 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
2600 lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
2601 gimple_seq_add_seq (stmt_list
,
2602 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
2604 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) = NULL
;
2606 x
= build_outer_var_ref (var
, ctx
);
2607 if (is_reference (var
))
2608 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
2609 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, x
, new_var
);
2610 gimplify_and_add (x
, stmt_list
);
2612 c
= OMP_CLAUSE_CHAIN (c
);
2613 if (c
== NULL
&& !par_clauses
)
2615 /* If this was a workshare clause, see if it had been combined
2616 with its parallel. In that case, continue looking for the
2617 clauses also on the parallel statement itself. */
2618 if (is_parallel_ctx (ctx
))
2622 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
2625 c
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
2626 OMP_CLAUSE_LASTPRIVATE
);
2632 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label
));
2636 /* Generate code to implement the REDUCTION clauses. */
2639 lower_reduction_clauses (tree clauses
, gimple_seq
*stmt_seqp
, omp_context
*ctx
)
2641 gimple_seq sub_seq
= NULL
;
2646 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2647 update in that case, otherwise use a lock. */
2648 for (c
= clauses
; c
&& count
< 2; c
= OMP_CLAUSE_CHAIN (c
))
2649 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
2651 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2653 /* Never use OMP_ATOMIC for array reductions. */
2663 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2665 tree var
, ref
, new_var
;
2666 enum tree_code code
;
2667 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2669 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
)
2672 var
= OMP_CLAUSE_DECL (c
);
2673 new_var
= lookup_decl (var
, ctx
);
2674 if (is_reference (var
))
2675 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
2676 ref
= build_outer_var_ref (var
, ctx
);
2677 code
= OMP_CLAUSE_REDUCTION_CODE (c
);
2679 /* reduction(-:var) sums up the partial results, so it acts
2680 identically to reduction(+:var). */
2681 if (code
== MINUS_EXPR
)
2686 tree addr
= build_fold_addr_expr_loc (clause_loc
, ref
);
2688 addr
= save_expr (addr
);
2689 ref
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (addr
)), addr
);
2690 x
= fold_build2_loc (clause_loc
, code
, TREE_TYPE (ref
), ref
, new_var
);
2691 x
= build2 (OMP_ATOMIC
, void_type_node
, addr
, x
);
2692 gimplify_and_add (x
, stmt_seqp
);
2696 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2698 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
2700 if (is_reference (var
))
2701 ref
= build_fold_addr_expr_loc (clause_loc
, ref
);
2702 SET_DECL_VALUE_EXPR (placeholder
, ref
);
2703 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
2704 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
2705 gimple_seq_add_seq (&sub_seq
, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
2706 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
2707 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
) = NULL
;
2711 x
= build2 (code
, TREE_TYPE (ref
), ref
, new_var
);
2712 ref
= build_outer_var_ref (var
, ctx
);
2713 gimplify_assign (ref
, x
, &sub_seq
);
2717 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START
),
2719 gimple_seq_add_stmt (stmt_seqp
, stmt
);
2721 gimple_seq_add_seq (stmt_seqp
, sub_seq
);
2723 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END
),
2725 gimple_seq_add_stmt (stmt_seqp
, stmt
);
2729 /* Generate code to implement the COPYPRIVATE clauses. */
2732 lower_copyprivate_clauses (tree clauses
, gimple_seq
*slist
, gimple_seq
*rlist
,
2737 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2739 tree var
, new_var
, ref
, x
;
2741 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2743 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYPRIVATE
)
2746 var
= OMP_CLAUSE_DECL (c
);
2747 by_ref
= use_pointer_for_field (var
, NULL
);
2749 ref
= build_sender_ref (var
, ctx
);
2750 x
= new_var
= lookup_decl_in_outer_ctx (var
, ctx
);
2753 x
= build_fold_addr_expr_loc (clause_loc
, new_var
);
2754 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ref
), x
);
2756 gimplify_assign (ref
, x
, slist
);
2758 ref
= build_receiver_ref (var
, false, ctx
);
2761 ref
= fold_convert_loc (clause_loc
,
2762 build_pointer_type (TREE_TYPE (new_var
)),
2764 ref
= build_fold_indirect_ref_loc (clause_loc
, ref
);
2766 if (is_reference (var
))
2768 ref
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), ref
);
2769 ref
= build_simple_mem_ref_loc (clause_loc
, ref
);
2770 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
2772 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, ref
);
2773 gimplify_and_add (x
, rlist
);
2778 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2779 and REDUCTION from the sender (aka parent) side. */
2782 lower_send_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*olist
,
2787 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2789 tree val
, ref
, x
, var
;
2790 bool by_ref
, do_in
= false, do_out
= false;
2791 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2793 switch (OMP_CLAUSE_CODE (c
))
2795 case OMP_CLAUSE_PRIVATE
:
2796 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
2799 case OMP_CLAUSE_FIRSTPRIVATE
:
2800 case OMP_CLAUSE_COPYIN
:
2801 case OMP_CLAUSE_LASTPRIVATE
:
2802 case OMP_CLAUSE_REDUCTION
:
2808 val
= OMP_CLAUSE_DECL (c
);
2809 var
= lookup_decl_in_outer_ctx (val
, ctx
);
2811 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYIN
2812 && is_global_var (var
))
2814 if (is_variable_sized (val
))
2816 by_ref
= use_pointer_for_field (val
, NULL
);
2818 switch (OMP_CLAUSE_CODE (c
))
2820 case OMP_CLAUSE_PRIVATE
:
2821 case OMP_CLAUSE_FIRSTPRIVATE
:
2822 case OMP_CLAUSE_COPYIN
:
2826 case OMP_CLAUSE_LASTPRIVATE
:
2827 if (by_ref
|| is_reference (val
))
2829 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2836 if (lang_hooks
.decls
.omp_private_outer_ref (val
))
2841 case OMP_CLAUSE_REDUCTION
:
2843 do_out
= !(by_ref
|| is_reference (val
));
2852 ref
= build_sender_ref (val
, ctx
);
2853 x
= by_ref
? build_fold_addr_expr_loc (clause_loc
, var
) : var
;
2854 gimplify_assign (ref
, x
, ilist
);
2855 if (is_task_ctx (ctx
))
2856 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref
, 1)) = NULL
;
2861 ref
= build_sender_ref (val
, ctx
);
2862 gimplify_assign (var
, ref
, olist
);
2867 /* Generate code to implement SHARED from the sender (aka parent)
2868 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2869 list things that got automatically shared. */
2872 lower_send_shared_vars (gimple_seq
*ilist
, gimple_seq
*olist
, omp_context
*ctx
)
2874 tree var
, ovar
, nvar
, f
, x
, record_type
;
2876 if (ctx
->record_type
== NULL
)
2879 record_type
= ctx
->srecord_type
? ctx
->srecord_type
: ctx
->record_type
;
2880 for (f
= TYPE_FIELDS (record_type
); f
; f
= DECL_CHAIN (f
))
2882 ovar
= DECL_ABSTRACT_ORIGIN (f
);
2883 nvar
= maybe_lookup_decl (ovar
, ctx
);
2884 if (!nvar
|| !DECL_HAS_VALUE_EXPR_P (nvar
))
2887 /* If CTX is a nested parallel directive. Find the immediately
2888 enclosing parallel or workshare construct that contains a
2889 mapping for OVAR. */
2890 var
= lookup_decl_in_outer_ctx (ovar
, ctx
);
2892 if (use_pointer_for_field (ovar
, ctx
))
2894 x
= build_sender_ref (ovar
, ctx
);
2895 var
= build_fold_addr_expr (var
);
2896 gimplify_assign (x
, var
, ilist
);
2900 x
= build_sender_ref (ovar
, ctx
);
2901 gimplify_assign (x
, var
, ilist
);
2903 if (!TREE_READONLY (var
)
2904 /* We don't need to receive a new reference to a result
2905 or parm decl. In fact we may not store to it as we will
2906 invalidate any pending RSO and generate wrong gimple
2908 && !((TREE_CODE (var
) == RESULT_DECL
2909 || TREE_CODE (var
) == PARM_DECL
)
2910 && DECL_BY_REFERENCE (var
)))
2912 x
= build_sender_ref (ovar
, ctx
);
2913 gimplify_assign (var
, x
, olist
);
2920 /* A convenience function to build an empty GIMPLE_COND with just the
2924 gimple_build_cond_empty (tree cond
)
2926 enum tree_code pred_code
;
2929 gimple_cond_get_ops_from_tree (cond
, &pred_code
, &lhs
, &rhs
);
2930 return gimple_build_cond (pred_code
, lhs
, rhs
, NULL_TREE
, NULL_TREE
);
2934 /* Build the function calls to GOMP_parallel_start etc to actually
2935 generate the parallel operation. REGION is the parallel region
2936 being expanded. BB is the block where to insert the code. WS_ARGS
2937 will be set if this is a call to a combined parallel+workshare
2938 construct, it contains the list of additional arguments needed by
2939 the workshare construct. */
2942 expand_parallel_call (struct omp_region
*region
, basic_block bb
,
2943 gimple entry_stmt
, VEC(tree
,gc
) *ws_args
)
2945 tree t
, t1
, t2
, val
, cond
, c
, clauses
;
2946 gimple_stmt_iterator gsi
;
2948 enum built_in_function start_ix
;
2950 location_t clause_loc
;
2953 clauses
= gimple_omp_parallel_clauses (entry_stmt
);
2955 /* Determine what flavor of GOMP_parallel_start we will be
2957 start_ix
= BUILT_IN_GOMP_PARALLEL_START
;
2958 if (is_combined_parallel (region
))
2960 switch (region
->inner
->type
)
2962 case GIMPLE_OMP_FOR
:
2963 gcc_assert (region
->inner
->sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
2964 start_ix2
= ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2965 + (region
->inner
->sched_kind
2966 == OMP_CLAUSE_SCHEDULE_RUNTIME
2967 ? 3 : region
->inner
->sched_kind
));
2968 start_ix
= (enum built_in_function
)start_ix2
;
2970 case GIMPLE_OMP_SECTIONS
:
2971 start_ix
= BUILT_IN_GOMP_PARALLEL_SECTIONS_START
;
2978 /* By default, the value of NUM_THREADS is zero (selected at run time)
2979 and there is no conditional. */
2981 val
= build_int_cst (unsigned_type_node
, 0);
2983 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
2985 cond
= OMP_CLAUSE_IF_EXPR (c
);
2987 c
= find_omp_clause (clauses
, OMP_CLAUSE_NUM_THREADS
);
2990 val
= OMP_CLAUSE_NUM_THREADS_EXPR (c
);
2991 clause_loc
= OMP_CLAUSE_LOCATION (c
);
2994 clause_loc
= gimple_location (entry_stmt
);
2996 /* Ensure 'val' is of the correct type. */
2997 val
= fold_convert_loc (clause_loc
, unsigned_type_node
, val
);
2999 /* If we found the clause 'if (cond)', build either
3000 (cond != 0) or (cond ? val : 1u). */
3003 gimple_stmt_iterator gsi
;
3005 cond
= gimple_boolify (cond
);
3007 if (integer_zerop (val
))
3008 val
= fold_build2_loc (clause_loc
,
3009 EQ_EXPR
, unsigned_type_node
, cond
,
3010 build_int_cst (TREE_TYPE (cond
), 0));
3013 basic_block cond_bb
, then_bb
, else_bb
;
3014 edge e
, e_then
, e_else
;
3015 tree tmp_then
, tmp_else
, tmp_join
, tmp_var
;
3017 tmp_var
= create_tmp_var (TREE_TYPE (val
), NULL
);
3018 if (gimple_in_ssa_p (cfun
))
3020 tmp_then
= make_ssa_name (tmp_var
, NULL
);
3021 tmp_else
= make_ssa_name (tmp_var
, NULL
);
3022 tmp_join
= make_ssa_name (tmp_var
, NULL
);
3031 e
= split_block (bb
, NULL
);
3036 then_bb
= create_empty_bb (cond_bb
);
3037 else_bb
= create_empty_bb (then_bb
);
3038 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
3039 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
3041 stmt
= gimple_build_cond_empty (cond
);
3042 gsi
= gsi_start_bb (cond_bb
);
3043 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3045 gsi
= gsi_start_bb (then_bb
);
3046 stmt
= gimple_build_assign (tmp_then
, val
);
3047 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3049 gsi
= gsi_start_bb (else_bb
);
3050 stmt
= gimple_build_assign
3051 (tmp_else
, build_int_cst (unsigned_type_node
, 1));
3052 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3054 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
3055 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
3056 e_then
= make_edge (then_bb
, bb
, EDGE_FALLTHRU
);
3057 e_else
= make_edge (else_bb
, bb
, EDGE_FALLTHRU
);
3059 if (gimple_in_ssa_p (cfun
))
3061 gimple phi
= create_phi_node (tmp_join
, bb
);
3062 SSA_NAME_DEF_STMT (tmp_join
) = phi
;
3063 add_phi_arg (phi
, tmp_then
, e_then
, UNKNOWN_LOCATION
);
3064 add_phi_arg (phi
, tmp_else
, e_else
, UNKNOWN_LOCATION
);
3070 gsi
= gsi_start_bb (bb
);
3071 val
= force_gimple_operand_gsi (&gsi
, val
, true, NULL_TREE
,
3072 false, GSI_CONTINUE_LINKING
);
3075 gsi
= gsi_last_bb (bb
);
3076 t
= gimple_omp_parallel_data_arg (entry_stmt
);
3078 t1
= null_pointer_node
;
3080 t1
= build_fold_addr_expr (t
);
3081 t2
= build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt
));
3083 args
= VEC_alloc (tree
, gc
, 3 + VEC_length (tree
, ws_args
));
3084 VEC_quick_push (tree
, args
, t2
);
3085 VEC_quick_push (tree
, args
, t1
);
3086 VEC_quick_push (tree
, args
, val
);
3087 VEC_splice (tree
, args
, ws_args
);
3089 t
= build_call_expr_loc_vec (UNKNOWN_LOCATION
,
3090 builtin_decl_explicit (start_ix
), args
);
3092 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3093 false, GSI_CONTINUE_LINKING
);
3095 t
= gimple_omp_parallel_data_arg (entry_stmt
);
3097 t
= null_pointer_node
;
3099 t
= build_fold_addr_expr (t
);
3100 t
= build_call_expr_loc (gimple_location (entry_stmt
),
3101 gimple_omp_parallel_child_fn (entry_stmt
), 1, t
);
3102 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3103 false, GSI_CONTINUE_LINKING
);
3105 t
= build_call_expr_loc (gimple_location (entry_stmt
),
3106 builtin_decl_explicit (BUILT_IN_GOMP_PARALLEL_END
),
3108 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3109 false, GSI_CONTINUE_LINKING
);
3113 /* Build the function call to GOMP_task to actually
3114 generate the task operation. BB is the block where to insert the code. */
3117 expand_task_call (basic_block bb
, gimple entry_stmt
)
3119 tree t
, t1
, t2
, t3
, flags
, cond
, c
, c2
, clauses
;
3120 gimple_stmt_iterator gsi
;
3121 location_t loc
= gimple_location (entry_stmt
);
3123 clauses
= gimple_omp_task_clauses (entry_stmt
);
3125 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
3127 cond
= gimple_boolify (OMP_CLAUSE_IF_EXPR (c
));
3129 cond
= boolean_true_node
;
3131 c
= find_omp_clause (clauses
, OMP_CLAUSE_UNTIED
);
3132 c2
= find_omp_clause (clauses
, OMP_CLAUSE_MERGEABLE
);
3133 flags
= build_int_cst (unsigned_type_node
,
3134 (c
? 1 : 0) + (c2
? 4 : 0));
3136 c
= find_omp_clause (clauses
, OMP_CLAUSE_FINAL
);
3139 c
= gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c
));
3140 c
= fold_build3_loc (loc
, COND_EXPR
, unsigned_type_node
, c
,
3141 build_int_cst (unsigned_type_node
, 2),
3142 build_int_cst (unsigned_type_node
, 0));
3143 flags
= fold_build2_loc (loc
, PLUS_EXPR
, unsigned_type_node
, flags
, c
);
3146 gsi
= gsi_last_bb (bb
);
3147 t
= gimple_omp_task_data_arg (entry_stmt
);
3149 t2
= null_pointer_node
;
3151 t2
= build_fold_addr_expr_loc (loc
, t
);
3152 t1
= build_fold_addr_expr_loc (loc
, gimple_omp_task_child_fn (entry_stmt
));
3153 t
= gimple_omp_task_copy_fn (entry_stmt
);
3155 t3
= null_pointer_node
;
3157 t3
= build_fold_addr_expr_loc (loc
, t
);
3159 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK
),
3161 gimple_omp_task_arg_size (entry_stmt
),
3162 gimple_omp_task_arg_align (entry_stmt
), cond
, flags
);
3164 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3165 false, GSI_CONTINUE_LINKING
);
3169 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3170 catch handler and return it. This prevents programs from violating the
3171 structured block semantics with throws. */
3174 maybe_catch_exception (gimple_seq body
)
3179 if (!flag_exceptions
)
3182 if (lang_hooks
.eh_protect_cleanup_actions
!= NULL
)
3183 decl
= lang_hooks
.eh_protect_cleanup_actions ();
3185 decl
= builtin_decl_explicit (BUILT_IN_TRAP
);
3187 g
= gimple_build_eh_must_not_throw (decl
);
3188 g
= gimple_build_try (body
, gimple_seq_alloc_with_stmt (g
),
3191 return gimple_seq_alloc_with_stmt (g
);
3194 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3197 vec2chain (VEC(tree
,gc
) *v
)
3199 tree chain
= NULL_TREE
, t
;
3202 FOR_EACH_VEC_ELT_REVERSE (tree
, v
, ix
, t
)
3204 DECL_CHAIN (t
) = chain
;
3212 /* Remove barriers in REGION->EXIT's block. Note that this is only
3213 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3214 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3215 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3219 remove_exit_barrier (struct omp_region
*region
)
3221 gimple_stmt_iterator gsi
;
3222 basic_block exit_bb
;
3226 int any_addressable_vars
= -1;
3228 exit_bb
= region
->exit
;
3230 /* If the parallel region doesn't return, we don't have REGION->EXIT
3235 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3236 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3237 statements that can appear in between are extremely limited -- no
3238 memory operations at all. Here, we allow nothing at all, so the
3239 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3240 gsi
= gsi_last_bb (exit_bb
);
3241 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
3243 if (!gsi_end_p (gsi
) && gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
3246 FOR_EACH_EDGE (e
, ei
, exit_bb
->preds
)
3248 gsi
= gsi_last_bb (e
->src
);
3249 if (gsi_end_p (gsi
))
3251 stmt
= gsi_stmt (gsi
);
3252 if (gimple_code (stmt
) == GIMPLE_OMP_RETURN
3253 && !gimple_omp_return_nowait_p (stmt
))
3255 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3256 in many cases. If there could be tasks queued, the barrier
3257 might be needed to let the tasks run before some local
3258 variable of the parallel that the task uses as shared
3259 runs out of scope. The task can be spawned either
3260 from within current function (this would be easy to check)
3261 or from some function it calls and gets passed an address
3262 of such a variable. */
3263 if (any_addressable_vars
< 0)
3265 gimple parallel_stmt
= last_stmt (region
->entry
);
3266 tree child_fun
= gimple_omp_parallel_child_fn (parallel_stmt
);
3267 tree local_decls
, block
, decl
;
3270 any_addressable_vars
= 0;
3271 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun
), ix
, decl
)
3272 if (TREE_ADDRESSABLE (decl
))
3274 any_addressable_vars
= 1;
3277 for (block
= gimple_block (stmt
);
3278 !any_addressable_vars
3280 && TREE_CODE (block
) == BLOCK
;
3281 block
= BLOCK_SUPERCONTEXT (block
))
3283 for (local_decls
= BLOCK_VARS (block
);
3285 local_decls
= DECL_CHAIN (local_decls
))
3286 if (TREE_ADDRESSABLE (local_decls
))
3288 any_addressable_vars
= 1;
3291 if (block
== gimple_block (parallel_stmt
))
3295 if (!any_addressable_vars
)
3296 gimple_omp_return_set_nowait (stmt
);
3302 remove_exit_barriers (struct omp_region
*region
)
3304 if (region
->type
== GIMPLE_OMP_PARALLEL
)
3305 remove_exit_barrier (region
);
3309 region
= region
->inner
;
3310 remove_exit_barriers (region
);
3311 while (region
->next
)
3313 region
= region
->next
;
3314 remove_exit_barriers (region
);
3319 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3320 calls. These can't be declared as const functions, but
3321 within one parallel body they are constant, so they can be
3322 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3323 which are declared const. Similarly for task body, except
3324 that in untied task omp_get_thread_num () can change at any task
3325 scheduling point. */
3328 optimize_omp_library_calls (gimple entry_stmt
)
3331 gimple_stmt_iterator gsi
;
3332 tree thr_num_tree
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
3333 tree thr_num_id
= DECL_ASSEMBLER_NAME (thr_num_tree
);
3334 tree num_thr_tree
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
3335 tree num_thr_id
= DECL_ASSEMBLER_NAME (num_thr_tree
);
3336 bool untied_task
= (gimple_code (entry_stmt
) == GIMPLE_OMP_TASK
3337 && find_omp_clause (gimple_omp_task_clauses (entry_stmt
),
3338 OMP_CLAUSE_UNTIED
) != NULL
);
3341 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3343 gimple call
= gsi_stmt (gsi
);
3346 if (is_gimple_call (call
)
3347 && (decl
= gimple_call_fndecl (call
))
3348 && DECL_EXTERNAL (decl
)
3349 && TREE_PUBLIC (decl
)
3350 && DECL_INITIAL (decl
) == NULL
)
3354 if (DECL_NAME (decl
) == thr_num_id
)
3356 /* In #pragma omp task untied omp_get_thread_num () can change
3357 during the execution of the task region. */
3360 built_in
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
3362 else if (DECL_NAME (decl
) == num_thr_id
)
3363 built_in
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
3367 if (DECL_ASSEMBLER_NAME (decl
) != DECL_ASSEMBLER_NAME (built_in
)
3368 || gimple_call_num_args (call
) != 0)
3371 if (flag_exceptions
&& !TREE_NOTHROW (decl
))
3374 if (TREE_CODE (TREE_TYPE (decl
)) != FUNCTION_TYPE
3375 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl
)),
3376 TREE_TYPE (TREE_TYPE (built_in
))))
3379 gimple_call_set_fndecl (call
, built_in
);
3384 /* Expand the OpenMP parallel or task directive starting at REGION. */
3387 expand_omp_taskreg (struct omp_region
*region
)
3389 basic_block entry_bb
, exit_bb
, new_bb
;
3390 struct function
*child_cfun
;
3391 tree child_fn
, block
, t
;
3393 gimple_stmt_iterator gsi
;
3394 gimple entry_stmt
, stmt
;
3396 VEC(tree
,gc
) *ws_args
;
3398 entry_stmt
= last_stmt (region
->entry
);
3399 child_fn
= gimple_omp_taskreg_child_fn (entry_stmt
);
3400 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
3401 /* If this function has been already instrumented, make sure
3402 the child function isn't instrumented again. */
3403 child_cfun
->after_tree_profile
= cfun
->after_tree_profile
;
3405 entry_bb
= region
->entry
;
3406 exit_bb
= region
->exit
;
3408 if (is_combined_parallel (region
))
3409 ws_args
= region
->ws_args
;
3413 if (child_cfun
->cfg
)
3415 /* Due to inlining, it may happen that we have already outlined
3416 the region, in which case all we need to do is make the
3417 sub-graph unreachable and emit the parallel call. */
3418 edge entry_succ_e
, exit_succ_e
;
3419 gimple_stmt_iterator gsi
;
3421 entry_succ_e
= single_succ_edge (entry_bb
);
3423 gsi
= gsi_last_bb (entry_bb
);
3424 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_PARALLEL
3425 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_TASK
);
3426 gsi_remove (&gsi
, true);
3431 exit_succ_e
= single_succ_edge (exit_bb
);
3432 make_edge (new_bb
, exit_succ_e
->dest
, EDGE_FALLTHRU
);
3434 remove_edge_and_dominated_blocks (entry_succ_e
);
3438 unsigned srcidx
, dstidx
, num
;
3440 /* If the parallel region needs data sent from the parent
3441 function, then the very first statement (except possible
3442 tree profile counter updates) of the parallel body
3443 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3444 &.OMP_DATA_O is passed as an argument to the child function,
3445 we need to replace it with the argument as seen by the child
3448 In most cases, this will end up being the identity assignment
3449 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3450 a function call that has been inlined, the original PARM_DECL
3451 .OMP_DATA_I may have been converted into a different local
3452 variable. In which case, we need to keep the assignment. */
3453 if (gimple_omp_taskreg_data_arg (entry_stmt
))
3455 basic_block entry_succ_bb
= single_succ (entry_bb
);
3456 gimple_stmt_iterator gsi
;
3458 gimple parcopy_stmt
= NULL
;
3460 for (gsi
= gsi_start_bb (entry_succ_bb
); ; gsi_next (&gsi
))
3464 gcc_assert (!gsi_end_p (gsi
));
3465 stmt
= gsi_stmt (gsi
);
3466 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
3469 if (gimple_num_ops (stmt
) == 2)
3471 tree arg
= gimple_assign_rhs1 (stmt
);
3473 /* We're ignore the subcode because we're
3474 effectively doing a STRIP_NOPS. */
3476 if (TREE_CODE (arg
) == ADDR_EXPR
3477 && TREE_OPERAND (arg
, 0)
3478 == gimple_omp_taskreg_data_arg (entry_stmt
))
3480 parcopy_stmt
= stmt
;
3486 gcc_assert (parcopy_stmt
!= NULL
);
3487 arg
= DECL_ARGUMENTS (child_fn
);
3489 if (!gimple_in_ssa_p (cfun
))
3491 if (gimple_assign_lhs (parcopy_stmt
) == arg
)
3492 gsi_remove (&gsi
, true);
3495 /* ?? Is setting the subcode really necessary ?? */
3496 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (arg
));
3497 gimple_assign_set_rhs1 (parcopy_stmt
, arg
);
3502 /* If we are in ssa form, we must load the value from the default
3503 definition of the argument. That should not be defined now,
3504 since the argument is not used uninitialized. */
3505 gcc_assert (gimple_default_def (cfun
, arg
) == NULL
);
3506 narg
= make_ssa_name (arg
, gimple_build_nop ());
3507 set_default_def (arg
, narg
);
3508 /* ?? Is setting the subcode really necessary ?? */
3509 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (narg
));
3510 gimple_assign_set_rhs1 (parcopy_stmt
, narg
);
3511 update_stmt (parcopy_stmt
);
3515 /* Declare local variables needed in CHILD_CFUN. */
3516 block
= DECL_INITIAL (child_fn
);
3517 BLOCK_VARS (block
) = vec2chain (child_cfun
->local_decls
);
3518 /* The gimplifier could record temporaries in parallel/task block
3519 rather than in containing function's local_decls chain,
3520 which would mean cgraph missed finalizing them. Do it now. */
3521 for (t
= BLOCK_VARS (block
); t
; t
= DECL_CHAIN (t
))
3522 if (TREE_CODE (t
) == VAR_DECL
3524 && !DECL_EXTERNAL (t
))
3525 varpool_finalize_decl (t
);
3526 DECL_SAVED_TREE (child_fn
) = NULL
;
3527 /* We'll create a CFG for child_fn, so no gimple body is needed. */
3528 gimple_set_body (child_fn
, NULL
);
3529 TREE_USED (block
) = 1;
3531 /* Reset DECL_CONTEXT on function arguments. */
3532 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
3533 DECL_CONTEXT (t
) = child_fn
;
3535 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3536 so that it can be moved to the child function. */
3537 gsi
= gsi_last_bb (entry_bb
);
3538 stmt
= gsi_stmt (gsi
);
3539 gcc_assert (stmt
&& (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
3540 || gimple_code (stmt
) == GIMPLE_OMP_TASK
));
3541 gsi_remove (&gsi
, true);
3542 e
= split_block (entry_bb
, stmt
);
3544 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
3546 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3549 gsi
= gsi_last_bb (exit_bb
);
3550 gcc_assert (!gsi_end_p (gsi
)
3551 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
3552 stmt
= gimple_build_return (NULL
);
3553 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
3554 gsi_remove (&gsi
, true);
3557 /* Move the parallel region into CHILD_CFUN. */
3559 if (gimple_in_ssa_p (cfun
))
3561 init_tree_ssa (child_cfun
);
3562 init_ssa_operands (child_cfun
);
3563 child_cfun
->gimple_df
->in_ssa_p
= true;
3567 block
= gimple_block (entry_stmt
);
3569 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
, block
);
3571 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
3573 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3574 num
= VEC_length (tree
, child_cfun
->local_decls
);
3575 for (srcidx
= 0, dstidx
= 0; srcidx
< num
; srcidx
++)
3577 t
= VEC_index (tree
, child_cfun
->local_decls
, srcidx
);
3578 if (DECL_CONTEXT (t
) == cfun
->decl
)
3580 if (srcidx
!= dstidx
)
3581 VEC_replace (tree
, child_cfun
->local_decls
, dstidx
, t
);
3585 VEC_truncate (tree
, child_cfun
->local_decls
, dstidx
);
3587 /* Inform the callgraph about the new function. */
3588 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
3589 = cfun
->curr_properties
& ~PROP_loops
;
3590 cgraph_add_new_function (child_fn
, true);
3592 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3593 fixed in a following pass. */
3594 push_cfun (child_cfun
);
3595 save_current
= current_function_decl
;
3596 current_function_decl
= child_fn
;
3598 optimize_omp_library_calls (entry_stmt
);
3599 rebuild_cgraph_edges ();
3601 /* Some EH regions might become dead, see PR34608. If
3602 pass_cleanup_cfg isn't the first pass to happen with the
3603 new child, these dead EH edges might cause problems.
3604 Clean them up now. */
3605 if (flag_exceptions
)
3608 bool changed
= false;
3611 changed
|= gimple_purge_dead_eh_edges (bb
);
3613 cleanup_tree_cfg ();
3615 if (gimple_in_ssa_p (cfun
))
3616 update_ssa (TODO_update_ssa
);
3617 current_function_decl
= save_current
;
3621 /* Emit a library call to launch the children threads. */
3622 if (gimple_code (entry_stmt
) == GIMPLE_OMP_PARALLEL
)
3623 expand_parallel_call (region
, new_bb
, entry_stmt
, ws_args
);
3625 expand_task_call (new_bb
, entry_stmt
);
3626 if (gimple_in_ssa_p (cfun
))
3627 update_ssa (TODO_update_ssa_only_virtuals
);
3631 /* A subroutine of expand_omp_for. Generate code for a parallel
3632 loop with any schedule. Given parameters:
3634 for (V = N1; V cond N2; V += STEP) BODY;
3636 where COND is "<" or ">", we generate pseudocode
3638 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3639 if (more) goto L0; else goto L3;
3646 if (V cond iend) goto L1; else goto L2;
3648 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3651 If this is a combined omp parallel loop, instead of the call to
3652 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3654 For collapsed loops, given parameters:
3656 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3657 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3658 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3661 we generate pseudocode
3667 count3 = (adj + N32 - N31) / STEP3;
3672 count2 = (adj + N22 - N21) / STEP2;
3677 count1 = (adj + N12 - N11) / STEP1;
3678 count = count1 * count2 * count3;
3679 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3680 if (more) goto L0; else goto L3;
3684 V3 = N31 + (T % count3) * STEP3;
3686 V2 = N21 + (T % count2) * STEP2;
3688 V1 = N11 + T * STEP1;
3693 if (V < iend) goto L10; else goto L2;
3696 if (V3 cond3 N32) goto L1; else goto L11;
3700 if (V2 cond2 N22) goto L1; else goto L12;
3706 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3712 expand_omp_for_generic (struct omp_region
*region
,
3713 struct omp_for_data
*fd
,
3714 enum built_in_function start_fn
,
3715 enum built_in_function next_fn
)
3717 tree type
, istart0
, iend0
, iend
;
3718 tree t
, vmain
, vback
, bias
= NULL_TREE
;
3719 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
, collapse_bb
;
3720 basic_block l2_bb
= NULL
, l3_bb
= NULL
;
3721 gimple_stmt_iterator gsi
;
3723 bool in_combined_parallel
= is_combined_parallel (region
);
3724 bool broken_loop
= region
->cont
== NULL
;
3726 tree
*counts
= NULL
;
3729 gcc_assert (!broken_loop
|| !in_combined_parallel
);
3730 gcc_assert (fd
->iter_type
== long_integer_type_node
3731 || !in_combined_parallel
);
3733 type
= TREE_TYPE (fd
->loop
.v
);
3734 istart0
= create_tmp_var (fd
->iter_type
, ".istart0");
3735 iend0
= create_tmp_var (fd
->iter_type
, ".iend0");
3736 TREE_ADDRESSABLE (istart0
) = 1;
3737 TREE_ADDRESSABLE (iend0
) = 1;
3738 if (gimple_referenced_vars (cfun
))
3740 add_referenced_var (istart0
);
3741 add_referenced_var (iend0
);
3744 /* See if we need to bias by LLONG_MIN. */
3745 if (fd
->iter_type
== long_long_unsigned_type_node
3746 && TREE_CODE (type
) == INTEGER_TYPE
3747 && !TYPE_UNSIGNED (type
))
3751 if (fd
->loop
.cond_code
== LT_EXPR
)
3754 n2
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
3758 n1
= fold_build2 (MINUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
3761 if (TREE_CODE (n1
) != INTEGER_CST
3762 || TREE_CODE (n2
) != INTEGER_CST
3763 || ((tree_int_cst_sgn (n1
) < 0) ^ (tree_int_cst_sgn (n2
) < 0)))
3764 bias
= fold_convert (fd
->iter_type
, TYPE_MIN_VALUE (type
));
3767 entry_bb
= region
->entry
;
3768 cont_bb
= region
->cont
;
3770 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
3771 gcc_assert (broken_loop
3772 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
3773 l0_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
3774 l1_bb
= single_succ (l0_bb
);
3777 l2_bb
= create_empty_bb (cont_bb
);
3778 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l1_bb
);
3779 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
3783 l3_bb
= BRANCH_EDGE (entry_bb
)->dest
;
3784 exit_bb
= region
->exit
;
3786 gsi
= gsi_last_bb (entry_bb
);
3788 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
3789 if (fd
->collapse
> 1)
3791 /* collapsed loops need work for expansion in SSA form. */
3792 gcc_assert (!gimple_in_ssa_p (cfun
));
3793 counts
= (tree
*) alloca (fd
->collapse
* sizeof (tree
));
3794 for (i
= 0; i
< fd
->collapse
; i
++)
3796 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
3798 if (POINTER_TYPE_P (itype
))
3799 itype
= signed_type_for (itype
);
3800 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
== LT_EXPR
3802 t
= fold_build2 (PLUS_EXPR
, itype
,
3803 fold_convert (itype
, fd
->loops
[i
].step
), t
);
3804 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
3805 fold_convert (itype
, fd
->loops
[i
].n2
));
3806 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
3807 fold_convert (itype
, fd
->loops
[i
].n1
));
3808 if (TYPE_UNSIGNED (itype
) && fd
->loops
[i
].cond_code
== GT_EXPR
)
3809 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
3810 fold_build1 (NEGATE_EXPR
, itype
, t
),
3811 fold_build1 (NEGATE_EXPR
, itype
,
3812 fold_convert (itype
,
3813 fd
->loops
[i
].step
)));
3815 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
,
3816 fold_convert (itype
, fd
->loops
[i
].step
));
3817 t
= fold_convert (type
, t
);
3818 if (TREE_CODE (t
) == INTEGER_CST
)
3822 counts
[i
] = make_rename_temp (type
, ".count");
3823 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3824 true, GSI_SAME_STMT
);
3825 stmt
= gimple_build_assign (counts
[i
], t
);
3826 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3828 if (SSA_VAR_P (fd
->loop
.n2
))
3834 t
= fold_build2 (MULT_EXPR
, type
, fd
->loop
.n2
, counts
[i
]);
3835 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3836 true, GSI_SAME_STMT
);
3838 stmt
= gimple_build_assign (fd
->loop
.n2
, t
);
3839 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3843 if (in_combined_parallel
)
3845 /* In a combined parallel loop, emit a call to
3846 GOMP_loop_foo_next. */
3847 t
= build_call_expr (builtin_decl_explicit (next_fn
), 2,
3848 build_fold_addr_expr (istart0
),
3849 build_fold_addr_expr (iend0
));
3853 tree t0
, t1
, t2
, t3
, t4
;
3854 /* If this is not a combined parallel loop, emit a call to
3855 GOMP_loop_foo_start in ENTRY_BB. */
3856 t4
= build_fold_addr_expr (iend0
);
3857 t3
= build_fold_addr_expr (istart0
);
3858 t2
= fold_convert (fd
->iter_type
, fd
->loop
.step
);
3859 if (POINTER_TYPE_P (type
)
3860 && TYPE_PRECISION (type
) != TYPE_PRECISION (fd
->iter_type
))
3862 /* Avoid casting pointers to integer of a different size. */
3863 tree itype
= signed_type_for (type
);
3864 t1
= fold_convert (fd
->iter_type
, fold_convert (itype
, fd
->loop
.n2
));
3865 t0
= fold_convert (fd
->iter_type
, fold_convert (itype
, fd
->loop
.n1
));
3869 t1
= fold_convert (fd
->iter_type
, fd
->loop
.n2
);
3870 t0
= fold_convert (fd
->iter_type
, fd
->loop
.n1
);
3874 t1
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t1
, bias
);
3875 t0
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t0
, bias
);
3877 if (fd
->iter_type
== long_integer_type_node
)
3881 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
3882 t
= build_call_expr (builtin_decl_explicit (start_fn
),
3883 6, t0
, t1
, t2
, t
, t3
, t4
);
3886 t
= build_call_expr (builtin_decl_explicit (start_fn
),
3887 5, t0
, t1
, t2
, t3
, t4
);
3895 /* The GOMP_loop_ull_*start functions have additional boolean
3896 argument, true for < loops and false for > loops.
3897 In Fortran, the C bool type can be different from
3898 boolean_type_node. */
3899 bfn_decl
= builtin_decl_explicit (start_fn
);
3900 c_bool_type
= TREE_TYPE (TREE_TYPE (bfn_decl
));
3901 t5
= build_int_cst (c_bool_type
,
3902 fd
->loop
.cond_code
== LT_EXPR
? 1 : 0);
3905 tree bfn_decl
= builtin_decl_explicit (start_fn
);
3906 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
3907 t
= build_call_expr (bfn_decl
, 7, t5
, t0
, t1
, t2
, t
, t3
, t4
);
3910 t
= build_call_expr (builtin_decl_explicit (start_fn
),
3911 6, t5
, t0
, t1
, t2
, t3
, t4
);
3914 if (TREE_TYPE (t
) != boolean_type_node
)
3915 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
3916 t
, build_int_cst (TREE_TYPE (t
), 0));
3917 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3918 true, GSI_SAME_STMT
);
3919 gsi_insert_after (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
3921 /* Remove the GIMPLE_OMP_FOR statement. */
3922 gsi_remove (&gsi
, true);
3924 /* Iteration setup for sequential loop goes in L0_BB. */
3925 gsi
= gsi_start_bb (l0_bb
);
3928 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
3929 if (POINTER_TYPE_P (type
))
3930 t
= fold_convert (signed_type_for (type
), t
);
3931 t
= fold_convert (type
, t
);
3932 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3933 false, GSI_CONTINUE_LINKING
);
3934 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
3935 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3939 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
3940 if (POINTER_TYPE_P (type
))
3941 t
= fold_convert (signed_type_for (type
), t
);
3942 t
= fold_convert (type
, t
);
3943 iend
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3944 false, GSI_CONTINUE_LINKING
);
3945 if (fd
->collapse
> 1)
3947 tree tem
= make_rename_temp (type
, ".tem");
3948 stmt
= gimple_build_assign (tem
, fd
->loop
.v
);
3949 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3950 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
3952 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
), itype
;
3954 if (POINTER_TYPE_P (vtype
))
3955 itype
= signed_type_for (vtype
);
3956 t
= fold_build2 (TRUNC_MOD_EXPR
, type
, tem
, counts
[i
]);
3957 t
= fold_convert (itype
, t
);
3958 t
= fold_build2 (MULT_EXPR
, itype
, t
,
3959 fold_convert (itype
, fd
->loops
[i
].step
));
3960 if (POINTER_TYPE_P (vtype
))
3961 t
= fold_build_pointer_plus (fd
->loops
[i
].n1
, t
);
3963 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[i
].n1
, t
);
3964 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3965 false, GSI_CONTINUE_LINKING
);
3966 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
3967 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3970 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, tem
, counts
[i
]);
3971 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3972 false, GSI_CONTINUE_LINKING
);
3973 stmt
= gimple_build_assign (tem
, t
);
3974 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3981 /* Code to control the increment and predicate for the sequential
3982 loop goes in the CONT_BB. */
3983 gsi
= gsi_last_bb (cont_bb
);
3984 stmt
= gsi_stmt (gsi
);
3985 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
3986 vmain
= gimple_omp_continue_control_use (stmt
);
3987 vback
= gimple_omp_continue_control_def (stmt
);
3989 if (POINTER_TYPE_P (type
))
3990 t
= fold_build_pointer_plus (vmain
, fd
->loop
.step
);
3992 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
3993 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3994 true, GSI_SAME_STMT
);
3995 stmt
= gimple_build_assign (vback
, t
);
3996 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3998 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, vback
, iend
);
3999 stmt
= gimple_build_cond_empty (t
);
4000 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4002 /* Remove GIMPLE_OMP_CONTINUE. */
4003 gsi_remove (&gsi
, true);
4005 if (fd
->collapse
> 1)
4007 basic_block last_bb
, bb
;
4010 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
4012 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
);
4014 bb
= create_empty_bb (last_bb
);
4015 gsi
= gsi_start_bb (bb
);
4017 if (i
< fd
->collapse
- 1)
4019 e
= make_edge (last_bb
, bb
, EDGE_FALSE_VALUE
);
4020 e
->probability
= REG_BR_PROB_BASE
/ 8;
4022 t
= fd
->loops
[i
+ 1].n1
;
4023 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4024 false, GSI_CONTINUE_LINKING
);
4025 stmt
= gimple_build_assign (fd
->loops
[i
+ 1].v
, t
);
4026 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4031 set_immediate_dominator (CDI_DOMINATORS
, bb
, last_bb
);
4033 if (POINTER_TYPE_P (vtype
))
4034 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, fd
->loops
[i
].step
);
4036 t
= fold_build2 (PLUS_EXPR
, vtype
, fd
->loops
[i
].v
,
4038 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4039 false, GSI_CONTINUE_LINKING
);
4040 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
4041 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4045 t
= fd
->loops
[i
].n2
;
4046 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4047 false, GSI_CONTINUE_LINKING
);
4048 t
= fold_build2 (fd
->loops
[i
].cond_code
, boolean_type_node
,
4050 stmt
= gimple_build_cond_empty (t
);
4051 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4052 e
= make_edge (bb
, l1_bb
, EDGE_TRUE_VALUE
);
4053 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
4056 make_edge (bb
, l1_bb
, EDGE_FALLTHRU
);
4061 /* Emit code to get the next parallel iteration in L2_BB. */
4062 gsi
= gsi_start_bb (l2_bb
);
4064 t
= build_call_expr (builtin_decl_explicit (next_fn
), 2,
4065 build_fold_addr_expr (istart0
),
4066 build_fold_addr_expr (iend0
));
4067 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4068 false, GSI_CONTINUE_LINKING
);
4069 if (TREE_TYPE (t
) != boolean_type_node
)
4070 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
4071 t
, build_int_cst (TREE_TYPE (t
), 0));
4072 stmt
= gimple_build_cond_empty (t
);
4073 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4076 /* Add the loop cleanup function. */
4077 gsi
= gsi_last_bb (exit_bb
);
4078 if (gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4079 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT
);
4081 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END
);
4082 stmt
= gimple_build_call (t
, 0);
4083 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
4084 gsi_remove (&gsi
, true);
4086 /* Connect the new blocks. */
4087 find_edge (entry_bb
, l0_bb
)->flags
= EDGE_TRUE_VALUE
;
4088 find_edge (entry_bb
, l3_bb
)->flags
= EDGE_FALSE_VALUE
;
4094 e
= find_edge (cont_bb
, l3_bb
);
4095 ne
= make_edge (l2_bb
, l3_bb
, EDGE_FALSE_VALUE
);
4097 phis
= phi_nodes (l3_bb
);
4098 for (gsi
= gsi_start (phis
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4100 gimple phi
= gsi_stmt (gsi
);
4101 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, ne
),
4102 PHI_ARG_DEF_FROM_EDGE (phi
, e
));
4106 make_edge (cont_bb
, l2_bb
, EDGE_FALSE_VALUE
);
4107 if (fd
->collapse
> 1)
4109 e
= find_edge (cont_bb
, l1_bb
);
4111 e
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
4115 e
= find_edge (cont_bb
, l1_bb
);
4116 e
->flags
= EDGE_TRUE_VALUE
;
4118 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
4119 find_edge (cont_bb
, l2_bb
)->probability
= REG_BR_PROB_BASE
/ 8;
4120 make_edge (l2_bb
, l0_bb
, EDGE_TRUE_VALUE
);
4122 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
,
4123 recompute_dominator (CDI_DOMINATORS
, l2_bb
));
4124 set_immediate_dominator (CDI_DOMINATORS
, l3_bb
,
4125 recompute_dominator (CDI_DOMINATORS
, l3_bb
));
4126 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
,
4127 recompute_dominator (CDI_DOMINATORS
, l0_bb
));
4128 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
,
4129 recompute_dominator (CDI_DOMINATORS
, l1_bb
));
4134 /* A subroutine of expand_omp_for. Generate code for a parallel
4135 loop with static schedule and no specified chunk size. Given
4138 for (V = N1; V cond N2; V += STEP) BODY;
4140 where COND is "<" or ">", we generate pseudocode
4146 if ((__typeof (V)) -1 > 0 && cond is >)
4147 n = -(adj + N2 - N1) / -STEP;
4149 n = (adj + N2 - N1) / STEP;
4152 if (threadid < tt) goto L3; else goto L4;
4157 s0 = q * threadid + tt;
4160 if (s0 >= e0) goto L2; else goto L0;
4166 if (V cond e) goto L1;
4171 expand_omp_for_static_nochunk (struct omp_region
*region
,
4172 struct omp_for_data
*fd
)
4174 tree n
, q
, s0
, e0
, e
, t
, tt
, nthreads
, threadid
;
4175 tree type
, itype
, vmain
, vback
;
4176 basic_block entry_bb
, second_bb
, third_bb
, exit_bb
, seq_start_bb
;
4177 basic_block body_bb
, cont_bb
;
4179 gimple_stmt_iterator gsi
;
4183 itype
= type
= TREE_TYPE (fd
->loop
.v
);
4184 if (POINTER_TYPE_P (type
))
4185 itype
= signed_type_for (type
);
4187 entry_bb
= region
->entry
;
4188 cont_bb
= region
->cont
;
4189 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
4190 gcc_assert (BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
4191 seq_start_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
4192 body_bb
= single_succ (seq_start_bb
);
4193 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
4194 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
4195 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
4196 exit_bb
= region
->exit
;
4198 /* Iteration space partitioning goes in ENTRY_BB. */
4199 gsi
= gsi_last_bb (entry_bb
);
4200 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4202 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
), 0);
4203 t
= fold_convert (itype
, t
);
4204 nthreads
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4205 true, GSI_SAME_STMT
);
4207 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
), 0);
4208 t
= fold_convert (itype
, t
);
4209 threadid
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4210 true, GSI_SAME_STMT
);
4213 = force_gimple_operand_gsi (&gsi
, fold_convert (type
, fd
->loop
.n1
),
4214 true, NULL_TREE
, true, GSI_SAME_STMT
);
4216 = force_gimple_operand_gsi (&gsi
, fold_convert (itype
, fd
->loop
.n2
),
4217 true, NULL_TREE
, true, GSI_SAME_STMT
);
4219 = force_gimple_operand_gsi (&gsi
, fold_convert (itype
, fd
->loop
.step
),
4220 true, NULL_TREE
, true, GSI_SAME_STMT
);
4222 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
4223 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loop
.step
, t
);
4224 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fd
->loop
.n2
);
4225 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, fd
->loop
.n1
));
4226 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
4227 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4228 fold_build1 (NEGATE_EXPR
, itype
, t
),
4229 fold_build1 (NEGATE_EXPR
, itype
, fd
->loop
.step
));
4231 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, fd
->loop
.step
);
4232 t
= fold_convert (itype
, t
);
4233 n
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4235 q
= make_rename_temp (itype
, "q");
4236 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, n
, nthreads
);
4237 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, true, GSI_SAME_STMT
);
4238 gsi_insert_before (&gsi
, gimple_build_assign (q
, t
), GSI_SAME_STMT
);
4240 tt
= make_rename_temp (itype
, "tt");
4241 t
= fold_build2 (TRUNC_MOD_EXPR
, itype
, n
, nthreads
);
4242 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, true, GSI_SAME_STMT
);
4243 gsi_insert_before (&gsi
, gimple_build_assign (tt
, t
), GSI_SAME_STMT
);
4245 t
= build2 (LT_EXPR
, boolean_type_node
, threadid
, tt
);
4246 stmt
= gimple_build_cond_empty (t
);
4247 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4249 second_bb
= split_block (entry_bb
, stmt
)->dest
;
4250 gsi
= gsi_last_bb (second_bb
);
4251 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4253 gsi_insert_before (&gsi
, gimple_build_assign (tt
, build_int_cst (itype
, 0)),
4255 stmt
= gimple_build_assign_with_ops (PLUS_EXPR
, q
, q
,
4256 build_int_cst (itype
, 1));
4257 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4259 third_bb
= split_block (second_bb
, stmt
)->dest
;
4260 gsi
= gsi_last_bb (third_bb
);
4261 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4263 t
= build2 (MULT_EXPR
, itype
, q
, threadid
);
4264 t
= build2 (PLUS_EXPR
, itype
, t
, tt
);
4265 s0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4267 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, q
);
4268 e0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4270 t
= build2 (GE_EXPR
, boolean_type_node
, s0
, e0
);
4271 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4273 /* Remove the GIMPLE_OMP_FOR statement. */
4274 gsi_remove (&gsi
, true);
4276 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4277 gsi
= gsi_start_bb (seq_start_bb
);
4279 t
= fold_convert (itype
, s0
);
4280 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4281 if (POINTER_TYPE_P (type
))
4282 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4284 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4285 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4286 false, GSI_CONTINUE_LINKING
);
4287 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4288 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4290 t
= fold_convert (itype
, e0
);
4291 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4292 if (POINTER_TYPE_P (type
))
4293 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4295 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4296 e
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4297 false, GSI_CONTINUE_LINKING
);
4299 /* The code controlling the sequential loop replaces the
4300 GIMPLE_OMP_CONTINUE. */
4301 gsi
= gsi_last_bb (cont_bb
);
4302 stmt
= gsi_stmt (gsi
);
4303 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4304 vmain
= gimple_omp_continue_control_use (stmt
);
4305 vback
= gimple_omp_continue_control_def (stmt
);
4307 if (POINTER_TYPE_P (type
))
4308 t
= fold_build_pointer_plus (vmain
, fd
->loop
.step
);
4310 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
4311 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4312 true, GSI_SAME_STMT
);
4313 stmt
= gimple_build_assign (vback
, t
);
4314 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4316 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, vback
, e
);
4317 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4319 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4320 gsi_remove (&gsi
, true);
4322 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4323 gsi
= gsi_last_bb (exit_bb
);
4324 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4325 force_gimple_operand_gsi (&gsi
, build_omp_barrier (), false, NULL_TREE
,
4326 false, GSI_SAME_STMT
);
4327 gsi_remove (&gsi
, true);
4329 /* Connect all the blocks. */
4330 ep
= make_edge (entry_bb
, third_bb
, EDGE_FALSE_VALUE
);
4331 ep
->probability
= REG_BR_PROB_BASE
/ 4 * 3;
4332 ep
= find_edge (entry_bb
, second_bb
);
4333 ep
->flags
= EDGE_TRUE_VALUE
;
4334 ep
->probability
= REG_BR_PROB_BASE
/ 4;
4335 find_edge (third_bb
, seq_start_bb
)->flags
= EDGE_FALSE_VALUE
;
4336 find_edge (third_bb
, fin_bb
)->flags
= EDGE_TRUE_VALUE
;
4338 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
4339 find_edge (cont_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
4341 set_immediate_dominator (CDI_DOMINATORS
, second_bb
, entry_bb
);
4342 set_immediate_dominator (CDI_DOMINATORS
, third_bb
, entry_bb
);
4343 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
, third_bb
);
4344 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
4345 recompute_dominator (CDI_DOMINATORS
, body_bb
));
4346 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
4347 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
4351 /* A subroutine of expand_omp_for. Generate code for a parallel
4352 loop with static schedule and a specified chunk size. Given
4355 for (V = N1; V cond N2; V += STEP) BODY;
4357 where COND is "<" or ">", we generate pseudocode
4363 if ((__typeof (V)) -1 > 0 && cond is >)
4364 n = -(adj + N2 - N1) / -STEP;
4366 n = (adj + N2 - N1) / STEP;
4368 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4369 here so that V is defined
4370 if the loop is not entered
4372 s0 = (trip * nthreads + threadid) * CHUNK;
4373 e0 = min(s0 + CHUNK, n);
4374 if (s0 < n) goto L1; else goto L4;
4381 if (V cond e) goto L2; else goto L3;
4389 expand_omp_for_static_chunk (struct omp_region
*region
, struct omp_for_data
*fd
)
4391 tree n
, s0
, e0
, e
, t
;
4392 tree trip_var
, trip_init
, trip_main
, trip_back
, nthreads
, threadid
;
4393 tree type
, itype
, v_main
, v_back
, v_extra
;
4394 basic_block entry_bb
, exit_bb
, body_bb
, seq_start_bb
, iter_part_bb
;
4395 basic_block trip_update_bb
, cont_bb
, fin_bb
;
4396 gimple_stmt_iterator si
;
4400 itype
= type
= TREE_TYPE (fd
->loop
.v
);
4401 if (POINTER_TYPE_P (type
))
4402 itype
= signed_type_for (type
);
4404 entry_bb
= region
->entry
;
4405 se
= split_block (entry_bb
, last_stmt (entry_bb
));
4407 iter_part_bb
= se
->dest
;
4408 cont_bb
= region
->cont
;
4409 gcc_assert (EDGE_COUNT (iter_part_bb
->succs
) == 2);
4410 gcc_assert (BRANCH_EDGE (iter_part_bb
)->dest
4411 == FALLTHRU_EDGE (cont_bb
)->dest
);
4412 seq_start_bb
= split_edge (FALLTHRU_EDGE (iter_part_bb
));
4413 body_bb
= single_succ (seq_start_bb
);
4414 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
4415 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
4416 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
4417 trip_update_bb
= split_edge (FALLTHRU_EDGE (cont_bb
));
4418 exit_bb
= region
->exit
;
4420 /* Trip and adjustment setup goes in ENTRY_BB. */
4421 si
= gsi_last_bb (entry_bb
);
4422 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_FOR
);
4424 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
), 0);
4425 t
= fold_convert (itype
, t
);
4426 nthreads
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4427 true, GSI_SAME_STMT
);
4429 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
), 0);
4430 t
= fold_convert (itype
, t
);
4431 threadid
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4432 true, GSI_SAME_STMT
);
4435 = force_gimple_operand_gsi (&si
, fold_convert (type
, fd
->loop
.n1
),
4436 true, NULL_TREE
, true, GSI_SAME_STMT
);
4438 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->loop
.n2
),
4439 true, NULL_TREE
, true, GSI_SAME_STMT
);
4441 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->loop
.step
),
4442 true, NULL_TREE
, true, GSI_SAME_STMT
);
4444 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->chunk_size
),
4445 true, NULL_TREE
, true, GSI_SAME_STMT
);
4447 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
4448 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loop
.step
, t
);
4449 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fd
->loop
.n2
);
4450 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, fd
->loop
.n1
));
4451 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
4452 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4453 fold_build1 (NEGATE_EXPR
, itype
, t
),
4454 fold_build1 (NEGATE_EXPR
, itype
, fd
->loop
.step
));
4456 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, fd
->loop
.step
);
4457 t
= fold_convert (itype
, t
);
4458 n
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4459 true, GSI_SAME_STMT
);
4461 trip_var
= create_tmp_reg (itype
, ".trip");
4462 if (gimple_in_ssa_p (cfun
))
4464 add_referenced_var (trip_var
);
4465 trip_init
= make_ssa_name (trip_var
, NULL
);
4466 trip_main
= make_ssa_name (trip_var
, NULL
);
4467 trip_back
= make_ssa_name (trip_var
, NULL
);
4471 trip_init
= trip_var
;
4472 trip_main
= trip_var
;
4473 trip_back
= trip_var
;
4476 stmt
= gimple_build_assign (trip_init
, build_int_cst (itype
, 0));
4477 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4479 t
= fold_build2 (MULT_EXPR
, itype
, threadid
, fd
->chunk_size
);
4480 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4481 if (POINTER_TYPE_P (type
))
4482 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4484 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4485 v_extra
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4486 true, GSI_SAME_STMT
);
4488 /* Remove the GIMPLE_OMP_FOR. */
4489 gsi_remove (&si
, true);
4491 /* Iteration space partitioning goes in ITER_PART_BB. */
4492 si
= gsi_last_bb (iter_part_bb
);
4494 t
= fold_build2 (MULT_EXPR
, itype
, trip_main
, nthreads
);
4495 t
= fold_build2 (PLUS_EXPR
, itype
, t
, threadid
);
4496 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->chunk_size
);
4497 s0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4498 false, GSI_CONTINUE_LINKING
);
4500 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, fd
->chunk_size
);
4501 t
= fold_build2 (MIN_EXPR
, itype
, t
, n
);
4502 e0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4503 false, GSI_CONTINUE_LINKING
);
4505 t
= build2 (LT_EXPR
, boolean_type_node
, s0
, n
);
4506 gsi_insert_after (&si
, gimple_build_cond_empty (t
), GSI_CONTINUE_LINKING
);
4508 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4509 si
= gsi_start_bb (seq_start_bb
);
4511 t
= fold_convert (itype
, s0
);
4512 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4513 if (POINTER_TYPE_P (type
))
4514 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4516 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4517 t
= force_gimple_operand_gsi (&si
, t
, false, NULL_TREE
,
4518 false, GSI_CONTINUE_LINKING
);
4519 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4520 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4522 t
= fold_convert (itype
, e0
);
4523 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4524 if (POINTER_TYPE_P (type
))
4525 t
= fold_build_pointer_plus (fd
->loop
.n1
, t
);
4527 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4528 e
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4529 false, GSI_CONTINUE_LINKING
);
4531 /* The code controlling the sequential loop goes in CONT_BB,
4532 replacing the GIMPLE_OMP_CONTINUE. */
4533 si
= gsi_last_bb (cont_bb
);
4534 stmt
= gsi_stmt (si
);
4535 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4536 v_main
= gimple_omp_continue_control_use (stmt
);
4537 v_back
= gimple_omp_continue_control_def (stmt
);
4539 if (POINTER_TYPE_P (type
))
4540 t
= fold_build_pointer_plus (v_main
, fd
->loop
.step
);
4542 t
= fold_build2 (PLUS_EXPR
, type
, v_main
, fd
->loop
.step
);
4543 stmt
= gimple_build_assign (v_back
, t
);
4544 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4546 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, v_back
, e
);
4547 gsi_insert_before (&si
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4549 /* Remove GIMPLE_OMP_CONTINUE. */
4550 gsi_remove (&si
, true);
4552 /* Trip update code goes into TRIP_UPDATE_BB. */
4553 si
= gsi_start_bb (trip_update_bb
);
4555 t
= build_int_cst (itype
, 1);
4556 t
= build2 (PLUS_EXPR
, itype
, trip_main
, t
);
4557 stmt
= gimple_build_assign (trip_back
, t
);
4558 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4560 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4561 si
= gsi_last_bb (exit_bb
);
4562 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)))
4563 force_gimple_operand_gsi (&si
, build_omp_barrier (), false, NULL_TREE
,
4564 false, GSI_SAME_STMT
);
4565 gsi_remove (&si
, true);
4567 /* Connect the new blocks. */
4568 find_edge (iter_part_bb
, seq_start_bb
)->flags
= EDGE_TRUE_VALUE
;
4569 find_edge (iter_part_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
4571 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
4572 find_edge (cont_bb
, trip_update_bb
)->flags
= EDGE_FALSE_VALUE
;
4574 redirect_edge_and_branch (single_succ_edge (trip_update_bb
), iter_part_bb
);
4576 if (gimple_in_ssa_p (cfun
))
4578 gimple_stmt_iterator psi
;
4581 edge_var_map_vector head
;
4585 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4586 remove arguments of the phi nodes in fin_bb. We need to create
4587 appropriate phi nodes in iter_part_bb instead. */
4588 se
= single_pred_edge (fin_bb
);
4589 re
= single_succ_edge (trip_update_bb
);
4590 head
= redirect_edge_var_map_vector (re
);
4591 ene
= single_succ_edge (entry_bb
);
4593 psi
= gsi_start_phis (fin_bb
);
4594 for (i
= 0; !gsi_end_p (psi
) && VEC_iterate (edge_var_map
, head
, i
, vm
);
4595 gsi_next (&psi
), ++i
)
4598 source_location locus
;
4600 phi
= gsi_stmt (psi
);
4601 t
= gimple_phi_result (phi
);
4602 gcc_assert (t
== redirect_edge_var_map_result (vm
));
4603 nphi
= create_phi_node (t
, iter_part_bb
);
4604 SSA_NAME_DEF_STMT (t
) = nphi
;
4606 t
= PHI_ARG_DEF_FROM_EDGE (phi
, se
);
4607 locus
= gimple_phi_arg_location_from_edge (phi
, se
);
4609 /* A special case -- fd->loop.v is not yet computed in
4610 iter_part_bb, we need to use v_extra instead. */
4611 if (t
== fd
->loop
.v
)
4613 add_phi_arg (nphi
, t
, ene
, locus
);
4614 locus
= redirect_edge_var_map_location (vm
);
4615 add_phi_arg (nphi
, redirect_edge_var_map_def (vm
), re
, locus
);
4617 gcc_assert (!gsi_end_p (psi
) && i
== VEC_length (edge_var_map
, head
));
4618 redirect_edge_var_map_clear (re
);
4621 psi
= gsi_start_phis (fin_bb
);
4622 if (gsi_end_p (psi
))
4624 remove_phi_node (&psi
, false);
4627 /* Make phi node for trip. */
4628 phi
= create_phi_node (trip_main
, iter_part_bb
);
4629 SSA_NAME_DEF_STMT (trip_main
) = phi
;
4630 add_phi_arg (phi
, trip_back
, single_succ_edge (trip_update_bb
),
4632 add_phi_arg (phi
, trip_init
, single_succ_edge (entry_bb
),
4636 set_immediate_dominator (CDI_DOMINATORS
, trip_update_bb
, cont_bb
);
4637 set_immediate_dominator (CDI_DOMINATORS
, iter_part_bb
,
4638 recompute_dominator (CDI_DOMINATORS
, iter_part_bb
));
4639 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
4640 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
4641 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
,
4642 recompute_dominator (CDI_DOMINATORS
, seq_start_bb
));
4643 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
4644 recompute_dominator (CDI_DOMINATORS
, body_bb
));
4648 /* Expand the OpenMP loop defined by REGION. */
4651 expand_omp_for (struct omp_region
*region
)
4653 struct omp_for_data fd
;
4654 struct omp_for_data_loop
*loops
;
4657 = (struct omp_for_data_loop
*)
4658 alloca (gimple_omp_for_collapse (last_stmt (region
->entry
))
4659 * sizeof (struct omp_for_data_loop
));
4660 extract_omp_for_data (last_stmt (region
->entry
), &fd
, loops
);
4661 region
->sched_kind
= fd
.sched_kind
;
4663 gcc_assert (EDGE_COUNT (region
->entry
->succs
) == 2);
4664 BRANCH_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
4665 FALLTHRU_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
4668 gcc_assert (EDGE_COUNT (region
->cont
->succs
) == 2);
4669 BRANCH_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
4670 FALLTHRU_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
4673 if (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
4676 && region
->cont
!= NULL
)
4678 if (fd
.chunk_size
== NULL
)
4679 expand_omp_for_static_nochunk (region
, &fd
);
4681 expand_omp_for_static_chunk (region
, &fd
);
4685 int fn_index
, start_ix
, next_ix
;
4687 if (fd
.chunk_size
== NULL
4688 && fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
4689 fd
.chunk_size
= integer_zero_node
;
4690 gcc_assert (fd
.sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
4691 fn_index
= (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
4692 ? 3 : fd
.sched_kind
;
4693 fn_index
+= fd
.have_ordered
* 4;
4694 start_ix
= ((int)BUILT_IN_GOMP_LOOP_STATIC_START
) + fn_index
;
4695 next_ix
= ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT
) + fn_index
;
4696 if (fd
.iter_type
== long_long_unsigned_type_node
)
4698 start_ix
+= ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4699 - (int)BUILT_IN_GOMP_LOOP_STATIC_START
);
4700 next_ix
+= ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4701 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT
);
4703 expand_omp_for_generic (region
, &fd
, (enum built_in_function
) start_ix
,
4704 (enum built_in_function
) next_ix
);
4707 if (gimple_in_ssa_p (cfun
))
4708 update_ssa (TODO_update_ssa_only_virtuals
);
4712 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4714 v = GOMP_sections_start (n);
4731 v = GOMP_sections_next ();
4736 If this is a combined parallel sections, replace the call to
4737 GOMP_sections_start with call to GOMP_sections_next. */
4740 expand_omp_sections (struct omp_region
*region
)
4742 tree t
, u
, vin
= NULL
, vmain
, vnext
, l2
;
4743 VEC (tree
,heap
) *label_vec
;
4745 basic_block entry_bb
, l0_bb
, l1_bb
, l2_bb
, default_bb
;
4746 gimple_stmt_iterator si
, switch_si
;
4747 gimple sections_stmt
, stmt
, cont
;
4750 struct omp_region
*inner
;
4752 bool exit_reachable
= region
->cont
!= NULL
;
4754 gcc_assert (exit_reachable
== (region
->exit
!= NULL
));
4755 entry_bb
= region
->entry
;
4756 l0_bb
= single_succ (entry_bb
);
4757 l1_bb
= region
->cont
;
4758 l2_bb
= region
->exit
;
4761 if (single_pred_p (l2_bb
) && single_pred (l2_bb
) == l0_bb
)
4762 l2
= gimple_block_label (l2_bb
);
4765 /* This can happen if there are reductions. */
4766 len
= EDGE_COUNT (l0_bb
->succs
);
4767 gcc_assert (len
> 0);
4768 e
= EDGE_SUCC (l0_bb
, len
- 1);
4769 si
= gsi_last_bb (e
->dest
);
4772 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
4773 l2
= gimple_block_label (e
->dest
);
4775 FOR_EACH_EDGE (e
, ei
, l0_bb
->succs
)
4777 si
= gsi_last_bb (e
->dest
);
4779 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
4781 l2
= gimple_block_label (e
->dest
);
4786 default_bb
= create_empty_bb (l1_bb
->prev_bb
);
4790 default_bb
= create_empty_bb (l0_bb
);
4791 l2
= gimple_block_label (default_bb
);
4794 /* We will build a switch() with enough cases for all the
4795 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4796 and a default case to abort if something goes wrong. */
4797 len
= EDGE_COUNT (l0_bb
->succs
);
4799 /* Use VEC_quick_push on label_vec throughout, since we know the size
4801 label_vec
= VEC_alloc (tree
, heap
, len
);
4803 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4804 GIMPLE_OMP_SECTIONS statement. */
4805 si
= gsi_last_bb (entry_bb
);
4806 sections_stmt
= gsi_stmt (si
);
4807 gcc_assert (gimple_code (sections_stmt
) == GIMPLE_OMP_SECTIONS
);
4808 vin
= gimple_omp_sections_control (sections_stmt
);
4809 if (!is_combined_parallel (region
))
4811 /* If we are not inside a combined parallel+sections region,
4812 call GOMP_sections_start. */
4813 t
= build_int_cst (unsigned_type_node
,
4814 exit_reachable
? len
- 1 : len
);
4815 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START
);
4816 stmt
= gimple_build_call (u
, 1, t
);
4820 /* Otherwise, call GOMP_sections_next. */
4821 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT
);
4822 stmt
= gimple_build_call (u
, 0);
4824 gimple_call_set_lhs (stmt
, vin
);
4825 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4826 gsi_remove (&si
, true);
4828 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4830 switch_si
= gsi_last_bb (l0_bb
);
4831 gcc_assert (gimple_code (gsi_stmt (switch_si
)) == GIMPLE_OMP_SECTIONS_SWITCH
);
4834 cont
= last_stmt (l1_bb
);
4835 gcc_assert (gimple_code (cont
) == GIMPLE_OMP_CONTINUE
);
4836 vmain
= gimple_omp_continue_control_use (cont
);
4837 vnext
= gimple_omp_continue_control_def (cont
);
4848 t
= build_case_label (build_int_cst (unsigned_type_node
, 0), NULL
, l2
);
4849 VEC_quick_push (tree
, label_vec
, t
);
4853 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4854 for (inner
= region
->inner
, casei
= 1;
4856 inner
= inner
->next
, i
++, casei
++)
4858 basic_block s_entry_bb
, s_exit_bb
;
4860 /* Skip optional reduction region. */
4861 if (inner
->type
== GIMPLE_OMP_ATOMIC_LOAD
)
4868 s_entry_bb
= inner
->entry
;
4869 s_exit_bb
= inner
->exit
;
4871 t
= gimple_block_label (s_entry_bb
);
4872 u
= build_int_cst (unsigned_type_node
, casei
);
4873 u
= build_case_label (u
, NULL
, t
);
4874 VEC_quick_push (tree
, label_vec
, u
);
4876 si
= gsi_last_bb (s_entry_bb
);
4877 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SECTION
);
4878 gcc_assert (i
< len
|| gimple_omp_section_last_p (gsi_stmt (si
)));
4879 gsi_remove (&si
, true);
4880 single_succ_edge (s_entry_bb
)->flags
= EDGE_FALLTHRU
;
4882 if (s_exit_bb
== NULL
)
4885 si
= gsi_last_bb (s_exit_bb
);
4886 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
4887 gsi_remove (&si
, true);
4889 single_succ_edge (s_exit_bb
)->flags
= EDGE_FALLTHRU
;
4892 /* Error handling code goes in DEFAULT_BB. */
4893 t
= gimple_block_label (default_bb
);
4894 u
= build_case_label (NULL
, NULL
, t
);
4895 make_edge (l0_bb
, default_bb
, 0);
4897 stmt
= gimple_build_switch_vec (vmain
, u
, label_vec
);
4898 gsi_insert_after (&switch_si
, stmt
, GSI_SAME_STMT
);
4899 gsi_remove (&switch_si
, true);
4900 VEC_free (tree
, heap
, label_vec
);
4902 si
= gsi_start_bb (default_bb
);
4903 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
4904 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4910 /* Code to get the next section goes in L1_BB. */
4911 si
= gsi_last_bb (l1_bb
);
4912 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CONTINUE
);
4914 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT
);
4915 stmt
= gimple_build_call (bfn_decl
, 0);
4916 gimple_call_set_lhs (stmt
, vnext
);
4917 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4918 gsi_remove (&si
, true);
4920 single_succ_edge (l1_bb
)->flags
= EDGE_FALLTHRU
;
4922 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4923 si
= gsi_last_bb (l2_bb
);
4924 if (gimple_omp_return_nowait_p (gsi_stmt (si
)))
4925 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT
);
4927 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END
);
4928 stmt
= gimple_build_call (t
, 0);
4929 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4930 gsi_remove (&si
, true);
4933 set_immediate_dominator (CDI_DOMINATORS
, default_bb
, l0_bb
);
4937 /* Expand code for an OpenMP single directive. We've already expanded
4938 much of the code, here we simply place the GOMP_barrier call. */
4941 expand_omp_single (struct omp_region
*region
)
4943 basic_block entry_bb
, exit_bb
;
4944 gimple_stmt_iterator si
;
4945 bool need_barrier
= false;
4947 entry_bb
= region
->entry
;
4948 exit_bb
= region
->exit
;
4950 si
= gsi_last_bb (entry_bb
);
4951 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4952 be removed. We need to ensure that the thread that entered the single
4953 does not exit before the data is copied out by the other threads. */
4954 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si
)),
4955 OMP_CLAUSE_COPYPRIVATE
))
4956 need_barrier
= true;
4957 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
);
4958 gsi_remove (&si
, true);
4959 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
4961 si
= gsi_last_bb (exit_bb
);
4962 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)) || need_barrier
)
4963 force_gimple_operand_gsi (&si
, build_omp_barrier (), false, NULL_TREE
,
4964 false, GSI_SAME_STMT
);
4965 gsi_remove (&si
, true);
4966 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
4970 /* Generic expansion for OpenMP synchronization directives: master,
4971 ordered and critical. All we need to do here is remove the entry
4972 and exit markers for REGION. */
4975 expand_omp_synch (struct omp_region
*region
)
4977 basic_block entry_bb
, exit_bb
;
4978 gimple_stmt_iterator si
;
4980 entry_bb
= region
->entry
;
4981 exit_bb
= region
->exit
;
4983 si
= gsi_last_bb (entry_bb
);
4984 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
4985 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_MASTER
4986 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ORDERED
4987 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CRITICAL
);
4988 gsi_remove (&si
, true);
4989 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
4993 si
= gsi_last_bb (exit_bb
);
4994 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
4995 gsi_remove (&si
, true);
4996 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
5000 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5001 operation as a normal volatile load. */
5004 expand_omp_atomic_load (basic_block load_bb
, tree addr
,
5005 tree loaded_val
, int index
)
5007 enum built_in_function tmpbase
;
5008 gimple_stmt_iterator gsi
;
5009 basic_block store_bb
;
5012 tree decl
, call
, type
, itype
;
5014 gsi
= gsi_last_bb (load_bb
);
5015 stmt
= gsi_stmt (gsi
);
5016 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_LOAD
);
5017 loc
= gimple_location (stmt
);
5019 /* ??? If the target does not implement atomic_load_optab[mode], and mode
5020 is smaller than word size, then expand_atomic_load assumes that the load
5021 is atomic. We could avoid the builtin entirely in this case. */
5023 tmpbase
= (enum built_in_function
) (BUILT_IN_ATOMIC_LOAD_N
+ index
+ 1);
5024 decl
= builtin_decl_explicit (tmpbase
);
5025 if (decl
== NULL_TREE
)
5028 type
= TREE_TYPE (loaded_val
);
5029 itype
= TREE_TYPE (TREE_TYPE (decl
));
5031 call
= build_call_expr_loc (loc
, decl
, 2, addr
,
5032 build_int_cst (NULL
, MEMMODEL_RELAXED
));
5033 if (!useless_type_conversion_p (type
, itype
))
5034 call
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, type
, call
);
5035 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, loaded_val
, call
);
5037 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5038 gsi_remove (&gsi
, true);
5040 store_bb
= single_succ (load_bb
);
5041 gsi
= gsi_last_bb (store_bb
);
5042 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
5043 gsi_remove (&gsi
, true);
5045 if (gimple_in_ssa_p (cfun
))
5046 update_ssa (TODO_update_ssa_no_phi
);
5051 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5052 operation as a normal volatile store. */
5055 expand_omp_atomic_store (basic_block load_bb
, tree addr
,
5056 tree loaded_val
, tree stored_val
, int index
)
5058 enum built_in_function tmpbase
;
5059 gimple_stmt_iterator gsi
;
5060 basic_block store_bb
= single_succ (load_bb
);
5063 tree decl
, call
, type
, itype
;
5064 enum machine_mode imode
;
5067 gsi
= gsi_last_bb (load_bb
);
5068 stmt
= gsi_stmt (gsi
);
5069 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_LOAD
);
5071 /* If the load value is needed, then this isn't a store but an exchange. */
5072 exchange
= gimple_omp_atomic_need_value_p (stmt
);
5074 gsi
= gsi_last_bb (store_bb
);
5075 stmt
= gsi_stmt (gsi
);
5076 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_STORE
);
5077 loc
= gimple_location (stmt
);
5079 /* ??? If the target does not implement atomic_store_optab[mode], and mode
5080 is smaller than word size, then expand_atomic_store assumes that the store
5081 is atomic. We could avoid the builtin entirely in this case. */
5083 tmpbase
= (exchange
? BUILT_IN_ATOMIC_EXCHANGE_N
: BUILT_IN_ATOMIC_STORE_N
);
5084 tmpbase
= (enum built_in_function
) ((int) tmpbase
+ index
+ 1);
5085 decl
= builtin_decl_explicit (tmpbase
);
5086 if (decl
== NULL_TREE
)
5089 type
= TREE_TYPE (stored_val
);
5091 /* Dig out the type of the function's second argument. */
5092 itype
= TREE_TYPE (decl
);
5093 itype
= TYPE_ARG_TYPES (itype
);
5094 itype
= TREE_CHAIN (itype
);
5095 itype
= TREE_VALUE (itype
);
5096 imode
= TYPE_MODE (itype
);
5098 if (exchange
&& !can_atomic_exchange_p (imode
, true))
5101 if (!useless_type_conversion_p (itype
, type
))
5102 stored_val
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, itype
, stored_val
);
5103 call
= build_call_expr_loc (loc
, decl
, 3, addr
, stored_val
,
5104 build_int_cst (NULL
, MEMMODEL_RELAXED
));
5107 if (!useless_type_conversion_p (type
, itype
))
5108 call
= build1_loc (loc
, VIEW_CONVERT_EXPR
, type
, call
);
5109 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, loaded_val
, call
);
5112 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5113 gsi_remove (&gsi
, true);
5115 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
5116 gsi
= gsi_last_bb (load_bb
);
5117 gsi_remove (&gsi
, true);
5119 if (gimple_in_ssa_p (cfun
))
5120 update_ssa (TODO_update_ssa_no_phi
);
5125 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
5126 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
5127 size of the data type, and thus usable to find the index of the builtin
5128 decl. Returns false if the expression is not of the proper form. */
5131 expand_omp_atomic_fetch_op (basic_block load_bb
,
5132 tree addr
, tree loaded_val
,
5133 tree stored_val
, int index
)
5135 enum built_in_function oldbase
, newbase
, tmpbase
;
5136 tree decl
, itype
, call
;
5138 basic_block store_bb
= single_succ (load_bb
);
5139 gimple_stmt_iterator gsi
;
5142 enum tree_code code
;
5143 bool need_old
, need_new
;
5144 enum machine_mode imode
;
5146 /* We expect to find the following sequences:
5149 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
5152 val = tmp OP something; (or: something OP tmp)
5153 GIMPLE_OMP_STORE (val)
5155 ???FIXME: Allow a more flexible sequence.
5156 Perhaps use data flow to pick the statements.
5160 gsi
= gsi_after_labels (store_bb
);
5161 stmt
= gsi_stmt (gsi
);
5162 loc
= gimple_location (stmt
);
5163 if (!is_gimple_assign (stmt
))
5166 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_OMP_ATOMIC_STORE
)
5168 need_new
= gimple_omp_atomic_need_value_p (gsi_stmt (gsi
));
5169 need_old
= gimple_omp_atomic_need_value_p (last_stmt (load_bb
));
5170 gcc_checking_assert (!need_old
|| !need_new
);
5172 if (!operand_equal_p (gimple_assign_lhs (stmt
), stored_val
, 0))
5175 /* Check for one of the supported fetch-op operations. */
5176 code
= gimple_assign_rhs_code (stmt
);
5180 case POINTER_PLUS_EXPR
:
5181 oldbase
= BUILT_IN_ATOMIC_FETCH_ADD_N
;
5182 newbase
= BUILT_IN_ATOMIC_ADD_FETCH_N
;
5185 oldbase
= BUILT_IN_ATOMIC_FETCH_SUB_N
;
5186 newbase
= BUILT_IN_ATOMIC_SUB_FETCH_N
;
5189 oldbase
= BUILT_IN_ATOMIC_FETCH_AND_N
;
5190 newbase
= BUILT_IN_ATOMIC_AND_FETCH_N
;
5193 oldbase
= BUILT_IN_ATOMIC_FETCH_OR_N
;
5194 newbase
= BUILT_IN_ATOMIC_OR_FETCH_N
;
5197 oldbase
= BUILT_IN_ATOMIC_FETCH_XOR_N
;
5198 newbase
= BUILT_IN_ATOMIC_XOR_FETCH_N
;
5204 /* Make sure the expression is of the proper form. */
5205 if (operand_equal_p (gimple_assign_rhs1 (stmt
), loaded_val
, 0))
5206 rhs
= gimple_assign_rhs2 (stmt
);
5207 else if (commutative_tree_code (gimple_assign_rhs_code (stmt
))
5208 && operand_equal_p (gimple_assign_rhs2 (stmt
), loaded_val
, 0))
5209 rhs
= gimple_assign_rhs1 (stmt
);
5213 tmpbase
= ((enum built_in_function
)
5214 ((need_new
? newbase
: oldbase
) + index
+ 1));
5215 decl
= builtin_decl_explicit (tmpbase
);
5216 if (decl
== NULL_TREE
)
5218 itype
= TREE_TYPE (TREE_TYPE (decl
));
5219 imode
= TYPE_MODE (itype
);
5221 /* We could test all of the various optabs involved, but the fact of the
5222 matter is that (with the exception of i486 vs i586 and xadd) all targets
5223 that support any atomic operaton optab also implements compare-and-swap.
5224 Let optabs.c take care of expanding any compare-and-swap loop. */
5225 if (!can_compare_and_swap_p (imode
, true))
5228 gsi
= gsi_last_bb (load_bb
);
5229 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5231 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
5232 It only requires that the operation happen atomically. Thus we can
5233 use the RELAXED memory model. */
5234 call
= build_call_expr_loc (loc
, decl
, 3, addr
,
5235 fold_convert_loc (loc
, itype
, rhs
),
5236 build_int_cst (NULL
, MEMMODEL_RELAXED
));
5238 if (need_old
|| need_new
)
5240 lhs
= need_old
? loaded_val
: stored_val
;
5241 call
= fold_convert_loc (loc
, TREE_TYPE (lhs
), call
);
5242 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, lhs
, call
);
5245 call
= fold_convert_loc (loc
, void_type_node
, call
);
5246 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5247 gsi_remove (&gsi
, true);
5249 gsi
= gsi_last_bb (store_bb
);
5250 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
5251 gsi_remove (&gsi
, true);
5252 gsi
= gsi_last_bb (store_bb
);
5253 gsi_remove (&gsi
, true);
5255 if (gimple_in_ssa_p (cfun
))
5256 update_ssa (TODO_update_ssa_no_phi
);
5261 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5265 newval = rhs; // with oldval replacing *addr in rhs
5266 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5267 if (oldval != newval)
5270 INDEX is log2 of the size of the data type, and thus usable to find the
5271 index of the builtin decl. */
5274 expand_omp_atomic_pipeline (basic_block load_bb
, basic_block store_bb
,
5275 tree addr
, tree loaded_val
, tree stored_val
,
5278 tree loadedi
, storedi
, initial
, new_storedi
, old_vali
;
5279 tree type
, itype
, cmpxchg
, iaddr
;
5280 gimple_stmt_iterator si
;
5281 basic_block loop_header
= single_succ (load_bb
);
5284 enum built_in_function fncode
;
5286 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
5287 order to use the RELAXED memory model effectively. */
5288 fncode
= (enum built_in_function
)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
5290 cmpxchg
= builtin_decl_explicit (fncode
);
5291 if (cmpxchg
== NULL_TREE
)
5293 type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
5294 itype
= TREE_TYPE (TREE_TYPE (cmpxchg
));
5296 if (!can_compare_and_swap_p (TYPE_MODE (itype
), true))
5299 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5300 si
= gsi_last_bb (load_bb
);
5301 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5303 /* For floating-point values, we'll need to view-convert them to integers
5304 so that we can perform the atomic compare and swap. Simplify the
5305 following code by always setting up the "i"ntegral variables. */
5306 if (!INTEGRAL_TYPE_P (type
) && !POINTER_TYPE_P (type
))
5310 iaddr
= make_rename_temp (build_pointer_type_for_mode (itype
, ptr_mode
,
5313 = force_gimple_operand_gsi (&si
,
5314 fold_convert (TREE_TYPE (iaddr
), addr
),
5315 false, NULL_TREE
, true, GSI_SAME_STMT
);
5316 stmt
= gimple_build_assign (iaddr
, iaddr_val
);
5317 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5318 loadedi
= create_tmp_var (itype
, NULL
);
5319 if (gimple_in_ssa_p (cfun
))
5321 add_referenced_var (iaddr
);
5322 add_referenced_var (loadedi
);
5323 loadedi
= make_ssa_name (loadedi
, NULL
);
5329 loadedi
= loaded_val
;
5333 = force_gimple_operand_gsi (&si
,
5334 build2 (MEM_REF
, TREE_TYPE (TREE_TYPE (iaddr
)),
5336 build_int_cst (TREE_TYPE (iaddr
), 0)),
5337 true, NULL_TREE
, true, GSI_SAME_STMT
);
5339 /* Move the value to the LOADEDI temporary. */
5340 if (gimple_in_ssa_p (cfun
))
5342 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header
)));
5343 phi
= create_phi_node (loadedi
, loop_header
);
5344 SSA_NAME_DEF_STMT (loadedi
) = phi
;
5345 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, single_succ_edge (load_bb
)),
5349 gsi_insert_before (&si
,
5350 gimple_build_assign (loadedi
, initial
),
5352 if (loadedi
!= loaded_val
)
5354 gimple_stmt_iterator gsi2
;
5357 x
= build1 (VIEW_CONVERT_EXPR
, type
, loadedi
);
5358 gsi2
= gsi_start_bb (loop_header
);
5359 if (gimple_in_ssa_p (cfun
))
5362 x
= force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
5363 true, GSI_SAME_STMT
);
5364 stmt
= gimple_build_assign (loaded_val
, x
);
5365 gsi_insert_before (&gsi2
, stmt
, GSI_SAME_STMT
);
5369 x
= build2 (MODIFY_EXPR
, TREE_TYPE (loaded_val
), loaded_val
, x
);
5370 force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
5371 true, GSI_SAME_STMT
);
5374 gsi_remove (&si
, true);
5376 si
= gsi_last_bb (store_bb
);
5377 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
5380 storedi
= stored_val
;
5383 force_gimple_operand_gsi (&si
,
5384 build1 (VIEW_CONVERT_EXPR
, itype
,
5385 stored_val
), true, NULL_TREE
, true,
5388 /* Build the compare&swap statement. */
5389 new_storedi
= build_call_expr (cmpxchg
, 3, iaddr
, loadedi
, storedi
);
5390 new_storedi
= force_gimple_operand_gsi (&si
,
5391 fold_convert (TREE_TYPE (loadedi
),
5394 true, GSI_SAME_STMT
);
5396 if (gimple_in_ssa_p (cfun
))
5400 old_vali
= create_tmp_var (TREE_TYPE (loadedi
), NULL
);
5401 if (gimple_in_ssa_p (cfun
))
5402 add_referenced_var (old_vali
);
5403 stmt
= gimple_build_assign (old_vali
, loadedi
);
5404 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5406 stmt
= gimple_build_assign (loadedi
, new_storedi
);
5407 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5410 /* Note that we always perform the comparison as an integer, even for
5411 floating point. This allows the atomic operation to properly
5412 succeed even with NaNs and -0.0. */
5413 stmt
= gimple_build_cond_empty
5414 (build2 (NE_EXPR
, boolean_type_node
,
5415 new_storedi
, old_vali
));
5416 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5419 e
= single_succ_edge (store_bb
);
5420 e
->flags
&= ~EDGE_FALLTHRU
;
5421 e
->flags
|= EDGE_FALSE_VALUE
;
5423 e
= make_edge (store_bb
, loop_header
, EDGE_TRUE_VALUE
);
5425 /* Copy the new value to loadedi (we already did that before the condition
5426 if we are not in SSA). */
5427 if (gimple_in_ssa_p (cfun
))
5429 phi
= gimple_seq_first_stmt (phi_nodes (loop_header
));
5430 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, e
), new_storedi
);
5433 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5434 gsi_remove (&si
, true);
5436 if (gimple_in_ssa_p (cfun
))
5437 update_ssa (TODO_update_ssa_no_phi
);
5442 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5444 GOMP_atomic_start ();
5448 The result is not globally atomic, but works so long as all parallel
5449 references are within #pragma omp atomic directives. According to
5450 responses received from omp@openmp.org, appears to be within spec.
5451 Which makes sense, since that's how several other compilers handle
5452 this situation as well.
5453 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5454 expanding. STORED_VAL is the operand of the matching
5455 GIMPLE_OMP_ATOMIC_STORE.
5458 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5462 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
5467 expand_omp_atomic_mutex (basic_block load_bb
, basic_block store_bb
,
5468 tree addr
, tree loaded_val
, tree stored_val
)
5470 gimple_stmt_iterator si
;
5474 si
= gsi_last_bb (load_bb
);
5475 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5477 t
= builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START
);
5478 t
= build_call_expr (t
, 0);
5479 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5481 stmt
= gimple_build_assign (loaded_val
, build_simple_mem_ref (addr
));
5482 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5483 gsi_remove (&si
, true);
5485 si
= gsi_last_bb (store_bb
);
5486 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
5488 stmt
= gimple_build_assign (build_simple_mem_ref (unshare_expr (addr
)),
5490 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5492 t
= builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END
);
5493 t
= build_call_expr (t
, 0);
5494 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5495 gsi_remove (&si
, true);
5497 if (gimple_in_ssa_p (cfun
))
5498 update_ssa (TODO_update_ssa_no_phi
);
5502 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5503 using expand_omp_atomic_fetch_op. If it failed, we try to
5504 call expand_omp_atomic_pipeline, and if it fails too, the
5505 ultimate fallback is wrapping the operation in a mutex
5506 (expand_omp_atomic_mutex). REGION is the atomic region built
5507 by build_omp_regions_1(). */
5510 expand_omp_atomic (struct omp_region
*region
)
5512 basic_block load_bb
= region
->entry
, store_bb
= region
->exit
;
5513 gimple load
= last_stmt (load_bb
), store
= last_stmt (store_bb
);
5514 tree loaded_val
= gimple_omp_atomic_load_lhs (load
);
5515 tree addr
= gimple_omp_atomic_load_rhs (load
);
5516 tree stored_val
= gimple_omp_atomic_store_val (store
);
5517 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
5518 HOST_WIDE_INT index
;
5520 /* Make sure the type is one of the supported sizes. */
5521 index
= tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
5522 index
= exact_log2 (index
);
5523 if (index
>= 0 && index
<= 4)
5525 unsigned int align
= TYPE_ALIGN_UNIT (type
);
5527 /* __sync builtins require strict data alignment. */
5528 if (exact_log2 (align
) >= index
)
5531 if (loaded_val
== stored_val
5532 && (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_INT
5533 || GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
)
5534 && GET_MODE_BITSIZE (TYPE_MODE (type
)) <= BITS_PER_WORD
5535 && expand_omp_atomic_load (load_bb
, addr
, loaded_val
, index
))
5539 if ((GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_INT
5540 || GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
)
5541 && GET_MODE_BITSIZE (TYPE_MODE (type
)) <= BITS_PER_WORD
5542 && store_bb
== single_succ (load_bb
)
5543 && first_stmt (store_bb
) == store
5544 && expand_omp_atomic_store (load_bb
, addr
, loaded_val
,
5548 /* When possible, use specialized atomic update functions. */
5549 if ((INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
))
5550 && store_bb
== single_succ (load_bb
)
5551 && expand_omp_atomic_fetch_op (load_bb
, addr
,
5552 loaded_val
, stored_val
, index
))
5555 /* If we don't have specialized __sync builtins, try and implement
5556 as a compare and swap loop. */
5557 if (expand_omp_atomic_pipeline (load_bb
, store_bb
, addr
,
5558 loaded_val
, stored_val
, index
))
5563 /* The ultimate fallback is wrapping the operation in a mutex. */
5564 expand_omp_atomic_mutex (load_bb
, store_bb
, addr
, loaded_val
, stored_val
);
5568 /* Expand the parallel region tree rooted at REGION. Expansion
5569 proceeds in depth-first order. Innermost regions are expanded
5570 first. This way, parallel regions that require a new function to
5571 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5572 internal dependencies in their body. */
5575 expand_omp (struct omp_region
*region
)
5579 location_t saved_location
;
5581 /* First, determine whether this is a combined parallel+workshare
5583 if (region
->type
== GIMPLE_OMP_PARALLEL
)
5584 determine_parallel_type (region
);
5587 expand_omp (region
->inner
);
5589 saved_location
= input_location
;
5590 if (gimple_has_location (last_stmt (region
->entry
)))
5591 input_location
= gimple_location (last_stmt (region
->entry
));
5593 switch (region
->type
)
5595 case GIMPLE_OMP_PARALLEL
:
5596 case GIMPLE_OMP_TASK
:
5597 expand_omp_taskreg (region
);
5600 case GIMPLE_OMP_FOR
:
5601 expand_omp_for (region
);
5604 case GIMPLE_OMP_SECTIONS
:
5605 expand_omp_sections (region
);
5608 case GIMPLE_OMP_SECTION
:
5609 /* Individual omp sections are handled together with their
5610 parent GIMPLE_OMP_SECTIONS region. */
5613 case GIMPLE_OMP_SINGLE
:
5614 expand_omp_single (region
);
5617 case GIMPLE_OMP_MASTER
:
5618 case GIMPLE_OMP_ORDERED
:
5619 case GIMPLE_OMP_CRITICAL
:
5620 expand_omp_synch (region
);
5623 case GIMPLE_OMP_ATOMIC_LOAD
:
5624 expand_omp_atomic (region
);
5631 input_location
= saved_location
;
5632 region
= region
->next
;
5637 /* Helper for build_omp_regions. Scan the dominator tree starting at
5638 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5639 true, the function ends once a single tree is built (otherwise, whole
5640 forest of OMP constructs may be built). */
5643 build_omp_regions_1 (basic_block bb
, struct omp_region
*parent
,
5646 gimple_stmt_iterator gsi
;
5650 gsi
= gsi_last_bb (bb
);
5651 if (!gsi_end_p (gsi
) && is_gimple_omp (gsi_stmt (gsi
)))
5653 struct omp_region
*region
;
5654 enum gimple_code code
;
5656 stmt
= gsi_stmt (gsi
);
5657 code
= gimple_code (stmt
);
5658 if (code
== GIMPLE_OMP_RETURN
)
5660 /* STMT is the return point out of region PARENT. Mark it
5661 as the exit point and make PARENT the immediately
5662 enclosing region. */
5663 gcc_assert (parent
);
5666 parent
= parent
->outer
;
5668 else if (code
== GIMPLE_OMP_ATOMIC_STORE
)
5670 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5671 GIMPLE_OMP_RETURN, but matches with
5672 GIMPLE_OMP_ATOMIC_LOAD. */
5673 gcc_assert (parent
);
5674 gcc_assert (parent
->type
== GIMPLE_OMP_ATOMIC_LOAD
);
5677 parent
= parent
->outer
;
5680 else if (code
== GIMPLE_OMP_CONTINUE
)
5682 gcc_assert (parent
);
5685 else if (code
== GIMPLE_OMP_SECTIONS_SWITCH
)
5687 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5688 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5693 /* Otherwise, this directive becomes the parent for a new
5695 region
= new_omp_region (bb
, code
, parent
);
5700 if (single_tree
&& !parent
)
5703 for (son
= first_dom_son (CDI_DOMINATORS
, bb
);
5705 son
= next_dom_son (CDI_DOMINATORS
, son
))
5706 build_omp_regions_1 (son
, parent
, single_tree
);
5709 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5713 build_omp_regions_root (basic_block root
)
5715 gcc_assert (root_omp_region
== NULL
);
5716 build_omp_regions_1 (root
, NULL
, true);
5717 gcc_assert (root_omp_region
!= NULL
);
5720 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5723 omp_expand_local (basic_block head
)
5725 build_omp_regions_root (head
);
5726 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5728 fprintf (dump_file
, "\nOMP region tree\n\n");
5729 dump_omp_region (dump_file
, root_omp_region
, 0);
5730 fprintf (dump_file
, "\n");
5733 remove_exit_barriers (root_omp_region
);
5734 expand_omp (root_omp_region
);
5736 free_omp_regions ();
5739 /* Scan the CFG and build a tree of OMP regions. Return the root of
5740 the OMP region tree. */
5743 build_omp_regions (void)
5745 gcc_assert (root_omp_region
== NULL
);
5746 calculate_dominance_info (CDI_DOMINATORS
);
5747 build_omp_regions_1 (ENTRY_BLOCK_PTR
, NULL
, false);
5750 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5753 execute_expand_omp (void)
5755 build_omp_regions ();
5757 if (!root_omp_region
)
5762 fprintf (dump_file
, "\nOMP region tree\n\n");
5763 dump_omp_region (dump_file
, root_omp_region
, 0);
5764 fprintf (dump_file
, "\n");
5767 remove_exit_barriers (root_omp_region
);
5769 expand_omp (root_omp_region
);
5771 cleanup_tree_cfg ();
5773 free_omp_regions ();
5778 /* OMP expansion -- the default pass, run before creation of SSA form. */
5781 gate_expand_omp (void)
5783 return (flag_openmp
!= 0 && !seen_error ());
5786 struct gimple_opt_pass pass_expand_omp
=
5790 "ompexp", /* name */
5791 gate_expand_omp
, /* gate */
5792 execute_expand_omp
, /* execute */
5795 0, /* static_pass_number */
5796 TV_NONE
, /* tv_id */
5797 PROP_gimple_any
, /* properties_required */
5798 0, /* properties_provided */
5799 0, /* properties_destroyed */
5800 0, /* todo_flags_start */
5801 0 /* todo_flags_finish */
5805 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5807 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5808 CTX is the enclosing OMP context for the current statement. */
5811 lower_omp_sections (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5813 tree block
, control
;
5814 gimple_stmt_iterator tgsi
;
5815 gimple stmt
, new_stmt
, bind
, t
;
5816 gimple_seq ilist
, dlist
, olist
, new_body
;
5817 struct gimplify_ctx gctx
;
5819 stmt
= gsi_stmt (*gsi_p
);
5821 push_gimplify_context (&gctx
);
5825 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt
),
5826 &ilist
, &dlist
, ctx
);
5828 new_body
= gimple_omp_body (stmt
);
5829 gimple_omp_set_body (stmt
, NULL
);
5830 tgsi
= gsi_start (new_body
);
5831 for (; !gsi_end_p (tgsi
); gsi_next (&tgsi
))
5836 sec_start
= gsi_stmt (tgsi
);
5837 sctx
= maybe_lookup_ctx (sec_start
);
5840 lower_omp (gimple_omp_body_ptr (sec_start
), sctx
);
5841 gsi_insert_seq_after (&tgsi
, gimple_omp_body (sec_start
),
5842 GSI_CONTINUE_LINKING
);
5843 gimple_omp_set_body (sec_start
, NULL
);
5845 if (gsi_one_before_end_p (tgsi
))
5847 gimple_seq l
= NULL
;
5848 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt
), NULL
,
5850 gsi_insert_seq_after (&tgsi
, l
, GSI_CONTINUE_LINKING
);
5851 gimple_omp_section_set_last (sec_start
);
5854 gsi_insert_after (&tgsi
, gimple_build_omp_return (false),
5855 GSI_CONTINUE_LINKING
);
5858 block
= make_node (BLOCK
);
5859 bind
= gimple_build_bind (NULL
, new_body
, block
);
5862 lower_reduction_clauses (gimple_omp_sections_clauses (stmt
), &olist
, ctx
);
5864 block
= make_node (BLOCK
);
5865 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
5866 gsi_replace (gsi_p
, new_stmt
, true);
5868 pop_gimplify_context (new_stmt
);
5869 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
5870 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
5871 if (BLOCK_VARS (block
))
5872 TREE_USED (block
) = 1;
5875 gimple_seq_add_seq (&new_body
, ilist
);
5876 gimple_seq_add_stmt (&new_body
, stmt
);
5877 gimple_seq_add_stmt (&new_body
, gimple_build_omp_sections_switch ());
5878 gimple_seq_add_stmt (&new_body
, bind
);
5880 control
= create_tmp_var (unsigned_type_node
, ".section");
5881 t
= gimple_build_omp_continue (control
, control
);
5882 gimple_omp_sections_set_control (stmt
, control
);
5883 gimple_seq_add_stmt (&new_body
, t
);
5885 gimple_seq_add_seq (&new_body
, olist
);
5886 gimple_seq_add_seq (&new_body
, dlist
);
5888 new_body
= maybe_catch_exception (new_body
);
5890 t
= gimple_build_omp_return
5891 (!!find_omp_clause (gimple_omp_sections_clauses (stmt
),
5892 OMP_CLAUSE_NOWAIT
));
5893 gimple_seq_add_stmt (&new_body
, t
);
5895 gimple_bind_set_body (new_stmt
, new_body
);
5899 /* A subroutine of lower_omp_single. Expand the simple form of
5900 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5902 if (GOMP_single_start ())
5904 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5906 FIXME. It may be better to delay expanding the logic of this until
5907 pass_expand_omp. The expanded logic may make the job more difficult
5908 to a synchronization analysis pass. */
5911 lower_omp_single_simple (gimple single_stmt
, gimple_seq
*pre_p
)
5913 location_t loc
= gimple_location (single_stmt
);
5914 tree tlabel
= create_artificial_label (loc
);
5915 tree flabel
= create_artificial_label (loc
);
5919 decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START
);
5920 lhs
= create_tmp_var (TREE_TYPE (TREE_TYPE (decl
)), NULL
);
5921 call
= gimple_build_call (decl
, 0);
5922 gimple_call_set_lhs (call
, lhs
);
5923 gimple_seq_add_stmt (pre_p
, call
);
5925 cond
= gimple_build_cond (EQ_EXPR
, lhs
,
5926 fold_convert_loc (loc
, TREE_TYPE (lhs
),
5929 gimple_seq_add_stmt (pre_p
, cond
);
5930 gimple_seq_add_stmt (pre_p
, gimple_build_label (tlabel
));
5931 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
5932 gimple_seq_add_stmt (pre_p
, gimple_build_label (flabel
));
5936 /* A subroutine of lower_omp_single. Expand the simple form of
5937 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5939 #pragma omp single copyprivate (a, b, c)
5941 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5944 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5950 GOMP_single_copy_end (©out);
5961 FIXME. It may be better to delay expanding the logic of this until
5962 pass_expand_omp. The expanded logic may make the job more difficult
5963 to a synchronization analysis pass. */
5966 lower_omp_single_copy (gimple single_stmt
, gimple_seq
*pre_p
, omp_context
*ctx
)
5968 tree ptr_type
, t
, l0
, l1
, l2
, bfn_decl
;
5969 gimple_seq copyin_seq
;
5970 location_t loc
= gimple_location (single_stmt
);
5972 ctx
->sender_decl
= create_tmp_var (ctx
->record_type
, ".omp_copy_o");
5974 ptr_type
= build_pointer_type (ctx
->record_type
);
5975 ctx
->receiver_decl
= create_tmp_var (ptr_type
, ".omp_copy_i");
5977 l0
= create_artificial_label (loc
);
5978 l1
= create_artificial_label (loc
);
5979 l2
= create_artificial_label (loc
);
5981 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START
);
5982 t
= build_call_expr_loc (loc
, bfn_decl
, 0);
5983 t
= fold_convert_loc (loc
, ptr_type
, t
);
5984 gimplify_assign (ctx
->receiver_decl
, t
, pre_p
);
5986 t
= build2 (EQ_EXPR
, boolean_type_node
, ctx
->receiver_decl
,
5987 build_int_cst (ptr_type
, 0));
5988 t
= build3 (COND_EXPR
, void_type_node
, t
,
5989 build_and_jump (&l0
), build_and_jump (&l1
));
5990 gimplify_and_add (t
, pre_p
);
5992 gimple_seq_add_stmt (pre_p
, gimple_build_label (l0
));
5994 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
5997 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt
), pre_p
,
6000 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
6001 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END
);
6002 t
= build_call_expr_loc (loc
, bfn_decl
, 1, t
);
6003 gimplify_and_add (t
, pre_p
);
6005 t
= build_and_jump (&l2
);
6006 gimplify_and_add (t
, pre_p
);
6008 gimple_seq_add_stmt (pre_p
, gimple_build_label (l1
));
6010 gimple_seq_add_seq (pre_p
, copyin_seq
);
6012 gimple_seq_add_stmt (pre_p
, gimple_build_label (l2
));
6016 /* Expand code for an OpenMP single directive. */
6019 lower_omp_single (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6022 gimple t
, bind
, single_stmt
= gsi_stmt (*gsi_p
);
6023 gimple_seq bind_body
, dlist
;
6024 struct gimplify_ctx gctx
;
6026 push_gimplify_context (&gctx
);
6028 block
= make_node (BLOCK
);
6029 bind
= gimple_build_bind (NULL
, NULL
, block
);
6030 gsi_replace (gsi_p
, bind
, true);
6033 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt
),
6034 &bind_body
, &dlist
, ctx
);
6035 lower_omp (gimple_omp_body_ptr (single_stmt
), ctx
);
6037 gimple_seq_add_stmt (&bind_body
, single_stmt
);
6039 if (ctx
->record_type
)
6040 lower_omp_single_copy (single_stmt
, &bind_body
, ctx
);
6042 lower_omp_single_simple (single_stmt
, &bind_body
);
6044 gimple_omp_set_body (single_stmt
, NULL
);
6046 gimple_seq_add_seq (&bind_body
, dlist
);
6048 bind_body
= maybe_catch_exception (bind_body
);
6050 t
= gimple_build_omp_return
6051 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt
),
6052 OMP_CLAUSE_NOWAIT
));
6053 gimple_seq_add_stmt (&bind_body
, t
);
6054 gimple_bind_set_body (bind
, bind_body
);
6056 pop_gimplify_context (bind
);
6058 gimple_bind_append_vars (bind
, ctx
->block_vars
);
6059 BLOCK_VARS (block
) = ctx
->block_vars
;
6060 if (BLOCK_VARS (block
))
6061 TREE_USED (block
) = 1;
6065 /* Expand code for an OpenMP master directive. */
6068 lower_omp_master (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6070 tree block
, lab
= NULL
, x
, bfn_decl
;
6071 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
6072 location_t loc
= gimple_location (stmt
);
6074 struct gimplify_ctx gctx
;
6076 push_gimplify_context (&gctx
);
6078 block
= make_node (BLOCK
);
6079 bind
= gimple_build_bind (NULL
, NULL
, block
);
6080 gsi_replace (gsi_p
, bind
, true);
6081 gimple_bind_add_stmt (bind
, stmt
);
6083 bfn_decl
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
6084 x
= build_call_expr_loc (loc
, bfn_decl
, 0);
6085 x
= build2 (EQ_EXPR
, boolean_type_node
, x
, integer_zero_node
);
6086 x
= build3 (COND_EXPR
, void_type_node
, x
, NULL
, build_and_jump (&lab
));
6088 gimplify_and_add (x
, &tseq
);
6089 gimple_bind_add_seq (bind
, tseq
);
6091 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
6092 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
6093 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
6094 gimple_omp_set_body (stmt
, NULL
);
6096 gimple_bind_add_stmt (bind
, gimple_build_label (lab
));
6098 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
6100 pop_gimplify_context (bind
);
6102 gimple_bind_append_vars (bind
, ctx
->block_vars
);
6103 BLOCK_VARS (block
) = ctx
->block_vars
;
6107 /* Expand code for an OpenMP ordered directive. */
6110 lower_omp_ordered (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6113 gimple stmt
= gsi_stmt (*gsi_p
), bind
, x
;
6114 struct gimplify_ctx gctx
;
6116 push_gimplify_context (&gctx
);
6118 block
= make_node (BLOCK
);
6119 bind
= gimple_build_bind (NULL
, NULL
, block
);
6120 gsi_replace (gsi_p
, bind
, true);
6121 gimple_bind_add_stmt (bind
, stmt
);
6123 x
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START
),
6125 gimple_bind_add_stmt (bind
, x
);
6127 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
6128 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
6129 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
6130 gimple_omp_set_body (stmt
, NULL
);
6132 x
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END
), 0);
6133 gimple_bind_add_stmt (bind
, x
);
6135 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
6137 pop_gimplify_context (bind
);
6139 gimple_bind_append_vars (bind
, ctx
->block_vars
);
6140 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
6144 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
6145 substitution of a couple of function calls. But in the NAMED case,
6146 requires that languages coordinate a symbol name. It is therefore
6147 best put here in common code. */
6149 static GTY((param1_is (tree
), param2_is (tree
)))
6150 splay_tree critical_name_mutexes
;
6153 lower_omp_critical (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6156 tree name
, lock
, unlock
;
6157 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
6158 location_t loc
= gimple_location (stmt
);
6160 struct gimplify_ctx gctx
;
6162 name
= gimple_omp_critical_name (stmt
);
6168 if (!critical_name_mutexes
)
6169 critical_name_mutexes
6170 = splay_tree_new_ggc (splay_tree_compare_pointers
,
6171 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s
,
6172 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s
);
6174 n
= splay_tree_lookup (critical_name_mutexes
, (splay_tree_key
) name
);
6179 decl
= create_tmp_var_raw (ptr_type_node
, NULL
);
6181 new_str
= ACONCAT ((".gomp_critical_user_",
6182 IDENTIFIER_POINTER (name
), NULL
));
6183 DECL_NAME (decl
) = get_identifier (new_str
);
6184 TREE_PUBLIC (decl
) = 1;
6185 TREE_STATIC (decl
) = 1;
6186 DECL_COMMON (decl
) = 1;
6187 DECL_ARTIFICIAL (decl
) = 1;
6188 DECL_IGNORED_P (decl
) = 1;
6189 varpool_finalize_decl (decl
);
6191 splay_tree_insert (critical_name_mutexes
, (splay_tree_key
) name
,
6192 (splay_tree_value
) decl
);
6195 decl
= (tree
) n
->value
;
6197 lock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START
);
6198 lock
= build_call_expr_loc (loc
, lock
, 1, build_fold_addr_expr_loc (loc
, decl
));
6200 unlock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END
);
6201 unlock
= build_call_expr_loc (loc
, unlock
, 1,
6202 build_fold_addr_expr_loc (loc
, decl
));
6206 lock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START
);
6207 lock
= build_call_expr_loc (loc
, lock
, 0);
6209 unlock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END
);
6210 unlock
= build_call_expr_loc (loc
, unlock
, 0);
6213 push_gimplify_context (&gctx
);
6215 block
= make_node (BLOCK
);
6216 bind
= gimple_build_bind (NULL
, NULL
, block
);
6217 gsi_replace (gsi_p
, bind
, true);
6218 gimple_bind_add_stmt (bind
, stmt
);
6220 tbody
= gimple_bind_body (bind
);
6221 gimplify_and_add (lock
, &tbody
);
6222 gimple_bind_set_body (bind
, tbody
);
6224 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
6225 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
6226 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
6227 gimple_omp_set_body (stmt
, NULL
);
6229 tbody
= gimple_bind_body (bind
);
6230 gimplify_and_add (unlock
, &tbody
);
6231 gimple_bind_set_body (bind
, tbody
);
6233 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
6235 pop_gimplify_context (bind
);
6236 gimple_bind_append_vars (bind
, ctx
->block_vars
);
6237 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
6241 /* A subroutine of lower_omp_for. Generate code to emit the predicate
6242 for a lastprivate clause. Given a loop control predicate of (V
6243 cond N2), we gate the clause on (!(V cond N2)). The lowered form
6244 is appended to *DLIST, iterator initialization is appended to
6248 lower_omp_for_lastprivate (struct omp_for_data
*fd
, gimple_seq
*body_p
,
6249 gimple_seq
*dlist
, struct omp_context
*ctx
)
6251 tree clauses
, cond
, vinit
;
6252 enum tree_code cond_code
;
6255 cond_code
= fd
->loop
.cond_code
;
6256 cond_code
= cond_code
== LT_EXPR
? GE_EXPR
: LE_EXPR
;
6258 /* When possible, use a strict equality expression. This can let VRP
6259 type optimizations deduce the value and remove a copy. */
6260 if (host_integerp (fd
->loop
.step
, 0))
6262 HOST_WIDE_INT step
= TREE_INT_CST_LOW (fd
->loop
.step
);
6263 if (step
== 1 || step
== -1)
6264 cond_code
= EQ_EXPR
;
6267 cond
= build2 (cond_code
, boolean_type_node
, fd
->loop
.v
, fd
->loop
.n2
);
6269 clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
6271 lower_lastprivate_clauses (clauses
, cond
, &stmts
, ctx
);
6272 if (!gimple_seq_empty_p (stmts
))
6274 gimple_seq_add_seq (&stmts
, *dlist
);
6277 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6278 vinit
= fd
->loop
.n1
;
6279 if (cond_code
== EQ_EXPR
6280 && host_integerp (fd
->loop
.n2
, 0)
6281 && ! integer_zerop (fd
->loop
.n2
))
6282 vinit
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
6284 /* Initialize the iterator variable, so that threads that don't execute
6285 any iterations don't execute the lastprivate clauses by accident. */
6286 gimplify_assign (fd
->loop
.v
, vinit
, body_p
);
6291 /* Lower code for an OpenMP loop directive. */
6294 lower_omp_for (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6297 struct omp_for_data fd
;
6298 gimple stmt
= gsi_stmt (*gsi_p
), new_stmt
;
6299 gimple_seq omp_for_body
, body
, dlist
;
6301 struct gimplify_ctx gctx
;
6303 push_gimplify_context (&gctx
);
6305 lower_omp (gimple_omp_for_pre_body_ptr (stmt
), ctx
);
6306 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
6308 block
= make_node (BLOCK
);
6309 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
6310 /* Replace at gsi right away, so that 'stmt' is no member
6311 of a sequence anymore as we're going to add to to a different
6313 gsi_replace (gsi_p
, new_stmt
, true);
6315 /* Move declaration of temporaries in the loop body before we make
6317 omp_for_body
= gimple_omp_body (stmt
);
6318 if (!gimple_seq_empty_p (omp_for_body
)
6319 && gimple_code (gimple_seq_first_stmt (omp_for_body
)) == GIMPLE_BIND
)
6321 tree vars
= gimple_bind_vars (gimple_seq_first_stmt (omp_for_body
));
6322 gimple_bind_append_vars (new_stmt
, vars
);
6325 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6328 lower_rec_input_clauses (gimple_omp_for_clauses (stmt
), &body
, &dlist
, ctx
);
6329 gimple_seq_add_seq (&body
, gimple_omp_for_pre_body (stmt
));
6331 /* Lower the header expressions. At this point, we can assume that
6332 the header is of the form:
6334 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6336 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6337 using the .omp_data_s mapping, if needed. */
6338 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
6340 rhs_p
= gimple_omp_for_initial_ptr (stmt
, i
);
6341 if (!is_gimple_min_invariant (*rhs_p
))
6342 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6344 rhs_p
= gimple_omp_for_final_ptr (stmt
, i
);
6345 if (!is_gimple_min_invariant (*rhs_p
))
6346 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6348 rhs_p
= &TREE_OPERAND (gimple_omp_for_incr (stmt
, i
), 1);
6349 if (!is_gimple_min_invariant (*rhs_p
))
6350 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6353 /* Once lowered, extract the bounds and clauses. */
6354 extract_omp_for_data (stmt
, &fd
, NULL
);
6356 lower_omp_for_lastprivate (&fd
, &body
, &dlist
, ctx
);
6358 gimple_seq_add_stmt (&body
, stmt
);
6359 gimple_seq_add_seq (&body
, gimple_omp_body (stmt
));
6361 gimple_seq_add_stmt (&body
, gimple_build_omp_continue (fd
.loop
.v
,
6364 /* After the loop, add exit clauses. */
6365 lower_reduction_clauses (gimple_omp_for_clauses (stmt
), &body
, ctx
);
6366 gimple_seq_add_seq (&body
, dlist
);
6368 body
= maybe_catch_exception (body
);
6370 /* Region exit marker goes at the end of the loop body. */
6371 gimple_seq_add_stmt (&body
, gimple_build_omp_return (fd
.have_nowait
));
6373 pop_gimplify_context (new_stmt
);
6375 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
6376 BLOCK_VARS (block
) = gimple_bind_vars (new_stmt
);
6377 if (BLOCK_VARS (block
))
6378 TREE_USED (block
) = 1;
6380 gimple_bind_set_body (new_stmt
, body
);
6381 gimple_omp_set_body (stmt
, NULL
);
6382 gimple_omp_for_set_pre_body (stmt
, NULL
);
6385 /* Callback for walk_stmts. Check if the current statement only contains
6386 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6389 check_combined_parallel (gimple_stmt_iterator
*gsi_p
,
6390 bool *handled_ops_p
,
6391 struct walk_stmt_info
*wi
)
6393 int *info
= (int *) wi
->info
;
6394 gimple stmt
= gsi_stmt (*gsi_p
);
6396 *handled_ops_p
= true;
6397 switch (gimple_code (stmt
))
6401 case GIMPLE_OMP_FOR
:
6402 case GIMPLE_OMP_SECTIONS
:
6403 *info
= *info
== 0 ? 1 : -1;
6412 struct omp_taskcopy_context
6414 /* This field must be at the beginning, as we do "inheritance": Some
6415 callback functions for tree-inline.c (e.g., omp_copy_decl)
6416 receive a copy_body_data pointer that is up-casted to an
6417 omp_context pointer. */
6423 task_copyfn_copy_decl (tree var
, copy_body_data
*cb
)
6425 struct omp_taskcopy_context
*tcctx
= (struct omp_taskcopy_context
*) cb
;
6427 if (splay_tree_lookup (tcctx
->ctx
->sfield_map
, (splay_tree_key
) var
))
6428 return create_tmp_var (TREE_TYPE (var
), NULL
);
6434 task_copyfn_remap_type (struct omp_taskcopy_context
*tcctx
, tree orig_type
)
6436 tree name
, new_fields
= NULL
, type
, f
;
6438 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6439 name
= DECL_NAME (TYPE_NAME (orig_type
));
6440 name
= build_decl (gimple_location (tcctx
->ctx
->stmt
),
6441 TYPE_DECL
, name
, type
);
6442 TYPE_NAME (type
) = name
;
6444 for (f
= TYPE_FIELDS (orig_type
); f
; f
= TREE_CHAIN (f
))
6446 tree new_f
= copy_node (f
);
6447 DECL_CONTEXT (new_f
) = type
;
6448 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &tcctx
->cb
);
6449 TREE_CHAIN (new_f
) = new_fields
;
6450 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
6451 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
6452 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
6455 *pointer_map_insert (tcctx
->cb
.decl_map
, f
) = new_f
;
6457 TYPE_FIELDS (type
) = nreverse (new_fields
);
6462 /* Create task copyfn. */
6465 create_task_copyfn (gimple task_stmt
, omp_context
*ctx
)
6467 struct function
*child_cfun
;
6468 tree child_fn
, t
, c
, src
, dst
, f
, sf
, arg
, sarg
, decl
;
6469 tree record_type
, srecord_type
, bind
, list
;
6470 bool record_needs_remap
= false, srecord_needs_remap
= false;
6472 struct omp_taskcopy_context tcctx
;
6473 struct gimplify_ctx gctx
;
6474 location_t loc
= gimple_location (task_stmt
);
6476 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
6477 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
6478 gcc_assert (child_cfun
->cfg
== NULL
);
6479 DECL_SAVED_TREE (child_fn
) = alloc_stmt_list ();
6481 /* Reset DECL_CONTEXT on function arguments. */
6482 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
6483 DECL_CONTEXT (t
) = child_fn
;
6485 /* Populate the function. */
6486 push_gimplify_context (&gctx
);
6487 current_function_decl
= child_fn
;
6489 bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
6490 TREE_SIDE_EFFECTS (bind
) = 1;
6492 DECL_SAVED_TREE (child_fn
) = bind
;
6493 DECL_SOURCE_LOCATION (child_fn
) = gimple_location (task_stmt
);
6495 /* Remap src and dst argument types if needed. */
6496 record_type
= ctx
->record_type
;
6497 srecord_type
= ctx
->srecord_type
;
6498 for (f
= TYPE_FIELDS (record_type
); f
; f
= DECL_CHAIN (f
))
6499 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
6501 record_needs_remap
= true;
6504 for (f
= TYPE_FIELDS (srecord_type
); f
; f
= DECL_CHAIN (f
))
6505 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
6507 srecord_needs_remap
= true;
6511 if (record_needs_remap
|| srecord_needs_remap
)
6513 memset (&tcctx
, '\0', sizeof (tcctx
));
6514 tcctx
.cb
.src_fn
= ctx
->cb
.src_fn
;
6515 tcctx
.cb
.dst_fn
= child_fn
;
6516 tcctx
.cb
.src_node
= cgraph_get_node (tcctx
.cb
.src_fn
);
6517 gcc_checking_assert (tcctx
.cb
.src_node
);
6518 tcctx
.cb
.dst_node
= tcctx
.cb
.src_node
;
6519 tcctx
.cb
.src_cfun
= ctx
->cb
.src_cfun
;
6520 tcctx
.cb
.copy_decl
= task_copyfn_copy_decl
;
6521 tcctx
.cb
.eh_lp_nr
= 0;
6522 tcctx
.cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
6523 tcctx
.cb
.decl_map
= pointer_map_create ();
6526 if (record_needs_remap
)
6527 record_type
= task_copyfn_remap_type (&tcctx
, record_type
);
6528 if (srecord_needs_remap
)
6529 srecord_type
= task_copyfn_remap_type (&tcctx
, srecord_type
);
6532 tcctx
.cb
.decl_map
= NULL
;
6534 push_cfun (child_cfun
);
6536 arg
= DECL_ARGUMENTS (child_fn
);
6537 TREE_TYPE (arg
) = build_pointer_type (record_type
);
6538 sarg
= DECL_CHAIN (arg
);
6539 TREE_TYPE (sarg
) = build_pointer_type (srecord_type
);
6541 /* First pass: initialize temporaries used in record_type and srecord_type
6542 sizes and field offsets. */
6543 if (tcctx
.cb
.decl_map
)
6544 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6545 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
6549 decl
= OMP_CLAUSE_DECL (c
);
6550 p
= (tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, decl
);
6553 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6554 sf
= (tree
) n
->value
;
6555 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6556 src
= build_simple_mem_ref_loc (loc
, sarg
);
6557 src
= omp_build_component_ref (src
, sf
);
6558 t
= build2 (MODIFY_EXPR
, TREE_TYPE (*p
), *p
, src
);
6559 append_to_statement_list (t
, &list
);
6562 /* Second pass: copy shared var pointers and copy construct non-VLA
6563 firstprivate vars. */
6564 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6565 switch (OMP_CLAUSE_CODE (c
))
6567 case OMP_CLAUSE_SHARED
:
6568 decl
= OMP_CLAUSE_DECL (c
);
6569 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6572 f
= (tree
) n
->value
;
6573 if (tcctx
.cb
.decl_map
)
6574 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6575 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6576 sf
= (tree
) n
->value
;
6577 if (tcctx
.cb
.decl_map
)
6578 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6579 src
= build_simple_mem_ref_loc (loc
, sarg
);
6580 src
= omp_build_component_ref (src
, sf
);
6581 dst
= build_simple_mem_ref_loc (loc
, arg
);
6582 dst
= omp_build_component_ref (dst
, f
);
6583 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
6584 append_to_statement_list (t
, &list
);
6586 case OMP_CLAUSE_FIRSTPRIVATE
:
6587 decl
= OMP_CLAUSE_DECL (c
);
6588 if (is_variable_sized (decl
))
6590 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6593 f
= (tree
) n
->value
;
6594 if (tcctx
.cb
.decl_map
)
6595 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6596 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6599 sf
= (tree
) n
->value
;
6600 if (tcctx
.cb
.decl_map
)
6601 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6602 src
= build_simple_mem_ref_loc (loc
, sarg
);
6603 src
= omp_build_component_ref (src
, sf
);
6604 if (use_pointer_for_field (decl
, NULL
) || is_reference (decl
))
6605 src
= build_simple_mem_ref_loc (loc
, src
);
6609 dst
= build_simple_mem_ref_loc (loc
, arg
);
6610 dst
= omp_build_component_ref (dst
, f
);
6611 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
6612 append_to_statement_list (t
, &list
);
6614 case OMP_CLAUSE_PRIVATE
:
6615 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
6617 decl
= OMP_CLAUSE_DECL (c
);
6618 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6619 f
= (tree
) n
->value
;
6620 if (tcctx
.cb
.decl_map
)
6621 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6622 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6625 sf
= (tree
) n
->value
;
6626 if (tcctx
.cb
.decl_map
)
6627 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6628 src
= build_simple_mem_ref_loc (loc
, sarg
);
6629 src
= omp_build_component_ref (src
, sf
);
6630 if (use_pointer_for_field (decl
, NULL
))
6631 src
= build_simple_mem_ref_loc (loc
, src
);
6635 dst
= build_simple_mem_ref_loc (loc
, arg
);
6636 dst
= omp_build_component_ref (dst
, f
);
6637 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
6638 append_to_statement_list (t
, &list
);
6644 /* Last pass: handle VLA firstprivates. */
6645 if (tcctx
.cb
.decl_map
)
6646 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6647 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
6651 decl
= OMP_CLAUSE_DECL (c
);
6652 if (!is_variable_sized (decl
))
6654 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6657 f
= (tree
) n
->value
;
6658 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6659 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl
));
6660 ind
= DECL_VALUE_EXPR (decl
);
6661 gcc_assert (TREE_CODE (ind
) == INDIRECT_REF
);
6662 gcc_assert (DECL_P (TREE_OPERAND (ind
, 0)));
6663 n
= splay_tree_lookup (ctx
->sfield_map
,
6664 (splay_tree_key
) TREE_OPERAND (ind
, 0));
6665 sf
= (tree
) n
->value
;
6666 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6667 src
= build_simple_mem_ref_loc (loc
, sarg
);
6668 src
= omp_build_component_ref (src
, sf
);
6669 src
= build_simple_mem_ref_loc (loc
, src
);
6670 dst
= build_simple_mem_ref_loc (loc
, arg
);
6671 dst
= omp_build_component_ref (dst
, f
);
6672 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
6673 append_to_statement_list (t
, &list
);
6674 n
= splay_tree_lookup (ctx
->field_map
,
6675 (splay_tree_key
) TREE_OPERAND (ind
, 0));
6676 df
= (tree
) n
->value
;
6677 df
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, df
);
6678 ptr
= build_simple_mem_ref_loc (loc
, arg
);
6679 ptr
= omp_build_component_ref (ptr
, df
);
6680 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ptr
), ptr
,
6681 build_fold_addr_expr_loc (loc
, dst
));
6682 append_to_statement_list (t
, &list
);
6685 t
= build1 (RETURN_EXPR
, void_type_node
, NULL
);
6686 append_to_statement_list (t
, &list
);
6688 if (tcctx
.cb
.decl_map
)
6689 pointer_map_destroy (tcctx
.cb
.decl_map
);
6690 pop_gimplify_context (NULL
);
6691 BIND_EXPR_BODY (bind
) = list
;
6693 current_function_decl
= ctx
->cb
.src_fn
;
6696 /* Lower the OpenMP parallel or task directive in the current statement
6697 in GSI_P. CTX holds context information for the directive. */
6700 lower_omp_taskreg (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6704 gimple stmt
= gsi_stmt (*gsi_p
);
6705 gimple par_bind
, bind
;
6706 gimple_seq par_body
, olist
, ilist
, par_olist
, par_ilist
, new_body
;
6707 struct gimplify_ctx gctx
;
6708 location_t loc
= gimple_location (stmt
);
6710 clauses
= gimple_omp_taskreg_clauses (stmt
);
6711 par_bind
= gimple_seq_first_stmt (gimple_omp_body (stmt
));
6712 par_body
= gimple_bind_body (par_bind
);
6713 child_fn
= ctx
->cb
.dst_fn
;
6714 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
6715 && !gimple_omp_parallel_combined_p (stmt
))
6717 struct walk_stmt_info wi
;
6720 memset (&wi
, 0, sizeof (wi
));
6723 walk_gimple_seq (par_body
, check_combined_parallel
, NULL
, &wi
);
6725 gimple_omp_parallel_set_combined_p (stmt
, true);
6727 if (ctx
->srecord_type
)
6728 create_task_copyfn (stmt
, ctx
);
6730 push_gimplify_context (&gctx
);
6734 lower_rec_input_clauses (clauses
, &par_ilist
, &par_olist
, ctx
);
6735 lower_omp (&par_body
, ctx
);
6736 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
)
6737 lower_reduction_clauses (clauses
, &par_olist
, ctx
);
6739 /* Declare all the variables created by mapping and the variables
6740 declared in the scope of the parallel body. */
6741 record_vars_into (ctx
->block_vars
, child_fn
);
6742 record_vars_into (gimple_bind_vars (par_bind
), child_fn
);
6744 if (ctx
->record_type
)
6747 = create_tmp_var (ctx
->srecord_type
? ctx
->srecord_type
6748 : ctx
->record_type
, ".omp_data_o");
6749 DECL_NAMELESS (ctx
->sender_decl
) = 1;
6750 TREE_ADDRESSABLE (ctx
->sender_decl
) = 1;
6751 gimple_omp_taskreg_set_data_arg (stmt
, ctx
->sender_decl
);
6756 lower_send_clauses (clauses
, &ilist
, &olist
, ctx
);
6757 lower_send_shared_vars (&ilist
, &olist
, ctx
);
6759 /* Once all the expansions are done, sequence all the different
6760 fragments inside gimple_omp_body. */
6764 if (ctx
->record_type
)
6766 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
6767 /* fixup_child_record_type might have changed receiver_decl's type. */
6768 t
= fold_convert_loc (loc
, TREE_TYPE (ctx
->receiver_decl
), t
);
6769 gimple_seq_add_stmt (&new_body
,
6770 gimple_build_assign (ctx
->receiver_decl
, t
));
6773 gimple_seq_add_seq (&new_body
, par_ilist
);
6774 gimple_seq_add_seq (&new_body
, par_body
);
6775 gimple_seq_add_seq (&new_body
, par_olist
);
6776 new_body
= maybe_catch_exception (new_body
);
6777 gimple_seq_add_stmt (&new_body
, gimple_build_omp_return (false));
6778 gimple_omp_set_body (stmt
, new_body
);
6780 bind
= gimple_build_bind (NULL
, NULL
, gimple_bind_block (par_bind
));
6781 gsi_replace (gsi_p
, bind
, true);
6782 gimple_bind_add_seq (bind
, ilist
);
6783 gimple_bind_add_stmt (bind
, stmt
);
6784 gimple_bind_add_seq (bind
, olist
);
6786 pop_gimplify_context (NULL
);
6789 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6790 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6791 of OpenMP context, but with task_shared_vars set. */
6794 lower_omp_regimplify_p (tree
*tp
, int *walk_subtrees
,
6799 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6800 if (TREE_CODE (t
) == VAR_DECL
&& data
== NULL
&& DECL_HAS_VALUE_EXPR_P (t
))
6803 if (task_shared_vars
6805 && bitmap_bit_p (task_shared_vars
, DECL_UID (t
)))
6808 /* If a global variable has been privatized, TREE_CONSTANT on
6809 ADDR_EXPR might be wrong. */
6810 if (data
== NULL
&& TREE_CODE (t
) == ADDR_EXPR
)
6811 recompute_tree_invariant_for_addr_expr (t
);
6813 *walk_subtrees
= !TYPE_P (t
) && !DECL_P (t
);
6818 lower_omp_1 (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6820 gimple stmt
= gsi_stmt (*gsi_p
);
6821 struct walk_stmt_info wi
;
6823 if (gimple_has_location (stmt
))
6824 input_location
= gimple_location (stmt
);
6826 if (task_shared_vars
)
6827 memset (&wi
, '\0', sizeof (wi
));
6829 /* If we have issued syntax errors, avoid doing any heavy lifting.
6830 Just replace the OpenMP directives with a NOP to avoid
6831 confusing RTL expansion. */
6832 if (seen_error () && is_gimple_omp (stmt
))
6834 gsi_replace (gsi_p
, gimple_build_nop (), true);
6838 switch (gimple_code (stmt
))
6841 if ((ctx
|| task_shared_vars
)
6842 && (walk_tree (gimple_cond_lhs_ptr (stmt
), lower_omp_regimplify_p
,
6843 ctx
? NULL
: &wi
, NULL
)
6844 || walk_tree (gimple_cond_rhs_ptr (stmt
), lower_omp_regimplify_p
,
6845 ctx
? NULL
: &wi
, NULL
)))
6846 gimple_regimplify_operands (stmt
, gsi_p
);
6849 lower_omp (gimple_catch_handler_ptr (stmt
), ctx
);
6851 case GIMPLE_EH_FILTER
:
6852 lower_omp (gimple_eh_filter_failure_ptr (stmt
), ctx
);
6855 lower_omp (gimple_try_eval_ptr (stmt
), ctx
);
6856 lower_omp (gimple_try_cleanup_ptr (stmt
), ctx
);
6859 lower_omp (gimple_bind_body_ptr (stmt
), ctx
);
6861 case GIMPLE_OMP_PARALLEL
:
6862 case GIMPLE_OMP_TASK
:
6863 ctx
= maybe_lookup_ctx (stmt
);
6864 lower_omp_taskreg (gsi_p
, ctx
);
6866 case GIMPLE_OMP_FOR
:
6867 ctx
= maybe_lookup_ctx (stmt
);
6869 lower_omp_for (gsi_p
, ctx
);
6871 case GIMPLE_OMP_SECTIONS
:
6872 ctx
= maybe_lookup_ctx (stmt
);
6874 lower_omp_sections (gsi_p
, ctx
);
6876 case GIMPLE_OMP_SINGLE
:
6877 ctx
= maybe_lookup_ctx (stmt
);
6879 lower_omp_single (gsi_p
, ctx
);
6881 case GIMPLE_OMP_MASTER
:
6882 ctx
= maybe_lookup_ctx (stmt
);
6884 lower_omp_master (gsi_p
, ctx
);
6886 case GIMPLE_OMP_ORDERED
:
6887 ctx
= maybe_lookup_ctx (stmt
);
6889 lower_omp_ordered (gsi_p
, ctx
);
6891 case GIMPLE_OMP_CRITICAL
:
6892 ctx
= maybe_lookup_ctx (stmt
);
6894 lower_omp_critical (gsi_p
, ctx
);
6896 case GIMPLE_OMP_ATOMIC_LOAD
:
6897 if ((ctx
|| task_shared_vars
)
6898 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt
),
6899 lower_omp_regimplify_p
, ctx
? NULL
: &wi
, NULL
))
6900 gimple_regimplify_operands (stmt
, gsi_p
);
6903 if ((ctx
|| task_shared_vars
)
6904 && walk_gimple_op (stmt
, lower_omp_regimplify_p
,
6906 gimple_regimplify_operands (stmt
, gsi_p
);
6912 lower_omp (gimple_seq
*body
, omp_context
*ctx
)
6914 location_t saved_location
= input_location
;
6915 gimple_stmt_iterator gsi
;
6916 for (gsi
= gsi_start (*body
); !gsi_end_p (gsi
); gsi_next (&gsi
))
6917 lower_omp_1 (&gsi
, ctx
);
6918 input_location
= saved_location
;
6921 /* Main entry point. */
6924 execute_lower_omp (void)
6928 /* This pass always runs, to provide PROP_gimple_lomp.
6929 But there is nothing to do unless -fopenmp is given. */
6930 if (flag_openmp
== 0)
6933 all_contexts
= splay_tree_new (splay_tree_compare_pointers
, 0,
6934 delete_omp_context
);
6936 body
= gimple_body (current_function_decl
);
6937 scan_omp (&body
, NULL
);
6938 gcc_assert (taskreg_nesting_level
== 0);
6940 if (all_contexts
->root
)
6942 struct gimplify_ctx gctx
;
6944 if (task_shared_vars
)
6945 push_gimplify_context (&gctx
);
6946 lower_omp (&body
, NULL
);
6947 if (task_shared_vars
)
6948 pop_gimplify_context (NULL
);
6953 splay_tree_delete (all_contexts
);
6954 all_contexts
= NULL
;
6956 BITMAP_FREE (task_shared_vars
);
6960 struct gimple_opt_pass pass_lower_omp
=
6964 "omplower", /* name */
6966 execute_lower_omp
, /* execute */
6969 0, /* static_pass_number */
6970 TV_NONE
, /* tv_id */
6971 PROP_gimple_any
, /* properties_required */
6972 PROP_gimple_lomp
, /* properties_provided */
6973 0, /* properties_destroyed */
6974 0, /* todo_flags_start */
6975 0 /* todo_flags_finish */
6979 /* The following is a utility to diagnose OpenMP structured block violations.
6980 It is not part of the "omplower" pass, as that's invoked too late. It
6981 should be invoked by the respective front ends after gimplification. */
6983 static splay_tree all_labels
;
6985 /* Check for mismatched contexts and generate an error if needed. Return
6986 true if an error is detected. */
6989 diagnose_sb_0 (gimple_stmt_iterator
*gsi_p
,
6990 gimple branch_ctx
, gimple label_ctx
)
6992 if (label_ctx
== branch_ctx
)
6997 Previously we kept track of the label's entire context in diagnose_sb_[12]
6998 so we could traverse it and issue a correct "exit" or "enter" error
6999 message upon a structured block violation.
7001 We built the context by building a list with tree_cons'ing, but there is
7002 no easy counterpart in gimple tuples. It seems like far too much work
7003 for issuing exit/enter error messages. If someone really misses the
7004 distinct error message... patches welcome.
7008 /* Try to avoid confusing the user by producing and error message
7009 with correct "exit" or "enter" verbiage. We prefer "exit"
7010 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
7011 if (branch_ctx
== NULL
)
7017 if (TREE_VALUE (label_ctx
) == branch_ctx
)
7022 label_ctx
= TREE_CHAIN (label_ctx
);
7027 error ("invalid exit from OpenMP structured block");
7029 error ("invalid entry to OpenMP structured block");
7032 /* If it's obvious we have an invalid entry, be specific about the error. */
7033 if (branch_ctx
== NULL
)
7034 error ("invalid entry to OpenMP structured block");
7036 /* Otherwise, be vague and lazy, but efficient. */
7037 error ("invalid branch to/from an OpenMP structured block");
7039 gsi_replace (gsi_p
, gimple_build_nop (), false);
7043 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
7044 where each label is found. */
7047 diagnose_sb_1 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
7048 struct walk_stmt_info
*wi
)
7050 gimple context
= (gimple
) wi
->info
;
7051 gimple inner_context
;
7052 gimple stmt
= gsi_stmt (*gsi_p
);
7054 *handled_ops_p
= true;
7056 switch (gimple_code (stmt
))
7060 case GIMPLE_OMP_PARALLEL
:
7061 case GIMPLE_OMP_TASK
:
7062 case GIMPLE_OMP_SECTIONS
:
7063 case GIMPLE_OMP_SINGLE
:
7064 case GIMPLE_OMP_SECTION
:
7065 case GIMPLE_OMP_MASTER
:
7066 case GIMPLE_OMP_ORDERED
:
7067 case GIMPLE_OMP_CRITICAL
:
7068 /* The minimal context here is just the current OMP construct. */
7069 inner_context
= stmt
;
7070 wi
->info
= inner_context
;
7071 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
7075 case GIMPLE_OMP_FOR
:
7076 inner_context
= stmt
;
7077 wi
->info
= inner_context
;
7078 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7080 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
7081 diagnose_sb_1
, NULL
, wi
);
7082 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
7087 splay_tree_insert (all_labels
, (splay_tree_key
) gimple_label_label (stmt
),
7088 (splay_tree_value
) context
);
7098 /* Pass 2: Check each branch and see if its context differs from that of
7099 the destination label's context. */
7102 diagnose_sb_2 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
7103 struct walk_stmt_info
*wi
)
7105 gimple context
= (gimple
) wi
->info
;
7107 gimple stmt
= gsi_stmt (*gsi_p
);
7109 *handled_ops_p
= true;
7111 switch (gimple_code (stmt
))
7115 case GIMPLE_OMP_PARALLEL
:
7116 case GIMPLE_OMP_TASK
:
7117 case GIMPLE_OMP_SECTIONS
:
7118 case GIMPLE_OMP_SINGLE
:
7119 case GIMPLE_OMP_SECTION
:
7120 case GIMPLE_OMP_MASTER
:
7121 case GIMPLE_OMP_ORDERED
:
7122 case GIMPLE_OMP_CRITICAL
:
7124 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt
), diagnose_sb_2
, NULL
, wi
);
7128 case GIMPLE_OMP_FOR
:
7130 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
7132 walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt
),
7133 diagnose_sb_2
, NULL
, wi
);
7134 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt
), diagnose_sb_2
, NULL
, wi
);
7140 tree lab
= gimple_cond_true_label (stmt
);
7143 n
= splay_tree_lookup (all_labels
,
7144 (splay_tree_key
) lab
);
7145 diagnose_sb_0 (gsi_p
, context
,
7146 n
? (gimple
) n
->value
: NULL
);
7148 lab
= gimple_cond_false_label (stmt
);
7151 n
= splay_tree_lookup (all_labels
,
7152 (splay_tree_key
) lab
);
7153 diagnose_sb_0 (gsi_p
, context
,
7154 n
? (gimple
) n
->value
: NULL
);
7161 tree lab
= gimple_goto_dest (stmt
);
7162 if (TREE_CODE (lab
) != LABEL_DECL
)
7165 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
7166 diagnose_sb_0 (gsi_p
, context
, n
? (gimple
) n
->value
: NULL
);
7173 for (i
= 0; i
< gimple_switch_num_labels (stmt
); ++i
)
7175 tree lab
= CASE_LABEL (gimple_switch_label (stmt
, i
));
7176 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
7177 if (n
&& diagnose_sb_0 (gsi_p
, context
, (gimple
) n
->value
))
7184 diagnose_sb_0 (gsi_p
, context
, NULL
);
7195 diagnose_omp_structured_block_errors (void)
7197 struct walk_stmt_info wi
;
7198 gimple_seq body
= gimple_body (current_function_decl
);
7200 all_labels
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
7202 memset (&wi
, 0, sizeof (wi
));
7203 walk_gimple_seq (body
, diagnose_sb_1
, NULL
, &wi
);
7205 memset (&wi
, 0, sizeof (wi
));
7206 wi
.want_locations
= true;
7207 walk_gimple_seq_mod (&body
, diagnose_sb_2
, NULL
, &wi
);
7209 gimple_set_body (current_function_decl
, body
);
7211 splay_tree_delete (all_labels
);
7218 gate_diagnose_omp_blocks (void)
7220 return flag_openmp
!= 0;
7223 struct gimple_opt_pass pass_diagnose_omp_blocks
=
7227 "*diagnose_omp_blocks", /* name */
7228 gate_diagnose_omp_blocks
, /* gate */
7229 diagnose_omp_structured_block_errors
, /* execute */
7232 0, /* static_pass_number */
7233 TV_NONE
, /* tv_id */
7234 PROP_gimple_any
, /* properties_required */
7235 0, /* properties_provided */
7236 0, /* properties_destroyed */
7237 0, /* todo_flags_start */
7238 0, /* todo_flags_finish */
7242 #include "gt-omp-low.h"