1 /* Lowering pass for OpenMP directives. Converts OpenMP directives
2 into explicit calls to the runtime library (libgomp) and data
3 marshalling to implement data sharing and copying clauses.
4 Contributed by Diego Novillo <dnovillo@redhat.com>
6 Copyright (C) 2005-2013 Free Software Foundation, Inc.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
32 #include "gimple-iterator.h"
33 #include "gimplify-me.h"
34 #include "gimple-walk.h"
35 #include "tree-iterator.h"
36 #include "tree-inline.h"
37 #include "langhooks.h"
38 #include "diagnostic-core.h"
39 #include "gimple-ssa.h"
42 #include "tree-phinodes.h"
43 #include "ssa-iterators.h"
44 #include "tree-ssanames.h"
45 #include "tree-into-ssa.h"
51 #include "tree-pass.h"
54 #include "splay-tree.h"
59 #include "gimple-low.h"
60 #include "tree-cfgcleanup.h"
63 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
64 phases. The first phase scans the function looking for OMP statements
65 and then for variables that must be replaced to satisfy data sharing
66 clauses. The second phase expands code for the constructs, as well as
67 re-gimplifying things when variables have been replaced with complex
70 Final code generation is done by pass_expand_omp. The flowgraph is
71 scanned for parallel regions which are then moved to a new
72 function, to be invoked by the thread library. */
74 /* Parallel region information. Every parallel and workshare
75 directive is enclosed between two markers, the OMP_* directive
76 and a corresponding OMP_RETURN statement. */
80 /* The enclosing region. */
81 struct omp_region
*outer
;
83 /* First child region. */
84 struct omp_region
*inner
;
86 /* Next peer region. */
87 struct omp_region
*next
;
89 /* Block containing the omp directive as its last stmt. */
92 /* Block containing the OMP_RETURN as its last stmt. */
95 /* Block containing the OMP_CONTINUE as its last stmt. */
98 /* If this is a combined parallel+workshare region, this is a list
99 of additional arguments needed by the combined parallel+workshare
101 vec
<tree
, va_gc
> *ws_args
;
103 /* The code for the omp directive of this region. */
104 enum gimple_code type
;
106 /* Schedule kind, only used for OMP_FOR type regions. */
107 enum omp_clause_schedule_kind sched_kind
;
109 /* True if this is a combined parallel+workshare region. */
110 bool is_combined_parallel
;
113 /* Context structure. Used to store information about each parallel
114 directive in the code. */
116 typedef struct omp_context
118 /* This field must be at the beginning, as we do "inheritance": Some
119 callback functions for tree-inline.c (e.g., omp_copy_decl)
120 receive a copy_body_data pointer that is up-casted to an
121 omp_context pointer. */
124 /* The tree of contexts corresponding to the encountered constructs. */
125 struct omp_context
*outer
;
128 /* Map variables to fields in a structure that allows communication
129 between sending and receiving threads. */
130 splay_tree field_map
;
135 /* These are used just by task contexts, if task firstprivate fn is
136 needed. srecord_type is used to communicate from the thread
137 that encountered the task construct to task firstprivate fn,
138 record_type is allocated by GOMP_task, initialized by task firstprivate
139 fn and passed to the task body fn. */
140 splay_tree sfield_map
;
143 /* A chain of variables to add to the top-level block surrounding the
144 construct. In the case of a parallel, this is in the child function. */
147 /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
148 barriers should jump to during omplower pass. */
151 /* What to do with variables with implicitly determined sharing
153 enum omp_clause_default_kind default_kind
;
155 /* Nesting depth of this context. Used to beautify error messages re
156 invalid gotos. The outermost ctx is depth 1, with depth 0 being
157 reserved for the main body of the function. */
160 /* True if this parallel directive is nested within another. */
163 /* True if this construct can be cancelled. */
168 struct omp_for_data_loop
170 tree v
, n1
, n2
, step
;
171 enum tree_code cond_code
;
174 /* A structure describing the main elements of a parallel loop. */
178 struct omp_for_data_loop loop
;
183 bool have_nowait
, have_ordered
;
184 enum omp_clause_schedule_kind sched_kind
;
185 struct omp_for_data_loop
*loops
;
189 static splay_tree all_contexts
;
190 static int taskreg_nesting_level
;
191 static int target_nesting_level
;
192 static struct omp_region
*root_omp_region
;
193 static bitmap task_shared_vars
;
195 static void scan_omp (gimple_seq
*, omp_context
*);
196 static tree
scan_omp_1_op (tree
*, int *, void *);
198 #define WALK_SUBSTMTS \
202 case GIMPLE_EH_FILTER: \
203 case GIMPLE_TRANSACTION: \
204 /* The sub-statements for these should be walked. */ \
205 *handled_ops_p = false; \
208 /* Convenience function for calling scan_omp_1_op on tree operands. */
211 scan_omp_op (tree
*tp
, omp_context
*ctx
)
213 struct walk_stmt_info wi
;
215 memset (&wi
, 0, sizeof (wi
));
217 wi
.want_locations
= true;
219 return walk_tree (tp
, scan_omp_1_op
, &wi
, NULL
);
222 static void lower_omp (gimple_seq
*, omp_context
*);
223 static tree
lookup_decl_in_outer_ctx (tree
, omp_context
*);
224 static tree
maybe_lookup_decl_in_outer_ctx (tree
, omp_context
*);
226 /* Find an OpenMP clause of type KIND within CLAUSES. */
229 find_omp_clause (tree clauses
, enum omp_clause_code kind
)
231 for (; clauses
; clauses
= OMP_CLAUSE_CHAIN (clauses
))
232 if (OMP_CLAUSE_CODE (clauses
) == kind
)
238 /* Return true if CTX is for an omp parallel. */
241 is_parallel_ctx (omp_context
*ctx
)
243 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
;
247 /* Return true if CTX is for an omp task. */
250 is_task_ctx (omp_context
*ctx
)
252 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_TASK
;
256 /* Return true if CTX is for an omp parallel or omp task. */
259 is_taskreg_ctx (omp_context
*ctx
)
261 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
262 || gimple_code (ctx
->stmt
) == GIMPLE_OMP_TASK
;
266 /* Return true if REGION is a combined parallel+workshare region. */
269 is_combined_parallel (struct omp_region
*region
)
271 return region
->is_combined_parallel
;
275 /* Extract the header elements of parallel loop FOR_STMT and store
279 extract_omp_for_data (gimple for_stmt
, struct omp_for_data
*fd
,
280 struct omp_for_data_loop
*loops
)
282 tree t
, var
, *collapse_iter
, *collapse_count
;
283 tree count
= NULL_TREE
, iter_type
= long_integer_type_node
;
284 struct omp_for_data_loop
*loop
;
286 struct omp_for_data_loop dummy_loop
;
287 location_t loc
= gimple_location (for_stmt
);
288 bool simd
= gimple_omp_for_kind (for_stmt
) & GF_OMP_FOR_KIND_SIMD
;
289 bool distribute
= gimple_omp_for_kind (for_stmt
)
290 == GF_OMP_FOR_KIND_DISTRIBUTE
;
292 fd
->for_stmt
= for_stmt
;
294 fd
->collapse
= gimple_omp_for_collapse (for_stmt
);
295 if (fd
->collapse
> 1)
298 fd
->loops
= &fd
->loop
;
300 fd
->have_nowait
= distribute
|| simd
;
301 fd
->have_ordered
= false;
302 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
303 fd
->chunk_size
= NULL_TREE
;
304 collapse_iter
= NULL
;
305 collapse_count
= NULL
;
307 for (t
= gimple_omp_for_clauses (for_stmt
); t
; t
= OMP_CLAUSE_CHAIN (t
))
308 switch (OMP_CLAUSE_CODE (t
))
310 case OMP_CLAUSE_NOWAIT
:
311 fd
->have_nowait
= true;
313 case OMP_CLAUSE_ORDERED
:
314 fd
->have_ordered
= true;
316 case OMP_CLAUSE_SCHEDULE
:
317 gcc_assert (!distribute
);
318 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_KIND (t
);
319 fd
->chunk_size
= OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t
);
321 case OMP_CLAUSE_DIST_SCHEDULE
:
322 gcc_assert (distribute
);
323 fd
->chunk_size
= OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t
);
325 case OMP_CLAUSE_COLLAPSE
:
326 if (fd
->collapse
> 1)
328 collapse_iter
= &OMP_CLAUSE_COLLAPSE_ITERVAR (t
);
329 collapse_count
= &OMP_CLAUSE_COLLAPSE_COUNT (t
);
335 /* FIXME: for now map schedule(auto) to schedule(static).
336 There should be analysis to determine whether all iterations
337 are approximately the same amount of work (then schedule(static)
338 is best) or if it varies (then schedule(dynamic,N) is better). */
339 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_AUTO
)
341 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
342 gcc_assert (fd
->chunk_size
== NULL
);
344 gcc_assert (fd
->collapse
== 1 || collapse_iter
!= NULL
);
345 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
346 gcc_assert (fd
->chunk_size
== NULL
);
347 else if (fd
->chunk_size
== NULL
)
349 /* We only need to compute a default chunk size for ordered
350 static loops and dynamic loops. */
351 if (fd
->sched_kind
!= OMP_CLAUSE_SCHEDULE_STATIC
353 fd
->chunk_size
= (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
354 ? integer_zero_node
: integer_one_node
;
357 for (i
= 0; i
< fd
->collapse
; i
++)
359 if (fd
->collapse
== 1)
361 else if (loops
!= NULL
)
366 loop
->v
= gimple_omp_for_index (for_stmt
, i
);
367 gcc_assert (SSA_VAR_P (loop
->v
));
368 gcc_assert (TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
369 || TREE_CODE (TREE_TYPE (loop
->v
)) == POINTER_TYPE
);
370 var
= TREE_CODE (loop
->v
) == SSA_NAME
? SSA_NAME_VAR (loop
->v
) : loop
->v
;
371 loop
->n1
= gimple_omp_for_initial (for_stmt
, i
);
373 loop
->cond_code
= gimple_omp_for_cond (for_stmt
, i
);
374 loop
->n2
= gimple_omp_for_final (for_stmt
, i
);
375 switch (loop
->cond_code
)
381 gcc_assert (gimple_omp_for_kind (for_stmt
)
382 == GF_OMP_FOR_KIND_CILKSIMD
);
385 if (POINTER_TYPE_P (TREE_TYPE (loop
->n2
)))
386 loop
->n2
= fold_build_pointer_plus_hwi_loc (loc
, loop
->n2
, 1);
388 loop
->n2
= fold_build2_loc (loc
,
389 PLUS_EXPR
, TREE_TYPE (loop
->n2
), loop
->n2
,
390 build_int_cst (TREE_TYPE (loop
->n2
), 1));
391 loop
->cond_code
= LT_EXPR
;
394 if (POINTER_TYPE_P (TREE_TYPE (loop
->n2
)))
395 loop
->n2
= fold_build_pointer_plus_hwi_loc (loc
, loop
->n2
, -1);
397 loop
->n2
= fold_build2_loc (loc
,
398 MINUS_EXPR
, TREE_TYPE (loop
->n2
), loop
->n2
,
399 build_int_cst (TREE_TYPE (loop
->n2
), 1));
400 loop
->cond_code
= GT_EXPR
;
406 t
= gimple_omp_for_incr (for_stmt
, i
);
407 gcc_assert (TREE_OPERAND (t
, 0) == var
);
408 switch (TREE_CODE (t
))
411 loop
->step
= TREE_OPERAND (t
, 1);
413 case POINTER_PLUS_EXPR
:
414 loop
->step
= fold_convert (ssizetype
, TREE_OPERAND (t
, 1));
417 loop
->step
= TREE_OPERAND (t
, 1);
418 loop
->step
= fold_build1_loc (loc
,
419 NEGATE_EXPR
, TREE_TYPE (loop
->step
),
427 || (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
428 && !fd
->have_ordered
))
430 if (fd
->collapse
== 1)
431 iter_type
= TREE_TYPE (loop
->v
);
433 || TYPE_PRECISION (iter_type
)
434 < TYPE_PRECISION (TREE_TYPE (loop
->v
)))
436 = build_nonstandard_integer_type
437 (TYPE_PRECISION (TREE_TYPE (loop
->v
)), 1);
439 else if (iter_type
!= long_long_unsigned_type_node
)
441 if (POINTER_TYPE_P (TREE_TYPE (loop
->v
)))
442 iter_type
= long_long_unsigned_type_node
;
443 else if (TYPE_UNSIGNED (TREE_TYPE (loop
->v
))
444 && TYPE_PRECISION (TREE_TYPE (loop
->v
))
445 >= TYPE_PRECISION (iter_type
))
449 if (loop
->cond_code
== LT_EXPR
)
450 n
= fold_build2_loc (loc
,
451 PLUS_EXPR
, TREE_TYPE (loop
->v
),
452 loop
->n2
, loop
->step
);
455 if (TREE_CODE (n
) != INTEGER_CST
456 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type
), n
))
457 iter_type
= long_long_unsigned_type_node
;
459 else if (TYPE_PRECISION (TREE_TYPE (loop
->v
))
460 > TYPE_PRECISION (iter_type
))
464 if (loop
->cond_code
== LT_EXPR
)
467 n2
= fold_build2_loc (loc
,
468 PLUS_EXPR
, TREE_TYPE (loop
->v
),
469 loop
->n2
, loop
->step
);
473 n1
= fold_build2_loc (loc
,
474 MINUS_EXPR
, TREE_TYPE (loop
->v
),
475 loop
->n2
, loop
->step
);
478 if (TREE_CODE (n1
) != INTEGER_CST
479 || TREE_CODE (n2
) != INTEGER_CST
480 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type
), n1
)
481 || !tree_int_cst_lt (n2
, TYPE_MAX_VALUE (iter_type
)))
482 iter_type
= long_long_unsigned_type_node
;
486 if (collapse_count
&& *collapse_count
== NULL
)
488 t
= fold_binary (loop
->cond_code
, boolean_type_node
,
489 fold_convert (TREE_TYPE (loop
->v
), loop
->n1
),
490 fold_convert (TREE_TYPE (loop
->v
), loop
->n2
));
491 if (t
&& integer_zerop (t
))
492 count
= build_zero_cst (long_long_unsigned_type_node
);
493 else if ((i
== 0 || count
!= NULL_TREE
)
494 && TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
495 && TREE_CONSTANT (loop
->n1
)
496 && TREE_CONSTANT (loop
->n2
)
497 && TREE_CODE (loop
->step
) == INTEGER_CST
)
499 tree itype
= TREE_TYPE (loop
->v
);
501 if (POINTER_TYPE_P (itype
))
502 itype
= signed_type_for (itype
);
503 t
= build_int_cst (itype
, (loop
->cond_code
== LT_EXPR
? -1 : 1));
504 t
= fold_build2_loc (loc
,
506 fold_convert_loc (loc
, itype
, loop
->step
), t
);
507 t
= fold_build2_loc (loc
, PLUS_EXPR
, itype
, t
,
508 fold_convert_loc (loc
, itype
, loop
->n2
));
509 t
= fold_build2_loc (loc
, MINUS_EXPR
, itype
, t
,
510 fold_convert_loc (loc
, itype
, loop
->n1
));
511 if (TYPE_UNSIGNED (itype
) && loop
->cond_code
== GT_EXPR
)
512 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
,
513 fold_build1_loc (loc
, NEGATE_EXPR
, itype
, t
),
514 fold_build1_loc (loc
, NEGATE_EXPR
, itype
,
515 fold_convert_loc (loc
, itype
,
518 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
, t
,
519 fold_convert_loc (loc
, itype
, loop
->step
));
520 t
= fold_convert_loc (loc
, long_long_unsigned_type_node
, t
);
521 if (count
!= NULL_TREE
)
522 count
= fold_build2_loc (loc
,
523 MULT_EXPR
, long_long_unsigned_type_node
,
527 if (TREE_CODE (count
) != INTEGER_CST
)
530 else if (count
&& !integer_zerop (count
))
537 && (fd
->sched_kind
!= OMP_CLAUSE_SCHEDULE_STATIC
538 || fd
->have_ordered
))
540 if (!tree_int_cst_lt (count
, TYPE_MAX_VALUE (long_integer_type_node
)))
541 iter_type
= long_long_unsigned_type_node
;
543 iter_type
= long_integer_type_node
;
545 else if (collapse_iter
&& *collapse_iter
!= NULL
)
546 iter_type
= TREE_TYPE (*collapse_iter
);
547 fd
->iter_type
= iter_type
;
548 if (collapse_iter
&& *collapse_iter
== NULL
)
549 *collapse_iter
= create_tmp_var (iter_type
, ".iter");
550 if (collapse_count
&& *collapse_count
== NULL
)
553 *collapse_count
= fold_convert_loc (loc
, iter_type
, count
);
555 *collapse_count
= create_tmp_var (iter_type
, ".count");
558 if (fd
->collapse
> 1)
560 fd
->loop
.v
= *collapse_iter
;
561 fd
->loop
.n1
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
562 fd
->loop
.n2
= *collapse_count
;
563 fd
->loop
.step
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 1);
564 fd
->loop
.cond_code
= LT_EXPR
;
569 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
570 is the immediate dominator of PAR_ENTRY_BB, return true if there
571 are no data dependencies that would prevent expanding the parallel
572 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
574 When expanding a combined parallel+workshare region, the call to
575 the child function may need additional arguments in the case of
576 GIMPLE_OMP_FOR regions. In some cases, these arguments are
577 computed out of variables passed in from the parent to the child
578 via 'struct .omp_data_s'. For instance:
580 #pragma omp parallel for schedule (guided, i * 4)
585 # BLOCK 2 (PAR_ENTRY_BB)
587 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
589 # BLOCK 3 (WS_ENTRY_BB)
590 .omp_data_i = &.omp_data_o;
591 D.1667 = .omp_data_i->i;
593 #pragma omp for schedule (guided, D.1598)
595 When we outline the parallel region, the call to the child function
596 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
597 that value is computed *after* the call site. So, in principle we
598 cannot do the transformation.
600 To see whether the code in WS_ENTRY_BB blocks the combined
601 parallel+workshare call, we collect all the variables used in the
602 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
603 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
606 FIXME. If we had the SSA form built at this point, we could merely
607 hoist the code in block 3 into block 2 and be done with it. But at
608 this point we don't have dataflow information and though we could
609 hack something up here, it is really not worth the aggravation. */
612 workshare_safe_to_combine_p (basic_block ws_entry_bb
)
614 struct omp_for_data fd
;
615 gimple ws_stmt
= last_stmt (ws_entry_bb
);
617 if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
620 gcc_assert (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
);
622 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
624 if (fd
.collapse
> 1 && TREE_CODE (fd
.loop
.n2
) != INTEGER_CST
)
626 if (fd
.iter_type
!= long_integer_type_node
)
629 /* FIXME. We give up too easily here. If any of these arguments
630 are not constants, they will likely involve variables that have
631 been mapped into fields of .omp_data_s for sharing with the child
632 function. With appropriate data flow, it would be possible to
634 if (!is_gimple_min_invariant (fd
.loop
.n1
)
635 || !is_gimple_min_invariant (fd
.loop
.n2
)
636 || !is_gimple_min_invariant (fd
.loop
.step
)
637 || (fd
.chunk_size
&& !is_gimple_min_invariant (fd
.chunk_size
)))
644 /* Collect additional arguments needed to emit a combined
645 parallel+workshare call. WS_STMT is the workshare directive being
648 static vec
<tree
, va_gc
> *
649 get_ws_args_for (gimple par_stmt
, gimple ws_stmt
)
652 location_t loc
= gimple_location (ws_stmt
);
653 vec
<tree
, va_gc
> *ws_args
;
655 if (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
)
657 struct omp_for_data fd
;
660 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
664 if (gimple_omp_for_combined_into_p (ws_stmt
))
667 = find_omp_clause (gimple_omp_parallel_clauses (par_stmt
),
668 OMP_CLAUSE__LOOPTEMP_
);
670 n1
= OMP_CLAUSE_DECL (innerc
);
671 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
672 OMP_CLAUSE__LOOPTEMP_
);
674 n2
= OMP_CLAUSE_DECL (innerc
);
677 vec_alloc (ws_args
, 3 + (fd
.chunk_size
!= 0));
679 t
= fold_convert_loc (loc
, long_integer_type_node
, n1
);
680 ws_args
->quick_push (t
);
682 t
= fold_convert_loc (loc
, long_integer_type_node
, n2
);
683 ws_args
->quick_push (t
);
685 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.step
);
686 ws_args
->quick_push (t
);
690 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.chunk_size
);
691 ws_args
->quick_push (t
);
696 else if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
698 /* Number of sections is equal to the number of edges from the
699 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
700 the exit of the sections region. */
701 basic_block bb
= single_succ (gimple_bb (ws_stmt
));
702 t
= build_int_cst (unsigned_type_node
, EDGE_COUNT (bb
->succs
) - 1);
703 vec_alloc (ws_args
, 1);
704 ws_args
->quick_push (t
);
712 /* Discover whether REGION is a combined parallel+workshare region. */
715 determine_parallel_type (struct omp_region
*region
)
717 basic_block par_entry_bb
, par_exit_bb
;
718 basic_block ws_entry_bb
, ws_exit_bb
;
720 if (region
== NULL
|| region
->inner
== NULL
721 || region
->exit
== NULL
|| region
->inner
->exit
== NULL
722 || region
->inner
->cont
== NULL
)
725 /* We only support parallel+for and parallel+sections. */
726 if (region
->type
!= GIMPLE_OMP_PARALLEL
727 || (region
->inner
->type
!= GIMPLE_OMP_FOR
728 && region
->inner
->type
!= GIMPLE_OMP_SECTIONS
))
731 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
732 WS_EXIT_BB -> PAR_EXIT_BB. */
733 par_entry_bb
= region
->entry
;
734 par_exit_bb
= region
->exit
;
735 ws_entry_bb
= region
->inner
->entry
;
736 ws_exit_bb
= region
->inner
->exit
;
738 if (single_succ (par_entry_bb
) == ws_entry_bb
739 && single_succ (ws_exit_bb
) == par_exit_bb
740 && workshare_safe_to_combine_p (ws_entry_bb
)
741 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb
))
742 || (last_and_only_stmt (ws_entry_bb
)
743 && last_and_only_stmt (par_exit_bb
))))
745 gimple par_stmt
= last_stmt (par_entry_bb
);
746 gimple ws_stmt
= last_stmt (ws_entry_bb
);
748 if (region
->inner
->type
== GIMPLE_OMP_FOR
)
750 /* If this is a combined parallel loop, we need to determine
751 whether or not to use the combined library calls. There
752 are two cases where we do not apply the transformation:
753 static loops and any kind of ordered loop. In the first
754 case, we already open code the loop so there is no need
755 to do anything else. In the latter case, the combined
756 parallel loop call would still need extra synchronization
757 to implement ordered semantics, so there would not be any
758 gain in using the combined call. */
759 tree clauses
= gimple_omp_for_clauses (ws_stmt
);
760 tree c
= find_omp_clause (clauses
, OMP_CLAUSE_SCHEDULE
);
762 || OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_STATIC
763 || find_omp_clause (clauses
, OMP_CLAUSE_ORDERED
))
765 region
->is_combined_parallel
= false;
766 region
->inner
->is_combined_parallel
= false;
771 region
->is_combined_parallel
= true;
772 region
->inner
->is_combined_parallel
= true;
773 region
->ws_args
= get_ws_args_for (par_stmt
, ws_stmt
);
778 /* Return true if EXPR is variable sized. */
781 is_variable_sized (const_tree expr
)
783 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr
)));
786 /* Return true if DECL is a reference type. */
789 is_reference (tree decl
)
791 return lang_hooks
.decls
.omp_privatize_by_reference (decl
);
794 /* Lookup variables in the decl or field splay trees. The "maybe" form
795 allows for the variable form to not have been entered, otherwise we
796 assert that the variable must have been entered. */
799 lookup_decl (tree var
, omp_context
*ctx
)
802 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
807 maybe_lookup_decl (const_tree var
, omp_context
*ctx
)
810 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
811 return n
? *n
: NULL_TREE
;
815 lookup_field (tree var
, omp_context
*ctx
)
818 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
819 return (tree
) n
->value
;
823 lookup_sfield (tree var
, omp_context
*ctx
)
826 n
= splay_tree_lookup (ctx
->sfield_map
827 ? ctx
->sfield_map
: ctx
->field_map
,
828 (splay_tree_key
) var
);
829 return (tree
) n
->value
;
833 maybe_lookup_field (tree var
, omp_context
*ctx
)
836 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
837 return n
? (tree
) n
->value
: NULL_TREE
;
840 /* Return true if DECL should be copied by pointer. SHARED_CTX is
841 the parallel context if DECL is to be shared. */
844 use_pointer_for_field (tree decl
, omp_context
*shared_ctx
)
846 if (AGGREGATE_TYPE_P (TREE_TYPE (decl
)))
849 /* We can only use copy-in/copy-out semantics for shared variables
850 when we know the value is not accessible from an outer scope. */
853 /* ??? Trivially accessible from anywhere. But why would we even
854 be passing an address in this case? Should we simply assert
855 this to be false, or should we have a cleanup pass that removes
856 these from the list of mappings? */
857 if (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
860 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
861 without analyzing the expression whether or not its location
862 is accessible to anyone else. In the case of nested parallel
863 regions it certainly may be. */
864 if (TREE_CODE (decl
) != RESULT_DECL
&& DECL_HAS_VALUE_EXPR_P (decl
))
867 /* Do not use copy-in/copy-out for variables that have their
869 if (TREE_ADDRESSABLE (decl
))
872 /* lower_send_shared_vars only uses copy-in, but not copy-out
874 if (TREE_READONLY (decl
)
875 || ((TREE_CODE (decl
) == RESULT_DECL
876 || TREE_CODE (decl
) == PARM_DECL
)
877 && DECL_BY_REFERENCE (decl
)))
880 /* Disallow copy-in/out in nested parallel if
881 decl is shared in outer parallel, otherwise
882 each thread could store the shared variable
883 in its own copy-in location, making the
884 variable no longer really shared. */
885 if (shared_ctx
->is_nested
)
889 for (up
= shared_ctx
->outer
; up
; up
= up
->outer
)
890 if (is_taskreg_ctx (up
) && maybe_lookup_decl (decl
, up
))
897 for (c
= gimple_omp_taskreg_clauses (up
->stmt
);
898 c
; c
= OMP_CLAUSE_CHAIN (c
))
899 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
900 && OMP_CLAUSE_DECL (c
) == decl
)
904 goto maybe_mark_addressable_and_ret
;
908 /* For tasks avoid using copy-in/out. As tasks can be
909 deferred or executed in different thread, when GOMP_task
910 returns, the task hasn't necessarily terminated. */
911 if (is_task_ctx (shared_ctx
))
914 maybe_mark_addressable_and_ret
:
915 outer
= maybe_lookup_decl_in_outer_ctx (decl
, shared_ctx
);
916 if (is_gimple_reg (outer
))
918 /* Taking address of OUTER in lower_send_shared_vars
919 might need regimplification of everything that uses the
921 if (!task_shared_vars
)
922 task_shared_vars
= BITMAP_ALLOC (NULL
);
923 bitmap_set_bit (task_shared_vars
, DECL_UID (outer
));
924 TREE_ADDRESSABLE (outer
) = 1;
933 /* Construct a new automatic decl similar to VAR. */
936 omp_copy_decl_2 (tree var
, tree name
, tree type
, omp_context
*ctx
)
938 tree copy
= copy_var_decl (var
, name
, type
);
940 DECL_CONTEXT (copy
) = current_function_decl
;
941 DECL_CHAIN (copy
) = ctx
->block_vars
;
942 ctx
->block_vars
= copy
;
948 omp_copy_decl_1 (tree var
, omp_context
*ctx
)
950 return omp_copy_decl_2 (var
, DECL_NAME (var
), TREE_TYPE (var
), ctx
);
953 /* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
956 omp_build_component_ref (tree obj
, tree field
)
958 tree ret
= build3 (COMPONENT_REF
, TREE_TYPE (field
), obj
, field
, NULL
);
959 if (TREE_THIS_VOLATILE (field
))
960 TREE_THIS_VOLATILE (ret
) |= 1;
961 if (TREE_READONLY (field
))
962 TREE_READONLY (ret
) |= 1;
966 /* Build tree nodes to access the field for VAR on the receiver side. */
969 build_receiver_ref (tree var
, bool by_ref
, omp_context
*ctx
)
971 tree x
, field
= lookup_field (var
, ctx
);
973 /* If the receiver record type was remapped in the child function,
974 remap the field into the new record type. */
975 x
= maybe_lookup_field (field
, ctx
);
979 x
= build_simple_mem_ref (ctx
->receiver_decl
);
980 x
= omp_build_component_ref (x
, field
);
982 x
= build_simple_mem_ref (x
);
987 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
988 of a parallel, this is a component reference; for workshare constructs
989 this is some variable. */
992 build_outer_var_ref (tree var
, omp_context
*ctx
)
996 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
, ctx
)))
998 else if (is_variable_sized (var
))
1000 x
= TREE_OPERAND (DECL_VALUE_EXPR (var
), 0);
1001 x
= build_outer_var_ref (x
, ctx
);
1002 x
= build_simple_mem_ref (x
);
1004 else if (is_taskreg_ctx (ctx
))
1006 bool by_ref
= use_pointer_for_field (var
, NULL
);
1007 x
= build_receiver_ref (var
, by_ref
, ctx
);
1009 else if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_FOR
1010 && gimple_omp_for_kind (ctx
->stmt
) & GF_OMP_FOR_KIND_SIMD
)
1012 /* #pragma omp simd isn't a worksharing construct, and can reference even
1013 private vars in its linear etc. clauses. */
1015 if (ctx
->outer
&& is_taskreg_ctx (ctx
))
1016 x
= lookup_decl (var
, ctx
->outer
);
1017 else if (ctx
->outer
)
1018 x
= maybe_lookup_decl_in_outer_ctx (var
, ctx
);
1022 else if (ctx
->outer
)
1023 x
= lookup_decl (var
, ctx
->outer
);
1024 else if (is_reference (var
))
1025 /* This can happen with orphaned constructs. If var is reference, it is
1026 possible it is shared and as such valid. */
1031 if (is_reference (var
))
1032 x
= build_simple_mem_ref (x
);
1037 /* Build tree nodes to access the field for VAR on the sender side. */
1040 build_sender_ref (tree var
, omp_context
*ctx
)
1042 tree field
= lookup_sfield (var
, ctx
);
1043 return omp_build_component_ref (ctx
->sender_decl
, field
);
1046 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
1049 install_var_field (tree var
, bool by_ref
, int mask
, omp_context
*ctx
)
1051 tree field
, type
, sfield
= NULL_TREE
;
1053 gcc_assert ((mask
& 1) == 0
1054 || !splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
));
1055 gcc_assert ((mask
& 2) == 0 || !ctx
->sfield_map
1056 || !splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) var
));
1058 type
= TREE_TYPE (var
);
1061 gcc_assert (TREE_CODE (type
) == ARRAY_TYPE
);
1062 type
= build_pointer_type (build_pointer_type (type
));
1065 type
= build_pointer_type (type
);
1066 else if ((mask
& 3) == 1 && is_reference (var
))
1067 type
= TREE_TYPE (type
);
1069 field
= build_decl (DECL_SOURCE_LOCATION (var
),
1070 FIELD_DECL
, DECL_NAME (var
), type
);
1072 /* Remember what variable this field was created for. This does have a
1073 side effect of making dwarf2out ignore this member, so for helpful
1074 debugging we clear it later in delete_omp_context. */
1075 DECL_ABSTRACT_ORIGIN (field
) = var
;
1076 if (type
== TREE_TYPE (var
))
1078 DECL_ALIGN (field
) = DECL_ALIGN (var
);
1079 DECL_USER_ALIGN (field
) = DECL_USER_ALIGN (var
);
1080 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (var
);
1083 DECL_ALIGN (field
) = TYPE_ALIGN (type
);
1085 if ((mask
& 3) == 3)
1087 insert_field_into_struct (ctx
->record_type
, field
);
1088 if (ctx
->srecord_type
)
1090 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
1091 FIELD_DECL
, DECL_NAME (var
), type
);
1092 DECL_ABSTRACT_ORIGIN (sfield
) = var
;
1093 DECL_ALIGN (sfield
) = DECL_ALIGN (field
);
1094 DECL_USER_ALIGN (sfield
) = DECL_USER_ALIGN (field
);
1095 TREE_THIS_VOLATILE (sfield
) = TREE_THIS_VOLATILE (field
);
1096 insert_field_into_struct (ctx
->srecord_type
, sfield
);
1101 if (ctx
->srecord_type
== NULL_TREE
)
1105 ctx
->srecord_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1106 ctx
->sfield_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1107 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= TREE_CHAIN (t
))
1109 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
1110 FIELD_DECL
, DECL_NAME (t
), TREE_TYPE (t
));
1111 DECL_ABSTRACT_ORIGIN (sfield
) = DECL_ABSTRACT_ORIGIN (t
);
1112 insert_field_into_struct (ctx
->srecord_type
, sfield
);
1113 splay_tree_insert (ctx
->sfield_map
,
1114 (splay_tree_key
) DECL_ABSTRACT_ORIGIN (t
),
1115 (splay_tree_value
) sfield
);
1119 insert_field_into_struct ((mask
& 1) ? ctx
->record_type
1120 : ctx
->srecord_type
, field
);
1124 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) var
,
1125 (splay_tree_value
) field
);
1126 if ((mask
& 2) && ctx
->sfield_map
)
1127 splay_tree_insert (ctx
->sfield_map
, (splay_tree_key
) var
,
1128 (splay_tree_value
) sfield
);
1132 install_var_local (tree var
, omp_context
*ctx
)
1134 tree new_var
= omp_copy_decl_1 (var
, ctx
);
1135 insert_decl_map (&ctx
->cb
, var
, new_var
);
1139 /* Adjust the replacement for DECL in CTX for the new context. This means
1140 copying the DECL_VALUE_EXPR, and fixing up the type. */
1143 fixup_remapped_decl (tree decl
, omp_context
*ctx
, bool private_debug
)
1145 tree new_decl
, size
;
1147 new_decl
= lookup_decl (decl
, ctx
);
1149 TREE_TYPE (new_decl
) = remap_type (TREE_TYPE (decl
), &ctx
->cb
);
1151 if ((!TREE_CONSTANT (DECL_SIZE (new_decl
)) || private_debug
)
1152 && DECL_HAS_VALUE_EXPR_P (decl
))
1154 tree ve
= DECL_VALUE_EXPR (decl
);
1155 walk_tree (&ve
, copy_tree_body_r
, &ctx
->cb
, NULL
);
1156 SET_DECL_VALUE_EXPR (new_decl
, ve
);
1157 DECL_HAS_VALUE_EXPR_P (new_decl
) = 1;
1160 if (!TREE_CONSTANT (DECL_SIZE (new_decl
)))
1162 size
= remap_decl (DECL_SIZE (decl
), &ctx
->cb
);
1163 if (size
== error_mark_node
)
1164 size
= TYPE_SIZE (TREE_TYPE (new_decl
));
1165 DECL_SIZE (new_decl
) = size
;
1167 size
= remap_decl (DECL_SIZE_UNIT (decl
), &ctx
->cb
);
1168 if (size
== error_mark_node
)
1169 size
= TYPE_SIZE_UNIT (TREE_TYPE (new_decl
));
1170 DECL_SIZE_UNIT (new_decl
) = size
;
1174 /* The callback for remap_decl. Search all containing contexts for a
1175 mapping of the variable; this avoids having to duplicate the splay
1176 tree ahead of time. We know a mapping doesn't already exist in the
1177 given context. Create new mappings to implement default semantics. */
1180 omp_copy_decl (tree var
, copy_body_data
*cb
)
1182 omp_context
*ctx
= (omp_context
*) cb
;
1185 if (TREE_CODE (var
) == LABEL_DECL
)
1187 new_var
= create_artificial_label (DECL_SOURCE_LOCATION (var
));
1188 DECL_CONTEXT (new_var
) = current_function_decl
;
1189 insert_decl_map (&ctx
->cb
, var
, new_var
);
1193 while (!is_taskreg_ctx (ctx
))
1198 new_var
= maybe_lookup_decl (var
, ctx
);
1203 if (is_global_var (var
) || decl_function_context (var
) != ctx
->cb
.src_fn
)
1206 return error_mark_node
;
1210 /* Return the parallel region associated with STMT. */
1212 /* Debugging dumps for parallel regions. */
1213 void dump_omp_region (FILE *, struct omp_region
*, int);
1214 void debug_omp_region (struct omp_region
*);
1215 void debug_all_omp_regions (void);
1217 /* Dump the parallel region tree rooted at REGION. */
1220 dump_omp_region (FILE *file
, struct omp_region
*region
, int indent
)
1222 fprintf (file
, "%*sbb %d: %s\n", indent
, "", region
->entry
->index
,
1223 gimple_code_name
[region
->type
]);
1226 dump_omp_region (file
, region
->inner
, indent
+ 4);
1230 fprintf (file
, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent
, "",
1231 region
->cont
->index
);
1235 fprintf (file
, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent
, "",
1236 region
->exit
->index
);
1238 fprintf (file
, "%*s[no exit marker]\n", indent
, "");
1241 dump_omp_region (file
, region
->next
, indent
);
1245 debug_omp_region (struct omp_region
*region
)
1247 dump_omp_region (stderr
, region
, 0);
1251 debug_all_omp_regions (void)
1253 dump_omp_region (stderr
, root_omp_region
, 0);
1257 /* Create a new parallel region starting at STMT inside region PARENT. */
1259 static struct omp_region
*
1260 new_omp_region (basic_block bb
, enum gimple_code type
,
1261 struct omp_region
*parent
)
1263 struct omp_region
*region
= XCNEW (struct omp_region
);
1265 region
->outer
= parent
;
1267 region
->type
= type
;
1271 /* This is a nested region. Add it to the list of inner
1272 regions in PARENT. */
1273 region
->next
= parent
->inner
;
1274 parent
->inner
= region
;
1278 /* This is a toplevel region. Add it to the list of toplevel
1279 regions in ROOT_OMP_REGION. */
1280 region
->next
= root_omp_region
;
1281 root_omp_region
= region
;
1287 /* Release the memory associated with the region tree rooted at REGION. */
1290 free_omp_region_1 (struct omp_region
*region
)
1292 struct omp_region
*i
, *n
;
1294 for (i
= region
->inner
; i
; i
= n
)
1297 free_omp_region_1 (i
);
1303 /* Release the memory for the entire omp region tree. */
1306 free_omp_regions (void)
1308 struct omp_region
*r
, *n
;
1309 for (r
= root_omp_region
; r
; r
= n
)
1312 free_omp_region_1 (r
);
1314 root_omp_region
= NULL
;
1318 /* Create a new context, with OUTER_CTX being the surrounding context. */
1320 static omp_context
*
1321 new_omp_context (gimple stmt
, omp_context
*outer_ctx
)
1323 omp_context
*ctx
= XCNEW (omp_context
);
1325 splay_tree_insert (all_contexts
, (splay_tree_key
) stmt
,
1326 (splay_tree_value
) ctx
);
1331 ctx
->outer
= outer_ctx
;
1332 ctx
->cb
= outer_ctx
->cb
;
1333 ctx
->cb
.block
= NULL
;
1334 ctx
->depth
= outer_ctx
->depth
+ 1;
1338 ctx
->cb
.src_fn
= current_function_decl
;
1339 ctx
->cb
.dst_fn
= current_function_decl
;
1340 ctx
->cb
.src_node
= cgraph_get_node (current_function_decl
);
1341 gcc_checking_assert (ctx
->cb
.src_node
);
1342 ctx
->cb
.dst_node
= ctx
->cb
.src_node
;
1343 ctx
->cb
.src_cfun
= cfun
;
1344 ctx
->cb
.copy_decl
= omp_copy_decl
;
1345 ctx
->cb
.eh_lp_nr
= 0;
1346 ctx
->cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
1350 ctx
->cb
.decl_map
= pointer_map_create ();
1355 static gimple_seq
maybe_catch_exception (gimple_seq
);
1357 /* Finalize task copyfn. */
1360 finalize_task_copyfn (gimple task_stmt
)
1362 struct function
*child_cfun
;
1364 gimple_seq seq
= NULL
, new_seq
;
1367 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
1368 if (child_fn
== NULL_TREE
)
1371 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
1372 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
= cfun
->curr_properties
;
1374 push_cfun (child_cfun
);
1375 bind
= gimplify_body (child_fn
, false);
1376 gimple_seq_add_stmt (&seq
, bind
);
1377 new_seq
= maybe_catch_exception (seq
);
1380 bind
= gimple_build_bind (NULL
, new_seq
, NULL
);
1382 gimple_seq_add_stmt (&seq
, bind
);
1384 gimple_set_body (child_fn
, seq
);
1387 /* Inform the callgraph about the new function. */
1388 cgraph_add_new_function (child_fn
, false);
1391 /* Destroy a omp_context data structures. Called through the splay tree
1392 value delete callback. */
1395 delete_omp_context (splay_tree_value value
)
1397 omp_context
*ctx
= (omp_context
*) value
;
1399 pointer_map_destroy (ctx
->cb
.decl_map
);
1402 splay_tree_delete (ctx
->field_map
);
1403 if (ctx
->sfield_map
)
1404 splay_tree_delete (ctx
->sfield_map
);
1406 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1407 it produces corrupt debug information. */
1408 if (ctx
->record_type
)
1411 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= DECL_CHAIN (t
))
1412 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1414 if (ctx
->srecord_type
)
1417 for (t
= TYPE_FIELDS (ctx
->srecord_type
); t
; t
= DECL_CHAIN (t
))
1418 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1421 if (is_task_ctx (ctx
))
1422 finalize_task_copyfn (ctx
->stmt
);
1427 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1431 fixup_child_record_type (omp_context
*ctx
)
1433 tree f
, type
= ctx
->record_type
;
1435 /* ??? It isn't sufficient to just call remap_type here, because
1436 variably_modified_type_p doesn't work the way we expect for
1437 record types. Testing each field for whether it needs remapping
1438 and creating a new record by hand works, however. */
1439 for (f
= TYPE_FIELDS (type
); f
; f
= DECL_CHAIN (f
))
1440 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
1444 tree name
, new_fields
= NULL
;
1446 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1447 name
= DECL_NAME (TYPE_NAME (ctx
->record_type
));
1448 name
= build_decl (DECL_SOURCE_LOCATION (ctx
->receiver_decl
),
1449 TYPE_DECL
, name
, type
);
1450 TYPE_NAME (type
) = name
;
1452 for (f
= TYPE_FIELDS (ctx
->record_type
); f
; f
= DECL_CHAIN (f
))
1454 tree new_f
= copy_node (f
);
1455 DECL_CONTEXT (new_f
) = type
;
1456 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &ctx
->cb
);
1457 DECL_CHAIN (new_f
) = new_fields
;
1458 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &ctx
->cb
, NULL
);
1459 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
,
1461 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
1465 /* Arrange to be able to look up the receiver field
1466 given the sender field. */
1467 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) f
,
1468 (splay_tree_value
) new_f
);
1470 TYPE_FIELDS (type
) = nreverse (new_fields
);
1474 TREE_TYPE (ctx
->receiver_decl
) = build_pointer_type (type
);
1477 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1478 specified by CLAUSES. */
1481 scan_sharing_clauses (tree clauses
, omp_context
*ctx
)
1484 bool scan_array_reductions
= false;
1486 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1490 switch (OMP_CLAUSE_CODE (c
))
1492 case OMP_CLAUSE_PRIVATE
:
1493 decl
= OMP_CLAUSE_DECL (c
);
1494 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
1496 else if (!is_variable_sized (decl
))
1497 install_var_local (decl
, ctx
);
1500 case OMP_CLAUSE_SHARED
:
1501 /* Ignore shared directives in teams construct. */
1502 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_TEAMS
)
1504 gcc_assert (is_taskreg_ctx (ctx
));
1505 decl
= OMP_CLAUSE_DECL (c
);
1506 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl
))
1507 || !is_variable_sized (decl
));
1508 /* Global variables don't need to be copied,
1509 the receiver side will use them directly. */
1510 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1512 by_ref
= use_pointer_for_field (decl
, ctx
);
1513 if (! TREE_READONLY (decl
)
1514 || TREE_ADDRESSABLE (decl
)
1516 || is_reference (decl
))
1518 install_var_field (decl
, by_ref
, 3, ctx
);
1519 install_var_local (decl
, ctx
);
1522 /* We don't need to copy const scalar vars back. */
1523 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_FIRSTPRIVATE
);
1526 case OMP_CLAUSE_LASTPRIVATE
:
1527 /* Let the corresponding firstprivate clause create
1529 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1533 case OMP_CLAUSE_FIRSTPRIVATE
:
1534 case OMP_CLAUSE_REDUCTION
:
1535 case OMP_CLAUSE_LINEAR
:
1536 decl
= OMP_CLAUSE_DECL (c
);
1538 if (is_variable_sized (decl
))
1540 if (is_task_ctx (ctx
))
1541 install_var_field (decl
, false, 1, ctx
);
1544 else if (is_taskreg_ctx (ctx
))
1547 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
));
1548 by_ref
= use_pointer_for_field (decl
, NULL
);
1550 if (is_task_ctx (ctx
)
1551 && (global
|| by_ref
|| is_reference (decl
)))
1553 install_var_field (decl
, false, 1, ctx
);
1555 install_var_field (decl
, by_ref
, 2, ctx
);
1558 install_var_field (decl
, by_ref
, 3, ctx
);
1560 install_var_local (decl
, ctx
);
1563 case OMP_CLAUSE__LOOPTEMP_
:
1564 gcc_assert (is_parallel_ctx (ctx
));
1565 decl
= OMP_CLAUSE_DECL (c
);
1566 install_var_field (decl
, false, 3, ctx
);
1567 install_var_local (decl
, ctx
);
1570 case OMP_CLAUSE_COPYPRIVATE
:
1571 case OMP_CLAUSE_COPYIN
:
1572 decl
= OMP_CLAUSE_DECL (c
);
1573 by_ref
= use_pointer_for_field (decl
, NULL
);
1574 install_var_field (decl
, by_ref
, 3, ctx
);
1577 case OMP_CLAUSE_DEFAULT
:
1578 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
1581 case OMP_CLAUSE_FINAL
:
1583 case OMP_CLAUSE_NUM_THREADS
:
1584 case OMP_CLAUSE_NUM_TEAMS
:
1585 case OMP_CLAUSE_THREAD_LIMIT
:
1586 case OMP_CLAUSE_DEVICE
:
1587 case OMP_CLAUSE_SCHEDULE
:
1588 case OMP_CLAUSE_DIST_SCHEDULE
:
1589 case OMP_CLAUSE_DEPEND
:
1591 scan_omp_op (&OMP_CLAUSE_OPERAND (c
, 0), ctx
->outer
);
1595 case OMP_CLAUSE_FROM
:
1596 case OMP_CLAUSE_MAP
:
1598 scan_omp_op (&OMP_CLAUSE_SIZE (c
), ctx
->outer
);
1599 decl
= OMP_CLAUSE_DECL (c
);
1600 /* Global variables with "omp declare target" attribute
1601 don't need to be copied, the receiver side will use them
1603 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
1605 && is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
))
1606 && lookup_attribute ("omp declare target",
1607 DECL_ATTRIBUTES (decl
)))
1609 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
1610 && OMP_CLAUSE_MAP_KIND (c
) == OMP_CLAUSE_MAP_POINTER
)
1612 /* Ignore OMP_CLAUSE_MAP_POINTER kind for arrays in
1613 #pragma omp target data, there is nothing to map for
1615 if (gimple_omp_target_kind (ctx
->stmt
) == GF_OMP_TARGET_KIND_DATA
1616 && !POINTER_TYPE_P (TREE_TYPE (decl
)))
1621 if (DECL_SIZE (decl
)
1622 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
1624 tree decl2
= DECL_VALUE_EXPR (decl
);
1625 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
1626 decl2
= TREE_OPERAND (decl2
, 0);
1627 gcc_assert (DECL_P (decl2
));
1628 install_var_field (decl2
, true, 3, ctx
);
1629 install_var_local (decl2
, ctx
);
1630 install_var_local (decl
, ctx
);
1634 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
1635 && OMP_CLAUSE_MAP_KIND (c
) == OMP_CLAUSE_MAP_POINTER
1636 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c
)
1637 && TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
1638 install_var_field (decl
, true, 7, ctx
);
1640 install_var_field (decl
, true, 3, ctx
);
1641 if (gimple_omp_target_kind (ctx
->stmt
)
1642 == GF_OMP_TARGET_KIND_REGION
)
1643 install_var_local (decl
, ctx
);
1648 tree base
= get_base_address (decl
);
1649 tree nc
= OMP_CLAUSE_CHAIN (c
);
1652 && OMP_CLAUSE_CODE (nc
) == OMP_CLAUSE_MAP
1653 && OMP_CLAUSE_DECL (nc
) == base
1654 && OMP_CLAUSE_MAP_KIND (nc
) == OMP_CLAUSE_MAP_POINTER
1655 && integer_zerop (OMP_CLAUSE_SIZE (nc
)))
1657 OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c
) = 1;
1658 OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc
) = 1;
1662 gcc_assert (!splay_tree_lookup (ctx
->field_map
,
1663 (splay_tree_key
) decl
));
1665 = build_decl (OMP_CLAUSE_LOCATION (c
),
1666 FIELD_DECL
, NULL_TREE
, ptr_type_node
);
1667 DECL_ALIGN (field
) = TYPE_ALIGN (ptr_type_node
);
1668 insert_field_into_struct (ctx
->record_type
, field
);
1669 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) decl
,
1670 (splay_tree_value
) field
);
1675 case OMP_CLAUSE_NOWAIT
:
1676 case OMP_CLAUSE_ORDERED
:
1677 case OMP_CLAUSE_COLLAPSE
:
1678 case OMP_CLAUSE_UNTIED
:
1679 case OMP_CLAUSE_MERGEABLE
:
1680 case OMP_CLAUSE_PROC_BIND
:
1681 case OMP_CLAUSE_SAFELEN
:
1684 case OMP_CLAUSE_ALIGNED
:
1685 decl
= OMP_CLAUSE_DECL (c
);
1686 if (is_global_var (decl
)
1687 && TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
)
1688 install_var_local (decl
, ctx
);
1696 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1698 switch (OMP_CLAUSE_CODE (c
))
1700 case OMP_CLAUSE_LASTPRIVATE
:
1701 /* Let the corresponding firstprivate clause create
1703 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1704 scan_array_reductions
= true;
1705 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1709 case OMP_CLAUSE_PRIVATE
:
1710 case OMP_CLAUSE_FIRSTPRIVATE
:
1711 case OMP_CLAUSE_REDUCTION
:
1712 case OMP_CLAUSE_LINEAR
:
1713 decl
= OMP_CLAUSE_DECL (c
);
1714 if (is_variable_sized (decl
))
1715 install_var_local (decl
, ctx
);
1716 fixup_remapped_decl (decl
, ctx
,
1717 OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_PRIVATE
1718 && OMP_CLAUSE_PRIVATE_DEBUG (c
));
1719 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1720 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1721 scan_array_reductions
= true;
1724 case OMP_CLAUSE_SHARED
:
1725 /* Ignore shared directives in teams construct. */
1726 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_TEAMS
)
1728 decl
= OMP_CLAUSE_DECL (c
);
1729 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1730 fixup_remapped_decl (decl
, ctx
, false);
1733 case OMP_CLAUSE_MAP
:
1734 if (gimple_omp_target_kind (ctx
->stmt
) == GF_OMP_TARGET_KIND_DATA
)
1736 decl
= OMP_CLAUSE_DECL (c
);
1738 && is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
))
1739 && lookup_attribute ("omp declare target",
1740 DECL_ATTRIBUTES (decl
)))
1744 if (OMP_CLAUSE_MAP_KIND (c
) == OMP_CLAUSE_MAP_POINTER
1745 && TREE_CODE (TREE_TYPE (decl
)) == ARRAY_TYPE
1746 && !COMPLETE_TYPE_P (TREE_TYPE (decl
)))
1748 tree new_decl
= lookup_decl (decl
, ctx
);
1749 TREE_TYPE (new_decl
)
1750 = remap_type (TREE_TYPE (decl
), &ctx
->cb
);
1752 else if (DECL_SIZE (decl
)
1753 && TREE_CODE (DECL_SIZE (decl
)) != INTEGER_CST
)
1755 tree decl2
= DECL_VALUE_EXPR (decl
);
1756 gcc_assert (TREE_CODE (decl2
) == INDIRECT_REF
);
1757 decl2
= TREE_OPERAND (decl2
, 0);
1758 gcc_assert (DECL_P (decl2
));
1759 fixup_remapped_decl (decl2
, ctx
, false);
1760 fixup_remapped_decl (decl
, ctx
, true);
1763 fixup_remapped_decl (decl
, ctx
, false);
1767 case OMP_CLAUSE_COPYPRIVATE
:
1768 case OMP_CLAUSE_COPYIN
:
1769 case OMP_CLAUSE_DEFAULT
:
1771 case OMP_CLAUSE_NUM_THREADS
:
1772 case OMP_CLAUSE_NUM_TEAMS
:
1773 case OMP_CLAUSE_THREAD_LIMIT
:
1774 case OMP_CLAUSE_DEVICE
:
1775 case OMP_CLAUSE_SCHEDULE
:
1776 case OMP_CLAUSE_DIST_SCHEDULE
:
1777 case OMP_CLAUSE_NOWAIT
:
1778 case OMP_CLAUSE_ORDERED
:
1779 case OMP_CLAUSE_COLLAPSE
:
1780 case OMP_CLAUSE_UNTIED
:
1781 case OMP_CLAUSE_FINAL
:
1782 case OMP_CLAUSE_MERGEABLE
:
1783 case OMP_CLAUSE_PROC_BIND
:
1784 case OMP_CLAUSE_SAFELEN
:
1785 case OMP_CLAUSE_ALIGNED
:
1786 case OMP_CLAUSE_DEPEND
:
1787 case OMP_CLAUSE__LOOPTEMP_
:
1789 case OMP_CLAUSE_FROM
:
1797 if (scan_array_reductions
)
1798 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1799 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1800 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1802 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
1803 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
1805 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
1806 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1807 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
1810 /* Create a new name for omp child function. Returns an identifier. */
1812 static GTY(()) unsigned int tmp_ompfn_id_num
;
1815 create_omp_child_function_name (bool task_copy
)
1817 return (clone_function_name (current_function_decl
,
1818 task_copy
? "_omp_cpyfn" : "_omp_fn"));
1821 /* Build a decl for the omp child function. It'll not contain a body
1822 yet, just the bare decl. */
1825 create_omp_child_function (omp_context
*ctx
, bool task_copy
)
1827 tree decl
, type
, name
, t
;
1829 name
= create_omp_child_function_name (task_copy
);
1831 type
= build_function_type_list (void_type_node
, ptr_type_node
,
1832 ptr_type_node
, NULL_TREE
);
1834 type
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
1836 decl
= build_decl (gimple_location (ctx
->stmt
),
1837 FUNCTION_DECL
, name
, type
);
1840 ctx
->cb
.dst_fn
= decl
;
1842 gimple_omp_task_set_copy_fn (ctx
->stmt
, decl
);
1844 TREE_STATIC (decl
) = 1;
1845 TREE_USED (decl
) = 1;
1846 DECL_ARTIFICIAL (decl
) = 1;
1847 DECL_NAMELESS (decl
) = 1;
1848 DECL_IGNORED_P (decl
) = 0;
1849 TREE_PUBLIC (decl
) = 0;
1850 DECL_UNINLINABLE (decl
) = 1;
1851 DECL_EXTERNAL (decl
) = 0;
1852 DECL_CONTEXT (decl
) = NULL_TREE
;
1853 DECL_INITIAL (decl
) = make_node (BLOCK
);
1854 bool target_p
= false;
1855 if (lookup_attribute ("omp declare target",
1856 DECL_ATTRIBUTES (current_function_decl
)))
1861 for (octx
= ctx
; octx
; octx
= octx
->outer
)
1862 if (gimple_code (octx
->stmt
) == GIMPLE_OMP_TARGET
1863 && gimple_omp_target_kind (octx
->stmt
)
1864 == GF_OMP_TARGET_KIND_REGION
)
1871 DECL_ATTRIBUTES (decl
)
1872 = tree_cons (get_identifier ("omp declare target"),
1873 NULL_TREE
, DECL_ATTRIBUTES (decl
));
1875 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1876 RESULT_DECL
, NULL_TREE
, void_type_node
);
1877 DECL_ARTIFICIAL (t
) = 1;
1878 DECL_IGNORED_P (t
) = 1;
1879 DECL_CONTEXT (t
) = decl
;
1880 DECL_RESULT (decl
) = t
;
1882 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1883 PARM_DECL
, get_identifier (".omp_data_i"), ptr_type_node
);
1884 DECL_ARTIFICIAL (t
) = 1;
1885 DECL_NAMELESS (t
) = 1;
1886 DECL_ARG_TYPE (t
) = ptr_type_node
;
1887 DECL_CONTEXT (t
) = current_function_decl
;
1889 DECL_ARGUMENTS (decl
) = t
;
1891 ctx
->receiver_decl
= t
;
1894 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1895 PARM_DECL
, get_identifier (".omp_data_o"),
1897 DECL_ARTIFICIAL (t
) = 1;
1898 DECL_NAMELESS (t
) = 1;
1899 DECL_ARG_TYPE (t
) = ptr_type_node
;
1900 DECL_CONTEXT (t
) = current_function_decl
;
1902 TREE_ADDRESSABLE (t
) = 1;
1903 DECL_CHAIN (t
) = DECL_ARGUMENTS (decl
);
1904 DECL_ARGUMENTS (decl
) = t
;
1907 /* Allocate memory for the function structure. The call to
1908 allocate_struct_function clobbers CFUN, so we need to restore
1910 push_struct_function (decl
);
1911 cfun
->function_end_locus
= gimple_location (ctx
->stmt
);
1915 /* Callback for walk_gimple_seq. Check if combined parallel
1916 contains gimple_omp_for_combined_into_p OMP_FOR. */
1919 find_combined_for (gimple_stmt_iterator
*gsi_p
,
1920 bool *handled_ops_p
,
1921 struct walk_stmt_info
*wi
)
1923 gimple stmt
= gsi_stmt (*gsi_p
);
1925 *handled_ops_p
= true;
1926 switch (gimple_code (stmt
))
1930 case GIMPLE_OMP_FOR
:
1931 if (gimple_omp_for_combined_into_p (stmt
)
1932 && gimple_omp_for_kind (stmt
) == GF_OMP_FOR_KIND_FOR
)
1935 return integer_zero_node
;
1944 /* Scan an OpenMP parallel directive. */
1947 scan_omp_parallel (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1951 gimple stmt
= gsi_stmt (*gsi
);
1953 /* Ignore parallel directives with empty bodies, unless there
1954 are copyin clauses. */
1956 && empty_body_p (gimple_omp_body (stmt
))
1957 && find_omp_clause (gimple_omp_parallel_clauses (stmt
),
1958 OMP_CLAUSE_COPYIN
) == NULL
)
1960 gsi_replace (gsi
, gimple_build_nop (), false);
1964 if (gimple_omp_parallel_combined_p (stmt
))
1967 struct walk_stmt_info wi
;
1969 memset (&wi
, 0, sizeof (wi
));
1971 walk_gimple_seq (gimple_omp_body (stmt
),
1972 find_combined_for
, NULL
, &wi
);
1973 for_stmt
= (gimple
) wi
.info
;
1976 struct omp_for_data fd
;
1977 extract_omp_for_data (for_stmt
, &fd
, NULL
);
1978 /* We need two temporaries with fd.loop.v type (istart/iend)
1979 and then (fd.collapse - 1) temporaries with the same
1980 type for count2 ... countN-1 vars if not constant. */
1981 size_t count
= 2, i
;
1982 tree type
= fd
.iter_type
;
1984 && TREE_CODE (fd
.loop
.n2
) != INTEGER_CST
)
1985 count
+= fd
.collapse
- 1;
1986 for (i
= 0; i
< count
; i
++)
1988 tree temp
= create_tmp_var (type
, NULL
);
1989 tree c
= build_omp_clause (UNKNOWN_LOCATION
,
1990 OMP_CLAUSE__LOOPTEMP_
);
1991 OMP_CLAUSE_DECL (c
) = temp
;
1992 OMP_CLAUSE_CHAIN (c
) = gimple_omp_parallel_clauses (stmt
);
1993 gimple_omp_parallel_set_clauses (stmt
, c
);
1998 ctx
= new_omp_context (stmt
, outer_ctx
);
1999 if (taskreg_nesting_level
> 1)
2000 ctx
->is_nested
= true;
2001 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
2002 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
2003 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
2004 name
= create_tmp_var_name (".omp_data_s");
2005 name
= build_decl (gimple_location (stmt
),
2006 TYPE_DECL
, name
, ctx
->record_type
);
2007 DECL_ARTIFICIAL (name
) = 1;
2008 DECL_NAMELESS (name
) = 1;
2009 TYPE_NAME (ctx
->record_type
) = name
;
2010 create_omp_child_function (ctx
, false);
2011 gimple_omp_parallel_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
2013 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt
), ctx
);
2014 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2016 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
2017 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
2020 layout_type (ctx
->record_type
);
2021 fixup_child_record_type (ctx
);
2025 /* Scan an OpenMP task directive. */
2028 scan_omp_task (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
2032 gimple stmt
= gsi_stmt (*gsi
);
2033 location_t loc
= gimple_location (stmt
);
2035 /* Ignore task directives with empty bodies. */
2037 && empty_body_p (gimple_omp_body (stmt
)))
2039 gsi_replace (gsi
, gimple_build_nop (), false);
2043 ctx
= new_omp_context (stmt
, outer_ctx
);
2044 if (taskreg_nesting_level
> 1)
2045 ctx
->is_nested
= true;
2046 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
2047 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
2048 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
2049 name
= create_tmp_var_name (".omp_data_s");
2050 name
= build_decl (gimple_location (stmt
),
2051 TYPE_DECL
, name
, ctx
->record_type
);
2052 DECL_ARTIFICIAL (name
) = 1;
2053 DECL_NAMELESS (name
) = 1;
2054 TYPE_NAME (ctx
->record_type
) = name
;
2055 create_omp_child_function (ctx
, false);
2056 gimple_omp_task_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
2058 scan_sharing_clauses (gimple_omp_task_clauses (stmt
), ctx
);
2060 if (ctx
->srecord_type
)
2062 name
= create_tmp_var_name (".omp_data_a");
2063 name
= build_decl (gimple_location (stmt
),
2064 TYPE_DECL
, name
, ctx
->srecord_type
);
2065 DECL_ARTIFICIAL (name
) = 1;
2066 DECL_NAMELESS (name
) = 1;
2067 TYPE_NAME (ctx
->srecord_type
) = name
;
2068 create_omp_child_function (ctx
, true);
2071 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2073 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
2075 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
2076 t
= build_int_cst (long_integer_type_node
, 0);
2077 gimple_omp_task_set_arg_size (stmt
, t
);
2078 t
= build_int_cst (long_integer_type_node
, 1);
2079 gimple_omp_task_set_arg_align (stmt
, t
);
2083 tree
*p
, vla_fields
= NULL_TREE
, *q
= &vla_fields
;
2084 /* Move VLA fields to the end. */
2085 p
= &TYPE_FIELDS (ctx
->record_type
);
2087 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p
))
2088 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p
))))
2091 *p
= TREE_CHAIN (*p
);
2092 TREE_CHAIN (*q
) = NULL_TREE
;
2093 q
= &TREE_CHAIN (*q
);
2096 p
= &DECL_CHAIN (*p
);
2098 layout_type (ctx
->record_type
);
2099 fixup_child_record_type (ctx
);
2100 if (ctx
->srecord_type
)
2101 layout_type (ctx
->srecord_type
);
2102 t
= fold_convert_loc (loc
, long_integer_type_node
,
2103 TYPE_SIZE_UNIT (ctx
->record_type
));
2104 gimple_omp_task_set_arg_size (stmt
, t
);
2105 t
= build_int_cst (long_integer_type_node
,
2106 TYPE_ALIGN_UNIT (ctx
->record_type
));
2107 gimple_omp_task_set_arg_align (stmt
, t
);
2112 /* Scan an OpenMP loop directive. */
2115 scan_omp_for (gimple stmt
, omp_context
*outer_ctx
)
2120 ctx
= new_omp_context (stmt
, outer_ctx
);
2122 scan_sharing_clauses (gimple_omp_for_clauses (stmt
), ctx
);
2124 scan_omp (gimple_omp_for_pre_body_ptr (stmt
), ctx
);
2125 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
2127 scan_omp_op (gimple_omp_for_index_ptr (stmt
, i
), ctx
);
2128 scan_omp_op (gimple_omp_for_initial_ptr (stmt
, i
), ctx
);
2129 scan_omp_op (gimple_omp_for_final_ptr (stmt
, i
), ctx
);
2130 scan_omp_op (gimple_omp_for_incr_ptr (stmt
, i
), ctx
);
2132 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2135 /* Scan an OpenMP sections directive. */
2138 scan_omp_sections (gimple stmt
, omp_context
*outer_ctx
)
2142 ctx
= new_omp_context (stmt
, outer_ctx
);
2143 scan_sharing_clauses (gimple_omp_sections_clauses (stmt
), ctx
);
2144 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2147 /* Scan an OpenMP single directive. */
2150 scan_omp_single (gimple stmt
, omp_context
*outer_ctx
)
2155 ctx
= new_omp_context (stmt
, outer_ctx
);
2156 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
2157 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
2158 name
= create_tmp_var_name (".omp_copy_s");
2159 name
= build_decl (gimple_location (stmt
),
2160 TYPE_DECL
, name
, ctx
->record_type
);
2161 TYPE_NAME (ctx
->record_type
) = name
;
2163 scan_sharing_clauses (gimple_omp_single_clauses (stmt
), ctx
);
2164 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2166 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
2167 ctx
->record_type
= NULL
;
2169 layout_type (ctx
->record_type
);
2172 /* Scan an OpenMP target{, data, update} directive. */
2175 scan_omp_target (gimple stmt
, omp_context
*outer_ctx
)
2179 int kind
= gimple_omp_target_kind (stmt
);
2181 ctx
= new_omp_context (stmt
, outer_ctx
);
2182 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
2183 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
2184 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
2185 name
= create_tmp_var_name (".omp_data_t");
2186 name
= build_decl (gimple_location (stmt
),
2187 TYPE_DECL
, name
, ctx
->record_type
);
2188 DECL_ARTIFICIAL (name
) = 1;
2189 DECL_NAMELESS (name
) = 1;
2190 TYPE_NAME (ctx
->record_type
) = name
;
2191 if (kind
== GF_OMP_TARGET_KIND_REGION
)
2193 create_omp_child_function (ctx
, false);
2194 gimple_omp_target_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
2197 scan_sharing_clauses (gimple_omp_target_clauses (stmt
), ctx
);
2198 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2200 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
2201 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
2204 TYPE_FIELDS (ctx
->record_type
)
2205 = nreverse (TYPE_FIELDS (ctx
->record_type
));
2206 #ifdef ENABLE_CHECKING
2208 unsigned int align
= DECL_ALIGN (TYPE_FIELDS (ctx
->record_type
));
2209 for (field
= TYPE_FIELDS (ctx
->record_type
);
2211 field
= DECL_CHAIN (field
))
2212 gcc_assert (DECL_ALIGN (field
) == align
);
2214 layout_type (ctx
->record_type
);
2215 if (kind
== GF_OMP_TARGET_KIND_REGION
)
2216 fixup_child_record_type (ctx
);
2220 /* Scan an OpenMP teams directive. */
2223 scan_omp_teams (gimple stmt
, omp_context
*outer_ctx
)
2225 omp_context
*ctx
= new_omp_context (stmt
, outer_ctx
);
2226 scan_sharing_clauses (gimple_omp_teams_clauses (stmt
), ctx
);
2227 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2230 /* Check OpenMP nesting restrictions. */
2232 check_omp_nesting_restrictions (gimple stmt
, omp_context
*ctx
)
2236 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_FOR
2237 && gimple_omp_for_kind (ctx
->stmt
) & GF_OMP_FOR_KIND_SIMD
)
2239 error_at (gimple_location (stmt
),
2240 "OpenMP constructs may not be nested inside simd region");
2243 else if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_TEAMS
)
2245 if ((gimple_code (stmt
) != GIMPLE_OMP_FOR
2246 || (gimple_omp_for_kind (stmt
)
2247 != GF_OMP_FOR_KIND_DISTRIBUTE
))
2248 && gimple_code (stmt
) != GIMPLE_OMP_PARALLEL
)
2250 error_at (gimple_location (stmt
),
2251 "only distribute or parallel constructs are allowed to "
2252 "be closely nested inside teams construct");
2257 switch (gimple_code (stmt
))
2259 case GIMPLE_OMP_FOR
:
2260 if (gimple_omp_for_kind (stmt
) & GF_OMP_FOR_KIND_SIMD
)
2262 if (gimple_omp_for_kind (stmt
) == GF_OMP_FOR_KIND_DISTRIBUTE
)
2264 if (ctx
!= NULL
&& gimple_code (ctx
->stmt
) != GIMPLE_OMP_TEAMS
)
2266 error_at (gimple_location (stmt
),
2267 "distribute construct must be closely nested inside "
2275 if (is_gimple_call (stmt
)
2276 && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
))
2277 == BUILT_IN_GOMP_CANCEL
2278 || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
))
2279 == BUILT_IN_GOMP_CANCELLATION_POINT
))
2281 const char *bad
= NULL
;
2282 const char *kind
= NULL
;
2285 error_at (gimple_location (stmt
), "orphaned %qs construct",
2286 DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
))
2287 == BUILT_IN_GOMP_CANCEL
2288 ? "#pragma omp cancel"
2289 : "#pragma omp cancellation point");
2292 switch (host_integerp (gimple_call_arg (stmt
, 0), 0)
2293 ? tree_low_cst (gimple_call_arg (stmt
, 0), 0)
2297 if (gimple_code (ctx
->stmt
) != GIMPLE_OMP_PARALLEL
)
2298 bad
= "#pragma omp parallel";
2299 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
))
2300 == BUILT_IN_GOMP_CANCEL
2301 && !integer_zerop (gimple_call_arg (stmt
, 1)))
2302 ctx
->cancellable
= true;
2306 if (gimple_code (ctx
->stmt
) != GIMPLE_OMP_FOR
2307 || gimple_omp_for_kind (ctx
->stmt
) != GF_OMP_FOR_KIND_FOR
)
2308 bad
= "#pragma omp for";
2309 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
))
2310 == BUILT_IN_GOMP_CANCEL
2311 && !integer_zerop (gimple_call_arg (stmt
, 1)))
2313 ctx
->cancellable
= true;
2314 if (find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
2316 warning_at (gimple_location (stmt
), 0,
2317 "%<#pragma omp cancel for%> inside "
2318 "%<nowait%> for construct");
2319 if (find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
2320 OMP_CLAUSE_ORDERED
))
2321 warning_at (gimple_location (stmt
), 0,
2322 "%<#pragma omp cancel for%> inside "
2323 "%<ordered%> for construct");
2328 if (gimple_code (ctx
->stmt
) != GIMPLE_OMP_SECTIONS
2329 && gimple_code (ctx
->stmt
) != GIMPLE_OMP_SECTION
)
2330 bad
= "#pragma omp sections";
2331 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
))
2332 == BUILT_IN_GOMP_CANCEL
2333 && !integer_zerop (gimple_call_arg (stmt
, 1)))
2335 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_SECTIONS
)
2337 ctx
->cancellable
= true;
2338 if (find_omp_clause (gimple_omp_sections_clauses
2341 warning_at (gimple_location (stmt
), 0,
2342 "%<#pragma omp cancel sections%> inside "
2343 "%<nowait%> sections construct");
2347 gcc_assert (ctx
->outer
2348 && gimple_code (ctx
->outer
->stmt
)
2349 == GIMPLE_OMP_SECTIONS
);
2350 ctx
->outer
->cancellable
= true;
2351 if (find_omp_clause (gimple_omp_sections_clauses
2354 warning_at (gimple_location (stmt
), 0,
2355 "%<#pragma omp cancel sections%> inside "
2356 "%<nowait%> sections construct");
2362 if (gimple_code (ctx
->stmt
) != GIMPLE_OMP_TASK
)
2363 bad
= "#pragma omp task";
2365 ctx
->cancellable
= true;
2369 error_at (gimple_location (stmt
), "invalid arguments");
2374 error_at (gimple_location (stmt
),
2375 "%<%s %s%> construct not closely nested inside of %qs",
2376 DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
))
2377 == BUILT_IN_GOMP_CANCEL
2378 ? "#pragma omp cancel"
2379 : "#pragma omp cancellation point", kind
, bad
);
2384 case GIMPLE_OMP_SECTIONS
:
2385 case GIMPLE_OMP_SINGLE
:
2386 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
2387 switch (gimple_code (ctx
->stmt
))
2389 case GIMPLE_OMP_FOR
:
2390 case GIMPLE_OMP_SECTIONS
:
2391 case GIMPLE_OMP_SINGLE
:
2392 case GIMPLE_OMP_ORDERED
:
2393 case GIMPLE_OMP_MASTER
:
2394 case GIMPLE_OMP_TASK
:
2395 case GIMPLE_OMP_CRITICAL
:
2396 if (is_gimple_call (stmt
))
2398 if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt
))
2399 != BUILT_IN_GOMP_BARRIER
)
2401 error_at (gimple_location (stmt
),
2402 "barrier region may not be closely nested inside "
2403 "of work-sharing, critical, ordered, master or "
2404 "explicit task region");
2407 error_at (gimple_location (stmt
),
2408 "work-sharing region may not be closely nested inside "
2409 "of work-sharing, critical, ordered, master or explicit "
2412 case GIMPLE_OMP_PARALLEL
:
2418 case GIMPLE_OMP_MASTER
:
2419 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
2420 switch (gimple_code (ctx
->stmt
))
2422 case GIMPLE_OMP_FOR
:
2423 case GIMPLE_OMP_SECTIONS
:
2424 case GIMPLE_OMP_SINGLE
:
2425 case GIMPLE_OMP_TASK
:
2426 error_at (gimple_location (stmt
),
2427 "master region may not be closely nested inside "
2428 "of work-sharing or explicit task region");
2430 case GIMPLE_OMP_PARALLEL
:
2436 case GIMPLE_OMP_ORDERED
:
2437 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
2438 switch (gimple_code (ctx
->stmt
))
2440 case GIMPLE_OMP_CRITICAL
:
2441 case GIMPLE_OMP_TASK
:
2442 error_at (gimple_location (stmt
),
2443 "ordered region may not be closely nested inside "
2444 "of critical or explicit task region");
2446 case GIMPLE_OMP_FOR
:
2447 if (find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
2448 OMP_CLAUSE_ORDERED
) == NULL
)
2450 error_at (gimple_location (stmt
),
2451 "ordered region must be closely nested inside "
2452 "a loop region with an ordered clause");
2456 case GIMPLE_OMP_PARALLEL
:
2457 error_at (gimple_location (stmt
),
2458 "ordered region must be closely nested inside "
2459 "a loop region with an ordered clause");
2465 case GIMPLE_OMP_CRITICAL
:
2466 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
2467 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_CRITICAL
2468 && (gimple_omp_critical_name (stmt
)
2469 == gimple_omp_critical_name (ctx
->stmt
)))
2471 error_at (gimple_location (stmt
),
2472 "critical region may not be nested inside a critical "
2473 "region with the same name");
2477 case GIMPLE_OMP_TEAMS
:
2479 || gimple_code (ctx
->stmt
) != GIMPLE_OMP_TARGET
2480 || gimple_omp_target_kind (ctx
->stmt
) != GF_OMP_TARGET_KIND_REGION
)
2482 error_at (gimple_location (stmt
),
2483 "teams construct not closely nested inside of target "
2495 /* Helper function scan_omp.
2497 Callback for walk_tree or operators in walk_gimple_stmt used to
2498 scan for OpenMP directives in TP. */
2501 scan_omp_1_op (tree
*tp
, int *walk_subtrees
, void *data
)
2503 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
2504 omp_context
*ctx
= (omp_context
*) wi
->info
;
2507 switch (TREE_CODE (t
))
2514 *tp
= remap_decl (t
, &ctx
->cb
);
2518 if (ctx
&& TYPE_P (t
))
2519 *tp
= remap_type (t
, &ctx
->cb
);
2520 else if (!DECL_P (t
))
2525 tree tem
= remap_type (TREE_TYPE (t
), &ctx
->cb
);
2526 if (tem
!= TREE_TYPE (t
))
2528 if (TREE_CODE (t
) == INTEGER_CST
)
2529 *tp
= build_int_cst_wide (tem
,
2530 TREE_INT_CST_LOW (t
),
2531 TREE_INT_CST_HIGH (t
));
2533 TREE_TYPE (t
) = tem
;
2543 /* Return true if FNDECL is a setjmp or a longjmp. */
2546 setjmp_or_longjmp_p (const_tree fndecl
)
2548 if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
2549 && (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_SETJMP
2550 || DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_LONGJMP
))
2553 tree declname
= DECL_NAME (fndecl
);
2556 const char *name
= IDENTIFIER_POINTER (declname
);
2557 return !strcmp (name
, "setjmp") || !strcmp (name
, "longjmp");
2561 /* Helper function for scan_omp.
2563 Callback for walk_gimple_stmt used to scan for OpenMP directives in
2564 the current statement in GSI. */
2567 scan_omp_1_stmt (gimple_stmt_iterator
*gsi
, bool *handled_ops_p
,
2568 struct walk_stmt_info
*wi
)
2570 gimple stmt
= gsi_stmt (*gsi
);
2571 omp_context
*ctx
= (omp_context
*) wi
->info
;
2573 if (gimple_has_location (stmt
))
2574 input_location
= gimple_location (stmt
);
2576 /* Check the OpenMP nesting restrictions. */
2577 bool remove
= false;
2578 if (is_gimple_omp (stmt
))
2579 remove
= !check_omp_nesting_restrictions (stmt
, ctx
);
2580 else if (is_gimple_call (stmt
))
2582 tree fndecl
= gimple_call_fndecl (stmt
);
2585 if (setjmp_or_longjmp_p (fndecl
)
2587 && gimple_code (ctx
->stmt
) == GIMPLE_OMP_FOR
2588 && gimple_omp_for_kind (ctx
->stmt
) & GF_OMP_FOR_KIND_SIMD
)
2591 error_at (gimple_location (stmt
),
2592 "setjmp/longjmp inside simd construct");
2594 else if (DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
2595 switch (DECL_FUNCTION_CODE (fndecl
))
2597 case BUILT_IN_GOMP_BARRIER
:
2598 case BUILT_IN_GOMP_CANCEL
:
2599 case BUILT_IN_GOMP_CANCELLATION_POINT
:
2600 case BUILT_IN_GOMP_TASKYIELD
:
2601 case BUILT_IN_GOMP_TASKWAIT
:
2602 case BUILT_IN_GOMP_TASKGROUP_START
:
2603 case BUILT_IN_GOMP_TASKGROUP_END
:
2604 remove
= !check_omp_nesting_restrictions (stmt
, ctx
);
2613 stmt
= gimple_build_nop ();
2614 gsi_replace (gsi
, stmt
, false);
2617 *handled_ops_p
= true;
2619 switch (gimple_code (stmt
))
2621 case GIMPLE_OMP_PARALLEL
:
2622 taskreg_nesting_level
++;
2623 scan_omp_parallel (gsi
, ctx
);
2624 taskreg_nesting_level
--;
2627 case GIMPLE_OMP_TASK
:
2628 taskreg_nesting_level
++;
2629 scan_omp_task (gsi
, ctx
);
2630 taskreg_nesting_level
--;
2633 case GIMPLE_OMP_FOR
:
2634 scan_omp_for (stmt
, ctx
);
2637 case GIMPLE_OMP_SECTIONS
:
2638 scan_omp_sections (stmt
, ctx
);
2641 case GIMPLE_OMP_SINGLE
:
2642 scan_omp_single (stmt
, ctx
);
2645 case GIMPLE_OMP_SECTION
:
2646 case GIMPLE_OMP_MASTER
:
2647 case GIMPLE_OMP_TASKGROUP
:
2648 case GIMPLE_OMP_ORDERED
:
2649 case GIMPLE_OMP_CRITICAL
:
2650 ctx
= new_omp_context (stmt
, ctx
);
2651 scan_omp (gimple_omp_body_ptr (stmt
), ctx
);
2654 case GIMPLE_OMP_TARGET
:
2655 scan_omp_target (stmt
, ctx
);
2658 case GIMPLE_OMP_TEAMS
:
2659 scan_omp_teams (stmt
, ctx
);
2666 *handled_ops_p
= false;
2668 for (var
= gimple_bind_vars (stmt
); var
; var
= DECL_CHAIN (var
))
2669 insert_decl_map (&ctx
->cb
, var
, var
);
2673 *handled_ops_p
= false;
2681 /* Scan all the statements starting at the current statement. CTX
2682 contains context information about the OpenMP directives and
2683 clauses found during the scan. */
2686 scan_omp (gimple_seq
*body_p
, omp_context
*ctx
)
2688 location_t saved_location
;
2689 struct walk_stmt_info wi
;
2691 memset (&wi
, 0, sizeof (wi
));
2693 wi
.want_locations
= true;
2695 saved_location
= input_location
;
2696 walk_gimple_seq_mod (body_p
, scan_omp_1_stmt
, scan_omp_1_op
, &wi
);
2697 input_location
= saved_location
;
2700 /* Re-gimplification and code generation routines. */
2702 /* Build a call to GOMP_barrier. */
2705 build_omp_barrier (tree lhs
)
2707 tree fndecl
= builtin_decl_explicit (lhs
? BUILT_IN_GOMP_BARRIER_CANCEL
2708 : BUILT_IN_GOMP_BARRIER
);
2709 gimple g
= gimple_build_call (fndecl
, 0);
2711 gimple_call_set_lhs (g
, lhs
);
2715 /* If a context was created for STMT when it was scanned, return it. */
2717 static omp_context
*
2718 maybe_lookup_ctx (gimple stmt
)
2721 n
= splay_tree_lookup (all_contexts
, (splay_tree_key
) stmt
);
2722 return n
? (omp_context
*) n
->value
: NULL
;
2726 /* Find the mapping for DECL in CTX or the immediately enclosing
2727 context that has a mapping for DECL.
2729 If CTX is a nested parallel directive, we may have to use the decl
2730 mappings created in CTX's parent context. Suppose that we have the
2731 following parallel nesting (variable UIDs showed for clarity):
2734 #omp parallel shared(iD.1562) -> outer parallel
2735 iD.1562 = iD.1562 + 1;
2737 #omp parallel shared (iD.1562) -> inner parallel
2738 iD.1562 = iD.1562 - 1;
2740 Each parallel structure will create a distinct .omp_data_s structure
2741 for copying iD.1562 in/out of the directive:
2743 outer parallel .omp_data_s.1.i -> iD.1562
2744 inner parallel .omp_data_s.2.i -> iD.1562
2746 A shared variable mapping will produce a copy-out operation before
2747 the parallel directive and a copy-in operation after it. So, in
2748 this case we would have:
2751 .omp_data_o.1.i = iD.1562;
2752 #omp parallel shared(iD.1562) -> outer parallel
2753 .omp_data_i.1 = &.omp_data_o.1
2754 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2756 .omp_data_o.2.i = iD.1562; -> **
2757 #omp parallel shared(iD.1562) -> inner parallel
2758 .omp_data_i.2 = &.omp_data_o.2
2759 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2762 ** This is a problem. The symbol iD.1562 cannot be referenced
2763 inside the body of the outer parallel region. But since we are
2764 emitting this copy operation while expanding the inner parallel
2765 directive, we need to access the CTX structure of the outer
2766 parallel directive to get the correct mapping:
2768 .omp_data_o.2.i = .omp_data_i.1->i
2770 Since there may be other workshare or parallel directives enclosing
2771 the parallel directive, it may be necessary to walk up the context
2772 parent chain. This is not a problem in general because nested
2773 parallelism happens only rarely. */
2776 lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2781 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2782 t
= maybe_lookup_decl (decl
, up
);
2784 gcc_assert (!ctx
->is_nested
|| t
|| is_global_var (decl
));
2786 return t
? t
: decl
;
2790 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2791 in outer contexts. */
2794 maybe_lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2799 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2800 t
= maybe_lookup_decl (decl
, up
);
2802 return t
? t
: decl
;
2806 /* Construct the initialization value for reduction CLAUSE. */
2809 omp_reduction_init (tree clause
, tree type
)
2811 location_t loc
= OMP_CLAUSE_LOCATION (clause
);
2812 switch (OMP_CLAUSE_REDUCTION_CODE (clause
))
2819 case TRUTH_ORIF_EXPR
:
2820 case TRUTH_XOR_EXPR
:
2822 return build_zero_cst (type
);
2825 case TRUTH_AND_EXPR
:
2826 case TRUTH_ANDIF_EXPR
:
2828 return fold_convert_loc (loc
, type
, integer_one_node
);
2831 return fold_convert_loc (loc
, type
, integer_minus_one_node
);
2834 if (SCALAR_FLOAT_TYPE_P (type
))
2836 REAL_VALUE_TYPE max
, min
;
2837 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2840 real_arithmetic (&min
, NEGATE_EXPR
, &max
, NULL
);
2843 real_maxval (&min
, 1, TYPE_MODE (type
));
2844 return build_real (type
, min
);
2848 gcc_assert (INTEGRAL_TYPE_P (type
));
2849 return TYPE_MIN_VALUE (type
);
2853 if (SCALAR_FLOAT_TYPE_P (type
))
2855 REAL_VALUE_TYPE max
;
2856 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2859 real_maxval (&max
, 0, TYPE_MODE (type
));
2860 return build_real (type
, max
);
2864 gcc_assert (INTEGRAL_TYPE_P (type
));
2865 return TYPE_MAX_VALUE (type
);
2873 /* Return alignment to be assumed for var in CLAUSE, which should be
2874 OMP_CLAUSE_ALIGNED. */
2877 omp_clause_aligned_alignment (tree clause
)
2879 if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause
))
2880 return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause
);
2882 /* Otherwise return implementation defined alignment. */
2883 unsigned int al
= 1;
2884 enum machine_mode mode
, vmode
;
2885 int vs
= targetm
.vectorize
.autovectorize_vector_sizes ();
2887 vs
= 1 << floor_log2 (vs
);
2888 static enum mode_class classes
[]
2889 = { MODE_INT
, MODE_VECTOR_INT
, MODE_FLOAT
, MODE_VECTOR_FLOAT
};
2890 for (int i
= 0; i
< 4; i
+= 2)
2891 for (mode
= GET_CLASS_NARROWEST_MODE (classes
[i
]);
2893 mode
= GET_MODE_WIDER_MODE (mode
))
2895 vmode
= targetm
.vectorize
.preferred_simd_mode (mode
);
2896 if (GET_MODE_CLASS (vmode
) != classes
[i
+ 1])
2899 && GET_MODE_SIZE (vmode
) < vs
2900 && GET_MODE_2XWIDER_MODE (vmode
) != VOIDmode
)
2901 vmode
= GET_MODE_2XWIDER_MODE (vmode
);
2903 tree type
= lang_hooks
.types
.type_for_mode (mode
, 1);
2904 if (type
== NULL_TREE
|| TYPE_MODE (type
) != mode
)
2906 type
= build_vector_type (type
, GET_MODE_SIZE (vmode
)
2907 / GET_MODE_SIZE (mode
));
2908 if (TYPE_MODE (type
) != vmode
)
2910 if (TYPE_ALIGN_UNIT (type
) > al
)
2911 al
= TYPE_ALIGN_UNIT (type
);
2913 return build_int_cst (integer_type_node
, al
);
2916 /* Return maximum possible vectorization factor for the target. */
2923 || (!flag_tree_loop_vectorize
2924 && (global_options_set
.x_flag_tree_loop_vectorize
2925 || global_options_set
.x_flag_tree_vectorize
)))
2928 int vs
= targetm
.vectorize
.autovectorize_vector_sizes ();
2931 vs
= 1 << floor_log2 (vs
);
2934 enum machine_mode vqimode
= targetm
.vectorize
.preferred_simd_mode (QImode
);
2935 if (GET_MODE_CLASS (vqimode
) == MODE_VECTOR_INT
)
2936 return GET_MODE_NUNITS (vqimode
);
2940 /* Helper function of lower_rec_input_clauses, used for #pragma omp simd
2944 lower_rec_simd_input_clauses (tree new_var
, omp_context
*ctx
, int &max_vf
,
2945 tree
&idx
, tree
&lane
, tree
&ivar
, tree
&lvar
)
2949 max_vf
= omp_max_vf ();
2952 tree c
= find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
2953 OMP_CLAUSE_SAFELEN
);
2955 && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c
), max_vf
) == -1)
2956 max_vf
= tree_low_cst (OMP_CLAUSE_SAFELEN_EXPR (c
), 0);
2960 idx
= create_tmp_var (unsigned_type_node
, NULL
);
2961 lane
= create_tmp_var (unsigned_type_node
, NULL
);
2967 tree atype
= build_array_type_nelts (TREE_TYPE (new_var
), max_vf
);
2968 tree avar
= create_tmp_var_raw (atype
, NULL
);
2969 if (TREE_ADDRESSABLE (new_var
))
2970 TREE_ADDRESSABLE (avar
) = 1;
2971 DECL_ATTRIBUTES (avar
)
2972 = tree_cons (get_identifier ("omp simd array"), NULL
,
2973 DECL_ATTRIBUTES (avar
));
2974 gimple_add_tmp_var (avar
);
2975 ivar
= build4 (ARRAY_REF
, TREE_TYPE (new_var
), avar
, idx
,
2976 NULL_TREE
, NULL_TREE
);
2977 lvar
= build4 (ARRAY_REF
, TREE_TYPE (new_var
), avar
, lane
,
2978 NULL_TREE
, NULL_TREE
);
2979 if (DECL_P (new_var
))
2981 SET_DECL_VALUE_EXPR (new_var
, lvar
);
2982 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2987 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2988 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2989 private variables. Initialization statements go in ILIST, while calls
2990 to destructors go in DLIST. */
2993 lower_rec_input_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*dlist
,
2994 omp_context
*ctx
, struct omp_for_data
*fd
)
2996 tree c
, dtor
, copyin_seq
, x
, ptr
;
2997 bool copyin_by_ref
= false;
2998 bool lastprivate_firstprivate
= false;
2999 bool reduction_omp_orig_ref
= false;
3001 bool is_simd
= (gimple_code (ctx
->stmt
) == GIMPLE_OMP_FOR
3002 && gimple_omp_for_kind (ctx
->stmt
) & GF_OMP_FOR_KIND_SIMD
);
3004 tree lane
= NULL_TREE
, idx
= NULL_TREE
;
3005 tree ivar
= NULL_TREE
, lvar
= NULL_TREE
;
3006 gimple_seq llist
[2] = { NULL
, NULL
};
3010 /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
3011 with data sharing clauses referencing variable sized vars. That
3012 is unnecessarily hard to support and very unlikely to result in
3013 vectorized code anyway. */
3015 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
3016 switch (OMP_CLAUSE_CODE (c
))
3018 case OMP_CLAUSE_REDUCTION
:
3019 case OMP_CLAUSE_PRIVATE
:
3020 case OMP_CLAUSE_FIRSTPRIVATE
:
3021 case OMP_CLAUSE_LASTPRIVATE
:
3022 case OMP_CLAUSE_LINEAR
:
3023 if (is_variable_sized (OMP_CLAUSE_DECL (c
)))
3030 /* Do all the fixed sized types in the first pass, and the variable sized
3031 types in the second pass. This makes sure that the scalar arguments to
3032 the variable sized types are processed before we use them in the
3033 variable sized operations. */
3034 for (pass
= 0; pass
< 2; ++pass
)
3036 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
3038 enum omp_clause_code c_kind
= OMP_CLAUSE_CODE (c
);
3041 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
3045 case OMP_CLAUSE_PRIVATE
:
3046 if (OMP_CLAUSE_PRIVATE_DEBUG (c
))
3049 case OMP_CLAUSE_SHARED
:
3050 /* Ignore shared directives in teams construct. */
3051 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_TEAMS
)
3053 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c
), ctx
) == NULL
)
3055 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c
)));
3058 case OMP_CLAUSE_FIRSTPRIVATE
:
3059 case OMP_CLAUSE_COPYIN
:
3060 case OMP_CLAUSE_LINEAR
:
3062 case OMP_CLAUSE_REDUCTION
:
3063 if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c
))
3064 reduction_omp_orig_ref
= true;
3066 case OMP_CLAUSE__LOOPTEMP_
:
3067 /* Handle _looptemp_ clauses only on parallel. */
3071 case OMP_CLAUSE_LASTPRIVATE
:
3072 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
3074 lastprivate_firstprivate
= true;
3079 case OMP_CLAUSE_ALIGNED
:
3082 var
= OMP_CLAUSE_DECL (c
);
3083 if (TREE_CODE (TREE_TYPE (var
)) == POINTER_TYPE
3084 && !is_global_var (var
))
3086 new_var
= maybe_lookup_decl (var
, ctx
);
3087 if (new_var
== NULL_TREE
)
3088 new_var
= maybe_lookup_decl_in_outer_ctx (var
, ctx
);
3089 x
= builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED
);
3090 x
= build_call_expr_loc (clause_loc
, x
, 2, new_var
,
3091 omp_clause_aligned_alignment (c
));
3092 x
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), x
);
3093 x
= build2 (MODIFY_EXPR
, TREE_TYPE (new_var
), new_var
, x
);
3094 gimplify_and_add (x
, ilist
);
3096 else if (TREE_CODE (TREE_TYPE (var
)) == ARRAY_TYPE
3097 && is_global_var (var
))
3099 tree ptype
= build_pointer_type (TREE_TYPE (var
)), t
, t2
;
3100 new_var
= lookup_decl (var
, ctx
);
3101 t
= maybe_lookup_decl_in_outer_ctx (var
, ctx
);
3102 t
= build_fold_addr_expr_loc (clause_loc
, t
);
3103 t2
= builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED
);
3104 t
= build_call_expr_loc (clause_loc
, t2
, 2, t
,
3105 omp_clause_aligned_alignment (c
));
3106 t
= fold_convert_loc (clause_loc
, ptype
, t
);
3107 x
= create_tmp_var (ptype
, NULL
);
3108 t
= build2 (MODIFY_EXPR
, ptype
, x
, t
);
3109 gimplify_and_add (t
, ilist
);
3110 t
= build_simple_mem_ref_loc (clause_loc
, x
);
3111 SET_DECL_VALUE_EXPR (new_var
, t
);
3112 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
3119 new_var
= var
= OMP_CLAUSE_DECL (c
);
3120 if (c_kind
!= OMP_CLAUSE_COPYIN
)
3121 new_var
= lookup_decl (var
, ctx
);
3123 if (c_kind
== OMP_CLAUSE_SHARED
|| c_kind
== OMP_CLAUSE_COPYIN
)
3128 else if (is_variable_sized (var
))
3130 /* For variable sized types, we need to allocate the
3131 actual storage here. Call alloca and store the
3132 result in the pointer decl that we created elsewhere. */
3136 if (c_kind
!= OMP_CLAUSE_FIRSTPRIVATE
|| !is_task_ctx (ctx
))
3141 ptr
= DECL_VALUE_EXPR (new_var
);
3142 gcc_assert (TREE_CODE (ptr
) == INDIRECT_REF
);
3143 ptr
= TREE_OPERAND (ptr
, 0);
3144 gcc_assert (DECL_P (ptr
));
3145 x
= TYPE_SIZE_UNIT (TREE_TYPE (new_var
));
3147 /* void *tmp = __builtin_alloca */
3148 atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA
);
3149 stmt
= gimple_build_call (atmp
, 1, x
);
3150 tmp
= create_tmp_var_raw (ptr_type_node
, NULL
);
3151 gimple_add_tmp_var (tmp
);
3152 gimple_call_set_lhs (stmt
, tmp
);
3154 gimple_seq_add_stmt (ilist
, stmt
);
3156 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ptr
), tmp
);
3157 gimplify_assign (ptr
, x
, ilist
);
3160 else if (is_reference (var
))
3162 /* For references that are being privatized for Fortran,
3163 allocate new backing storage for the new pointer
3164 variable. This allows us to avoid changing all the
3165 code that expects a pointer to something that expects
3166 a direct variable. */
3170 x
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var
)));
3171 if (c_kind
== OMP_CLAUSE_FIRSTPRIVATE
&& is_task_ctx (ctx
))
3173 x
= build_receiver_ref (var
, false, ctx
);
3174 x
= build_fold_addr_expr_loc (clause_loc
, x
);
3176 else if (TREE_CONSTANT (x
))
3178 const char *name
= NULL
;
3179 if (DECL_NAME (var
))
3180 name
= IDENTIFIER_POINTER (DECL_NAME (new_var
));
3182 x
= create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var
)),
3184 gimple_add_tmp_var (x
);
3185 TREE_ADDRESSABLE (x
) = 1;
3186 x
= build_fold_addr_expr_loc (clause_loc
, x
);
3190 tree atmp
= builtin_decl_explicit (BUILT_IN_ALLOCA
);
3191 x
= build_call_expr_loc (clause_loc
, atmp
, 1, x
);
3194 x
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), x
);
3195 gimplify_assign (new_var
, x
, ilist
);
3197 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
3199 else if (c_kind
== OMP_CLAUSE_REDUCTION
3200 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
3208 switch (OMP_CLAUSE_CODE (c
))
3210 case OMP_CLAUSE_SHARED
:
3211 /* Ignore shared directives in teams construct. */
3212 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_TEAMS
)
3214 /* Shared global vars are just accessed directly. */
3215 if (is_global_var (new_var
))
3217 /* Set up the DECL_VALUE_EXPR for shared variables now. This
3218 needs to be delayed until after fixup_child_record_type so
3219 that we get the correct type during the dereference. */
3220 by_ref
= use_pointer_for_field (var
, ctx
);
3221 x
= build_receiver_ref (var
, by_ref
, ctx
);
3222 SET_DECL_VALUE_EXPR (new_var
, x
);
3223 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
3225 /* ??? If VAR is not passed by reference, and the variable
3226 hasn't been initialized yet, then we'll get a warning for
3227 the store into the omp_data_s structure. Ideally, we'd be
3228 able to notice this and not store anything at all, but
3229 we're generating code too early. Suppress the warning. */
3231 TREE_NO_WARNING (var
) = 1;
3234 case OMP_CLAUSE_LASTPRIVATE
:
3235 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
3239 case OMP_CLAUSE_PRIVATE
:
3240 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_PRIVATE
)
3241 x
= build_outer_var_ref (var
, ctx
);
3242 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
3244 if (is_task_ctx (ctx
))
3245 x
= build_receiver_ref (var
, false, ctx
);
3247 x
= build_outer_var_ref (var
, ctx
);
3253 nx
= lang_hooks
.decls
.omp_clause_default_ctor (c
, new_var
, x
);
3256 tree y
= lang_hooks
.decls
.omp_clause_dtor (c
, new_var
);
3257 if ((TREE_ADDRESSABLE (new_var
) || nx
|| y
3258 || OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
3259 && lower_rec_simd_input_clauses (new_var
, ctx
, max_vf
,
3260 idx
, lane
, ivar
, lvar
))
3263 x
= lang_hooks
.decls
.omp_clause_default_ctor
3264 (c
, unshare_expr (ivar
), x
);
3266 gimplify_and_add (x
, &llist
[0]);
3269 y
= lang_hooks
.decls
.omp_clause_dtor (c
, ivar
);
3272 gimple_seq tseq
= NULL
;
3275 gimplify_stmt (&dtor
, &tseq
);
3276 gimple_seq_add_seq (&llist
[1], tseq
);
3283 gimplify_and_add (nx
, ilist
);
3287 x
= lang_hooks
.decls
.omp_clause_dtor (c
, new_var
);
3290 gimple_seq tseq
= NULL
;
3293 gimplify_stmt (&dtor
, &tseq
);
3294 gimple_seq_add_seq (dlist
, tseq
);
3298 case OMP_CLAUSE_LINEAR
:
3299 if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
3300 goto do_firstprivate
;
3301 if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c
))
3304 x
= build_outer_var_ref (var
, ctx
);
3307 case OMP_CLAUSE_FIRSTPRIVATE
:
3308 if (is_task_ctx (ctx
))
3310 if (is_reference (var
) || is_variable_sized (var
))
3312 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
,
3314 || use_pointer_for_field (var
, NULL
))
3316 x
= build_receiver_ref (var
, false, ctx
);
3317 SET_DECL_VALUE_EXPR (new_var
, x
);
3318 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
3323 x
= build_outer_var_ref (var
, ctx
);
3326 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
3327 && gimple_omp_for_combined_into_p (ctx
->stmt
))
3329 tree stept
= POINTER_TYPE_P (TREE_TYPE (x
))
3330 ? sizetype
: TREE_TYPE (x
);
3331 tree t
= fold_convert (stept
,
3332 OMP_CLAUSE_LINEAR_STEP (c
));
3333 tree c
= find_omp_clause (clauses
,
3334 OMP_CLAUSE__LOOPTEMP_
);
3336 tree l
= OMP_CLAUSE_DECL (c
);
3337 if (fd
->collapse
== 1)
3339 tree n1
= fd
->loop
.n1
;
3340 tree step
= fd
->loop
.step
;
3341 tree itype
= TREE_TYPE (l
);
3342 if (POINTER_TYPE_P (itype
))
3343 itype
= signed_type_for (itype
);
3344 l
= fold_build2 (MINUS_EXPR
, itype
, l
, n1
);
3345 if (TYPE_UNSIGNED (itype
)
3346 && fd
->loop
.cond_code
== GT_EXPR
)
3347 l
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
3348 fold_build1 (NEGATE_EXPR
,
3350 fold_build1 (NEGATE_EXPR
,
3353 l
= fold_build2 (TRUNC_DIV_EXPR
, itype
, l
, step
);
3355 t
= fold_build2 (MULT_EXPR
, stept
,
3356 fold_convert (stept
, l
), t
);
3357 if (POINTER_TYPE_P (TREE_TYPE (x
)))
3358 x
= fold_build2 (POINTER_PLUS_EXPR
,
3359 TREE_TYPE (x
), x
, t
);
3361 x
= fold_build2 (PLUS_EXPR
, TREE_TYPE (x
), x
, t
);
3364 if ((OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_LINEAR
3365 || TREE_ADDRESSABLE (new_var
))
3366 && lower_rec_simd_input_clauses (new_var
, ctx
, max_vf
,
3367 idx
, lane
, ivar
, lvar
))
3369 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
)
3371 tree iv
= create_tmp_var (TREE_TYPE (new_var
), NULL
);
3372 x
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, iv
, x
);
3373 gimplify_and_add (x
, ilist
);
3374 gimple_stmt_iterator gsi
3375 = gsi_start_1 (gimple_omp_body_ptr (ctx
->stmt
));
3377 = gimple_build_assign (unshare_expr (lvar
), iv
);
3378 gsi_insert_before_without_update (&gsi
, g
,
3380 tree stept
= POINTER_TYPE_P (TREE_TYPE (x
))
3381 ? sizetype
: TREE_TYPE (x
);
3382 tree t
= fold_convert (stept
,
3383 OMP_CLAUSE_LINEAR_STEP (c
));
3384 enum tree_code code
= PLUS_EXPR
;
3385 if (POINTER_TYPE_P (TREE_TYPE (new_var
)))
3386 code
= POINTER_PLUS_EXPR
;
3387 g
= gimple_build_assign_with_ops (code
, iv
, iv
, t
);
3388 gsi_insert_before_without_update (&gsi
, g
,
3392 x
= lang_hooks
.decls
.omp_clause_copy_ctor
3393 (c
, unshare_expr (ivar
), x
);
3394 gimplify_and_add (x
, &llist
[0]);
3395 x
= lang_hooks
.decls
.omp_clause_dtor (c
, ivar
);
3398 gimple_seq tseq
= NULL
;
3401 gimplify_stmt (&dtor
, &tseq
);
3402 gimple_seq_add_seq (&llist
[1], tseq
);
3407 x
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, new_var
, x
);
3408 gimplify_and_add (x
, ilist
);
3411 case OMP_CLAUSE__LOOPTEMP_
:
3412 gcc_assert (is_parallel_ctx (ctx
));
3413 x
= build_outer_var_ref (var
, ctx
);
3414 x
= build2 (MODIFY_EXPR
, TREE_TYPE (new_var
), new_var
, x
);
3415 gimplify_and_add (x
, ilist
);
3418 case OMP_CLAUSE_COPYIN
:
3419 by_ref
= use_pointer_for_field (var
, NULL
);
3420 x
= build_receiver_ref (var
, by_ref
, ctx
);
3421 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, x
);
3422 append_to_statement_list (x
, ©in_seq
);
3423 copyin_by_ref
|= by_ref
;
3426 case OMP_CLAUSE_REDUCTION
:
3427 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
3429 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
3431 x
= build_outer_var_ref (var
, ctx
);
3433 if (is_reference (var
)
3434 && !useless_type_conversion_p (TREE_TYPE (placeholder
),
3436 x
= build_fold_addr_expr_loc (clause_loc
, x
);
3437 SET_DECL_VALUE_EXPR (placeholder
, x
);
3438 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
3439 tree new_vard
= new_var
;
3440 if (is_reference (var
))
3442 gcc_assert (TREE_CODE (new_var
) == MEM_REF
);
3443 new_vard
= TREE_OPERAND (new_var
, 0);
3444 gcc_assert (DECL_P (new_vard
));
3447 && lower_rec_simd_input_clauses (new_var
, ctx
, max_vf
,
3448 idx
, lane
, ivar
, lvar
))
3450 if (new_vard
== new_var
)
3452 gcc_assert (DECL_VALUE_EXPR (new_var
) == lvar
);
3453 SET_DECL_VALUE_EXPR (new_var
, ivar
);
3457 SET_DECL_VALUE_EXPR (new_vard
,
3458 build_fold_addr_expr (ivar
));
3459 DECL_HAS_VALUE_EXPR_P (new_vard
) = 1;
3461 x
= lang_hooks
.decls
.omp_clause_default_ctor
3462 (c
, unshare_expr (ivar
),
3463 build_outer_var_ref (var
, ctx
));
3465 gimplify_and_add (x
, &llist
[0]);
3466 if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
))
3468 tseq
= OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
);
3469 lower_omp (&tseq
, ctx
);
3470 gimple_seq_add_seq (&llist
[0], tseq
);
3472 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
3473 tseq
= OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
);
3474 lower_omp (&tseq
, ctx
);
3475 gimple_seq_add_seq (&llist
[1], tseq
);
3476 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
3477 DECL_HAS_VALUE_EXPR_P (placeholder
) = 0;
3478 if (new_vard
== new_var
)
3479 SET_DECL_VALUE_EXPR (new_var
, lvar
);
3481 SET_DECL_VALUE_EXPR (new_vard
,
3482 build_fold_addr_expr (lvar
));
3483 x
= lang_hooks
.decls
.omp_clause_dtor (c
, ivar
);
3488 gimplify_stmt (&dtor
, &tseq
);
3489 gimple_seq_add_seq (&llist
[1], tseq
);
3493 x
= lang_hooks
.decls
.omp_clause_default_ctor
3494 (c
, new_var
, unshare_expr (x
));
3496 gimplify_and_add (x
, ilist
);
3497 if (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
))
3499 tseq
= OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
);
3500 lower_omp (&tseq
, ctx
);
3501 gimple_seq_add_seq (ilist
, tseq
);
3503 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
3506 tseq
= OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
);
3507 lower_omp (&tseq
, ctx
);
3508 gimple_seq_add_seq (dlist
, tseq
);
3509 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
3511 DECL_HAS_VALUE_EXPR_P (placeholder
) = 0;
3516 x
= omp_reduction_init (c
, TREE_TYPE (new_var
));
3517 gcc_assert (TREE_CODE (TREE_TYPE (new_var
)) != ARRAY_TYPE
);
3519 && lower_rec_simd_input_clauses (new_var
, ctx
, max_vf
,
3520 idx
, lane
, ivar
, lvar
))
3522 enum tree_code code
= OMP_CLAUSE_REDUCTION_CODE (c
);
3523 tree ref
= build_outer_var_ref (var
, ctx
);
3525 gimplify_assign (unshare_expr (ivar
), x
, &llist
[0]);
3527 /* reduction(-:var) sums up the partial results, so it
3528 acts identically to reduction(+:var). */
3529 if (code
== MINUS_EXPR
)
3532 x
= build2 (code
, TREE_TYPE (ref
), ref
, ivar
);
3533 ref
= build_outer_var_ref (var
, ctx
);
3534 gimplify_assign (ref
, x
, &llist
[1]);
3538 gimplify_assign (new_var
, x
, ilist
);
3540 gimplify_assign (build_outer_var_ref (var
, ctx
),
3554 tree uid
= create_tmp_var (ptr_type_node
, "simduid");
3555 /* Don't want uninit warnings on simduid, it is always uninitialized,
3556 but we use it not for the value, but for the DECL_UID only. */
3557 TREE_NO_WARNING (uid
) = 1;
3559 = gimple_build_call_internal (IFN_GOMP_SIMD_LANE
, 1, uid
);
3560 gimple_call_set_lhs (g
, lane
);
3561 gimple_stmt_iterator gsi
= gsi_start_1 (gimple_omp_body_ptr (ctx
->stmt
));
3562 gsi_insert_before_without_update (&gsi
, g
, GSI_SAME_STMT
);
3563 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__SIMDUID_
);
3564 OMP_CLAUSE__SIMDUID__DECL (c
) = uid
;
3565 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (ctx
->stmt
);
3566 gimple_omp_for_set_clauses (ctx
->stmt
, c
);
3567 g
= gimple_build_assign_with_ops (INTEGER_CST
, lane
,
3568 build_int_cst (unsigned_type_node
, 0),
3570 gimple_seq_add_stmt (ilist
, g
);
3571 for (int i
= 0; i
< 2; i
++)
3574 tree vf
= create_tmp_var (unsigned_type_node
, NULL
);
3575 g
= gimple_build_call_internal (IFN_GOMP_SIMD_VF
, 1, uid
);
3576 gimple_call_set_lhs (g
, vf
);
3577 gimple_seq
*seq
= i
== 0 ? ilist
: dlist
;
3578 gimple_seq_add_stmt (seq
, g
);
3579 tree t
= build_int_cst (unsigned_type_node
, 0);
3580 g
= gimple_build_assign_with_ops (INTEGER_CST
, idx
, t
, NULL_TREE
);
3581 gimple_seq_add_stmt (seq
, g
);
3582 tree body
= create_artificial_label (UNKNOWN_LOCATION
);
3583 tree header
= create_artificial_label (UNKNOWN_LOCATION
);
3584 tree end
= create_artificial_label (UNKNOWN_LOCATION
);
3585 gimple_seq_add_stmt (seq
, gimple_build_goto (header
));
3586 gimple_seq_add_stmt (seq
, gimple_build_label (body
));
3587 gimple_seq_add_seq (seq
, llist
[i
]);
3588 t
= build_int_cst (unsigned_type_node
, 1);
3589 g
= gimple_build_assign_with_ops (PLUS_EXPR
, idx
, idx
, t
);
3590 gimple_seq_add_stmt (seq
, g
);
3591 gimple_seq_add_stmt (seq
, gimple_build_label (header
));
3592 g
= gimple_build_cond (LT_EXPR
, idx
, vf
, body
, end
);
3593 gimple_seq_add_stmt (seq
, g
);
3594 gimple_seq_add_stmt (seq
, gimple_build_label (end
));
3598 /* The copyin sequence is not to be executed by the main thread, since
3599 that would result in self-copies. Perhaps not visible to scalars,
3600 but it certainly is to C++ operator=. */
3603 x
= build_call_expr (builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
),
3605 x
= build2 (NE_EXPR
, boolean_type_node
, x
,
3606 build_int_cst (TREE_TYPE (x
), 0));
3607 x
= build3 (COND_EXPR
, void_type_node
, x
, copyin_seq
, NULL
);
3608 gimplify_and_add (x
, ilist
);
3611 /* If any copyin variable is passed by reference, we must ensure the
3612 master thread doesn't modify it before it is copied over in all
3613 threads. Similarly for variables in both firstprivate and
3614 lastprivate clauses we need to ensure the lastprivate copying
3615 happens after firstprivate copying in all threads. And similarly
3616 for UDRs if initializer expression refers to omp_orig. */
3617 if (copyin_by_ref
|| lastprivate_firstprivate
|| reduction_omp_orig_ref
)
3619 /* Don't add any barrier for #pragma omp simd or
3620 #pragma omp distribute. */
3621 if (gimple_code (ctx
->stmt
) != GIMPLE_OMP_FOR
3622 || gimple_omp_for_kind (ctx
->stmt
) & GF_OMP_FOR_KIND_FOR
)
3623 gimple_seq_add_stmt (ilist
, build_omp_barrier (NULL_TREE
));
3626 /* If max_vf is non-zero, then we can use only a vectorization factor
3627 up to the max_vf we chose. So stick it into the safelen clause. */
3630 tree c
= find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
3631 OMP_CLAUSE_SAFELEN
);
3633 || compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c
),
3636 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_SAFELEN
);
3637 OMP_CLAUSE_SAFELEN_EXPR (c
) = build_int_cst (integer_type_node
,
3639 OMP_CLAUSE_CHAIN (c
) = gimple_omp_for_clauses (ctx
->stmt
);
3640 gimple_omp_for_set_clauses (ctx
->stmt
, c
);
3646 /* Generate code to implement the LASTPRIVATE clauses. This is used for
3647 both parallel and workshare constructs. PREDICATE may be NULL if it's
3651 lower_lastprivate_clauses (tree clauses
, tree predicate
, gimple_seq
*stmt_list
,
3654 tree x
, c
, label
= NULL
, orig_clauses
= clauses
;
3655 bool par_clauses
= false;
3656 tree simduid
= NULL
, lastlane
= NULL
;
3658 /* Early exit if there are no lastprivate or linear clauses. */
3659 for (; clauses
; clauses
= OMP_CLAUSE_CHAIN (clauses
))
3660 if (OMP_CLAUSE_CODE (clauses
) == OMP_CLAUSE_LASTPRIVATE
3661 || (OMP_CLAUSE_CODE (clauses
) == OMP_CLAUSE_LINEAR
3662 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses
)))
3664 if (clauses
== NULL
)
3666 /* If this was a workshare clause, see if it had been combined
3667 with its parallel. In that case, look for the clauses on the
3668 parallel statement itself. */
3669 if (is_parallel_ctx (ctx
))
3673 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
3676 clauses
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
3677 OMP_CLAUSE_LASTPRIVATE
);
3678 if (clauses
== NULL
)
3686 tree label_true
, arm1
, arm2
;
3688 label
= create_artificial_label (UNKNOWN_LOCATION
);
3689 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
3690 arm1
= TREE_OPERAND (predicate
, 0);
3691 arm2
= TREE_OPERAND (predicate
, 1);
3692 gimplify_expr (&arm1
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
3693 gimplify_expr (&arm2
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
3694 stmt
= gimple_build_cond (TREE_CODE (predicate
), arm1
, arm2
,
3696 gimple_seq_add_stmt (stmt_list
, stmt
);
3697 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label_true
));
3700 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_FOR
3701 && gimple_omp_for_kind (ctx
->stmt
) & GF_OMP_FOR_KIND_SIMD
)
3703 simduid
= find_omp_clause (orig_clauses
, OMP_CLAUSE__SIMDUID_
);
3705 simduid
= OMP_CLAUSE__SIMDUID__DECL (simduid
);
3708 for (c
= clauses
; c
;)
3711 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
3713 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
3714 || (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
3715 && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c
)))
3717 var
= OMP_CLAUSE_DECL (c
);
3718 new_var
= lookup_decl (var
, ctx
);
3720 if (simduid
&& DECL_HAS_VALUE_EXPR_P (new_var
))
3722 tree val
= DECL_VALUE_EXPR (new_var
);
3723 if (TREE_CODE (val
) == ARRAY_REF
3724 && VAR_P (TREE_OPERAND (val
, 0))
3725 && lookup_attribute ("omp simd array",
3726 DECL_ATTRIBUTES (TREE_OPERAND (val
,
3729 if (lastlane
== NULL
)
3731 lastlane
= create_tmp_var (unsigned_type_node
, NULL
);
3733 = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE
,
3735 TREE_OPERAND (val
, 1));
3736 gimple_call_set_lhs (g
, lastlane
);
3737 gimple_seq_add_stmt (stmt_list
, g
);
3739 new_var
= build4 (ARRAY_REF
, TREE_TYPE (val
),
3740 TREE_OPERAND (val
, 0), lastlane
,
3741 NULL_TREE
, NULL_TREE
);
3745 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
3746 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
3748 lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
3749 gimple_seq_add_seq (stmt_list
,
3750 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
3751 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) = NULL
;
3754 x
= build_outer_var_ref (var
, ctx
);
3755 if (is_reference (var
))
3756 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
3757 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, x
, new_var
);
3758 gimplify_and_add (x
, stmt_list
);
3760 c
= OMP_CLAUSE_CHAIN (c
);
3761 if (c
== NULL
&& !par_clauses
)
3763 /* If this was a workshare clause, see if it had been combined
3764 with its parallel. In that case, continue looking for the
3765 clauses also on the parallel statement itself. */
3766 if (is_parallel_ctx (ctx
))
3770 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
3773 c
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
3774 OMP_CLAUSE_LASTPRIVATE
);
3780 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label
));
3784 /* Generate code to implement the REDUCTION clauses. */
3787 lower_reduction_clauses (tree clauses
, gimple_seq
*stmt_seqp
, omp_context
*ctx
)
3789 gimple_seq sub_seq
= NULL
;
3794 /* SIMD reductions are handled in lower_rec_input_clauses. */
3795 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_FOR
3796 && gimple_omp_for_kind (ctx
->stmt
) & GF_OMP_FOR_KIND_SIMD
)
3799 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
3800 update in that case, otherwise use a lock. */
3801 for (c
= clauses
; c
&& count
< 2; c
= OMP_CLAUSE_CHAIN (c
))
3802 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
3804 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
3806 /* Never use OMP_ATOMIC for array reductions or UDRs. */
3816 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
3818 tree var
, ref
, new_var
;
3819 enum tree_code code
;
3820 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
3822 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
)
3825 var
= OMP_CLAUSE_DECL (c
);
3826 new_var
= lookup_decl (var
, ctx
);
3827 if (is_reference (var
))
3828 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
3829 ref
= build_outer_var_ref (var
, ctx
);
3830 code
= OMP_CLAUSE_REDUCTION_CODE (c
);
3832 /* reduction(-:var) sums up the partial results, so it acts
3833 identically to reduction(+:var). */
3834 if (code
== MINUS_EXPR
)
3839 tree addr
= build_fold_addr_expr_loc (clause_loc
, ref
);
3841 addr
= save_expr (addr
);
3842 ref
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (addr
)), addr
);
3843 x
= fold_build2_loc (clause_loc
, code
, TREE_TYPE (ref
), ref
, new_var
);
3844 x
= build2 (OMP_ATOMIC
, void_type_node
, addr
, x
);
3845 gimplify_and_add (x
, stmt_seqp
);
3849 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
3851 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
3853 if (is_reference (var
)
3854 && !useless_type_conversion_p (TREE_TYPE (placeholder
),
3856 ref
= build_fold_addr_expr_loc (clause_loc
, ref
);
3857 SET_DECL_VALUE_EXPR (placeholder
, ref
);
3858 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
3859 lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
3860 gimple_seq_add_seq (&sub_seq
, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
3861 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
3862 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
) = NULL
;
3866 x
= build2 (code
, TREE_TYPE (ref
), ref
, new_var
);
3867 ref
= build_outer_var_ref (var
, ctx
);
3868 gimplify_assign (ref
, x
, &sub_seq
);
3872 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START
),
3874 gimple_seq_add_stmt (stmt_seqp
, stmt
);
3876 gimple_seq_add_seq (stmt_seqp
, sub_seq
);
3878 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END
),
3880 gimple_seq_add_stmt (stmt_seqp
, stmt
);
3884 /* Generate code to implement the COPYPRIVATE clauses. */
3887 lower_copyprivate_clauses (tree clauses
, gimple_seq
*slist
, gimple_seq
*rlist
,
3892 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
3894 tree var
, new_var
, ref
, x
;
3896 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
3898 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYPRIVATE
)
3901 var
= OMP_CLAUSE_DECL (c
);
3902 by_ref
= use_pointer_for_field (var
, NULL
);
3904 ref
= build_sender_ref (var
, ctx
);
3905 x
= new_var
= lookup_decl_in_outer_ctx (var
, ctx
);
3908 x
= build_fold_addr_expr_loc (clause_loc
, new_var
);
3909 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ref
), x
);
3911 gimplify_assign (ref
, x
, slist
);
3913 ref
= build_receiver_ref (var
, false, ctx
);
3916 ref
= fold_convert_loc (clause_loc
,
3917 build_pointer_type (TREE_TYPE (new_var
)),
3919 ref
= build_fold_indirect_ref_loc (clause_loc
, ref
);
3921 if (is_reference (var
))
3923 ref
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), ref
);
3924 ref
= build_simple_mem_ref_loc (clause_loc
, ref
);
3925 new_var
= build_simple_mem_ref_loc (clause_loc
, new_var
);
3927 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, ref
);
3928 gimplify_and_add (x
, rlist
);
3933 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
3934 and REDUCTION from the sender (aka parent) side. */
3937 lower_send_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*olist
,
3942 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
3944 tree val
, ref
, x
, var
;
3945 bool by_ref
, do_in
= false, do_out
= false;
3946 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
3948 switch (OMP_CLAUSE_CODE (c
))
3950 case OMP_CLAUSE_PRIVATE
:
3951 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
3954 case OMP_CLAUSE_FIRSTPRIVATE
:
3955 case OMP_CLAUSE_COPYIN
:
3956 case OMP_CLAUSE_LASTPRIVATE
:
3957 case OMP_CLAUSE_REDUCTION
:
3958 case OMP_CLAUSE__LOOPTEMP_
:
3964 val
= OMP_CLAUSE_DECL (c
);
3965 var
= lookup_decl_in_outer_ctx (val
, ctx
);
3967 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYIN
3968 && is_global_var (var
))
3970 if (is_variable_sized (val
))
3972 by_ref
= use_pointer_for_field (val
, NULL
);
3974 switch (OMP_CLAUSE_CODE (c
))
3976 case OMP_CLAUSE_PRIVATE
:
3977 case OMP_CLAUSE_FIRSTPRIVATE
:
3978 case OMP_CLAUSE_COPYIN
:
3979 case OMP_CLAUSE__LOOPTEMP_
:
3983 case OMP_CLAUSE_LASTPRIVATE
:
3984 if (by_ref
|| is_reference (val
))
3986 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
3993 if (lang_hooks
.decls
.omp_private_outer_ref (val
))
3998 case OMP_CLAUSE_REDUCTION
:
4000 do_out
= !(by_ref
|| is_reference (val
));
4009 ref
= build_sender_ref (val
, ctx
);
4010 x
= by_ref
? build_fold_addr_expr_loc (clause_loc
, var
) : var
;
4011 gimplify_assign (ref
, x
, ilist
);
4012 if (is_task_ctx (ctx
))
4013 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref
, 1)) = NULL
;
4018 ref
= build_sender_ref (val
, ctx
);
4019 gimplify_assign (var
, ref
, olist
);
4024 /* Generate code to implement SHARED from the sender (aka parent)
4025 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
4026 list things that got automatically shared. */
4029 lower_send_shared_vars (gimple_seq
*ilist
, gimple_seq
*olist
, omp_context
*ctx
)
4031 tree var
, ovar
, nvar
, f
, x
, record_type
;
4033 if (ctx
->record_type
== NULL
)
4036 record_type
= ctx
->srecord_type
? ctx
->srecord_type
: ctx
->record_type
;
4037 for (f
= TYPE_FIELDS (record_type
); f
; f
= DECL_CHAIN (f
))
4039 ovar
= DECL_ABSTRACT_ORIGIN (f
);
4040 nvar
= maybe_lookup_decl (ovar
, ctx
);
4041 if (!nvar
|| !DECL_HAS_VALUE_EXPR_P (nvar
))
4044 /* If CTX is a nested parallel directive. Find the immediately
4045 enclosing parallel or workshare construct that contains a
4046 mapping for OVAR. */
4047 var
= lookup_decl_in_outer_ctx (ovar
, ctx
);
4049 if (use_pointer_for_field (ovar
, ctx
))
4051 x
= build_sender_ref (ovar
, ctx
);
4052 var
= build_fold_addr_expr (var
);
4053 gimplify_assign (x
, var
, ilist
);
4057 x
= build_sender_ref (ovar
, ctx
);
4058 gimplify_assign (x
, var
, ilist
);
4060 if (!TREE_READONLY (var
)
4061 /* We don't need to receive a new reference to a result
4062 or parm decl. In fact we may not store to it as we will
4063 invalidate any pending RSO and generate wrong gimple
4065 && !((TREE_CODE (var
) == RESULT_DECL
4066 || TREE_CODE (var
) == PARM_DECL
)
4067 && DECL_BY_REFERENCE (var
)))
4069 x
= build_sender_ref (ovar
, ctx
);
4070 gimplify_assign (var
, x
, olist
);
4077 /* A convenience function to build an empty GIMPLE_COND with just the
4081 gimple_build_cond_empty (tree cond
)
4083 enum tree_code pred_code
;
4086 gimple_cond_get_ops_from_tree (cond
, &pred_code
, &lhs
, &rhs
);
4087 return gimple_build_cond (pred_code
, lhs
, rhs
, NULL_TREE
, NULL_TREE
);
4091 /* Build the function calls to GOMP_parallel_start etc to actually
4092 generate the parallel operation. REGION is the parallel region
4093 being expanded. BB is the block where to insert the code. WS_ARGS
4094 will be set if this is a call to a combined parallel+workshare
4095 construct, it contains the list of additional arguments needed by
4096 the workshare construct. */
4099 expand_parallel_call (struct omp_region
*region
, basic_block bb
,
4100 gimple entry_stmt
, vec
<tree
, va_gc
> *ws_args
)
4102 tree t
, t1
, t2
, val
, cond
, c
, clauses
, flags
;
4103 gimple_stmt_iterator gsi
;
4105 enum built_in_function start_ix
;
4107 location_t clause_loc
;
4108 vec
<tree
, va_gc
> *args
;
4110 clauses
= gimple_omp_parallel_clauses (entry_stmt
);
4112 /* Determine what flavor of GOMP_parallel we will be
4114 start_ix
= BUILT_IN_GOMP_PARALLEL
;
4115 if (is_combined_parallel (region
))
4117 switch (region
->inner
->type
)
4119 case GIMPLE_OMP_FOR
:
4120 gcc_assert (region
->inner
->sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
4121 start_ix2
= ((int)BUILT_IN_GOMP_PARALLEL_LOOP_STATIC
4122 + (region
->inner
->sched_kind
4123 == OMP_CLAUSE_SCHEDULE_RUNTIME
4124 ? 3 : region
->inner
->sched_kind
));
4125 start_ix
= (enum built_in_function
)start_ix2
;
4127 case GIMPLE_OMP_SECTIONS
:
4128 start_ix
= BUILT_IN_GOMP_PARALLEL_SECTIONS
;
4135 /* By default, the value of NUM_THREADS is zero (selected at run time)
4136 and there is no conditional. */
4138 val
= build_int_cst (unsigned_type_node
, 0);
4139 flags
= build_int_cst (unsigned_type_node
, 0);
4141 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
4143 cond
= OMP_CLAUSE_IF_EXPR (c
);
4145 c
= find_omp_clause (clauses
, OMP_CLAUSE_NUM_THREADS
);
4148 val
= OMP_CLAUSE_NUM_THREADS_EXPR (c
);
4149 clause_loc
= OMP_CLAUSE_LOCATION (c
);
4152 clause_loc
= gimple_location (entry_stmt
);
4154 c
= find_omp_clause (clauses
, OMP_CLAUSE_PROC_BIND
);
4156 flags
= build_int_cst (unsigned_type_node
, OMP_CLAUSE_PROC_BIND_KIND (c
));
4158 /* Ensure 'val' is of the correct type. */
4159 val
= fold_convert_loc (clause_loc
, unsigned_type_node
, val
);
4161 /* If we found the clause 'if (cond)', build either
4162 (cond != 0) or (cond ? val : 1u). */
4165 gimple_stmt_iterator gsi
;
4167 cond
= gimple_boolify (cond
);
4169 if (integer_zerop (val
))
4170 val
= fold_build2_loc (clause_loc
,
4171 EQ_EXPR
, unsigned_type_node
, cond
,
4172 build_int_cst (TREE_TYPE (cond
), 0));
4175 basic_block cond_bb
, then_bb
, else_bb
;
4176 edge e
, e_then
, e_else
;
4177 tree tmp_then
, tmp_else
, tmp_join
, tmp_var
;
4179 tmp_var
= create_tmp_var (TREE_TYPE (val
), NULL
);
4180 if (gimple_in_ssa_p (cfun
))
4182 tmp_then
= make_ssa_name (tmp_var
, NULL
);
4183 tmp_else
= make_ssa_name (tmp_var
, NULL
);
4184 tmp_join
= make_ssa_name (tmp_var
, NULL
);
4193 e
= split_block (bb
, NULL
);
4198 then_bb
= create_empty_bb (cond_bb
);
4199 else_bb
= create_empty_bb (then_bb
);
4200 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
4201 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
4203 stmt
= gimple_build_cond_empty (cond
);
4204 gsi
= gsi_start_bb (cond_bb
);
4205 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4207 gsi
= gsi_start_bb (then_bb
);
4208 stmt
= gimple_build_assign (tmp_then
, val
);
4209 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4211 gsi
= gsi_start_bb (else_bb
);
4212 stmt
= gimple_build_assign
4213 (tmp_else
, build_int_cst (unsigned_type_node
, 1));
4214 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4216 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
4217 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
4220 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
4221 add_bb_to_loop (else_bb
, cond_bb
->loop_father
);
4223 e_then
= make_edge (then_bb
, bb
, EDGE_FALLTHRU
);
4224 e_else
= make_edge (else_bb
, bb
, EDGE_FALLTHRU
);
4226 if (gimple_in_ssa_p (cfun
))
4228 gimple phi
= create_phi_node (tmp_join
, bb
);
4229 add_phi_arg (phi
, tmp_then
, e_then
, UNKNOWN_LOCATION
);
4230 add_phi_arg (phi
, tmp_else
, e_else
, UNKNOWN_LOCATION
);
4236 gsi
= gsi_start_bb (bb
);
4237 val
= force_gimple_operand_gsi (&gsi
, val
, true, NULL_TREE
,
4238 false, GSI_CONTINUE_LINKING
);
4241 gsi
= gsi_last_bb (bb
);
4242 t
= gimple_omp_parallel_data_arg (entry_stmt
);
4244 t1
= null_pointer_node
;
4246 t1
= build_fold_addr_expr (t
);
4247 t2
= build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt
));
4249 vec_alloc (args
, 4 + vec_safe_length (ws_args
));
4250 args
->quick_push (t2
);
4251 args
->quick_push (t1
);
4252 args
->quick_push (val
);
4254 args
->splice (*ws_args
);
4255 args
->quick_push (flags
);
4257 t
= build_call_expr_loc_vec (UNKNOWN_LOCATION
,
4258 builtin_decl_explicit (start_ix
), args
);
4260 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4261 false, GSI_CONTINUE_LINKING
);
4265 /* Build the function call to GOMP_task to actually
4266 generate the task operation. BB is the block where to insert the code. */
4269 expand_task_call (basic_block bb
, gimple entry_stmt
)
4271 tree t
, t1
, t2
, t3
, flags
, cond
, c
, c2
, clauses
, depend
;
4272 gimple_stmt_iterator gsi
;
4273 location_t loc
= gimple_location (entry_stmt
);
4275 clauses
= gimple_omp_task_clauses (entry_stmt
);
4277 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
4279 cond
= gimple_boolify (OMP_CLAUSE_IF_EXPR (c
));
4281 cond
= boolean_true_node
;
4283 c
= find_omp_clause (clauses
, OMP_CLAUSE_UNTIED
);
4284 c2
= find_omp_clause (clauses
, OMP_CLAUSE_MERGEABLE
);
4285 depend
= find_omp_clause (clauses
, OMP_CLAUSE_DEPEND
);
4286 flags
= build_int_cst (unsigned_type_node
,
4287 (c
? 1 : 0) + (c2
? 4 : 0) + (depend
? 8 : 0));
4289 c
= find_omp_clause (clauses
, OMP_CLAUSE_FINAL
);
4292 c
= gimple_boolify (OMP_CLAUSE_FINAL_EXPR (c
));
4293 c
= fold_build3_loc (loc
, COND_EXPR
, unsigned_type_node
, c
,
4294 build_int_cst (unsigned_type_node
, 2),
4295 build_int_cst (unsigned_type_node
, 0));
4296 flags
= fold_build2_loc (loc
, PLUS_EXPR
, unsigned_type_node
, flags
, c
);
4299 depend
= OMP_CLAUSE_DECL (depend
);
4301 depend
= build_int_cst (ptr_type_node
, 0);
4303 gsi
= gsi_last_bb (bb
);
4304 t
= gimple_omp_task_data_arg (entry_stmt
);
4306 t2
= null_pointer_node
;
4308 t2
= build_fold_addr_expr_loc (loc
, t
);
4309 t1
= build_fold_addr_expr_loc (loc
, gimple_omp_task_child_fn (entry_stmt
));
4310 t
= gimple_omp_task_copy_fn (entry_stmt
);
4312 t3
= null_pointer_node
;
4314 t3
= build_fold_addr_expr_loc (loc
, t
);
4316 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK
),
4318 gimple_omp_task_arg_size (entry_stmt
),
4319 gimple_omp_task_arg_align (entry_stmt
), cond
, flags
,
4322 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4323 false, GSI_CONTINUE_LINKING
);
4327 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
4328 catch handler and return it. This prevents programs from violating the
4329 structured block semantics with throws. */
4332 maybe_catch_exception (gimple_seq body
)
4337 if (!flag_exceptions
)
4340 if (lang_hooks
.eh_protect_cleanup_actions
!= NULL
)
4341 decl
= lang_hooks
.eh_protect_cleanup_actions ();
4343 decl
= builtin_decl_explicit (BUILT_IN_TRAP
);
4345 g
= gimple_build_eh_must_not_throw (decl
);
4346 g
= gimple_build_try (body
, gimple_seq_alloc_with_stmt (g
),
4349 return gimple_seq_alloc_with_stmt (g
);
4352 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
4355 vec2chain (vec
<tree
, va_gc
> *v
)
4357 tree chain
= NULL_TREE
, t
;
4360 FOR_EACH_VEC_SAFE_ELT_REVERSE (v
, ix
, t
)
4362 DECL_CHAIN (t
) = chain
;
4370 /* Remove barriers in REGION->EXIT's block. Note that this is only
4371 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
4372 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
4373 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
4377 remove_exit_barrier (struct omp_region
*region
)
4379 gimple_stmt_iterator gsi
;
4380 basic_block exit_bb
;
4384 int any_addressable_vars
= -1;
4386 exit_bb
= region
->exit
;
4388 /* If the parallel region doesn't return, we don't have REGION->EXIT
4393 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
4394 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
4395 statements that can appear in between are extremely limited -- no
4396 memory operations at all. Here, we allow nothing at all, so the
4397 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
4398 gsi
= gsi_last_bb (exit_bb
);
4399 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
4401 if (!gsi_end_p (gsi
) && gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
4404 FOR_EACH_EDGE (e
, ei
, exit_bb
->preds
)
4406 gsi
= gsi_last_bb (e
->src
);
4407 if (gsi_end_p (gsi
))
4409 stmt
= gsi_stmt (gsi
);
4410 if (gimple_code (stmt
) == GIMPLE_OMP_RETURN
4411 && !gimple_omp_return_nowait_p (stmt
))
4413 /* OpenMP 3.0 tasks unfortunately prevent this optimization
4414 in many cases. If there could be tasks queued, the barrier
4415 might be needed to let the tasks run before some local
4416 variable of the parallel that the task uses as shared
4417 runs out of scope. The task can be spawned either
4418 from within current function (this would be easy to check)
4419 or from some function it calls and gets passed an address
4420 of such a variable. */
4421 if (any_addressable_vars
< 0)
4423 gimple parallel_stmt
= last_stmt (region
->entry
);
4424 tree child_fun
= gimple_omp_parallel_child_fn (parallel_stmt
);
4425 tree local_decls
, block
, decl
;
4428 any_addressable_vars
= 0;
4429 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun
), ix
, decl
)
4430 if (TREE_ADDRESSABLE (decl
))
4432 any_addressable_vars
= 1;
4435 for (block
= gimple_block (stmt
);
4436 !any_addressable_vars
4438 && TREE_CODE (block
) == BLOCK
;
4439 block
= BLOCK_SUPERCONTEXT (block
))
4441 for (local_decls
= BLOCK_VARS (block
);
4443 local_decls
= DECL_CHAIN (local_decls
))
4444 if (TREE_ADDRESSABLE (local_decls
))
4446 any_addressable_vars
= 1;
4449 if (block
== gimple_block (parallel_stmt
))
4453 if (!any_addressable_vars
)
4454 gimple_omp_return_set_nowait (stmt
);
4460 remove_exit_barriers (struct omp_region
*region
)
4462 if (region
->type
== GIMPLE_OMP_PARALLEL
)
4463 remove_exit_barrier (region
);
4467 region
= region
->inner
;
4468 remove_exit_barriers (region
);
4469 while (region
->next
)
4471 region
= region
->next
;
4472 remove_exit_barriers (region
);
4477 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
4478 calls. These can't be declared as const functions, but
4479 within one parallel body they are constant, so they can be
4480 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
4481 which are declared const. Similarly for task body, except
4482 that in untied task omp_get_thread_num () can change at any task
4483 scheduling point. */
4486 optimize_omp_library_calls (gimple entry_stmt
)
4489 gimple_stmt_iterator gsi
;
4490 tree thr_num_tree
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
4491 tree thr_num_id
= DECL_ASSEMBLER_NAME (thr_num_tree
);
4492 tree num_thr_tree
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
4493 tree num_thr_id
= DECL_ASSEMBLER_NAME (num_thr_tree
);
4494 bool untied_task
= (gimple_code (entry_stmt
) == GIMPLE_OMP_TASK
4495 && find_omp_clause (gimple_omp_task_clauses (entry_stmt
),
4496 OMP_CLAUSE_UNTIED
) != NULL
);
4499 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4501 gimple call
= gsi_stmt (gsi
);
4504 if (is_gimple_call (call
)
4505 && (decl
= gimple_call_fndecl (call
))
4506 && DECL_EXTERNAL (decl
)
4507 && TREE_PUBLIC (decl
)
4508 && DECL_INITIAL (decl
) == NULL
)
4512 if (DECL_NAME (decl
) == thr_num_id
)
4514 /* In #pragma omp task untied omp_get_thread_num () can change
4515 during the execution of the task region. */
4518 built_in
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
4520 else if (DECL_NAME (decl
) == num_thr_id
)
4521 built_in
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
4525 if (DECL_ASSEMBLER_NAME (decl
) != DECL_ASSEMBLER_NAME (built_in
)
4526 || gimple_call_num_args (call
) != 0)
4529 if (flag_exceptions
&& !TREE_NOTHROW (decl
))
4532 if (TREE_CODE (TREE_TYPE (decl
)) != FUNCTION_TYPE
4533 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl
)),
4534 TREE_TYPE (TREE_TYPE (built_in
))))
4537 gimple_call_set_fndecl (call
, built_in
);
4542 /* Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be
4546 expand_omp_regimplify_p (tree
*tp
, int *walk_subtrees
, void *)
4550 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
4551 if (TREE_CODE (t
) == VAR_DECL
&& DECL_HAS_VALUE_EXPR_P (t
))
4554 if (TREE_CODE (t
) == ADDR_EXPR
)
4555 recompute_tree_invariant_for_addr_expr (t
);
4557 *walk_subtrees
= !TYPE_P (t
) && !DECL_P (t
);
4561 /* Prepend TO = FROM assignment before *GSI_P. */
4564 expand_omp_build_assign (gimple_stmt_iterator
*gsi_p
, tree to
, tree from
)
4566 bool simple_p
= DECL_P (to
) && TREE_ADDRESSABLE (to
);
4567 from
= force_gimple_operand_gsi (gsi_p
, from
, simple_p
, NULL_TREE
,
4568 true, GSI_SAME_STMT
);
4569 gimple stmt
= gimple_build_assign (to
, from
);
4570 gsi_insert_before (gsi_p
, stmt
, GSI_SAME_STMT
);
4571 if (walk_tree (&from
, expand_omp_regimplify_p
, NULL
, NULL
)
4572 || walk_tree (&to
, expand_omp_regimplify_p
, NULL
, NULL
))
4574 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
4575 gimple_regimplify_operands (stmt
, &gsi
);
4579 /* Expand the OpenMP parallel or task directive starting at REGION. */
4582 expand_omp_taskreg (struct omp_region
*region
)
4584 basic_block entry_bb
, exit_bb
, new_bb
;
4585 struct function
*child_cfun
;
4586 tree child_fn
, block
, t
;
4587 gimple_stmt_iterator gsi
;
4588 gimple entry_stmt
, stmt
;
4590 vec
<tree
, va_gc
> *ws_args
;
4592 entry_stmt
= last_stmt (region
->entry
);
4593 child_fn
= gimple_omp_taskreg_child_fn (entry_stmt
);
4594 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
4596 entry_bb
= region
->entry
;
4597 exit_bb
= region
->exit
;
4599 if (is_combined_parallel (region
))
4600 ws_args
= region
->ws_args
;
4604 if (child_cfun
->cfg
)
4606 /* Due to inlining, it may happen that we have already outlined
4607 the region, in which case all we need to do is make the
4608 sub-graph unreachable and emit the parallel call. */
4609 edge entry_succ_e
, exit_succ_e
;
4610 gimple_stmt_iterator gsi
;
4612 entry_succ_e
= single_succ_edge (entry_bb
);
4614 gsi
= gsi_last_bb (entry_bb
);
4615 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_PARALLEL
4616 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_TASK
);
4617 gsi_remove (&gsi
, true);
4622 exit_succ_e
= single_succ_edge (exit_bb
);
4623 make_edge (new_bb
, exit_succ_e
->dest
, EDGE_FALLTHRU
);
4625 remove_edge_and_dominated_blocks (entry_succ_e
);
4629 unsigned srcidx
, dstidx
, num
;
4631 /* If the parallel region needs data sent from the parent
4632 function, then the very first statement (except possible
4633 tree profile counter updates) of the parallel body
4634 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
4635 &.OMP_DATA_O is passed as an argument to the child function,
4636 we need to replace it with the argument as seen by the child
4639 In most cases, this will end up being the identity assignment
4640 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
4641 a function call that has been inlined, the original PARM_DECL
4642 .OMP_DATA_I may have been converted into a different local
4643 variable. In which case, we need to keep the assignment. */
4644 if (gimple_omp_taskreg_data_arg (entry_stmt
))
4646 basic_block entry_succ_bb
= single_succ (entry_bb
);
4647 gimple_stmt_iterator gsi
;
4649 gimple parcopy_stmt
= NULL
;
4651 for (gsi
= gsi_start_bb (entry_succ_bb
); ; gsi_next (&gsi
))
4655 gcc_assert (!gsi_end_p (gsi
));
4656 stmt
= gsi_stmt (gsi
);
4657 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
4660 if (gimple_num_ops (stmt
) == 2)
4662 tree arg
= gimple_assign_rhs1 (stmt
);
4664 /* We're ignore the subcode because we're
4665 effectively doing a STRIP_NOPS. */
4667 if (TREE_CODE (arg
) == ADDR_EXPR
4668 && TREE_OPERAND (arg
, 0)
4669 == gimple_omp_taskreg_data_arg (entry_stmt
))
4671 parcopy_stmt
= stmt
;
4677 gcc_assert (parcopy_stmt
!= NULL
);
4678 arg
= DECL_ARGUMENTS (child_fn
);
4680 if (!gimple_in_ssa_p (cfun
))
4682 if (gimple_assign_lhs (parcopy_stmt
) == arg
)
4683 gsi_remove (&gsi
, true);
4686 /* ?? Is setting the subcode really necessary ?? */
4687 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (arg
));
4688 gimple_assign_set_rhs1 (parcopy_stmt
, arg
);
4693 /* If we are in ssa form, we must load the value from the default
4694 definition of the argument. That should not be defined now,
4695 since the argument is not used uninitialized. */
4696 gcc_assert (ssa_default_def (cfun
, arg
) == NULL
);
4697 narg
= make_ssa_name (arg
, gimple_build_nop ());
4698 set_ssa_default_def (cfun
, arg
, narg
);
4699 /* ?? Is setting the subcode really necessary ?? */
4700 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (narg
));
4701 gimple_assign_set_rhs1 (parcopy_stmt
, narg
);
4702 update_stmt (parcopy_stmt
);
4706 /* Declare local variables needed in CHILD_CFUN. */
4707 block
= DECL_INITIAL (child_fn
);
4708 BLOCK_VARS (block
) = vec2chain (child_cfun
->local_decls
);
4709 /* The gimplifier could record temporaries in parallel/task block
4710 rather than in containing function's local_decls chain,
4711 which would mean cgraph missed finalizing them. Do it now. */
4712 for (t
= BLOCK_VARS (block
); t
; t
= DECL_CHAIN (t
))
4713 if (TREE_CODE (t
) == VAR_DECL
4715 && !DECL_EXTERNAL (t
))
4716 varpool_finalize_decl (t
);
4717 DECL_SAVED_TREE (child_fn
) = NULL
;
4718 /* We'll create a CFG for child_fn, so no gimple body is needed. */
4719 gimple_set_body (child_fn
, NULL
);
4720 TREE_USED (block
) = 1;
4722 /* Reset DECL_CONTEXT on function arguments. */
4723 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
4724 DECL_CONTEXT (t
) = child_fn
;
4726 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
4727 so that it can be moved to the child function. */
4728 gsi
= gsi_last_bb (entry_bb
);
4729 stmt
= gsi_stmt (gsi
);
4730 gcc_assert (stmt
&& (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
4731 || gimple_code (stmt
) == GIMPLE_OMP_TASK
));
4732 gsi_remove (&gsi
, true);
4733 e
= split_block (entry_bb
, stmt
);
4735 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
4737 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
4740 gsi
= gsi_last_bb (exit_bb
);
4741 gcc_assert (!gsi_end_p (gsi
)
4742 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
4743 stmt
= gimple_build_return (NULL
);
4744 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
4745 gsi_remove (&gsi
, true);
4748 /* Move the parallel region into CHILD_CFUN. */
4750 if (gimple_in_ssa_p (cfun
))
4752 init_tree_ssa (child_cfun
);
4753 init_ssa_operands (child_cfun
);
4754 child_cfun
->gimple_df
->in_ssa_p
= true;
4758 block
= gimple_block (entry_stmt
);
4760 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
, block
);
4762 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
4763 /* When the OMP expansion process cannot guarantee an up-to-date
4764 loop tree arrange for the child function to fixup loops. */
4765 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
4766 child_cfun
->x_current_loops
->state
|= LOOPS_NEED_FIXUP
;
4768 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
4769 num
= vec_safe_length (child_cfun
->local_decls
);
4770 for (srcidx
= 0, dstidx
= 0; srcidx
< num
; srcidx
++)
4772 t
= (*child_cfun
->local_decls
)[srcidx
];
4773 if (DECL_CONTEXT (t
) == cfun
->decl
)
4775 if (srcidx
!= dstidx
)
4776 (*child_cfun
->local_decls
)[dstidx
] = t
;
4780 vec_safe_truncate (child_cfun
->local_decls
, dstidx
);
4782 /* Inform the callgraph about the new function. */
4783 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
= cfun
->curr_properties
;
4784 cgraph_add_new_function (child_fn
, true);
4786 /* Fix the callgraph edges for child_cfun. Those for cfun will be
4787 fixed in a following pass. */
4788 push_cfun (child_cfun
);
4790 optimize_omp_library_calls (entry_stmt
);
4791 rebuild_cgraph_edges ();
4793 /* Some EH regions might become dead, see PR34608. If
4794 pass_cleanup_cfg isn't the first pass to happen with the
4795 new child, these dead EH edges might cause problems.
4796 Clean them up now. */
4797 if (flag_exceptions
)
4800 bool changed
= false;
4803 changed
|= gimple_purge_dead_eh_edges (bb
);
4805 cleanup_tree_cfg ();
4807 if (gimple_in_ssa_p (cfun
))
4808 update_ssa (TODO_update_ssa
);
4812 /* Emit a library call to launch the children threads. */
4813 if (gimple_code (entry_stmt
) == GIMPLE_OMP_PARALLEL
)
4814 expand_parallel_call (region
, new_bb
, entry_stmt
, ws_args
);
4816 expand_task_call (new_bb
, entry_stmt
);
4817 if (gimple_in_ssa_p (cfun
))
4818 update_ssa (TODO_update_ssa_only_virtuals
);
4822 /* Helper function for expand_omp_{for_*,simd}. If this is the outermost
4823 of the combined collapse > 1 loop constructs, generate code like:
4824 if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
4829 count3 = (adj + N32 - N31) / STEP3;
4830 if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
4835 count2 = (adj + N22 - N21) / STEP2;
4836 if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
4841 count1 = (adj + N12 - N11) / STEP1;
4842 count = count1 * count2 * count3;
4843 Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
4845 and set ZERO_ITER_BB to that bb. If this isn't the outermost
4846 of the combined loop constructs, just initialize COUNTS array
4847 from the _looptemp_ clauses. */
4849 /* NOTE: It *could* be better to moosh all of the BBs together,
4850 creating one larger BB with all the computation and the unexpected
4851 jump at the end. I.e.
4853 bool zero3, zero2, zero1, zero;
4856 count3 = (N32 - N31) /[cl] STEP3;
4858 count2 = (N22 - N21) /[cl] STEP2;
4860 count1 = (N12 - N11) /[cl] STEP1;
4861 zero = zero3 || zero2 || zero1;
4862 count = count1 * count2 * count3;
4863 if (__builtin_expect(zero, false)) goto zero_iter_bb;
4865 After all, we expect the zero=false, and thus we expect to have to
4866 evaluate all of the comparison expressions, so short-circuiting
4867 oughtn't be a win. Since the condition isn't protecting a
4868 denominator, we're not concerned about divide-by-zero, so we can
4869 fully evaluate count even if a numerator turned out to be wrong.
4871 It seems like putting this all together would create much better
4872 scheduling opportunities, and less pressure on the chip's branch
4876 expand_omp_for_init_counts (struct omp_for_data
*fd
, gimple_stmt_iterator
*gsi
,
4877 basic_block
&entry_bb
, tree
*counts
,
4878 basic_block
&zero_iter_bb
, int &first_zero_iter
,
4879 basic_block
&l2_dom_bb
)
4881 tree t
, type
= TREE_TYPE (fd
->loop
.v
);
4886 /* Collapsed loops need work for expansion into SSA form. */
4887 gcc_assert (!gimple_in_ssa_p (cfun
));
4889 if (gimple_omp_for_combined_into_p (fd
->for_stmt
)
4890 && TREE_CODE (fd
->loop
.n2
) != INTEGER_CST
)
4892 /* First two _looptemp_ clauses are for istart/iend, counts[0]
4893 isn't supposed to be handled, as the inner loop doesn't
4895 tree innerc
= find_omp_clause (gimple_omp_for_clauses (fd
->for_stmt
),
4896 OMP_CLAUSE__LOOPTEMP_
);
4897 gcc_assert (innerc
);
4898 for (i
= 0; i
< fd
->collapse
; i
++)
4900 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
4901 OMP_CLAUSE__LOOPTEMP_
);
4902 gcc_assert (innerc
);
4904 counts
[i
] = OMP_CLAUSE_DECL (innerc
);
4906 counts
[0] = NULL_TREE
;
4911 for (i
= 0; i
< fd
->collapse
; i
++)
4913 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
4915 if (SSA_VAR_P (fd
->loop
.n2
)
4916 && ((t
= fold_binary (fd
->loops
[i
].cond_code
, boolean_type_node
,
4917 fold_convert (itype
, fd
->loops
[i
].n1
),
4918 fold_convert (itype
, fd
->loops
[i
].n2
)))
4919 == NULL_TREE
|| !integer_onep (t
)))
4922 n1
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n1
));
4923 n1
= force_gimple_operand_gsi (gsi
, n1
, true, NULL_TREE
,
4924 true, GSI_SAME_STMT
);
4925 n2
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
4926 n2
= force_gimple_operand_gsi (gsi
, n2
, true, NULL_TREE
,
4927 true, GSI_SAME_STMT
);
4928 stmt
= gimple_build_cond (fd
->loops
[i
].cond_code
, n1
, n2
,
4929 NULL_TREE
, NULL_TREE
);
4930 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
4931 if (walk_tree (gimple_cond_lhs_ptr (stmt
),
4932 expand_omp_regimplify_p
, NULL
, NULL
)
4933 || walk_tree (gimple_cond_rhs_ptr (stmt
),
4934 expand_omp_regimplify_p
, NULL
, NULL
))
4936 *gsi
= gsi_for_stmt (stmt
);
4937 gimple_regimplify_operands (stmt
, gsi
);
4939 e
= split_block (entry_bb
, stmt
);
4940 if (zero_iter_bb
== NULL
)
4942 first_zero_iter
= i
;
4943 zero_iter_bb
= create_empty_bb (entry_bb
);
4945 add_bb_to_loop (zero_iter_bb
, entry_bb
->loop_father
);
4946 *gsi
= gsi_after_labels (zero_iter_bb
);
4947 stmt
= gimple_build_assign (fd
->loop
.n2
,
4948 build_zero_cst (type
));
4949 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
4950 set_immediate_dominator (CDI_DOMINATORS
, zero_iter_bb
,
4953 ne
= make_edge (entry_bb
, zero_iter_bb
, EDGE_FALSE_VALUE
);
4954 ne
->probability
= REG_BR_PROB_BASE
/ 2000 - 1;
4955 e
->flags
= EDGE_TRUE_VALUE
;
4956 e
->probability
= REG_BR_PROB_BASE
- ne
->probability
;
4957 if (l2_dom_bb
== NULL
)
4958 l2_dom_bb
= entry_bb
;
4960 *gsi
= gsi_last_bb (entry_bb
);
4963 if (POINTER_TYPE_P (itype
))
4964 itype
= signed_type_for (itype
);
4965 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
== LT_EXPR
4967 t
= fold_build2 (PLUS_EXPR
, itype
,
4968 fold_convert (itype
, fd
->loops
[i
].step
), t
);
4969 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
4970 fold_convert (itype
, fd
->loops
[i
].n2
));
4971 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
4972 fold_convert (itype
, fd
->loops
[i
].n1
));
4973 /* ?? We could probably use CEIL_DIV_EXPR instead of
4974 TRUNC_DIV_EXPR and adjusting by hand. Unless we can't
4975 generate the same code in the end because generically we
4976 don't know that the values involved must be negative for
4978 if (TYPE_UNSIGNED (itype
) && fd
->loops
[i
].cond_code
== GT_EXPR
)
4979 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4980 fold_build1 (NEGATE_EXPR
, itype
, t
),
4981 fold_build1 (NEGATE_EXPR
, itype
,
4982 fold_convert (itype
,
4983 fd
->loops
[i
].step
)));
4985 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
,
4986 fold_convert (itype
, fd
->loops
[i
].step
));
4987 t
= fold_convert (type
, t
);
4988 if (TREE_CODE (t
) == INTEGER_CST
)
4992 counts
[i
] = create_tmp_reg (type
, ".count");
4993 expand_omp_build_assign (gsi
, counts
[i
], t
);
4995 if (SSA_VAR_P (fd
->loop
.n2
))
5000 t
= fold_build2 (MULT_EXPR
, type
, fd
->loop
.n2
, counts
[i
]);
5001 expand_omp_build_assign (gsi
, fd
->loop
.n2
, t
);
5007 /* Helper function for expand_omp_{for_*,simd}. Generate code like:
5009 V3 = N31 + (T % count3) * STEP3;
5011 V2 = N21 + (T % count2) * STEP2;
5013 V1 = N11 + T * STEP1;
5014 if this loop doesn't have an inner loop construct combined with it.
5015 If it does have an inner loop construct combined with it and the
5016 iteration count isn't known constant, store values from counts array
5017 into its _looptemp_ temporaries instead. */
5020 expand_omp_for_init_vars (struct omp_for_data
*fd
, gimple_stmt_iterator
*gsi
,
5021 tree
*counts
, gimple inner_stmt
, tree startvar
)
5024 if (gimple_omp_for_combined_p (fd
->for_stmt
))
5026 /* If fd->loop.n2 is constant, then no propagation of the counts
5027 is needed, they are constant. */
5028 if (TREE_CODE (fd
->loop
.n2
) == INTEGER_CST
)
5031 tree clauses
= gimple_code (inner_stmt
) == GIMPLE_OMP_PARALLEL
5032 ? gimple_omp_parallel_clauses (inner_stmt
)
5033 : gimple_omp_for_clauses (inner_stmt
);
5034 /* First two _looptemp_ clauses are for istart/iend, counts[0]
5035 isn't supposed to be handled, as the inner loop doesn't
5037 tree innerc
= find_omp_clause (clauses
, OMP_CLAUSE__LOOPTEMP_
);
5038 gcc_assert (innerc
);
5039 for (i
= 0; i
< fd
->collapse
; i
++)
5041 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
5042 OMP_CLAUSE__LOOPTEMP_
);
5043 gcc_assert (innerc
);
5046 tree tem
= OMP_CLAUSE_DECL (innerc
);
5047 tree t
= fold_convert (TREE_TYPE (tem
), counts
[i
]);
5048 t
= force_gimple_operand_gsi (gsi
, t
, false, NULL_TREE
,
5049 false, GSI_CONTINUE_LINKING
);
5050 gimple stmt
= gimple_build_assign (tem
, t
);
5051 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
5057 tree type
= TREE_TYPE (fd
->loop
.v
);
5058 tree tem
= create_tmp_reg (type
, ".tem");
5059 gimple stmt
= gimple_build_assign (tem
, startvar
);
5060 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
5062 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
5064 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
), itype
, t
;
5066 if (POINTER_TYPE_P (vtype
))
5067 itype
= signed_type_for (vtype
);
5069 t
= fold_build2 (TRUNC_MOD_EXPR
, type
, tem
, counts
[i
]);
5072 t
= fold_convert (itype
, t
);
5073 t
= fold_build2 (MULT_EXPR
, itype
, t
,
5074 fold_convert (itype
, fd
->loops
[i
].step
));
5075 if (POINTER_TYPE_P (vtype
))
5076 t
= fold_build_pointer_plus (fd
->loops
[i
].n1
, t
);
5078 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[i
].n1
, t
);
5079 t
= force_gimple_operand_gsi (gsi
, t
,
5080 DECL_P (fd
->loops
[i
].v
)
5081 && TREE_ADDRESSABLE (fd
->loops
[i
].v
),
5083 GSI_CONTINUE_LINKING
);
5084 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
5085 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
5088 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, tem
, counts
[i
]);
5089 t
= force_gimple_operand_gsi (gsi
, t
, false, NULL_TREE
,
5090 false, GSI_CONTINUE_LINKING
);
5091 stmt
= gimple_build_assign (tem
, t
);
5092 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
5098 /* Helper function for expand_omp_for_*. Generate code like:
5101 if (V3 cond3 N32) goto BODY_BB; else goto L11;
5105 if (V2 cond2 N22) goto BODY_BB; else goto L12;
5112 extract_omp_for_update_vars (struct omp_for_data
*fd
, basic_block cont_bb
,
5113 basic_block body_bb
)
5115 basic_block last_bb
, bb
, collapse_bb
= NULL
;
5117 gimple_stmt_iterator gsi
;
5123 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
5125 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
);
5127 bb
= create_empty_bb (last_bb
);
5129 add_bb_to_loop (bb
, last_bb
->loop_father
);
5130 gsi
= gsi_start_bb (bb
);
5132 if (i
< fd
->collapse
- 1)
5134 e
= make_edge (last_bb
, bb
, EDGE_FALSE_VALUE
);
5135 e
->probability
= REG_BR_PROB_BASE
/ 8;
5137 t
= fd
->loops
[i
+ 1].n1
;
5138 t
= force_gimple_operand_gsi (&gsi
, t
,
5139 DECL_P (fd
->loops
[i
+ 1].v
)
5140 && TREE_ADDRESSABLE (fd
->loops
[i
5143 GSI_CONTINUE_LINKING
);
5144 stmt
= gimple_build_assign (fd
->loops
[i
+ 1].v
, t
);
5145 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
5150 set_immediate_dominator (CDI_DOMINATORS
, bb
, last_bb
);
5152 if (POINTER_TYPE_P (vtype
))
5153 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, fd
->loops
[i
].step
);
5155 t
= fold_build2 (PLUS_EXPR
, vtype
, fd
->loops
[i
].v
, fd
->loops
[i
].step
);
5156 t
= force_gimple_operand_gsi (&gsi
, t
,
5157 DECL_P (fd
->loops
[i
].v
)
5158 && TREE_ADDRESSABLE (fd
->loops
[i
].v
),
5159 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
5160 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
5161 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
5165 t
= fd
->loops
[i
].n2
;
5166 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5167 false, GSI_CONTINUE_LINKING
);
5168 tree v
= fd
->loops
[i
].v
;
5169 if (DECL_P (v
) && TREE_ADDRESSABLE (v
))
5170 v
= force_gimple_operand_gsi (&gsi
, v
, true, NULL_TREE
,
5171 false, GSI_CONTINUE_LINKING
);
5172 t
= fold_build2 (fd
->loops
[i
].cond_code
, boolean_type_node
, v
, t
);
5173 stmt
= gimple_build_cond_empty (t
);
5174 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
5175 e
= make_edge (bb
, body_bb
, EDGE_TRUE_VALUE
);
5176 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
5179 make_edge (bb
, body_bb
, EDGE_FALLTHRU
);
5187 /* A subroutine of expand_omp_for. Generate code for a parallel
5188 loop with any schedule. Given parameters:
5190 for (V = N1; V cond N2; V += STEP) BODY;
5192 where COND is "<" or ">", we generate pseudocode
5194 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
5195 if (more) goto L0; else goto L3;
5202 if (V cond iend) goto L1; else goto L2;
5204 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
5207 If this is a combined omp parallel loop, instead of the call to
5208 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
5209 If this is gimple_omp_for_combined_p loop, then instead of assigning
5210 V and iend in L0 we assign the first two _looptemp_ clause decls of the
5211 inner GIMPLE_OMP_FOR and V += STEP; and
5212 if (V cond iend) goto L1; else goto L2; are removed.
5214 For collapsed loops, given parameters:
5216 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
5217 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
5218 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
5221 we generate pseudocode
5223 if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
5228 count3 = (adj + N32 - N31) / STEP3;
5229 if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
5234 count2 = (adj + N22 - N21) / STEP2;
5235 if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
5240 count1 = (adj + N12 - N11) / STEP1;
5241 count = count1 * count2 * count3;
5246 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
5247 if (more) goto L0; else goto L3;
5251 V3 = N31 + (T % count3) * STEP3;
5253 V2 = N21 + (T % count2) * STEP2;
5255 V1 = N11 + T * STEP1;
5260 if (V < iend) goto L10; else goto L2;
5263 if (V3 cond3 N32) goto L1; else goto L11;
5267 if (V2 cond2 N22) goto L1; else goto L12;
5273 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
5279 expand_omp_for_generic (struct omp_region
*region
,
5280 struct omp_for_data
*fd
,
5281 enum built_in_function start_fn
,
5282 enum built_in_function next_fn
,
5285 tree type
, istart0
, iend0
, iend
;
5286 tree t
, vmain
, vback
, bias
= NULL_TREE
;
5287 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
, collapse_bb
;
5288 basic_block l2_bb
= NULL
, l3_bb
= NULL
;
5289 gimple_stmt_iterator gsi
;
5291 bool in_combined_parallel
= is_combined_parallel (region
);
5292 bool broken_loop
= region
->cont
== NULL
;
5294 tree
*counts
= NULL
;
5297 gcc_assert (!broken_loop
|| !in_combined_parallel
);
5298 gcc_assert (fd
->iter_type
== long_integer_type_node
5299 || !in_combined_parallel
);
5301 type
= TREE_TYPE (fd
->loop
.v
);
5302 istart0
= create_tmp_var (fd
->iter_type
, ".istart0");
5303 iend0
= create_tmp_var (fd
->iter_type
, ".iend0");
5304 TREE_ADDRESSABLE (istart0
) = 1;
5305 TREE_ADDRESSABLE (iend0
) = 1;
5307 /* See if we need to bias by LLONG_MIN. */
5308 if (fd
->iter_type
== long_long_unsigned_type_node
5309 && TREE_CODE (type
) == INTEGER_TYPE
5310 && !TYPE_UNSIGNED (type
))
5314 if (fd
->loop
.cond_code
== LT_EXPR
)
5317 n2
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
5321 n1
= fold_build2 (MINUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
5324 if (TREE_CODE (n1
) != INTEGER_CST
5325 || TREE_CODE (n2
) != INTEGER_CST
5326 || ((tree_int_cst_sgn (n1
) < 0) ^ (tree_int_cst_sgn (n2
) < 0)))
5327 bias
= fold_convert (fd
->iter_type
, TYPE_MIN_VALUE (type
));
5330 entry_bb
= region
->entry
;
5331 cont_bb
= region
->cont
;
5333 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
5334 gcc_assert (broken_loop
5335 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
5336 l0_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
5337 l1_bb
= single_succ (l0_bb
);
5340 l2_bb
= create_empty_bb (cont_bb
);
5341 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l1_bb
);
5342 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
5346 l3_bb
= BRANCH_EDGE (entry_bb
)->dest
;
5347 exit_bb
= region
->exit
;
5349 gsi
= gsi_last_bb (entry_bb
);
5351 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
5352 if (fd
->collapse
> 1)
5354 int first_zero_iter
= -1;
5355 basic_block zero_iter_bb
= NULL
, l2_dom_bb
= NULL
;
5357 counts
= XALLOCAVEC (tree
, fd
->collapse
);
5358 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
5359 zero_iter_bb
, first_zero_iter
,
5364 /* Some counts[i] vars might be uninitialized if
5365 some loop has zero iterations. But the body shouldn't
5366 be executed in that case, so just avoid uninit warnings. */
5367 for (i
= first_zero_iter
; i
< fd
->collapse
; i
++)
5368 if (SSA_VAR_P (counts
[i
]))
5369 TREE_NO_WARNING (counts
[i
]) = 1;
5371 e
= split_block (entry_bb
, gsi_stmt (gsi
));
5373 make_edge (zero_iter_bb
, entry_bb
, EDGE_FALLTHRU
);
5374 gsi
= gsi_last_bb (entry_bb
);
5375 set_immediate_dominator (CDI_DOMINATORS
, entry_bb
,
5376 get_immediate_dominator (CDI_DOMINATORS
,
5380 if (in_combined_parallel
)
5382 /* In a combined parallel loop, emit a call to
5383 GOMP_loop_foo_next. */
5384 t
= build_call_expr (builtin_decl_explicit (next_fn
), 2,
5385 build_fold_addr_expr (istart0
),
5386 build_fold_addr_expr (iend0
));
5390 tree t0
, t1
, t2
, t3
, t4
;
5391 /* If this is not a combined parallel loop, emit a call to
5392 GOMP_loop_foo_start in ENTRY_BB. */
5393 t4
= build_fold_addr_expr (iend0
);
5394 t3
= build_fold_addr_expr (istart0
);
5395 t2
= fold_convert (fd
->iter_type
, fd
->loop
.step
);
5398 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
5400 tree innerc
= find_omp_clause (gimple_omp_for_clauses (fd
->for_stmt
),
5401 OMP_CLAUSE__LOOPTEMP_
);
5402 gcc_assert (innerc
);
5403 t0
= OMP_CLAUSE_DECL (innerc
);
5404 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
5405 OMP_CLAUSE__LOOPTEMP_
);
5406 gcc_assert (innerc
);
5407 t1
= OMP_CLAUSE_DECL (innerc
);
5409 if (POINTER_TYPE_P (TREE_TYPE (t0
))
5410 && TYPE_PRECISION (TREE_TYPE (t0
))
5411 != TYPE_PRECISION (fd
->iter_type
))
5413 /* Avoid casting pointers to integer of a different size. */
5414 tree itype
= signed_type_for (type
);
5415 t1
= fold_convert (fd
->iter_type
, fold_convert (itype
, t1
));
5416 t0
= fold_convert (fd
->iter_type
, fold_convert (itype
, t0
));
5420 t1
= fold_convert (fd
->iter_type
, t1
);
5421 t0
= fold_convert (fd
->iter_type
, t0
);
5425 t1
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t1
, bias
);
5426 t0
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t0
, bias
);
5428 if (fd
->iter_type
== long_integer_type_node
)
5432 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
5433 t
= build_call_expr (builtin_decl_explicit (start_fn
),
5434 6, t0
, t1
, t2
, t
, t3
, t4
);
5437 t
= build_call_expr (builtin_decl_explicit (start_fn
),
5438 5, t0
, t1
, t2
, t3
, t4
);
5446 /* The GOMP_loop_ull_*start functions have additional boolean
5447 argument, true for < loops and false for > loops.
5448 In Fortran, the C bool type can be different from
5449 boolean_type_node. */
5450 bfn_decl
= builtin_decl_explicit (start_fn
);
5451 c_bool_type
= TREE_TYPE (TREE_TYPE (bfn_decl
));
5452 t5
= build_int_cst (c_bool_type
,
5453 fd
->loop
.cond_code
== LT_EXPR
? 1 : 0);
5456 tree bfn_decl
= builtin_decl_explicit (start_fn
);
5457 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
5458 t
= build_call_expr (bfn_decl
, 7, t5
, t0
, t1
, t2
, t
, t3
, t4
);
5461 t
= build_call_expr (builtin_decl_explicit (start_fn
),
5462 6, t5
, t0
, t1
, t2
, t3
, t4
);
5465 if (TREE_TYPE (t
) != boolean_type_node
)
5466 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
5467 t
, build_int_cst (TREE_TYPE (t
), 0));
5468 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5469 true, GSI_SAME_STMT
);
5470 gsi_insert_after (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
5472 /* Remove the GIMPLE_OMP_FOR statement. */
5473 gsi_remove (&gsi
, true);
5475 /* Iteration setup for sequential loop goes in L0_BB. */
5476 tree startvar
= fd
->loop
.v
;
5477 tree endvar
= NULL_TREE
;
5479 if (gimple_omp_for_combined_p (fd
->for_stmt
))
5481 gcc_assert (gimple_code (inner_stmt
) == GIMPLE_OMP_FOR
5482 && gimple_omp_for_kind (inner_stmt
)
5483 == GF_OMP_FOR_KIND_SIMD
);
5484 tree innerc
= find_omp_clause (gimple_omp_for_clauses (inner_stmt
),
5485 OMP_CLAUSE__LOOPTEMP_
);
5486 gcc_assert (innerc
);
5487 startvar
= OMP_CLAUSE_DECL (innerc
);
5488 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
5489 OMP_CLAUSE__LOOPTEMP_
);
5490 gcc_assert (innerc
);
5491 endvar
= OMP_CLAUSE_DECL (innerc
);
5494 gsi
= gsi_start_bb (l0_bb
);
5497 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
5498 if (POINTER_TYPE_P (TREE_TYPE (startvar
)))
5499 t
= fold_convert (signed_type_for (TREE_TYPE (startvar
)), t
);
5500 t
= fold_convert (TREE_TYPE (startvar
), t
);
5501 t
= force_gimple_operand_gsi (&gsi
, t
,
5503 && TREE_ADDRESSABLE (startvar
),
5504 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
5505 stmt
= gimple_build_assign (startvar
, t
);
5506 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
5510 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
5511 if (POINTER_TYPE_P (TREE_TYPE (startvar
)))
5512 t
= fold_convert (signed_type_for (TREE_TYPE (startvar
)), t
);
5513 t
= fold_convert (TREE_TYPE (startvar
), t
);
5514 iend
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5515 false, GSI_CONTINUE_LINKING
);
5518 stmt
= gimple_build_assign (endvar
, iend
);
5519 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
5521 if (fd
->collapse
> 1)
5522 expand_omp_for_init_vars (fd
, &gsi
, counts
, inner_stmt
, startvar
);
5526 /* Code to control the increment and predicate for the sequential
5527 loop goes in the CONT_BB. */
5528 gsi
= gsi_last_bb (cont_bb
);
5529 stmt
= gsi_stmt (gsi
);
5530 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
5531 vmain
= gimple_omp_continue_control_use (stmt
);
5532 vback
= gimple_omp_continue_control_def (stmt
);
5534 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
5536 if (POINTER_TYPE_P (type
))
5537 t
= fold_build_pointer_plus (vmain
, fd
->loop
.step
);
5539 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
5540 t
= force_gimple_operand_gsi (&gsi
, t
,
5542 && TREE_ADDRESSABLE (vback
),
5543 NULL_TREE
, true, GSI_SAME_STMT
);
5544 stmt
= gimple_build_assign (vback
, t
);
5545 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
5547 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
5548 DECL_P (vback
) && TREE_ADDRESSABLE (vback
) ? t
: vback
,
5550 stmt
= gimple_build_cond_empty (t
);
5551 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
5554 /* Remove GIMPLE_OMP_CONTINUE. */
5555 gsi_remove (&gsi
, true);
5557 if (fd
->collapse
> 1 && !gimple_omp_for_combined_p (fd
->for_stmt
))
5558 collapse_bb
= extract_omp_for_update_vars (fd
, cont_bb
, l1_bb
);
5560 /* Emit code to get the next parallel iteration in L2_BB. */
5561 gsi
= gsi_start_bb (l2_bb
);
5563 t
= build_call_expr (builtin_decl_explicit (next_fn
), 2,
5564 build_fold_addr_expr (istart0
),
5565 build_fold_addr_expr (iend0
));
5566 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5567 false, GSI_CONTINUE_LINKING
);
5568 if (TREE_TYPE (t
) != boolean_type_node
)
5569 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
5570 t
, build_int_cst (TREE_TYPE (t
), 0));
5571 stmt
= gimple_build_cond_empty (t
);
5572 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
5575 /* Add the loop cleanup function. */
5576 gsi
= gsi_last_bb (exit_bb
);
5577 if (gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
5578 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT
);
5579 else if (gimple_omp_return_lhs (gsi_stmt (gsi
)))
5580 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL
);
5582 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END
);
5583 stmt
= gimple_build_call (t
, 0);
5584 if (gimple_omp_return_lhs (gsi_stmt (gsi
)))
5585 gimple_call_set_lhs (stmt
, gimple_omp_return_lhs (gsi_stmt (gsi
)));
5586 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
5587 gsi_remove (&gsi
, true);
5589 /* Connect the new blocks. */
5590 find_edge (entry_bb
, l0_bb
)->flags
= EDGE_TRUE_VALUE
;
5591 find_edge (entry_bb
, l3_bb
)->flags
= EDGE_FALSE_VALUE
;
5597 e
= find_edge (cont_bb
, l3_bb
);
5598 ne
= make_edge (l2_bb
, l3_bb
, EDGE_FALSE_VALUE
);
5600 phis
= phi_nodes (l3_bb
);
5601 for (gsi
= gsi_start (phis
); !gsi_end_p (gsi
); gsi_next (&gsi
))
5603 gimple phi
= gsi_stmt (gsi
);
5604 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, ne
),
5605 PHI_ARG_DEF_FROM_EDGE (phi
, e
));
5609 make_edge (cont_bb
, l2_bb
, EDGE_FALSE_VALUE
);
5611 add_bb_to_loop (l2_bb
, cont_bb
->loop_father
);
5612 e
= find_edge (cont_bb
, l1_bb
);
5613 if (gimple_omp_for_combined_p (fd
->for_stmt
))
5618 else if (fd
->collapse
> 1)
5621 e
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
5624 e
->flags
= EDGE_TRUE_VALUE
;
5627 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
5628 find_edge (cont_bb
, l2_bb
)->probability
= REG_BR_PROB_BASE
/ 8;
5632 e
= find_edge (cont_bb
, l2_bb
);
5633 e
->flags
= EDGE_FALLTHRU
;
5635 make_edge (l2_bb
, l0_bb
, EDGE_TRUE_VALUE
);
5637 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
,
5638 recompute_dominator (CDI_DOMINATORS
, l2_bb
));
5639 set_immediate_dominator (CDI_DOMINATORS
, l3_bb
,
5640 recompute_dominator (CDI_DOMINATORS
, l3_bb
));
5641 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
,
5642 recompute_dominator (CDI_DOMINATORS
, l0_bb
));
5643 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
,
5644 recompute_dominator (CDI_DOMINATORS
, l1_bb
));
5646 struct loop
*outer_loop
= alloc_loop ();
5647 outer_loop
->header
= l0_bb
;
5648 outer_loop
->latch
= l2_bb
;
5649 add_loop (outer_loop
, l0_bb
->loop_father
);
5651 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
5653 struct loop
*loop
= alloc_loop ();
5654 loop
->header
= l1_bb
;
5655 /* The loop may have multiple latches. */
5656 add_loop (loop
, outer_loop
);
5662 /* A subroutine of expand_omp_for. Generate code for a parallel
5663 loop with static schedule and no specified chunk size. Given
5666 for (V = N1; V cond N2; V += STEP) BODY;
5668 where COND is "<" or ">", we generate pseudocode
5670 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
5675 if ((__typeof (V)) -1 > 0 && cond is >)
5676 n = -(adj + N2 - N1) / -STEP;
5678 n = (adj + N2 - N1) / STEP;
5681 if (threadid < tt) goto L3; else goto L4;
5686 s0 = q * threadid + tt;
5689 if (s0 >= e0) goto L2; else goto L0;
5695 if (V cond e) goto L1;
5700 expand_omp_for_static_nochunk (struct omp_region
*region
,
5701 struct omp_for_data
*fd
,
5704 tree n
, q
, s0
, e0
, e
, t
, tt
, nthreads
, threadid
;
5705 tree type
, itype
, vmain
, vback
;
5706 basic_block entry_bb
, second_bb
, third_bb
, exit_bb
, seq_start_bb
;
5707 basic_block body_bb
, cont_bb
, collapse_bb
= NULL
;
5709 gimple_stmt_iterator gsi
;
5712 enum built_in_function get_num_threads
= BUILT_IN_OMP_GET_NUM_THREADS
;
5713 enum built_in_function get_thread_num
= BUILT_IN_OMP_GET_THREAD_NUM
;
5714 bool broken_loop
= region
->cont
== NULL
;
5715 tree
*counts
= NULL
;
5718 itype
= type
= TREE_TYPE (fd
->loop
.v
);
5719 if (POINTER_TYPE_P (type
))
5720 itype
= signed_type_for (type
);
5722 entry_bb
= region
->entry
;
5723 cont_bb
= region
->cont
;
5724 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
5725 fin_bb
= BRANCH_EDGE (entry_bb
)->dest
;
5726 gcc_assert (broken_loop
5727 || (fin_bb
== FALLTHRU_EDGE (cont_bb
)->dest
));
5728 seq_start_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
5729 body_bb
= single_succ (seq_start_bb
);
5732 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
5733 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
5735 exit_bb
= region
->exit
;
5737 /* Iteration space partitioning goes in ENTRY_BB. */
5738 gsi
= gsi_last_bb (entry_bb
);
5739 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
5741 if (gimple_omp_for_kind (fd
->for_stmt
) == GF_OMP_FOR_KIND_DISTRIBUTE
)
5743 get_num_threads
= BUILT_IN_OMP_GET_NUM_TEAMS
;
5744 get_thread_num
= BUILT_IN_OMP_GET_TEAM_NUM
;
5747 if (fd
->collapse
> 1)
5749 int first_zero_iter
= -1;
5750 basic_block l2_dom_bb
= NULL
;
5752 counts
= XALLOCAVEC (tree
, fd
->collapse
);
5753 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
5754 fin_bb
, first_zero_iter
,
5758 else if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
5759 t
= integer_one_node
;
5761 t
= fold_binary (fd
->loop
.cond_code
, boolean_type_node
,
5762 fold_convert (type
, fd
->loop
.n1
),
5763 fold_convert (type
, fd
->loop
.n2
));
5764 if (fd
->collapse
== 1
5765 && TYPE_UNSIGNED (type
)
5766 && (t
== NULL_TREE
|| !integer_onep (t
)))
5768 n1
= fold_convert (type
, unshare_expr (fd
->loop
.n1
));
5769 n1
= force_gimple_operand_gsi (&gsi
, n1
, true, NULL_TREE
,
5770 true, GSI_SAME_STMT
);
5771 n2
= fold_convert (type
, unshare_expr (fd
->loop
.n2
));
5772 n2
= force_gimple_operand_gsi (&gsi
, n2
, true, NULL_TREE
,
5773 true, GSI_SAME_STMT
);
5774 stmt
= gimple_build_cond (fd
->loop
.cond_code
, n1
, n2
,
5775 NULL_TREE
, NULL_TREE
);
5776 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
5777 if (walk_tree (gimple_cond_lhs_ptr (stmt
),
5778 expand_omp_regimplify_p
, NULL
, NULL
)
5779 || walk_tree (gimple_cond_rhs_ptr (stmt
),
5780 expand_omp_regimplify_p
, NULL
, NULL
))
5782 gsi
= gsi_for_stmt (stmt
);
5783 gimple_regimplify_operands (stmt
, &gsi
);
5785 ep
= split_block (entry_bb
, stmt
);
5786 ep
->flags
= EDGE_TRUE_VALUE
;
5787 entry_bb
= ep
->dest
;
5788 ep
->probability
= REG_BR_PROB_BASE
- (REG_BR_PROB_BASE
/ 2000 - 1);
5789 ep
= make_edge (ep
->src
, fin_bb
, EDGE_FALSE_VALUE
);
5790 ep
->probability
= REG_BR_PROB_BASE
/ 2000 - 1;
5791 if (gimple_in_ssa_p (cfun
))
5793 int dest_idx
= find_edge (entry_bb
, fin_bb
)->dest_idx
;
5794 for (gsi
= gsi_start_phis (fin_bb
);
5795 !gsi_end_p (gsi
); gsi_next (&gsi
))
5797 gimple phi
= gsi_stmt (gsi
);
5798 add_phi_arg (phi
, gimple_phi_arg_def (phi
, dest_idx
),
5799 ep
, UNKNOWN_LOCATION
);
5802 gsi
= gsi_last_bb (entry_bb
);
5805 t
= build_call_expr (builtin_decl_explicit (get_num_threads
), 0);
5806 t
= fold_convert (itype
, t
);
5807 nthreads
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5808 true, GSI_SAME_STMT
);
5810 t
= build_call_expr (builtin_decl_explicit (get_thread_num
), 0);
5811 t
= fold_convert (itype
, t
);
5812 threadid
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5813 true, GSI_SAME_STMT
);
5817 step
= fd
->loop
.step
;
5818 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
5820 tree innerc
= find_omp_clause (gimple_omp_for_clauses (fd
->for_stmt
),
5821 OMP_CLAUSE__LOOPTEMP_
);
5822 gcc_assert (innerc
);
5823 n1
= OMP_CLAUSE_DECL (innerc
);
5824 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
5825 OMP_CLAUSE__LOOPTEMP_
);
5826 gcc_assert (innerc
);
5827 n2
= OMP_CLAUSE_DECL (innerc
);
5829 n1
= force_gimple_operand_gsi (&gsi
, fold_convert (type
, n1
),
5830 true, NULL_TREE
, true, GSI_SAME_STMT
);
5831 n2
= force_gimple_operand_gsi (&gsi
, fold_convert (itype
, n2
),
5832 true, NULL_TREE
, true, GSI_SAME_STMT
);
5833 step
= force_gimple_operand_gsi (&gsi
, fold_convert (itype
, step
),
5834 true, NULL_TREE
, true, GSI_SAME_STMT
);
5836 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
5837 t
= fold_build2 (PLUS_EXPR
, itype
, step
, t
);
5838 t
= fold_build2 (PLUS_EXPR
, itype
, t
, n2
);
5839 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, n1
));
5840 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
5841 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
5842 fold_build1 (NEGATE_EXPR
, itype
, t
),
5843 fold_build1 (NEGATE_EXPR
, itype
, step
));
5845 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
5846 t
= fold_convert (itype
, t
);
5847 n
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5849 q
= create_tmp_reg (itype
, "q");
5850 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, n
, nthreads
);
5851 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, true, GSI_SAME_STMT
);
5852 gsi_insert_before (&gsi
, gimple_build_assign (q
, t
), GSI_SAME_STMT
);
5854 tt
= create_tmp_reg (itype
, "tt");
5855 t
= fold_build2 (TRUNC_MOD_EXPR
, itype
, n
, nthreads
);
5856 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, true, GSI_SAME_STMT
);
5857 gsi_insert_before (&gsi
, gimple_build_assign (tt
, t
), GSI_SAME_STMT
);
5859 t
= build2 (LT_EXPR
, boolean_type_node
, threadid
, tt
);
5860 stmt
= gimple_build_cond_empty (t
);
5861 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
5863 second_bb
= split_block (entry_bb
, stmt
)->dest
;
5864 gsi
= gsi_last_bb (second_bb
);
5865 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
5867 gsi_insert_before (&gsi
, gimple_build_assign (tt
, build_int_cst (itype
, 0)),
5869 stmt
= gimple_build_assign_with_ops (PLUS_EXPR
, q
, q
,
5870 build_int_cst (itype
, 1));
5871 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
5873 third_bb
= split_block (second_bb
, stmt
)->dest
;
5874 gsi
= gsi_last_bb (third_bb
);
5875 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
5877 t
= build2 (MULT_EXPR
, itype
, q
, threadid
);
5878 t
= build2 (PLUS_EXPR
, itype
, t
, tt
);
5879 s0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5881 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, q
);
5882 e0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5884 t
= build2 (GE_EXPR
, boolean_type_node
, s0
, e0
);
5885 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
5887 /* Remove the GIMPLE_OMP_FOR statement. */
5888 gsi_remove (&gsi
, true);
5890 /* Setup code for sequential iteration goes in SEQ_START_BB. */
5891 gsi
= gsi_start_bb (seq_start_bb
);
5893 tree startvar
= fd
->loop
.v
;
5894 tree endvar
= NULL_TREE
;
5896 if (gimple_omp_for_combined_p (fd
->for_stmt
))
5898 tree clauses
= gimple_code (inner_stmt
) == GIMPLE_OMP_PARALLEL
5899 ? gimple_omp_parallel_clauses (inner_stmt
)
5900 : gimple_omp_for_clauses (inner_stmt
);
5901 tree innerc
= find_omp_clause (clauses
, OMP_CLAUSE__LOOPTEMP_
);
5902 gcc_assert (innerc
);
5903 startvar
= OMP_CLAUSE_DECL (innerc
);
5904 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
5905 OMP_CLAUSE__LOOPTEMP_
);
5906 gcc_assert (innerc
);
5907 endvar
= OMP_CLAUSE_DECL (innerc
);
5909 t
= fold_convert (itype
, s0
);
5910 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
5911 if (POINTER_TYPE_P (type
))
5912 t
= fold_build_pointer_plus (n1
, t
);
5914 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
5915 t
= fold_convert (TREE_TYPE (startvar
), t
);
5916 t
= force_gimple_operand_gsi (&gsi
, t
,
5918 && TREE_ADDRESSABLE (startvar
),
5919 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
5920 stmt
= gimple_build_assign (startvar
, t
);
5921 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
5923 t
= fold_convert (itype
, e0
);
5924 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
5925 if (POINTER_TYPE_P (type
))
5926 t
= fold_build_pointer_plus (n1
, t
);
5928 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
5929 t
= fold_convert (TREE_TYPE (startvar
), t
);
5930 e
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5931 false, GSI_CONTINUE_LINKING
);
5934 stmt
= gimple_build_assign (endvar
, e
);
5935 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
5937 if (fd
->collapse
> 1)
5938 expand_omp_for_init_vars (fd
, &gsi
, counts
, inner_stmt
, startvar
);
5942 /* The code controlling the sequential loop replaces the
5943 GIMPLE_OMP_CONTINUE. */
5944 gsi
= gsi_last_bb (cont_bb
);
5945 stmt
= gsi_stmt (gsi
);
5946 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
5947 vmain
= gimple_omp_continue_control_use (stmt
);
5948 vback
= gimple_omp_continue_control_def (stmt
);
5950 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
5952 if (POINTER_TYPE_P (type
))
5953 t
= fold_build_pointer_plus (vmain
, step
);
5955 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, step
);
5956 t
= force_gimple_operand_gsi (&gsi
, t
,
5958 && TREE_ADDRESSABLE (vback
),
5959 NULL_TREE
, true, GSI_SAME_STMT
);
5960 stmt
= gimple_build_assign (vback
, t
);
5961 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
5963 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
5964 DECL_P (vback
) && TREE_ADDRESSABLE (vback
)
5966 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
5969 /* Remove the GIMPLE_OMP_CONTINUE statement. */
5970 gsi_remove (&gsi
, true);
5972 if (fd
->collapse
> 1 && !gimple_omp_for_combined_p (fd
->for_stmt
))
5973 collapse_bb
= extract_omp_for_update_vars (fd
, cont_bb
, body_bb
);
5976 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
5977 gsi
= gsi_last_bb (exit_bb
);
5978 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
5980 t
= gimple_omp_return_lhs (gsi_stmt (gsi
));
5981 gsi_insert_after (&gsi
, build_omp_barrier (t
), GSI_SAME_STMT
);
5983 gsi_remove (&gsi
, true);
5985 /* Connect all the blocks. */
5986 ep
= make_edge (entry_bb
, third_bb
, EDGE_FALSE_VALUE
);
5987 ep
->probability
= REG_BR_PROB_BASE
/ 4 * 3;
5988 ep
= find_edge (entry_bb
, second_bb
);
5989 ep
->flags
= EDGE_TRUE_VALUE
;
5990 ep
->probability
= REG_BR_PROB_BASE
/ 4;
5991 find_edge (third_bb
, seq_start_bb
)->flags
= EDGE_FALSE_VALUE
;
5992 find_edge (third_bb
, fin_bb
)->flags
= EDGE_TRUE_VALUE
;
5996 ep
= find_edge (cont_bb
, body_bb
);
5997 if (gimple_omp_for_combined_p (fd
->for_stmt
))
6002 else if (fd
->collapse
> 1)
6005 ep
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
6008 ep
->flags
= EDGE_TRUE_VALUE
;
6009 find_edge (cont_bb
, fin_bb
)->flags
6010 = ep
? EDGE_FALSE_VALUE
: EDGE_FALLTHRU
;
6013 set_immediate_dominator (CDI_DOMINATORS
, second_bb
, entry_bb
);
6014 set_immediate_dominator (CDI_DOMINATORS
, third_bb
, entry_bb
);
6015 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
, third_bb
);
6017 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
6018 recompute_dominator (CDI_DOMINATORS
, body_bb
));
6019 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
6020 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
6022 if (!broken_loop
&& !gimple_omp_for_combined_p (fd
->for_stmt
))
6024 struct loop
*loop
= alloc_loop ();
6025 loop
->header
= body_bb
;
6026 if (collapse_bb
== NULL
)
6027 loop
->latch
= cont_bb
;
6028 add_loop (loop
, body_bb
->loop_father
);
6033 /* A subroutine of expand_omp_for. Generate code for a parallel
6034 loop with static schedule and a specified chunk size. Given
6037 for (V = N1; V cond N2; V += STEP) BODY;
6039 where COND is "<" or ">", we generate pseudocode
6041 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
6046 if ((__typeof (V)) -1 > 0 && cond is >)
6047 n = -(adj + N2 - N1) / -STEP;
6049 n = (adj + N2 - N1) / STEP;
6051 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
6052 here so that V is defined
6053 if the loop is not entered
6055 s0 = (trip * nthreads + threadid) * CHUNK;
6056 e0 = min(s0 + CHUNK, n);
6057 if (s0 < n) goto L1; else goto L4;
6064 if (V cond e) goto L2; else goto L3;
6072 expand_omp_for_static_chunk (struct omp_region
*region
,
6073 struct omp_for_data
*fd
, gimple inner_stmt
)
6075 tree n
, s0
, e0
, e
, t
;
6076 tree trip_var
, trip_init
, trip_main
, trip_back
, nthreads
, threadid
;
6077 tree type
, itype
, v_main
, v_back
, v_extra
;
6078 basic_block entry_bb
, exit_bb
, body_bb
, seq_start_bb
, iter_part_bb
;
6079 basic_block trip_update_bb
= NULL
, cont_bb
, collapse_bb
= NULL
, fin_bb
;
6080 gimple_stmt_iterator si
;
6083 enum built_in_function get_num_threads
= BUILT_IN_OMP_GET_NUM_THREADS
;
6084 enum built_in_function get_thread_num
= BUILT_IN_OMP_GET_THREAD_NUM
;
6085 bool broken_loop
= region
->cont
== NULL
;
6086 tree
*counts
= NULL
;
6089 itype
= type
= TREE_TYPE (fd
->loop
.v
);
6090 if (POINTER_TYPE_P (type
))
6091 itype
= signed_type_for (type
);
6093 entry_bb
= region
->entry
;
6094 se
= split_block (entry_bb
, last_stmt (entry_bb
));
6096 iter_part_bb
= se
->dest
;
6097 cont_bb
= region
->cont
;
6098 gcc_assert (EDGE_COUNT (iter_part_bb
->succs
) == 2);
6099 fin_bb
= BRANCH_EDGE (iter_part_bb
)->dest
;
6100 gcc_assert (broken_loop
6101 || fin_bb
== FALLTHRU_EDGE (cont_bb
)->dest
);
6102 seq_start_bb
= split_edge (FALLTHRU_EDGE (iter_part_bb
));
6103 body_bb
= single_succ (seq_start_bb
);
6106 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
6107 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
6108 trip_update_bb
= split_edge (FALLTHRU_EDGE (cont_bb
));
6110 exit_bb
= region
->exit
;
6112 /* Trip and adjustment setup goes in ENTRY_BB. */
6113 si
= gsi_last_bb (entry_bb
);
6114 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_FOR
);
6116 if (gimple_omp_for_kind (fd
->for_stmt
) == GF_OMP_FOR_KIND_DISTRIBUTE
)
6118 get_num_threads
= BUILT_IN_OMP_GET_NUM_TEAMS
;
6119 get_thread_num
= BUILT_IN_OMP_GET_TEAM_NUM
;
6122 if (fd
->collapse
> 1)
6124 int first_zero_iter
= -1;
6125 basic_block l2_dom_bb
= NULL
;
6127 counts
= XALLOCAVEC (tree
, fd
->collapse
);
6128 expand_omp_for_init_counts (fd
, &si
, entry_bb
, counts
,
6129 fin_bb
, first_zero_iter
,
6133 else if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
6134 t
= integer_one_node
;
6136 t
= fold_binary (fd
->loop
.cond_code
, boolean_type_node
,
6137 fold_convert (type
, fd
->loop
.n1
),
6138 fold_convert (type
, fd
->loop
.n2
));
6139 if (fd
->collapse
== 1
6140 && TYPE_UNSIGNED (type
)
6141 && (t
== NULL_TREE
|| !integer_onep (t
)))
6143 n1
= fold_convert (type
, unshare_expr (fd
->loop
.n1
));
6144 n1
= force_gimple_operand_gsi (&si
, n1
, true, NULL_TREE
,
6145 true, GSI_SAME_STMT
);
6146 n2
= fold_convert (type
, unshare_expr (fd
->loop
.n2
));
6147 n2
= force_gimple_operand_gsi (&si
, n2
, true, NULL_TREE
,
6148 true, GSI_SAME_STMT
);
6149 stmt
= gimple_build_cond (fd
->loop
.cond_code
, n1
, n2
,
6150 NULL_TREE
, NULL_TREE
);
6151 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
6152 if (walk_tree (gimple_cond_lhs_ptr (stmt
),
6153 expand_omp_regimplify_p
, NULL
, NULL
)
6154 || walk_tree (gimple_cond_rhs_ptr (stmt
),
6155 expand_omp_regimplify_p
, NULL
, NULL
))
6157 si
= gsi_for_stmt (stmt
);
6158 gimple_regimplify_operands (stmt
, &si
);
6160 se
= split_block (entry_bb
, stmt
);
6161 se
->flags
= EDGE_TRUE_VALUE
;
6162 entry_bb
= se
->dest
;
6163 se
->probability
= REG_BR_PROB_BASE
- (REG_BR_PROB_BASE
/ 2000 - 1);
6164 se
= make_edge (se
->src
, fin_bb
, EDGE_FALSE_VALUE
);
6165 se
->probability
= REG_BR_PROB_BASE
/ 2000 - 1;
6166 if (gimple_in_ssa_p (cfun
))
6168 int dest_idx
= find_edge (entry_bb
, fin_bb
)->dest_idx
;
6169 for (si
= gsi_start_phis (fin_bb
);
6170 !gsi_end_p (si
); gsi_next (&si
))
6172 gimple phi
= gsi_stmt (si
);
6173 add_phi_arg (phi
, gimple_phi_arg_def (phi
, dest_idx
),
6174 se
, UNKNOWN_LOCATION
);
6177 si
= gsi_last_bb (entry_bb
);
6180 t
= build_call_expr (builtin_decl_explicit (get_num_threads
), 0);
6181 t
= fold_convert (itype
, t
);
6182 nthreads
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
6183 true, GSI_SAME_STMT
);
6185 t
= build_call_expr (builtin_decl_explicit (get_thread_num
), 0);
6186 t
= fold_convert (itype
, t
);
6187 threadid
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
6188 true, GSI_SAME_STMT
);
6192 step
= fd
->loop
.step
;
6193 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
6195 tree innerc
= find_omp_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6196 OMP_CLAUSE__LOOPTEMP_
);
6197 gcc_assert (innerc
);
6198 n1
= OMP_CLAUSE_DECL (innerc
);
6199 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
6200 OMP_CLAUSE__LOOPTEMP_
);
6201 gcc_assert (innerc
);
6202 n2
= OMP_CLAUSE_DECL (innerc
);
6204 n1
= force_gimple_operand_gsi (&si
, fold_convert (type
, n1
),
6205 true, NULL_TREE
, true, GSI_SAME_STMT
);
6206 n2
= force_gimple_operand_gsi (&si
, fold_convert (itype
, n2
),
6207 true, NULL_TREE
, true, GSI_SAME_STMT
);
6208 step
= force_gimple_operand_gsi (&si
, fold_convert (itype
, step
),
6209 true, NULL_TREE
, true, GSI_SAME_STMT
);
6211 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->chunk_size
),
6212 true, NULL_TREE
, true, GSI_SAME_STMT
);
6214 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
6215 t
= fold_build2 (PLUS_EXPR
, itype
, step
, t
);
6216 t
= fold_build2 (PLUS_EXPR
, itype
, t
, n2
);
6217 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, n1
));
6218 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
6219 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
6220 fold_build1 (NEGATE_EXPR
, itype
, t
),
6221 fold_build1 (NEGATE_EXPR
, itype
, step
));
6223 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
6224 t
= fold_convert (itype
, t
);
6225 n
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
6226 true, GSI_SAME_STMT
);
6228 trip_var
= create_tmp_reg (itype
, ".trip");
6229 if (gimple_in_ssa_p (cfun
))
6231 trip_init
= make_ssa_name (trip_var
, NULL
);
6232 trip_main
= make_ssa_name (trip_var
, NULL
);
6233 trip_back
= make_ssa_name (trip_var
, NULL
);
6237 trip_init
= trip_var
;
6238 trip_main
= trip_var
;
6239 trip_back
= trip_var
;
6242 stmt
= gimple_build_assign (trip_init
, build_int_cst (itype
, 0));
6243 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
6245 t
= fold_build2 (MULT_EXPR
, itype
, threadid
, fd
->chunk_size
);
6246 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
6247 if (POINTER_TYPE_P (type
))
6248 t
= fold_build_pointer_plus (n1
, t
);
6250 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
6251 v_extra
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
6252 true, GSI_SAME_STMT
);
6254 /* Remove the GIMPLE_OMP_FOR. */
6255 gsi_remove (&si
, true);
6257 /* Iteration space partitioning goes in ITER_PART_BB. */
6258 si
= gsi_last_bb (iter_part_bb
);
6260 t
= fold_build2 (MULT_EXPR
, itype
, trip_main
, nthreads
);
6261 t
= fold_build2 (PLUS_EXPR
, itype
, t
, threadid
);
6262 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->chunk_size
);
6263 s0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
6264 false, GSI_CONTINUE_LINKING
);
6266 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, fd
->chunk_size
);
6267 t
= fold_build2 (MIN_EXPR
, itype
, t
, n
);
6268 e0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
6269 false, GSI_CONTINUE_LINKING
);
6271 t
= build2 (LT_EXPR
, boolean_type_node
, s0
, n
);
6272 gsi_insert_after (&si
, gimple_build_cond_empty (t
), GSI_CONTINUE_LINKING
);
6274 /* Setup code for sequential iteration goes in SEQ_START_BB. */
6275 si
= gsi_start_bb (seq_start_bb
);
6277 tree startvar
= fd
->loop
.v
;
6278 tree endvar
= NULL_TREE
;
6280 if (gimple_omp_for_combined_p (fd
->for_stmt
))
6282 tree clauses
= gimple_code (inner_stmt
) == GIMPLE_OMP_PARALLEL
6283 ? gimple_omp_parallel_clauses (inner_stmt
)
6284 : gimple_omp_for_clauses (inner_stmt
);
6285 tree innerc
= find_omp_clause (clauses
, OMP_CLAUSE__LOOPTEMP_
);
6286 gcc_assert (innerc
);
6287 startvar
= OMP_CLAUSE_DECL (innerc
);
6288 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
6289 OMP_CLAUSE__LOOPTEMP_
);
6290 gcc_assert (innerc
);
6291 endvar
= OMP_CLAUSE_DECL (innerc
);
6294 t
= fold_convert (itype
, s0
);
6295 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
6296 if (POINTER_TYPE_P (type
))
6297 t
= fold_build_pointer_plus (n1
, t
);
6299 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
6300 t
= fold_convert (TREE_TYPE (startvar
), t
);
6301 t
= force_gimple_operand_gsi (&si
, t
,
6303 && TREE_ADDRESSABLE (startvar
),
6304 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
6305 stmt
= gimple_build_assign (startvar
, t
);
6306 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
6308 t
= fold_convert (itype
, e0
);
6309 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
6310 if (POINTER_TYPE_P (type
))
6311 t
= fold_build_pointer_plus (n1
, t
);
6313 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
6314 t
= fold_convert (TREE_TYPE (startvar
), t
);
6315 e
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
6316 false, GSI_CONTINUE_LINKING
);
6319 stmt
= gimple_build_assign (endvar
, e
);
6320 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
6322 if (fd
->collapse
> 1)
6323 expand_omp_for_init_vars (fd
, &si
, counts
, inner_stmt
, startvar
);
6327 /* The code controlling the sequential loop goes in CONT_BB,
6328 replacing the GIMPLE_OMP_CONTINUE. */
6329 si
= gsi_last_bb (cont_bb
);
6330 stmt
= gsi_stmt (si
);
6331 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
6332 v_main
= gimple_omp_continue_control_use (stmt
);
6333 v_back
= gimple_omp_continue_control_def (stmt
);
6335 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
6337 if (POINTER_TYPE_P (type
))
6338 t
= fold_build_pointer_plus (v_main
, step
);
6340 t
= fold_build2 (PLUS_EXPR
, type
, v_main
, step
);
6341 if (DECL_P (v_back
) && TREE_ADDRESSABLE (v_back
))
6342 t
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
6343 true, GSI_SAME_STMT
);
6344 stmt
= gimple_build_assign (v_back
, t
);
6345 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
6347 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
6348 DECL_P (v_back
) && TREE_ADDRESSABLE (v_back
)
6350 gsi_insert_before (&si
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
6353 /* Remove GIMPLE_OMP_CONTINUE. */
6354 gsi_remove (&si
, true);
6356 if (fd
->collapse
> 1 && !gimple_omp_for_combined_p (fd
->for_stmt
))
6357 collapse_bb
= extract_omp_for_update_vars (fd
, cont_bb
, body_bb
);
6359 /* Trip update code goes into TRIP_UPDATE_BB. */
6360 si
= gsi_start_bb (trip_update_bb
);
6362 t
= build_int_cst (itype
, 1);
6363 t
= build2 (PLUS_EXPR
, itype
, trip_main
, t
);
6364 stmt
= gimple_build_assign (trip_back
, t
);
6365 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
6368 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
6369 si
= gsi_last_bb (exit_bb
);
6370 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)))
6372 t
= gimple_omp_return_lhs (gsi_stmt (si
));
6373 gsi_insert_after (&si
, build_omp_barrier (t
), GSI_SAME_STMT
);
6375 gsi_remove (&si
, true);
6377 /* Connect the new blocks. */
6378 find_edge (iter_part_bb
, seq_start_bb
)->flags
= EDGE_TRUE_VALUE
;
6379 find_edge (iter_part_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
6383 se
= find_edge (cont_bb
, body_bb
);
6384 if (gimple_omp_for_combined_p (fd
->for_stmt
))
6389 else if (fd
->collapse
> 1)
6392 se
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
6395 se
->flags
= EDGE_TRUE_VALUE
;
6396 find_edge (cont_bb
, trip_update_bb
)->flags
6397 = se
? EDGE_FALSE_VALUE
: EDGE_FALLTHRU
;
6399 redirect_edge_and_branch (single_succ_edge (trip_update_bb
), iter_part_bb
);
6402 if (gimple_in_ssa_p (cfun
))
6404 gimple_stmt_iterator psi
;
6407 edge_var_map_vector
*head
;
6411 gcc_assert (fd
->collapse
== 1 && !broken_loop
);
6413 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
6414 remove arguments of the phi nodes in fin_bb. We need to create
6415 appropriate phi nodes in iter_part_bb instead. */
6416 se
= single_pred_edge (fin_bb
);
6417 re
= single_succ_edge (trip_update_bb
);
6418 head
= redirect_edge_var_map_vector (re
);
6419 ene
= single_succ_edge (entry_bb
);
6421 psi
= gsi_start_phis (fin_bb
);
6422 for (i
= 0; !gsi_end_p (psi
) && head
->iterate (i
, &vm
);
6423 gsi_next (&psi
), ++i
)
6426 source_location locus
;
6428 phi
= gsi_stmt (psi
);
6429 t
= gimple_phi_result (phi
);
6430 gcc_assert (t
== redirect_edge_var_map_result (vm
));
6431 nphi
= create_phi_node (t
, iter_part_bb
);
6433 t
= PHI_ARG_DEF_FROM_EDGE (phi
, se
);
6434 locus
= gimple_phi_arg_location_from_edge (phi
, se
);
6436 /* A special case -- fd->loop.v is not yet computed in
6437 iter_part_bb, we need to use v_extra instead. */
6438 if (t
== fd
->loop
.v
)
6440 add_phi_arg (nphi
, t
, ene
, locus
);
6441 locus
= redirect_edge_var_map_location (vm
);
6442 add_phi_arg (nphi
, redirect_edge_var_map_def (vm
), re
, locus
);
6444 gcc_assert (!gsi_end_p (psi
) && i
== head
->length ());
6445 redirect_edge_var_map_clear (re
);
6448 psi
= gsi_start_phis (fin_bb
);
6449 if (gsi_end_p (psi
))
6451 remove_phi_node (&psi
, false);
6454 /* Make phi node for trip. */
6455 phi
= create_phi_node (trip_main
, iter_part_bb
);
6456 add_phi_arg (phi
, trip_back
, single_succ_edge (trip_update_bb
),
6458 add_phi_arg (phi
, trip_init
, single_succ_edge (entry_bb
),
6463 set_immediate_dominator (CDI_DOMINATORS
, trip_update_bb
, cont_bb
);
6464 set_immediate_dominator (CDI_DOMINATORS
, iter_part_bb
,
6465 recompute_dominator (CDI_DOMINATORS
, iter_part_bb
));
6466 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
6467 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
6468 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
,
6469 recompute_dominator (CDI_DOMINATORS
, seq_start_bb
));
6470 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
6471 recompute_dominator (CDI_DOMINATORS
, body_bb
));
6475 struct loop
*trip_loop
= alloc_loop ();
6476 trip_loop
->header
= iter_part_bb
;
6477 trip_loop
->latch
= trip_update_bb
;
6478 add_loop (trip_loop
, iter_part_bb
->loop_father
);
6480 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
6482 struct loop
*loop
= alloc_loop ();
6483 loop
->header
= body_bb
;
6484 loop
->latch
= cont_bb
;
6485 add_loop (loop
, trip_loop
);
6491 /* A subroutine of expand_omp_for. Generate code for a simd non-worksharing
6492 loop. Given parameters:
6494 for (V = N1; V cond N2; V += STEP) BODY;
6496 where COND is "<" or ">", we generate pseudocode
6504 if (V cond N2) goto L0; else goto L2;
6507 For collapsed loops, given parameters:
6509 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
6510 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
6511 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
6514 we generate pseudocode
6520 count3 = (adj + N32 - N31) / STEP3;
6525 count2 = (adj + N22 - N21) / STEP2;
6530 count1 = (adj + N12 - N11) / STEP1;
6531 count = count1 * count2 * count3;
6541 V2 += (V3 cond3 N32) ? 0 : STEP2;
6542 V3 = (V3 cond3 N32) ? V3 : N31;
6543 V1 += (V2 cond2 N22) ? 0 : STEP1;
6544 V2 = (V2 cond2 N22) ? V2 : N21;
6546 if (V < count) goto L0; else goto L2;
6552 expand_omp_simd (struct omp_region
*region
, struct omp_for_data
*fd
)
6555 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
, l2_bb
, l2_dom_bb
;
6556 gimple_stmt_iterator gsi
;
6558 bool broken_loop
= region
->cont
== NULL
;
6560 tree
*counts
= NULL
;
6562 tree safelen
= find_omp_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6563 OMP_CLAUSE_SAFELEN
);
6564 tree simduid
= find_omp_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6565 OMP_CLAUSE__SIMDUID_
);
6568 type
= TREE_TYPE (fd
->loop
.v
);
6569 entry_bb
= region
->entry
;
6570 cont_bb
= region
->cont
;
6571 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
6572 gcc_assert (broken_loop
6573 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
6574 l0_bb
= FALLTHRU_EDGE (entry_bb
)->dest
;
6577 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l0_bb
);
6578 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
6579 l1_bb
= split_block (cont_bb
, last_stmt (cont_bb
))->dest
;
6580 l2_bb
= BRANCH_EDGE (entry_bb
)->dest
;
6584 BRANCH_EDGE (entry_bb
)->flags
&= ~EDGE_ABNORMAL
;
6585 l1_bb
= split_edge (BRANCH_EDGE (entry_bb
));
6586 l2_bb
= single_succ (l1_bb
);
6588 exit_bb
= region
->exit
;
6591 gsi
= gsi_last_bb (entry_bb
);
6593 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
6594 /* Not needed in SSA form right now. */
6595 gcc_assert (!gimple_in_ssa_p (cfun
));
6596 if (fd
->collapse
> 1)
6598 int first_zero_iter
= -1;
6599 basic_block zero_iter_bb
= l2_bb
;
6601 counts
= XALLOCAVEC (tree
, fd
->collapse
);
6602 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
6603 zero_iter_bb
, first_zero_iter
,
6606 if (l2_dom_bb
== NULL
)
6611 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
6613 tree innerc
= find_omp_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6614 OMP_CLAUSE__LOOPTEMP_
);
6615 gcc_assert (innerc
);
6616 n1
= OMP_CLAUSE_DECL (innerc
);
6617 innerc
= find_omp_clause (OMP_CLAUSE_CHAIN (innerc
),
6618 OMP_CLAUSE__LOOPTEMP_
);
6619 gcc_assert (innerc
);
6620 n2
= OMP_CLAUSE_DECL (innerc
);
6621 expand_omp_build_assign (&gsi
, fd
->loop
.v
,
6622 fold_convert (type
, n1
));
6623 if (fd
->collapse
> 1)
6626 expand_omp_for_init_vars (fd
, &gsi
, counts
, NULL
, n1
);
6632 expand_omp_build_assign (&gsi
, fd
->loop
.v
,
6633 fold_convert (type
, fd
->loop
.n1
));
6634 if (fd
->collapse
> 1)
6635 for (i
= 0; i
< fd
->collapse
; i
++)
6637 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
6638 if (POINTER_TYPE_P (itype
))
6639 itype
= signed_type_for (itype
);
6640 t
= fold_convert (TREE_TYPE (fd
->loops
[i
].v
), fd
->loops
[i
].n1
);
6641 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
, t
);
6645 /* Remove the GIMPLE_OMP_FOR statement. */
6646 gsi_remove (&gsi
, true);
6650 /* Code to control the increment goes in the CONT_BB. */
6651 gsi
= gsi_last_bb (cont_bb
);
6652 stmt
= gsi_stmt (gsi
);
6653 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
6655 if (POINTER_TYPE_P (type
))
6656 t
= fold_build_pointer_plus (fd
->loop
.v
, fd
->loop
.step
);
6658 t
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.v
, fd
->loop
.step
);
6659 expand_omp_build_assign (&gsi
, fd
->loop
.v
, t
);
6661 if (fd
->collapse
> 1)
6663 i
= fd
->collapse
- 1;
6664 if (POINTER_TYPE_P (TREE_TYPE (fd
->loops
[i
].v
)))
6666 t
= fold_convert (sizetype
, fd
->loops
[i
].step
);
6667 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, t
);
6671 t
= fold_convert (TREE_TYPE (fd
->loops
[i
].v
),
6673 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (fd
->loops
[i
].v
),
6676 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
, t
);
6678 for (i
= fd
->collapse
- 1; i
> 0; i
--)
6680 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
6681 tree itype2
= TREE_TYPE (fd
->loops
[i
- 1].v
);
6682 if (POINTER_TYPE_P (itype2
))
6683 itype2
= signed_type_for (itype2
);
6684 t
= build3 (COND_EXPR
, itype2
,
6685 build2 (fd
->loops
[i
].cond_code
, boolean_type_node
,
6687 fold_convert (itype
, fd
->loops
[i
].n2
)),
6688 build_int_cst (itype2
, 0),
6689 fold_convert (itype2
, fd
->loops
[i
- 1].step
));
6690 if (POINTER_TYPE_P (TREE_TYPE (fd
->loops
[i
- 1].v
)))
6691 t
= fold_build_pointer_plus (fd
->loops
[i
- 1].v
, t
);
6693 t
= fold_build2 (PLUS_EXPR
, itype2
, fd
->loops
[i
- 1].v
, t
);
6694 expand_omp_build_assign (&gsi
, fd
->loops
[i
- 1].v
, t
);
6696 t
= build3 (COND_EXPR
, itype
,
6697 build2 (fd
->loops
[i
].cond_code
, boolean_type_node
,
6699 fold_convert (itype
, fd
->loops
[i
].n2
)),
6701 fold_convert (itype
, fd
->loops
[i
].n1
));
6702 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
, t
);
6706 /* Remove GIMPLE_OMP_CONTINUE. */
6707 gsi_remove (&gsi
, true);
6710 /* Emit the condition in L1_BB. */
6711 gsi
= gsi_start_bb (l1_bb
);
6713 t
= fold_convert (type
, n2
);
6714 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6715 false, GSI_CONTINUE_LINKING
);
6716 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, fd
->loop
.v
, t
);
6717 stmt
= gimple_build_cond_empty (t
);
6718 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
6719 if (walk_tree (gimple_cond_lhs_ptr (stmt
), expand_omp_regimplify_p
,
6721 || walk_tree (gimple_cond_rhs_ptr (stmt
), expand_omp_regimplify_p
,
6724 gsi
= gsi_for_stmt (stmt
);
6725 gimple_regimplify_operands (stmt
, &gsi
);
6728 /* Remove GIMPLE_OMP_RETURN. */
6729 gsi
= gsi_last_bb (exit_bb
);
6730 gsi_remove (&gsi
, true);
6732 /* Connect the new blocks. */
6733 remove_edge (FALLTHRU_EDGE (entry_bb
));
6737 remove_edge (BRANCH_EDGE (entry_bb
));
6738 make_edge (entry_bb
, l1_bb
, EDGE_FALLTHRU
);
6740 e
= BRANCH_EDGE (l1_bb
);
6741 ne
= FALLTHRU_EDGE (l1_bb
);
6742 e
->flags
= EDGE_TRUE_VALUE
;
6746 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
6748 ne
= single_succ_edge (l1_bb
);
6749 e
= make_edge (l1_bb
, l0_bb
, EDGE_TRUE_VALUE
);
6752 ne
->flags
= EDGE_FALSE_VALUE
;
6753 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
6754 ne
->probability
= REG_BR_PROB_BASE
/ 8;
6756 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
, entry_bb
);
6757 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
, l2_dom_bb
);
6758 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
, l1_bb
);
6762 struct loop
*loop
= alloc_loop ();
6763 loop
->header
= l1_bb
;
6764 loop
->latch
= e
->dest
;
6765 add_loop (loop
, l1_bb
->loop_father
);
6766 if (safelen
== NULL_TREE
)
6767 loop
->safelen
= INT_MAX
;
6770 safelen
= OMP_CLAUSE_SAFELEN_EXPR (safelen
);
6771 if (!host_integerp (safelen
, 1)
6772 || (unsigned HOST_WIDE_INT
) tree_low_cst (safelen
, 1)
6774 loop
->safelen
= INT_MAX
;
6776 loop
->safelen
= tree_low_cst (safelen
, 1);
6777 if (loop
->safelen
== 1)
6782 loop
->simduid
= OMP_CLAUSE__SIMDUID__DECL (simduid
);
6783 cfun
->has_simduid_loops
= true;
6785 /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
6787 if ((flag_tree_loop_vectorize
6788 || (!global_options_set
.x_flag_tree_loop_vectorize
6789 && !global_options_set
.x_flag_tree_vectorize
))
6790 && loop
->safelen
> 1)
6792 loop
->force_vect
= true;
6793 cfun
->has_force_vect_loops
= true;
6799 /* Expand the OpenMP loop defined by REGION. */
6802 expand_omp_for (struct omp_region
*region
, gimple inner_stmt
)
6804 struct omp_for_data fd
;
6805 struct omp_for_data_loop
*loops
;
6808 = (struct omp_for_data_loop
*)
6809 alloca (gimple_omp_for_collapse (last_stmt (region
->entry
))
6810 * sizeof (struct omp_for_data_loop
));
6811 extract_omp_for_data (last_stmt (region
->entry
), &fd
, loops
);
6812 region
->sched_kind
= fd
.sched_kind
;
6814 gcc_assert (EDGE_COUNT (region
->entry
->succs
) == 2);
6815 BRANCH_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
6816 FALLTHRU_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
6819 gcc_assert (EDGE_COUNT (region
->cont
->succs
) == 2);
6820 BRANCH_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
6821 FALLTHRU_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
6824 /* If there isn't a continue then this is a degerate case where
6825 the introduction of abnormal edges during lowering will prevent
6826 original loops from being detected. Fix that up. */
6827 loops_state_set (LOOPS_NEED_FIXUP
);
6829 if (gimple_omp_for_kind (fd
.for_stmt
) & GF_OMP_FOR_KIND_SIMD
)
6830 expand_omp_simd (region
, &fd
);
6831 else if (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
6832 && !fd
.have_ordered
)
6834 if (fd
.chunk_size
== NULL
)
6835 expand_omp_for_static_nochunk (region
, &fd
, inner_stmt
);
6837 expand_omp_for_static_chunk (region
, &fd
, inner_stmt
);
6841 int fn_index
, start_ix
, next_ix
;
6843 gcc_assert (gimple_omp_for_kind (fd
.for_stmt
)
6844 == GF_OMP_FOR_KIND_FOR
);
6845 if (fd
.chunk_size
== NULL
6846 && fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
6847 fd
.chunk_size
= integer_zero_node
;
6848 gcc_assert (fd
.sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
6849 fn_index
= (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
6850 ? 3 : fd
.sched_kind
;
6851 fn_index
+= fd
.have_ordered
* 4;
6852 start_ix
= ((int)BUILT_IN_GOMP_LOOP_STATIC_START
) + fn_index
;
6853 next_ix
= ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT
) + fn_index
;
6854 if (fd
.iter_type
== long_long_unsigned_type_node
)
6856 start_ix
+= ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
6857 - (int)BUILT_IN_GOMP_LOOP_STATIC_START
);
6858 next_ix
+= ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
6859 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT
);
6861 expand_omp_for_generic (region
, &fd
, (enum built_in_function
) start_ix
,
6862 (enum built_in_function
) next_ix
, inner_stmt
);
6865 if (gimple_in_ssa_p (cfun
))
6866 update_ssa (TODO_update_ssa_only_virtuals
);
6870 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
6872 v = GOMP_sections_start (n);
6889 v = GOMP_sections_next ();
6894 If this is a combined parallel sections, replace the call to
6895 GOMP_sections_start with call to GOMP_sections_next. */
6898 expand_omp_sections (struct omp_region
*region
)
6900 tree t
, u
, vin
= NULL
, vmain
, vnext
, l2
;
6901 vec
<tree
> label_vec
;
6903 basic_block entry_bb
, l0_bb
, l1_bb
, l2_bb
, default_bb
;
6904 gimple_stmt_iterator si
, switch_si
;
6905 gimple sections_stmt
, stmt
, cont
;
6908 struct omp_region
*inner
;
6910 bool exit_reachable
= region
->cont
!= NULL
;
6912 gcc_assert (region
->exit
!= NULL
);
6913 entry_bb
= region
->entry
;
6914 l0_bb
= single_succ (entry_bb
);
6915 l1_bb
= region
->cont
;
6916 l2_bb
= region
->exit
;
6917 if (single_pred_p (l2_bb
) && single_pred (l2_bb
) == l0_bb
)
6918 l2
= gimple_block_label (l2_bb
);
6921 /* This can happen if there are reductions. */
6922 len
= EDGE_COUNT (l0_bb
->succs
);
6923 gcc_assert (len
> 0);
6924 e
= EDGE_SUCC (l0_bb
, len
- 1);
6925 si
= gsi_last_bb (e
->dest
);
6928 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
6929 l2
= gimple_block_label (e
->dest
);
6931 FOR_EACH_EDGE (e
, ei
, l0_bb
->succs
)
6933 si
= gsi_last_bb (e
->dest
);
6935 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
6937 l2
= gimple_block_label (e
->dest
);
6943 default_bb
= create_empty_bb (l1_bb
->prev_bb
);
6945 default_bb
= create_empty_bb (l0_bb
);
6947 /* We will build a switch() with enough cases for all the
6948 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
6949 and a default case to abort if something goes wrong. */
6950 len
= EDGE_COUNT (l0_bb
->succs
);
6952 /* Use vec::quick_push on label_vec throughout, since we know the size
6954 label_vec
.create (len
);
6956 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
6957 GIMPLE_OMP_SECTIONS statement. */
6958 si
= gsi_last_bb (entry_bb
);
6959 sections_stmt
= gsi_stmt (si
);
6960 gcc_assert (gimple_code (sections_stmt
) == GIMPLE_OMP_SECTIONS
);
6961 vin
= gimple_omp_sections_control (sections_stmt
);
6962 if (!is_combined_parallel (region
))
6964 /* If we are not inside a combined parallel+sections region,
6965 call GOMP_sections_start. */
6966 t
= build_int_cst (unsigned_type_node
, len
- 1);
6967 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START
);
6968 stmt
= gimple_build_call (u
, 1, t
);
6972 /* Otherwise, call GOMP_sections_next. */
6973 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT
);
6974 stmt
= gimple_build_call (u
, 0);
6976 gimple_call_set_lhs (stmt
, vin
);
6977 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
6978 gsi_remove (&si
, true);
6980 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
6982 switch_si
= gsi_last_bb (l0_bb
);
6983 gcc_assert (gimple_code (gsi_stmt (switch_si
)) == GIMPLE_OMP_SECTIONS_SWITCH
);
6986 cont
= last_stmt (l1_bb
);
6987 gcc_assert (gimple_code (cont
) == GIMPLE_OMP_CONTINUE
);
6988 vmain
= gimple_omp_continue_control_use (cont
);
6989 vnext
= gimple_omp_continue_control_def (cont
);
6997 t
= build_case_label (build_int_cst (unsigned_type_node
, 0), NULL
, l2
);
6998 label_vec
.quick_push (t
);
7001 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
7002 for (inner
= region
->inner
, casei
= 1;
7004 inner
= inner
->next
, i
++, casei
++)
7006 basic_block s_entry_bb
, s_exit_bb
;
7008 /* Skip optional reduction region. */
7009 if (inner
->type
== GIMPLE_OMP_ATOMIC_LOAD
)
7016 s_entry_bb
= inner
->entry
;
7017 s_exit_bb
= inner
->exit
;
7019 t
= gimple_block_label (s_entry_bb
);
7020 u
= build_int_cst (unsigned_type_node
, casei
);
7021 u
= build_case_label (u
, NULL
, t
);
7022 label_vec
.quick_push (u
);
7024 si
= gsi_last_bb (s_entry_bb
);
7025 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SECTION
);
7026 gcc_assert (i
< len
|| gimple_omp_section_last_p (gsi_stmt (si
)));
7027 gsi_remove (&si
, true);
7028 single_succ_edge (s_entry_bb
)->flags
= EDGE_FALLTHRU
;
7030 if (s_exit_bb
== NULL
)
7033 si
= gsi_last_bb (s_exit_bb
);
7034 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
7035 gsi_remove (&si
, true);
7037 single_succ_edge (s_exit_bb
)->flags
= EDGE_FALLTHRU
;
7040 /* Error handling code goes in DEFAULT_BB. */
7041 t
= gimple_block_label (default_bb
);
7042 u
= build_case_label (NULL
, NULL
, t
);
7043 make_edge (l0_bb
, default_bb
, 0);
7045 add_bb_to_loop (default_bb
, current_loops
->tree_root
);
7047 stmt
= gimple_build_switch (vmain
, u
, label_vec
);
7048 gsi_insert_after (&switch_si
, stmt
, GSI_SAME_STMT
);
7049 gsi_remove (&switch_si
, true);
7050 label_vec
.release ();
7052 si
= gsi_start_bb (default_bb
);
7053 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
7054 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
7060 /* Code to get the next section goes in L1_BB. */
7061 si
= gsi_last_bb (l1_bb
);
7062 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CONTINUE
);
7064 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT
);
7065 stmt
= gimple_build_call (bfn_decl
, 0);
7066 gimple_call_set_lhs (stmt
, vnext
);
7067 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
7068 gsi_remove (&si
, true);
7070 single_succ_edge (l1_bb
)->flags
= EDGE_FALLTHRU
;
7073 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
7074 si
= gsi_last_bb (l2_bb
);
7075 if (gimple_omp_return_nowait_p (gsi_stmt (si
)))
7076 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT
);
7077 else if (gimple_omp_return_lhs (gsi_stmt (si
)))
7078 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_CANCEL
);
7080 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END
);
7081 stmt
= gimple_build_call (t
, 0);
7082 if (gimple_omp_return_lhs (gsi_stmt (si
)))
7083 gimple_call_set_lhs (stmt
, gimple_omp_return_lhs (gsi_stmt (si
)));
7084 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
7085 gsi_remove (&si
, true);
7087 set_immediate_dominator (CDI_DOMINATORS
, default_bb
, l0_bb
);
7091 /* Expand code for an OpenMP single directive. We've already expanded
7092 much of the code, here we simply place the GOMP_barrier call. */
7095 expand_omp_single (struct omp_region
*region
)
7097 basic_block entry_bb
, exit_bb
;
7098 gimple_stmt_iterator si
;
7100 entry_bb
= region
->entry
;
7101 exit_bb
= region
->exit
;
7103 si
= gsi_last_bb (entry_bb
);
7104 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
);
7105 gsi_remove (&si
, true);
7106 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
7108 si
= gsi_last_bb (exit_bb
);
7109 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)))
7111 tree t
= gimple_omp_return_lhs (gsi_stmt (si
));
7112 gsi_insert_after (&si
, build_omp_barrier (t
), GSI_SAME_STMT
);
7114 gsi_remove (&si
, true);
7115 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
7119 /* Generic expansion for OpenMP synchronization directives: master,
7120 ordered and critical. All we need to do here is remove the entry
7121 and exit markers for REGION. */
7124 expand_omp_synch (struct omp_region
*region
)
7126 basic_block entry_bb
, exit_bb
;
7127 gimple_stmt_iterator si
;
7129 entry_bb
= region
->entry
;
7130 exit_bb
= region
->exit
;
7132 si
= gsi_last_bb (entry_bb
);
7133 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
7134 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_MASTER
7135 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_TASKGROUP
7136 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ORDERED
7137 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CRITICAL
7138 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_TEAMS
);
7139 gsi_remove (&si
, true);
7140 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
7144 si
= gsi_last_bb (exit_bb
);
7145 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
7146 gsi_remove (&si
, true);
7147 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
7151 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
7152 operation as a normal volatile load. */
7155 expand_omp_atomic_load (basic_block load_bb
, tree addr
,
7156 tree loaded_val
, int index
)
7158 enum built_in_function tmpbase
;
7159 gimple_stmt_iterator gsi
;
7160 basic_block store_bb
;
7163 tree decl
, call
, type
, itype
;
7165 gsi
= gsi_last_bb (load_bb
);
7166 stmt
= gsi_stmt (gsi
);
7167 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_LOAD
);
7168 loc
= gimple_location (stmt
);
7170 /* ??? If the target does not implement atomic_load_optab[mode], and mode
7171 is smaller than word size, then expand_atomic_load assumes that the load
7172 is atomic. We could avoid the builtin entirely in this case. */
7174 tmpbase
= (enum built_in_function
) (BUILT_IN_ATOMIC_LOAD_N
+ index
+ 1);
7175 decl
= builtin_decl_explicit (tmpbase
);
7176 if (decl
== NULL_TREE
)
7179 type
= TREE_TYPE (loaded_val
);
7180 itype
= TREE_TYPE (TREE_TYPE (decl
));
7182 call
= build_call_expr_loc (loc
, decl
, 2, addr
,
7183 build_int_cst (NULL
,
7184 gimple_omp_atomic_seq_cst_p (stmt
)
7186 : MEMMODEL_RELAXED
));
7187 if (!useless_type_conversion_p (type
, itype
))
7188 call
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, type
, call
);
7189 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, loaded_val
, call
);
7191 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
7192 gsi_remove (&gsi
, true);
7194 store_bb
= single_succ (load_bb
);
7195 gsi
= gsi_last_bb (store_bb
);
7196 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
7197 gsi_remove (&gsi
, true);
7199 if (gimple_in_ssa_p (cfun
))
7200 update_ssa (TODO_update_ssa_no_phi
);
7205 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
7206 operation as a normal volatile store. */
7209 expand_omp_atomic_store (basic_block load_bb
, tree addr
,
7210 tree loaded_val
, tree stored_val
, int index
)
7212 enum built_in_function tmpbase
;
7213 gimple_stmt_iterator gsi
;
7214 basic_block store_bb
= single_succ (load_bb
);
7217 tree decl
, call
, type
, itype
;
7218 enum machine_mode imode
;
7221 gsi
= gsi_last_bb (load_bb
);
7222 stmt
= gsi_stmt (gsi
);
7223 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_LOAD
);
7225 /* If the load value is needed, then this isn't a store but an exchange. */
7226 exchange
= gimple_omp_atomic_need_value_p (stmt
);
7228 gsi
= gsi_last_bb (store_bb
);
7229 stmt
= gsi_stmt (gsi
);
7230 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_STORE
);
7231 loc
= gimple_location (stmt
);
7233 /* ??? If the target does not implement atomic_store_optab[mode], and mode
7234 is smaller than word size, then expand_atomic_store assumes that the store
7235 is atomic. We could avoid the builtin entirely in this case. */
7237 tmpbase
= (exchange
? BUILT_IN_ATOMIC_EXCHANGE_N
: BUILT_IN_ATOMIC_STORE_N
);
7238 tmpbase
= (enum built_in_function
) ((int) tmpbase
+ index
+ 1);
7239 decl
= builtin_decl_explicit (tmpbase
);
7240 if (decl
== NULL_TREE
)
7243 type
= TREE_TYPE (stored_val
);
7245 /* Dig out the type of the function's second argument. */
7246 itype
= TREE_TYPE (decl
);
7247 itype
= TYPE_ARG_TYPES (itype
);
7248 itype
= TREE_CHAIN (itype
);
7249 itype
= TREE_VALUE (itype
);
7250 imode
= TYPE_MODE (itype
);
7252 if (exchange
&& !can_atomic_exchange_p (imode
, true))
7255 if (!useless_type_conversion_p (itype
, type
))
7256 stored_val
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, itype
, stored_val
);
7257 call
= build_call_expr_loc (loc
, decl
, 3, addr
, stored_val
,
7258 build_int_cst (NULL
,
7259 gimple_omp_atomic_seq_cst_p (stmt
)
7261 : MEMMODEL_RELAXED
));
7264 if (!useless_type_conversion_p (type
, itype
))
7265 call
= build1_loc (loc
, VIEW_CONVERT_EXPR
, type
, call
);
7266 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, loaded_val
, call
);
7269 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
7270 gsi_remove (&gsi
, true);
7272 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
7273 gsi
= gsi_last_bb (load_bb
);
7274 gsi_remove (&gsi
, true);
7276 if (gimple_in_ssa_p (cfun
))
7277 update_ssa (TODO_update_ssa_no_phi
);
7282 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
7283 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
7284 size of the data type, and thus usable to find the index of the builtin
7285 decl. Returns false if the expression is not of the proper form. */
7288 expand_omp_atomic_fetch_op (basic_block load_bb
,
7289 tree addr
, tree loaded_val
,
7290 tree stored_val
, int index
)
7292 enum built_in_function oldbase
, newbase
, tmpbase
;
7293 tree decl
, itype
, call
;
7295 basic_block store_bb
= single_succ (load_bb
);
7296 gimple_stmt_iterator gsi
;
7299 enum tree_code code
;
7300 bool need_old
, need_new
;
7301 enum machine_mode imode
;
7304 /* We expect to find the following sequences:
7307 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
7310 val = tmp OP something; (or: something OP tmp)
7311 GIMPLE_OMP_STORE (val)
7313 ???FIXME: Allow a more flexible sequence.
7314 Perhaps use data flow to pick the statements.
7318 gsi
= gsi_after_labels (store_bb
);
7319 stmt
= gsi_stmt (gsi
);
7320 loc
= gimple_location (stmt
);
7321 if (!is_gimple_assign (stmt
))
7324 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_OMP_ATOMIC_STORE
)
7326 need_new
= gimple_omp_atomic_need_value_p (gsi_stmt (gsi
));
7327 need_old
= gimple_omp_atomic_need_value_p (last_stmt (load_bb
));
7328 seq_cst
= gimple_omp_atomic_seq_cst_p (last_stmt (load_bb
));
7329 gcc_checking_assert (!need_old
|| !need_new
);
7331 if (!operand_equal_p (gimple_assign_lhs (stmt
), stored_val
, 0))
7334 /* Check for one of the supported fetch-op operations. */
7335 code
= gimple_assign_rhs_code (stmt
);
7339 case POINTER_PLUS_EXPR
:
7340 oldbase
= BUILT_IN_ATOMIC_FETCH_ADD_N
;
7341 newbase
= BUILT_IN_ATOMIC_ADD_FETCH_N
;
7344 oldbase
= BUILT_IN_ATOMIC_FETCH_SUB_N
;
7345 newbase
= BUILT_IN_ATOMIC_SUB_FETCH_N
;
7348 oldbase
= BUILT_IN_ATOMIC_FETCH_AND_N
;
7349 newbase
= BUILT_IN_ATOMIC_AND_FETCH_N
;
7352 oldbase
= BUILT_IN_ATOMIC_FETCH_OR_N
;
7353 newbase
= BUILT_IN_ATOMIC_OR_FETCH_N
;
7356 oldbase
= BUILT_IN_ATOMIC_FETCH_XOR_N
;
7357 newbase
= BUILT_IN_ATOMIC_XOR_FETCH_N
;
7363 /* Make sure the expression is of the proper form. */
7364 if (operand_equal_p (gimple_assign_rhs1 (stmt
), loaded_val
, 0))
7365 rhs
= gimple_assign_rhs2 (stmt
);
7366 else if (commutative_tree_code (gimple_assign_rhs_code (stmt
))
7367 && operand_equal_p (gimple_assign_rhs2 (stmt
), loaded_val
, 0))
7368 rhs
= gimple_assign_rhs1 (stmt
);
7372 tmpbase
= ((enum built_in_function
)
7373 ((need_new
? newbase
: oldbase
) + index
+ 1));
7374 decl
= builtin_decl_explicit (tmpbase
);
7375 if (decl
== NULL_TREE
)
7377 itype
= TREE_TYPE (TREE_TYPE (decl
));
7378 imode
= TYPE_MODE (itype
);
7380 /* We could test all of the various optabs involved, but the fact of the
7381 matter is that (with the exception of i486 vs i586 and xadd) all targets
7382 that support any atomic operaton optab also implements compare-and-swap.
7383 Let optabs.c take care of expanding any compare-and-swap loop. */
7384 if (!can_compare_and_swap_p (imode
, true))
7387 gsi
= gsi_last_bb (load_bb
);
7388 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_LOAD
);
7390 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
7391 It only requires that the operation happen atomically. Thus we can
7392 use the RELAXED memory model. */
7393 call
= build_call_expr_loc (loc
, decl
, 3, addr
,
7394 fold_convert_loc (loc
, itype
, rhs
),
7395 build_int_cst (NULL
,
7396 seq_cst
? MEMMODEL_SEQ_CST
7397 : MEMMODEL_RELAXED
));
7399 if (need_old
|| need_new
)
7401 lhs
= need_old
? loaded_val
: stored_val
;
7402 call
= fold_convert_loc (loc
, TREE_TYPE (lhs
), call
);
7403 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, lhs
, call
);
7406 call
= fold_convert_loc (loc
, void_type_node
, call
);
7407 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
7408 gsi_remove (&gsi
, true);
7410 gsi
= gsi_last_bb (store_bb
);
7411 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
7412 gsi_remove (&gsi
, true);
7413 gsi
= gsi_last_bb (store_bb
);
7414 gsi_remove (&gsi
, true);
7416 if (gimple_in_ssa_p (cfun
))
7417 update_ssa (TODO_update_ssa_no_phi
);
7422 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
7426 newval = rhs; // with oldval replacing *addr in rhs
7427 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
7428 if (oldval != newval)
7431 INDEX is log2 of the size of the data type, and thus usable to find the
7432 index of the builtin decl. */
7435 expand_omp_atomic_pipeline (basic_block load_bb
, basic_block store_bb
,
7436 tree addr
, tree loaded_val
, tree stored_val
,
7439 tree loadedi
, storedi
, initial
, new_storedi
, old_vali
;
7440 tree type
, itype
, cmpxchg
, iaddr
;
7441 gimple_stmt_iterator si
;
7442 basic_block loop_header
= single_succ (load_bb
);
7445 enum built_in_function fncode
;
7447 /* ??? We need a non-pointer interface to __atomic_compare_exchange in
7448 order to use the RELAXED memory model effectively. */
7449 fncode
= (enum built_in_function
)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
7451 cmpxchg
= builtin_decl_explicit (fncode
);
7452 if (cmpxchg
== NULL_TREE
)
7454 type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
7455 itype
= TREE_TYPE (TREE_TYPE (cmpxchg
));
7457 if (!can_compare_and_swap_p (TYPE_MODE (itype
), true))
7460 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
7461 si
= gsi_last_bb (load_bb
);
7462 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
7464 /* For floating-point values, we'll need to view-convert them to integers
7465 so that we can perform the atomic compare and swap. Simplify the
7466 following code by always setting up the "i"ntegral variables. */
7467 if (!INTEGRAL_TYPE_P (type
) && !POINTER_TYPE_P (type
))
7471 iaddr
= create_tmp_reg (build_pointer_type_for_mode (itype
, ptr_mode
,
7474 = force_gimple_operand_gsi (&si
,
7475 fold_convert (TREE_TYPE (iaddr
), addr
),
7476 false, NULL_TREE
, true, GSI_SAME_STMT
);
7477 stmt
= gimple_build_assign (iaddr
, iaddr_val
);
7478 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
7479 loadedi
= create_tmp_var (itype
, NULL
);
7480 if (gimple_in_ssa_p (cfun
))
7481 loadedi
= make_ssa_name (loadedi
, NULL
);
7486 loadedi
= loaded_val
;
7490 = force_gimple_operand_gsi (&si
,
7491 build2 (MEM_REF
, TREE_TYPE (TREE_TYPE (iaddr
)),
7493 build_int_cst (TREE_TYPE (iaddr
), 0)),
7494 true, NULL_TREE
, true, GSI_SAME_STMT
);
7496 /* Move the value to the LOADEDI temporary. */
7497 if (gimple_in_ssa_p (cfun
))
7499 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header
)));
7500 phi
= create_phi_node (loadedi
, loop_header
);
7501 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, single_succ_edge (load_bb
)),
7505 gsi_insert_before (&si
,
7506 gimple_build_assign (loadedi
, initial
),
7508 if (loadedi
!= loaded_val
)
7510 gimple_stmt_iterator gsi2
;
7513 x
= build1 (VIEW_CONVERT_EXPR
, type
, loadedi
);
7514 gsi2
= gsi_start_bb (loop_header
);
7515 if (gimple_in_ssa_p (cfun
))
7518 x
= force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
7519 true, GSI_SAME_STMT
);
7520 stmt
= gimple_build_assign (loaded_val
, x
);
7521 gsi_insert_before (&gsi2
, stmt
, GSI_SAME_STMT
);
7525 x
= build2 (MODIFY_EXPR
, TREE_TYPE (loaded_val
), loaded_val
, x
);
7526 force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
7527 true, GSI_SAME_STMT
);
7530 gsi_remove (&si
, true);
7532 si
= gsi_last_bb (store_bb
);
7533 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
7536 storedi
= stored_val
;
7539 force_gimple_operand_gsi (&si
,
7540 build1 (VIEW_CONVERT_EXPR
, itype
,
7541 stored_val
), true, NULL_TREE
, true,
7544 /* Build the compare&swap statement. */
7545 new_storedi
= build_call_expr (cmpxchg
, 3, iaddr
, loadedi
, storedi
);
7546 new_storedi
= force_gimple_operand_gsi (&si
,
7547 fold_convert (TREE_TYPE (loadedi
),
7550 true, GSI_SAME_STMT
);
7552 if (gimple_in_ssa_p (cfun
))
7556 old_vali
= create_tmp_var (TREE_TYPE (loadedi
), NULL
);
7557 stmt
= gimple_build_assign (old_vali
, loadedi
);
7558 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
7560 stmt
= gimple_build_assign (loadedi
, new_storedi
);
7561 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
7564 /* Note that we always perform the comparison as an integer, even for
7565 floating point. This allows the atomic operation to properly
7566 succeed even with NaNs and -0.0. */
7567 stmt
= gimple_build_cond_empty
7568 (build2 (NE_EXPR
, boolean_type_node
,
7569 new_storedi
, old_vali
));
7570 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
7573 e
= single_succ_edge (store_bb
);
7574 e
->flags
&= ~EDGE_FALLTHRU
;
7575 e
->flags
|= EDGE_FALSE_VALUE
;
7577 e
= make_edge (store_bb
, loop_header
, EDGE_TRUE_VALUE
);
7579 /* Copy the new value to loadedi (we already did that before the condition
7580 if we are not in SSA). */
7581 if (gimple_in_ssa_p (cfun
))
7583 phi
= gimple_seq_first_stmt (phi_nodes (loop_header
));
7584 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, e
), new_storedi
);
7587 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
7588 gsi_remove (&si
, true);
7590 struct loop
*loop
= alloc_loop ();
7591 loop
->header
= loop_header
;
7592 loop
->latch
= store_bb
;
7593 add_loop (loop
, loop_header
->loop_father
);
7595 if (gimple_in_ssa_p (cfun
))
7596 update_ssa (TODO_update_ssa_no_phi
);
7601 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
7603 GOMP_atomic_start ();
7607 The result is not globally atomic, but works so long as all parallel
7608 references are within #pragma omp atomic directives. According to
7609 responses received from omp@openmp.org, appears to be within spec.
7610 Which makes sense, since that's how several other compilers handle
7611 this situation as well.
7612 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
7613 expanding. STORED_VAL is the operand of the matching
7614 GIMPLE_OMP_ATOMIC_STORE.
7617 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
7621 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
7626 expand_omp_atomic_mutex (basic_block load_bb
, basic_block store_bb
,
7627 tree addr
, tree loaded_val
, tree stored_val
)
7629 gimple_stmt_iterator si
;
7633 si
= gsi_last_bb (load_bb
);
7634 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
7636 t
= builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START
);
7637 t
= build_call_expr (t
, 0);
7638 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
7640 stmt
= gimple_build_assign (loaded_val
, build_simple_mem_ref (addr
));
7641 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
7642 gsi_remove (&si
, true);
7644 si
= gsi_last_bb (store_bb
);
7645 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
7647 stmt
= gimple_build_assign (build_simple_mem_ref (unshare_expr (addr
)),
7649 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
7651 t
= builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END
);
7652 t
= build_call_expr (t
, 0);
7653 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
7654 gsi_remove (&si
, true);
7656 if (gimple_in_ssa_p (cfun
))
7657 update_ssa (TODO_update_ssa_no_phi
);
7661 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
7662 using expand_omp_atomic_fetch_op. If it failed, we try to
7663 call expand_omp_atomic_pipeline, and if it fails too, the
7664 ultimate fallback is wrapping the operation in a mutex
7665 (expand_omp_atomic_mutex). REGION is the atomic region built
7666 by build_omp_regions_1(). */
7669 expand_omp_atomic (struct omp_region
*region
)
7671 basic_block load_bb
= region
->entry
, store_bb
= region
->exit
;
7672 gimple load
= last_stmt (load_bb
), store
= last_stmt (store_bb
);
7673 tree loaded_val
= gimple_omp_atomic_load_lhs (load
);
7674 tree addr
= gimple_omp_atomic_load_rhs (load
);
7675 tree stored_val
= gimple_omp_atomic_store_val (store
);
7676 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
7677 HOST_WIDE_INT index
;
7679 /* Make sure the type is one of the supported sizes. */
7680 index
= tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
7681 index
= exact_log2 (index
);
7682 if (index
>= 0 && index
<= 4)
7684 unsigned int align
= TYPE_ALIGN_UNIT (type
);
7686 /* __sync builtins require strict data alignment. */
7687 if (exact_log2 (align
) >= index
)
7690 if (loaded_val
== stored_val
7691 && (GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_INT
7692 || GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
)
7693 && GET_MODE_BITSIZE (TYPE_MODE (type
)) <= BITS_PER_WORD
7694 && expand_omp_atomic_load (load_bb
, addr
, loaded_val
, index
))
7698 if ((GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_INT
7699 || GET_MODE_CLASS (TYPE_MODE (type
)) == MODE_FLOAT
)
7700 && GET_MODE_BITSIZE (TYPE_MODE (type
)) <= BITS_PER_WORD
7701 && store_bb
== single_succ (load_bb
)
7702 && first_stmt (store_bb
) == store
7703 && expand_omp_atomic_store (load_bb
, addr
, loaded_val
,
7707 /* When possible, use specialized atomic update functions. */
7708 if ((INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
))
7709 && store_bb
== single_succ (load_bb
)
7710 && expand_omp_atomic_fetch_op (load_bb
, addr
,
7711 loaded_val
, stored_val
, index
))
7714 /* If we don't have specialized __sync builtins, try and implement
7715 as a compare and swap loop. */
7716 if (expand_omp_atomic_pipeline (load_bb
, store_bb
, addr
,
7717 loaded_val
, stored_val
, index
))
7722 /* The ultimate fallback is wrapping the operation in a mutex. */
7723 expand_omp_atomic_mutex (load_bb
, store_bb
, addr
, loaded_val
, stored_val
);
7727 /* Expand the OpenMP target{, data, update} directive starting at REGION. */
7730 expand_omp_target (struct omp_region
*region
)
7732 basic_block entry_bb
, exit_bb
, new_bb
;
7733 struct function
*child_cfun
= NULL
;
7734 tree child_fn
= NULL_TREE
, block
, t
;
7735 gimple_stmt_iterator gsi
;
7736 gimple entry_stmt
, stmt
;
7739 entry_stmt
= last_stmt (region
->entry
);
7740 new_bb
= region
->entry
;
7741 int kind
= gimple_omp_target_kind (entry_stmt
);
7742 if (kind
== GF_OMP_TARGET_KIND_REGION
)
7744 child_fn
= gimple_omp_target_child_fn (entry_stmt
);
7745 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
7748 entry_bb
= region
->entry
;
7749 exit_bb
= region
->exit
;
7751 if (kind
== GF_OMP_TARGET_KIND_REGION
)
7753 unsigned srcidx
, dstidx
, num
;
7755 /* If the target region needs data sent from the parent
7756 function, then the very first statement (except possible
7757 tree profile counter updates) of the parallel body
7758 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
7759 &.OMP_DATA_O is passed as an argument to the child function,
7760 we need to replace it with the argument as seen by the child
7763 In most cases, this will end up being the identity assignment
7764 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
7765 a function call that has been inlined, the original PARM_DECL
7766 .OMP_DATA_I may have been converted into a different local
7767 variable. In which case, we need to keep the assignment. */
7768 if (gimple_omp_target_data_arg (entry_stmt
))
7770 basic_block entry_succ_bb
= single_succ (entry_bb
);
7771 gimple_stmt_iterator gsi
;
7773 gimple tgtcopy_stmt
= NULL
;
7775 = TREE_VEC_ELT (gimple_omp_target_data_arg (entry_stmt
), 0);
7777 for (gsi
= gsi_start_bb (entry_succ_bb
); ; gsi_next (&gsi
))
7779 gcc_assert (!gsi_end_p (gsi
));
7780 stmt
= gsi_stmt (gsi
);
7781 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
7784 if (gimple_num_ops (stmt
) == 2)
7786 tree arg
= gimple_assign_rhs1 (stmt
);
7788 /* We're ignoring the subcode because we're
7789 effectively doing a STRIP_NOPS. */
7791 if (TREE_CODE (arg
) == ADDR_EXPR
7792 && TREE_OPERAND (arg
, 0) == sender
)
7794 tgtcopy_stmt
= stmt
;
7800 gcc_assert (tgtcopy_stmt
!= NULL
);
7801 arg
= DECL_ARGUMENTS (child_fn
);
7803 gcc_assert (gimple_assign_lhs (tgtcopy_stmt
) == arg
);
7804 gsi_remove (&gsi
, true);
7807 /* Declare local variables needed in CHILD_CFUN. */
7808 block
= DECL_INITIAL (child_fn
);
7809 BLOCK_VARS (block
) = vec2chain (child_cfun
->local_decls
);
7810 /* The gimplifier could record temporaries in target block
7811 rather than in containing function's local_decls chain,
7812 which would mean cgraph missed finalizing them. Do it now. */
7813 for (t
= BLOCK_VARS (block
); t
; t
= DECL_CHAIN (t
))
7814 if (TREE_CODE (t
) == VAR_DECL
7816 && !DECL_EXTERNAL (t
))
7817 varpool_finalize_decl (t
);
7818 DECL_SAVED_TREE (child_fn
) = NULL
;
7819 /* We'll create a CFG for child_fn, so no gimple body is needed. */
7820 gimple_set_body (child_fn
, NULL
);
7821 TREE_USED (block
) = 1;
7823 /* Reset DECL_CONTEXT on function arguments. */
7824 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
7825 DECL_CONTEXT (t
) = child_fn
;
7827 /* Split ENTRY_BB at GIMPLE_OMP_TARGET,
7828 so that it can be moved to the child function. */
7829 gsi
= gsi_last_bb (entry_bb
);
7830 stmt
= gsi_stmt (gsi
);
7831 gcc_assert (stmt
&& gimple_code (stmt
) == GIMPLE_OMP_TARGET
7832 && gimple_omp_target_kind (stmt
)
7833 == GF_OMP_TARGET_KIND_REGION
);
7834 gsi_remove (&gsi
, true);
7835 e
= split_block (entry_bb
, stmt
);
7837 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
7839 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
7842 gsi
= gsi_last_bb (exit_bb
);
7843 gcc_assert (!gsi_end_p (gsi
)
7844 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
7845 stmt
= gimple_build_return (NULL
);
7846 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
7847 gsi_remove (&gsi
, true);
7850 /* Move the target region into CHILD_CFUN. */
7852 block
= gimple_block (entry_stmt
);
7854 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
, block
);
7856 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
7857 /* When the OMP expansion process cannot guarantee an up-to-date
7858 loop tree arrange for the child function to fixup loops. */
7859 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
7860 child_cfun
->x_current_loops
->state
|= LOOPS_NEED_FIXUP
;
7862 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
7863 num
= vec_safe_length (child_cfun
->local_decls
);
7864 for (srcidx
= 0, dstidx
= 0; srcidx
< num
; srcidx
++)
7866 t
= (*child_cfun
->local_decls
)[srcidx
];
7867 if (DECL_CONTEXT (t
) == cfun
->decl
)
7869 if (srcidx
!= dstidx
)
7870 (*child_cfun
->local_decls
)[dstidx
] = t
;
7874 vec_safe_truncate (child_cfun
->local_decls
, dstidx
);
7876 /* Inform the callgraph about the new function. */
7877 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
= cfun
->curr_properties
;
7878 cgraph_add_new_function (child_fn
, true);
7880 /* Fix the callgraph edges for child_cfun. Those for cfun will be
7881 fixed in a following pass. */
7882 push_cfun (child_cfun
);
7883 rebuild_cgraph_edges ();
7885 /* Some EH regions might become dead, see PR34608. If
7886 pass_cleanup_cfg isn't the first pass to happen with the
7887 new child, these dead EH edges might cause problems.
7888 Clean them up now. */
7889 if (flag_exceptions
)
7892 bool changed
= false;
7895 changed
|= gimple_purge_dead_eh_edges (bb
);
7897 cleanup_tree_cfg ();
7902 /* Emit a library call to launch the target region, or do data
7904 tree t1
, t2
, t3
, t4
, device
, cond
, c
, clauses
;
7905 enum built_in_function start_ix
;
7906 location_t clause_loc
;
7908 clauses
= gimple_omp_target_clauses (entry_stmt
);
7910 if (kind
== GF_OMP_TARGET_KIND_REGION
)
7911 start_ix
= BUILT_IN_GOMP_TARGET
;
7912 else if (kind
== GF_OMP_TARGET_KIND_DATA
)
7913 start_ix
= BUILT_IN_GOMP_TARGET_DATA
;
7915 start_ix
= BUILT_IN_GOMP_TARGET_UPDATE
;
7917 /* By default, the value of DEVICE is -1 (let runtime library choose)
7918 and there is no conditional. */
7920 device
= build_int_cst (integer_type_node
, -1);
7922 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
7924 cond
= OMP_CLAUSE_IF_EXPR (c
);
7926 c
= find_omp_clause (clauses
, OMP_CLAUSE_DEVICE
);
7929 device
= OMP_CLAUSE_DEVICE_ID (c
);
7930 clause_loc
= OMP_CLAUSE_LOCATION (c
);
7933 clause_loc
= gimple_location (entry_stmt
);
7935 /* Ensure 'device' is of the correct type. */
7936 device
= fold_convert_loc (clause_loc
, integer_type_node
, device
);
7938 /* If we found the clause 'if (cond)', build
7939 (cond ? device : -2). */
7942 cond
= gimple_boolify (cond
);
7944 basic_block cond_bb
, then_bb
, else_bb
;
7948 tmp_var
= create_tmp_var (TREE_TYPE (device
), NULL
);
7949 if (kind
!= GF_OMP_TARGET_KIND_REGION
)
7951 gsi
= gsi_last_bb (new_bb
);
7953 e
= split_block (new_bb
, gsi_stmt (gsi
));
7956 e
= split_block (new_bb
, NULL
);
7961 then_bb
= create_empty_bb (cond_bb
);
7962 else_bb
= create_empty_bb (then_bb
);
7963 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
7964 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
7966 stmt
= gimple_build_cond_empty (cond
);
7967 gsi
= gsi_last_bb (cond_bb
);
7968 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
7970 gsi
= gsi_start_bb (then_bb
);
7971 stmt
= gimple_build_assign (tmp_var
, device
);
7972 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
7974 gsi
= gsi_start_bb (else_bb
);
7975 stmt
= gimple_build_assign (tmp_var
,
7976 build_int_cst (integer_type_node
, -2));
7977 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
7979 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
7980 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
7983 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
7984 add_bb_to_loop (else_bb
, cond_bb
->loop_father
);
7986 make_edge (then_bb
, new_bb
, EDGE_FALLTHRU
);
7987 make_edge (else_bb
, new_bb
, EDGE_FALLTHRU
);
7992 gsi
= gsi_last_bb (new_bb
);
7993 t
= gimple_omp_target_data_arg (entry_stmt
);
7996 t1
= size_zero_node
;
7997 t2
= build_zero_cst (ptr_type_node
);
8003 t1
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (TREE_VEC_ELT (t
, 1))));
8004 t1
= size_binop (PLUS_EXPR
, t1
, size_int (1));
8005 t2
= build_fold_addr_expr (TREE_VEC_ELT (t
, 0));
8006 t3
= build_fold_addr_expr (TREE_VEC_ELT (t
, 1));
8007 t4
= build_fold_addr_expr (TREE_VEC_ELT (t
, 2));
8011 /* FIXME: This will be address of
8012 extern char __OPENMP_TARGET__[] __attribute__((visibility ("hidden")))
8013 symbol, as soon as the linker plugin is able to create it for us. */
8014 tree openmp_target
= build_zero_cst (ptr_type_node
);
8015 if (kind
== GF_OMP_TARGET_KIND_REGION
)
8017 tree fnaddr
= build_fold_addr_expr (child_fn
);
8018 g
= gimple_build_call (builtin_decl_explicit (start_ix
), 7,
8019 device
, fnaddr
, openmp_target
, t1
, t2
, t3
, t4
);
8022 g
= gimple_build_call (builtin_decl_explicit (start_ix
), 6,
8023 device
, openmp_target
, t1
, t2
, t3
, t4
);
8024 gimple_set_location (g
, gimple_location (entry_stmt
));
8025 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
8026 if (kind
!= GF_OMP_TARGET_KIND_REGION
)
8029 gcc_assert (g
&& gimple_code (g
) == GIMPLE_OMP_TARGET
);
8030 gsi_remove (&gsi
, true);
8032 if (kind
== GF_OMP_TARGET_KIND_DATA
&& region
->exit
)
8034 gsi
= gsi_last_bb (region
->exit
);
8036 gcc_assert (g
&& gimple_code (g
) == GIMPLE_OMP_RETURN
);
8037 gsi_remove (&gsi
, true);
8042 /* Expand the parallel region tree rooted at REGION. Expansion
8043 proceeds in depth-first order. Innermost regions are expanded
8044 first. This way, parallel regions that require a new function to
8045 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
8046 internal dependencies in their body. */
8049 expand_omp (struct omp_region
*region
)
8053 location_t saved_location
;
8054 gimple inner_stmt
= NULL
;
8056 /* First, determine whether this is a combined parallel+workshare
8058 if (region
->type
== GIMPLE_OMP_PARALLEL
)
8059 determine_parallel_type (region
);
8061 if (region
->type
== GIMPLE_OMP_FOR
8062 && gimple_omp_for_combined_p (last_stmt (region
->entry
)))
8063 inner_stmt
= last_stmt (region
->inner
->entry
);
8066 expand_omp (region
->inner
);
8068 saved_location
= input_location
;
8069 if (gimple_has_location (last_stmt (region
->entry
)))
8070 input_location
= gimple_location (last_stmt (region
->entry
));
8072 switch (region
->type
)
8074 case GIMPLE_OMP_PARALLEL
:
8075 case GIMPLE_OMP_TASK
:
8076 expand_omp_taskreg (region
);
8079 case GIMPLE_OMP_FOR
:
8080 expand_omp_for (region
, inner_stmt
);
8083 case GIMPLE_OMP_SECTIONS
:
8084 expand_omp_sections (region
);
8087 case GIMPLE_OMP_SECTION
:
8088 /* Individual omp sections are handled together with their
8089 parent GIMPLE_OMP_SECTIONS region. */
8092 case GIMPLE_OMP_SINGLE
:
8093 expand_omp_single (region
);
8096 case GIMPLE_OMP_MASTER
:
8097 case GIMPLE_OMP_TASKGROUP
:
8098 case GIMPLE_OMP_ORDERED
:
8099 case GIMPLE_OMP_CRITICAL
:
8100 case GIMPLE_OMP_TEAMS
:
8101 expand_omp_synch (region
);
8104 case GIMPLE_OMP_ATOMIC_LOAD
:
8105 expand_omp_atomic (region
);
8108 case GIMPLE_OMP_TARGET
:
8109 expand_omp_target (region
);
8116 input_location
= saved_location
;
8117 region
= region
->next
;
8122 /* Helper for build_omp_regions. Scan the dominator tree starting at
8123 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
8124 true, the function ends once a single tree is built (otherwise, whole
8125 forest of OMP constructs may be built). */
8128 build_omp_regions_1 (basic_block bb
, struct omp_region
*parent
,
8131 gimple_stmt_iterator gsi
;
8135 gsi
= gsi_last_bb (bb
);
8136 if (!gsi_end_p (gsi
) && is_gimple_omp (gsi_stmt (gsi
)))
8138 struct omp_region
*region
;
8139 enum gimple_code code
;
8141 stmt
= gsi_stmt (gsi
);
8142 code
= gimple_code (stmt
);
8143 if (code
== GIMPLE_OMP_RETURN
)
8145 /* STMT is the return point out of region PARENT. Mark it
8146 as the exit point and make PARENT the immediately
8147 enclosing region. */
8148 gcc_assert (parent
);
8151 parent
= parent
->outer
;
8153 else if (code
== GIMPLE_OMP_ATOMIC_STORE
)
8155 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
8156 GIMPLE_OMP_RETURN, but matches with
8157 GIMPLE_OMP_ATOMIC_LOAD. */
8158 gcc_assert (parent
);
8159 gcc_assert (parent
->type
== GIMPLE_OMP_ATOMIC_LOAD
);
8162 parent
= parent
->outer
;
8165 else if (code
== GIMPLE_OMP_CONTINUE
)
8167 gcc_assert (parent
);
8170 else if (code
== GIMPLE_OMP_SECTIONS_SWITCH
)
8172 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
8173 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
8176 else if (code
== GIMPLE_OMP_TARGET
8177 && gimple_omp_target_kind (stmt
) == GF_OMP_TARGET_KIND_UPDATE
)
8178 new_omp_region (bb
, code
, parent
);
8181 /* Otherwise, this directive becomes the parent for a new
8183 region
= new_omp_region (bb
, code
, parent
);
8188 if (single_tree
&& !parent
)
8191 for (son
= first_dom_son (CDI_DOMINATORS
, bb
);
8193 son
= next_dom_son (CDI_DOMINATORS
, son
))
8194 build_omp_regions_1 (son
, parent
, single_tree
);
8197 /* Builds the tree of OMP regions rooted at ROOT, storing it to
8201 build_omp_regions_root (basic_block root
)
8203 gcc_assert (root_omp_region
== NULL
);
8204 build_omp_regions_1 (root
, NULL
, true);
8205 gcc_assert (root_omp_region
!= NULL
);
8208 /* Expands omp construct (and its subconstructs) starting in HEAD. */
8211 omp_expand_local (basic_block head
)
8213 build_omp_regions_root (head
);
8214 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
8216 fprintf (dump_file
, "\nOMP region tree\n\n");
8217 dump_omp_region (dump_file
, root_omp_region
, 0);
8218 fprintf (dump_file
, "\n");
8221 remove_exit_barriers (root_omp_region
);
8222 expand_omp (root_omp_region
);
8224 free_omp_regions ();
8227 /* Scan the CFG and build a tree of OMP regions. Return the root of
8228 the OMP region tree. */
8231 build_omp_regions (void)
8233 gcc_assert (root_omp_region
== NULL
);
8234 calculate_dominance_info (CDI_DOMINATORS
);
8235 build_omp_regions_1 (ENTRY_BLOCK_PTR
, NULL
, false);
8238 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
8241 execute_expand_omp (void)
8243 build_omp_regions ();
8245 if (!root_omp_region
)
8250 fprintf (dump_file
, "\nOMP region tree\n\n");
8251 dump_omp_region (dump_file
, root_omp_region
, 0);
8252 fprintf (dump_file
, "\n");
8255 remove_exit_barriers (root_omp_region
);
8257 expand_omp (root_omp_region
);
8259 cleanup_tree_cfg ();
8261 free_omp_regions ();
8266 /* OMP expansion -- the default pass, run before creation of SSA form. */
8269 gate_expand_omp (void)
8271 return ((flag_openmp
!= 0 || flag_openmp_simd
!= 0
8272 || flag_enable_cilkplus
!= 0) && !seen_error ());
8277 const pass_data pass_data_expand_omp
=
8279 GIMPLE_PASS
, /* type */
8280 "ompexp", /* name */
8281 OPTGROUP_NONE
, /* optinfo_flags */
8282 true, /* has_gate */
8283 true, /* has_execute */
8284 TV_NONE
, /* tv_id */
8285 PROP_gimple_any
, /* properties_required */
8286 0, /* properties_provided */
8287 0, /* properties_destroyed */
8288 0, /* todo_flags_start */
8289 0, /* todo_flags_finish */
8292 class pass_expand_omp
: public gimple_opt_pass
8295 pass_expand_omp (gcc::context
*ctxt
)
8296 : gimple_opt_pass (pass_data_expand_omp
, ctxt
)
8299 /* opt_pass methods: */
8300 bool gate () { return gate_expand_omp (); }
8301 unsigned int execute () { return execute_expand_omp (); }
8303 }; // class pass_expand_omp
8308 make_pass_expand_omp (gcc::context
*ctxt
)
8310 return new pass_expand_omp (ctxt
);
8313 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
8315 /* If ctx is a worksharing context inside of a cancellable parallel
8316 region and it isn't nowait, add lhs to its GIMPLE_OMP_RETURN
8317 and conditional branch to parallel's cancel_label to handle
8318 cancellation in the implicit barrier. */
8321 maybe_add_implicit_barrier_cancel (omp_context
*ctx
, gimple_seq
*body
)
8323 gimple omp_return
= gimple_seq_last_stmt (*body
);
8324 gcc_assert (gimple_code (omp_return
) == GIMPLE_OMP_RETURN
);
8325 if (gimple_omp_return_nowait_p (omp_return
))
8328 && gimple_code (ctx
->outer
->stmt
) == GIMPLE_OMP_PARALLEL
8329 && ctx
->outer
->cancellable
)
8331 tree lhs
= create_tmp_var (boolean_type_node
, NULL
);
8332 gimple_omp_return_set_lhs (omp_return
, lhs
);
8333 tree fallthru_label
= create_artificial_label (UNKNOWN_LOCATION
);
8334 gimple g
= gimple_build_cond (NE_EXPR
, lhs
, boolean_false_node
,
8335 ctx
->outer
->cancel_label
, fallthru_label
);
8336 gimple_seq_add_stmt (body
, g
);
8337 gimple_seq_add_stmt (body
, gimple_build_label (fallthru_label
));
8341 /* Lower the OpenMP sections directive in the current statement in GSI_P.
8342 CTX is the enclosing OMP context for the current statement. */
8345 lower_omp_sections (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
8347 tree block
, control
;
8348 gimple_stmt_iterator tgsi
;
8349 gimple stmt
, new_stmt
, bind
, t
;
8350 gimple_seq ilist
, dlist
, olist
, new_body
;
8351 struct gimplify_ctx gctx
;
8353 stmt
= gsi_stmt (*gsi_p
);
8355 push_gimplify_context (&gctx
);
8359 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt
),
8360 &ilist
, &dlist
, ctx
, NULL
);
8362 new_body
= gimple_omp_body (stmt
);
8363 gimple_omp_set_body (stmt
, NULL
);
8364 tgsi
= gsi_start (new_body
);
8365 for (; !gsi_end_p (tgsi
); gsi_next (&tgsi
))
8370 sec_start
= gsi_stmt (tgsi
);
8371 sctx
= maybe_lookup_ctx (sec_start
);
8374 lower_omp (gimple_omp_body_ptr (sec_start
), sctx
);
8375 gsi_insert_seq_after (&tgsi
, gimple_omp_body (sec_start
),
8376 GSI_CONTINUE_LINKING
);
8377 gimple_omp_set_body (sec_start
, NULL
);
8379 if (gsi_one_before_end_p (tgsi
))
8381 gimple_seq l
= NULL
;
8382 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt
), NULL
,
8384 gsi_insert_seq_after (&tgsi
, l
, GSI_CONTINUE_LINKING
);
8385 gimple_omp_section_set_last (sec_start
);
8388 gsi_insert_after (&tgsi
, gimple_build_omp_return (false),
8389 GSI_CONTINUE_LINKING
);
8392 block
= make_node (BLOCK
);
8393 bind
= gimple_build_bind (NULL
, new_body
, block
);
8396 lower_reduction_clauses (gimple_omp_sections_clauses (stmt
), &olist
, ctx
);
8398 block
= make_node (BLOCK
);
8399 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
8400 gsi_replace (gsi_p
, new_stmt
, true);
8402 pop_gimplify_context (new_stmt
);
8403 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
8404 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
8405 if (BLOCK_VARS (block
))
8406 TREE_USED (block
) = 1;
8409 gimple_seq_add_seq (&new_body
, ilist
);
8410 gimple_seq_add_stmt (&new_body
, stmt
);
8411 gimple_seq_add_stmt (&new_body
, gimple_build_omp_sections_switch ());
8412 gimple_seq_add_stmt (&new_body
, bind
);
8414 control
= create_tmp_var (unsigned_type_node
, ".section");
8415 t
= gimple_build_omp_continue (control
, control
);
8416 gimple_omp_sections_set_control (stmt
, control
);
8417 gimple_seq_add_stmt (&new_body
, t
);
8419 gimple_seq_add_seq (&new_body
, olist
);
8420 if (ctx
->cancellable
)
8421 gimple_seq_add_stmt (&new_body
, gimple_build_label (ctx
->cancel_label
));
8422 gimple_seq_add_seq (&new_body
, dlist
);
8424 new_body
= maybe_catch_exception (new_body
);
8426 t
= gimple_build_omp_return
8427 (!!find_omp_clause (gimple_omp_sections_clauses (stmt
),
8428 OMP_CLAUSE_NOWAIT
));
8429 gimple_seq_add_stmt (&new_body
, t
);
8430 maybe_add_implicit_barrier_cancel (ctx
, &new_body
);
8432 gimple_bind_set_body (new_stmt
, new_body
);
8436 /* A subroutine of lower_omp_single. Expand the simple form of
8437 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
8439 if (GOMP_single_start ())
8441 [ GOMP_barrier (); ] -> unless 'nowait' is present.
8443 FIXME. It may be better to delay expanding the logic of this until
8444 pass_expand_omp. The expanded logic may make the job more difficult
8445 to a synchronization analysis pass. */
8448 lower_omp_single_simple (gimple single_stmt
, gimple_seq
*pre_p
)
8450 location_t loc
= gimple_location (single_stmt
);
8451 tree tlabel
= create_artificial_label (loc
);
8452 tree flabel
= create_artificial_label (loc
);
8456 decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_START
);
8457 lhs
= create_tmp_var (TREE_TYPE (TREE_TYPE (decl
)), NULL
);
8458 call
= gimple_build_call (decl
, 0);
8459 gimple_call_set_lhs (call
, lhs
);
8460 gimple_seq_add_stmt (pre_p
, call
);
8462 cond
= gimple_build_cond (EQ_EXPR
, lhs
,
8463 fold_convert_loc (loc
, TREE_TYPE (lhs
),
8466 gimple_seq_add_stmt (pre_p
, cond
);
8467 gimple_seq_add_stmt (pre_p
, gimple_build_label (tlabel
));
8468 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
8469 gimple_seq_add_stmt (pre_p
, gimple_build_label (flabel
));
8473 /* A subroutine of lower_omp_single. Expand the simple form of
8474 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
8476 #pragma omp single copyprivate (a, b, c)
8478 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
8481 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
8487 GOMP_single_copy_end (©out);
8498 FIXME. It may be better to delay expanding the logic of this until
8499 pass_expand_omp. The expanded logic may make the job more difficult
8500 to a synchronization analysis pass. */
8503 lower_omp_single_copy (gimple single_stmt
, gimple_seq
*pre_p
, omp_context
*ctx
)
8505 tree ptr_type
, t
, l0
, l1
, l2
, bfn_decl
;
8506 gimple_seq copyin_seq
;
8507 location_t loc
= gimple_location (single_stmt
);
8509 ctx
->sender_decl
= create_tmp_var (ctx
->record_type
, ".omp_copy_o");
8511 ptr_type
= build_pointer_type (ctx
->record_type
);
8512 ctx
->receiver_decl
= create_tmp_var (ptr_type
, ".omp_copy_i");
8514 l0
= create_artificial_label (loc
);
8515 l1
= create_artificial_label (loc
);
8516 l2
= create_artificial_label (loc
);
8518 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_START
);
8519 t
= build_call_expr_loc (loc
, bfn_decl
, 0);
8520 t
= fold_convert_loc (loc
, ptr_type
, t
);
8521 gimplify_assign (ctx
->receiver_decl
, t
, pre_p
);
8523 t
= build2 (EQ_EXPR
, boolean_type_node
, ctx
->receiver_decl
,
8524 build_int_cst (ptr_type
, 0));
8525 t
= build3 (COND_EXPR
, void_type_node
, t
,
8526 build_and_jump (&l0
), build_and_jump (&l1
));
8527 gimplify_and_add (t
, pre_p
);
8529 gimple_seq_add_stmt (pre_p
, gimple_build_label (l0
));
8531 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
8534 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt
), pre_p
,
8537 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
8538 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SINGLE_COPY_END
);
8539 t
= build_call_expr_loc (loc
, bfn_decl
, 1, t
);
8540 gimplify_and_add (t
, pre_p
);
8542 t
= build_and_jump (&l2
);
8543 gimplify_and_add (t
, pre_p
);
8545 gimple_seq_add_stmt (pre_p
, gimple_build_label (l1
));
8547 gimple_seq_add_seq (pre_p
, copyin_seq
);
8549 gimple_seq_add_stmt (pre_p
, gimple_build_label (l2
));
8553 /* Expand code for an OpenMP single directive. */
8556 lower_omp_single (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
8559 gimple t
, bind
, single_stmt
= gsi_stmt (*gsi_p
);
8560 gimple_seq bind_body
, bind_body_tail
= NULL
, dlist
;
8561 struct gimplify_ctx gctx
;
8563 push_gimplify_context (&gctx
);
8565 block
= make_node (BLOCK
);
8566 bind
= gimple_build_bind (NULL
, NULL
, block
);
8567 gsi_replace (gsi_p
, bind
, true);
8570 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt
),
8571 &bind_body
, &dlist
, ctx
, NULL
);
8572 lower_omp (gimple_omp_body_ptr (single_stmt
), ctx
);
8574 gimple_seq_add_stmt (&bind_body
, single_stmt
);
8576 if (ctx
->record_type
)
8577 lower_omp_single_copy (single_stmt
, &bind_body
, ctx
);
8579 lower_omp_single_simple (single_stmt
, &bind_body
);
8581 gimple_omp_set_body (single_stmt
, NULL
);
8583 gimple_seq_add_seq (&bind_body
, dlist
);
8585 bind_body
= maybe_catch_exception (bind_body
);
8587 t
= gimple_build_omp_return
8588 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt
),
8589 OMP_CLAUSE_NOWAIT
));
8590 gimple_seq_add_stmt (&bind_body_tail
, t
);
8591 maybe_add_implicit_barrier_cancel (ctx
, &bind_body_tail
);
8592 if (ctx
->record_type
)
8594 gimple_stmt_iterator gsi
= gsi_start (bind_body_tail
);
8595 tree clobber
= build_constructor (ctx
->record_type
, NULL
);
8596 TREE_THIS_VOLATILE (clobber
) = 1;
8597 gsi_insert_after (&gsi
, gimple_build_assign (ctx
->sender_decl
,
8598 clobber
), GSI_SAME_STMT
);
8600 gimple_seq_add_seq (&bind_body
, bind_body_tail
);
8601 gimple_bind_set_body (bind
, bind_body
);
8603 pop_gimplify_context (bind
);
8605 gimple_bind_append_vars (bind
, ctx
->block_vars
);
8606 BLOCK_VARS (block
) = ctx
->block_vars
;
8607 if (BLOCK_VARS (block
))
8608 TREE_USED (block
) = 1;
8612 /* Expand code for an OpenMP master directive. */
8615 lower_omp_master (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
8617 tree block
, lab
= NULL
, x
, bfn_decl
;
8618 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
8619 location_t loc
= gimple_location (stmt
);
8621 struct gimplify_ctx gctx
;
8623 push_gimplify_context (&gctx
);
8625 block
= make_node (BLOCK
);
8626 bind
= gimple_build_bind (NULL
, NULL
, block
);
8627 gsi_replace (gsi_p
, bind
, true);
8628 gimple_bind_add_stmt (bind
, stmt
);
8630 bfn_decl
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
8631 x
= build_call_expr_loc (loc
, bfn_decl
, 0);
8632 x
= build2 (EQ_EXPR
, boolean_type_node
, x
, integer_zero_node
);
8633 x
= build3 (COND_EXPR
, void_type_node
, x
, NULL
, build_and_jump (&lab
));
8635 gimplify_and_add (x
, &tseq
);
8636 gimple_bind_add_seq (bind
, tseq
);
8638 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
8639 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
8640 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
8641 gimple_omp_set_body (stmt
, NULL
);
8643 gimple_bind_add_stmt (bind
, gimple_build_label (lab
));
8645 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
8647 pop_gimplify_context (bind
);
8649 gimple_bind_append_vars (bind
, ctx
->block_vars
);
8650 BLOCK_VARS (block
) = ctx
->block_vars
;
8654 /* Expand code for an OpenMP taskgroup directive. */
8657 lower_omp_taskgroup (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
8659 gimple stmt
= gsi_stmt (*gsi_p
), bind
, x
;
8660 tree block
= make_node (BLOCK
);
8662 bind
= gimple_build_bind (NULL
, NULL
, block
);
8663 gsi_replace (gsi_p
, bind
, true);
8664 gimple_bind_add_stmt (bind
, stmt
);
8666 x
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_TASKGROUP_START
),
8668 gimple_bind_add_stmt (bind
, x
);
8670 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
8671 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
8672 gimple_omp_set_body (stmt
, NULL
);
8674 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
8676 gimple_bind_append_vars (bind
, ctx
->block_vars
);
8677 BLOCK_VARS (block
) = ctx
->block_vars
;
8681 /* Expand code for an OpenMP ordered directive. */
8684 lower_omp_ordered (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
8687 gimple stmt
= gsi_stmt (*gsi_p
), bind
, x
;
8688 struct gimplify_ctx gctx
;
8690 push_gimplify_context (&gctx
);
8692 block
= make_node (BLOCK
);
8693 bind
= gimple_build_bind (NULL
, NULL
, block
);
8694 gsi_replace (gsi_p
, bind
, true);
8695 gimple_bind_add_stmt (bind
, stmt
);
8697 x
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START
),
8699 gimple_bind_add_stmt (bind
, x
);
8701 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
8702 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
8703 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
8704 gimple_omp_set_body (stmt
, NULL
);
8706 x
= gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_END
), 0);
8707 gimple_bind_add_stmt (bind
, x
);
8709 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
8711 pop_gimplify_context (bind
);
8713 gimple_bind_append_vars (bind
, ctx
->block_vars
);
8714 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
8718 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
8719 substitution of a couple of function calls. But in the NAMED case,
8720 requires that languages coordinate a symbol name. It is therefore
8721 best put here in common code. */
8723 static GTY((param1_is (tree
), param2_is (tree
)))
8724 splay_tree critical_name_mutexes
;
8727 lower_omp_critical (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
8730 tree name
, lock
, unlock
;
8731 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
8732 location_t loc
= gimple_location (stmt
);
8734 struct gimplify_ctx gctx
;
8736 name
= gimple_omp_critical_name (stmt
);
8742 if (!critical_name_mutexes
)
8743 critical_name_mutexes
8744 = splay_tree_new_ggc (splay_tree_compare_pointers
,
8745 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_s
,
8746 ggc_alloc_splay_tree_tree_node_tree_node_splay_tree_node_s
);
8748 n
= splay_tree_lookup (critical_name_mutexes
, (splay_tree_key
) name
);
8753 decl
= create_tmp_var_raw (ptr_type_node
, NULL
);
8755 new_str
= ACONCAT ((".gomp_critical_user_",
8756 IDENTIFIER_POINTER (name
), NULL
));
8757 DECL_NAME (decl
) = get_identifier (new_str
);
8758 TREE_PUBLIC (decl
) = 1;
8759 TREE_STATIC (decl
) = 1;
8760 DECL_COMMON (decl
) = 1;
8761 DECL_ARTIFICIAL (decl
) = 1;
8762 DECL_IGNORED_P (decl
) = 1;
8763 varpool_finalize_decl (decl
);
8765 splay_tree_insert (critical_name_mutexes
, (splay_tree_key
) name
,
8766 (splay_tree_value
) decl
);
8769 decl
= (tree
) n
->value
;
8771 lock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_START
);
8772 lock
= build_call_expr_loc (loc
, lock
, 1, build_fold_addr_expr_loc (loc
, decl
));
8774 unlock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_NAME_END
);
8775 unlock
= build_call_expr_loc (loc
, unlock
, 1,
8776 build_fold_addr_expr_loc (loc
, decl
));
8780 lock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_START
);
8781 lock
= build_call_expr_loc (loc
, lock
, 0);
8783 unlock
= builtin_decl_explicit (BUILT_IN_GOMP_CRITICAL_END
);
8784 unlock
= build_call_expr_loc (loc
, unlock
, 0);
8787 push_gimplify_context (&gctx
);
8789 block
= make_node (BLOCK
);
8790 bind
= gimple_build_bind (NULL
, NULL
, block
);
8791 gsi_replace (gsi_p
, bind
, true);
8792 gimple_bind_add_stmt (bind
, stmt
);
8794 tbody
= gimple_bind_body (bind
);
8795 gimplify_and_add (lock
, &tbody
);
8796 gimple_bind_set_body (bind
, tbody
);
8798 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
8799 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
8800 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
8801 gimple_omp_set_body (stmt
, NULL
);
8803 tbody
= gimple_bind_body (bind
);
8804 gimplify_and_add (unlock
, &tbody
);
8805 gimple_bind_set_body (bind
, tbody
);
8807 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
8809 pop_gimplify_context (bind
);
8810 gimple_bind_append_vars (bind
, ctx
->block_vars
);
8811 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
8815 /* A subroutine of lower_omp_for. Generate code to emit the predicate
8816 for a lastprivate clause. Given a loop control predicate of (V
8817 cond N2), we gate the clause on (!(V cond N2)). The lowered form
8818 is appended to *DLIST, iterator initialization is appended to
8822 lower_omp_for_lastprivate (struct omp_for_data
*fd
, gimple_seq
*body_p
,
8823 gimple_seq
*dlist
, struct omp_context
*ctx
)
8825 tree clauses
, cond
, vinit
;
8826 enum tree_code cond_code
;
8829 cond_code
= fd
->loop
.cond_code
;
8830 cond_code
= cond_code
== LT_EXPR
? GE_EXPR
: LE_EXPR
;
8832 /* When possible, use a strict equality expression. This can let VRP
8833 type optimizations deduce the value and remove a copy. */
8834 if (host_integerp (fd
->loop
.step
, 0))
8836 HOST_WIDE_INT step
= TREE_INT_CST_LOW (fd
->loop
.step
);
8837 if (step
== 1 || step
== -1)
8838 cond_code
= EQ_EXPR
;
8841 cond
= build2 (cond_code
, boolean_type_node
, fd
->loop
.v
, fd
->loop
.n2
);
8843 clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
8845 lower_lastprivate_clauses (clauses
, cond
, &stmts
, ctx
);
8846 if (!gimple_seq_empty_p (stmts
))
8848 gimple_seq_add_seq (&stmts
, *dlist
);
8851 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
8852 vinit
= fd
->loop
.n1
;
8853 if (cond_code
== EQ_EXPR
8854 && host_integerp (fd
->loop
.n2
, 0)
8855 && ! integer_zerop (fd
->loop
.n2
))
8856 vinit
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
8858 vinit
= unshare_expr (vinit
);
8860 /* Initialize the iterator variable, so that threads that don't execute
8861 any iterations don't execute the lastprivate clauses by accident. */
8862 gimplify_assign (fd
->loop
.v
, vinit
, body_p
);
8867 /* Lower code for an OpenMP loop directive. */
8870 lower_omp_for (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
8873 struct omp_for_data fd
, *fdp
= NULL
;
8874 gimple stmt
= gsi_stmt (*gsi_p
), new_stmt
;
8875 gimple_seq omp_for_body
, body
, dlist
;
8877 struct gimplify_ctx gctx
;
8879 push_gimplify_context (&gctx
);
8881 lower_omp (gimple_omp_for_pre_body_ptr (stmt
), ctx
);
8883 block
= make_node (BLOCK
);
8884 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
8885 /* Replace at gsi right away, so that 'stmt' is no member
8886 of a sequence anymore as we're going to add to to a different
8888 gsi_replace (gsi_p
, new_stmt
, true);
8890 /* Move declaration of temporaries in the loop body before we make
8892 omp_for_body
= gimple_omp_body (stmt
);
8893 if (!gimple_seq_empty_p (omp_for_body
)
8894 && gimple_code (gimple_seq_first_stmt (omp_for_body
)) == GIMPLE_BIND
)
8896 tree vars
= gimple_bind_vars (gimple_seq_first_stmt (omp_for_body
));
8897 gimple_bind_append_vars (new_stmt
, vars
);
8900 if (gimple_omp_for_combined_into_p (stmt
))
8902 extract_omp_for_data (stmt
, &fd
, NULL
);
8905 /* We need two temporaries with fd.loop.v type (istart/iend)
8906 and then (fd.collapse - 1) temporaries with the same
8907 type for count2 ... countN-1 vars if not constant. */
8909 tree type
= fd
.iter_type
;
8911 && TREE_CODE (fd
.loop
.n2
) != INTEGER_CST
)
8912 count
+= fd
.collapse
- 1;
8913 bool parallel_for
= gimple_omp_for_kind (stmt
) == GF_OMP_FOR_KIND_FOR
;
8914 tree outerc
= NULL
, *pc
= gimple_omp_for_clauses_ptr (stmt
);
8918 = find_omp_clause (gimple_omp_parallel_clauses (ctx
->outer
->stmt
),
8919 OMP_CLAUSE__LOOPTEMP_
);
8920 for (i
= 0; i
< count
; i
++)
8925 gcc_assert (outerc
);
8926 temp
= lookup_decl (OMP_CLAUSE_DECL (outerc
), ctx
->outer
);
8927 outerc
= find_omp_clause (OMP_CLAUSE_CHAIN (outerc
),
8928 OMP_CLAUSE__LOOPTEMP_
);
8931 temp
= create_tmp_var (type
, NULL
);
8932 *pc
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE__LOOPTEMP_
);
8933 OMP_CLAUSE_DECL (*pc
) = temp
;
8934 pc
= &OMP_CLAUSE_CHAIN (*pc
);
8939 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
8942 lower_rec_input_clauses (gimple_omp_for_clauses (stmt
), &body
, &dlist
, ctx
,
8944 gimple_seq_add_seq (&body
, gimple_omp_for_pre_body (stmt
));
8946 lower_omp (gimple_omp_body_ptr (stmt
), ctx
);
8948 /* Lower the header expressions. At this point, we can assume that
8949 the header is of the form:
8951 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
8953 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
8954 using the .omp_data_s mapping, if needed. */
8955 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
8957 rhs_p
= gimple_omp_for_initial_ptr (stmt
, i
);
8958 if (!is_gimple_min_invariant (*rhs_p
))
8959 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
8961 rhs_p
= gimple_omp_for_final_ptr (stmt
, i
);
8962 if (!is_gimple_min_invariant (*rhs_p
))
8963 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
8965 rhs_p
= &TREE_OPERAND (gimple_omp_for_incr (stmt
, i
), 1);
8966 if (!is_gimple_min_invariant (*rhs_p
))
8967 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
8970 /* Once lowered, extract the bounds and clauses. */
8971 extract_omp_for_data (stmt
, &fd
, NULL
);
8973 lower_omp_for_lastprivate (&fd
, &body
, &dlist
, ctx
);
8975 gimple_seq_add_stmt (&body
, stmt
);
8976 gimple_seq_add_seq (&body
, gimple_omp_body (stmt
));
8978 gimple_seq_add_stmt (&body
, gimple_build_omp_continue (fd
.loop
.v
,
8981 /* After the loop, add exit clauses. */
8982 lower_reduction_clauses (gimple_omp_for_clauses (stmt
), &body
, ctx
);
8984 if (ctx
->cancellable
)
8985 gimple_seq_add_stmt (&body
, gimple_build_label (ctx
->cancel_label
));
8987 gimple_seq_add_seq (&body
, dlist
);
8989 body
= maybe_catch_exception (body
);
8991 /* Region exit marker goes at the end of the loop body. */
8992 gimple_seq_add_stmt (&body
, gimple_build_omp_return (fd
.have_nowait
));
8993 maybe_add_implicit_barrier_cancel (ctx
, &body
);
8994 pop_gimplify_context (new_stmt
);
8996 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
8997 BLOCK_VARS (block
) = gimple_bind_vars (new_stmt
);
8998 if (BLOCK_VARS (block
))
8999 TREE_USED (block
) = 1;
9001 gimple_bind_set_body (new_stmt
, body
);
9002 gimple_omp_set_body (stmt
, NULL
);
9003 gimple_omp_for_set_pre_body (stmt
, NULL
);
9006 /* Callback for walk_stmts. Check if the current statement only contains
9007 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
9010 check_combined_parallel (gimple_stmt_iterator
*gsi_p
,
9011 bool *handled_ops_p
,
9012 struct walk_stmt_info
*wi
)
9014 int *info
= (int *) wi
->info
;
9015 gimple stmt
= gsi_stmt (*gsi_p
);
9017 *handled_ops_p
= true;
9018 switch (gimple_code (stmt
))
9022 case GIMPLE_OMP_FOR
:
9023 case GIMPLE_OMP_SECTIONS
:
9024 *info
= *info
== 0 ? 1 : -1;
9033 struct omp_taskcopy_context
9035 /* This field must be at the beginning, as we do "inheritance": Some
9036 callback functions for tree-inline.c (e.g., omp_copy_decl)
9037 receive a copy_body_data pointer that is up-casted to an
9038 omp_context pointer. */
9044 task_copyfn_copy_decl (tree var
, copy_body_data
*cb
)
9046 struct omp_taskcopy_context
*tcctx
= (struct omp_taskcopy_context
*) cb
;
9048 if (splay_tree_lookup (tcctx
->ctx
->sfield_map
, (splay_tree_key
) var
))
9049 return create_tmp_var (TREE_TYPE (var
), NULL
);
9055 task_copyfn_remap_type (struct omp_taskcopy_context
*tcctx
, tree orig_type
)
9057 tree name
, new_fields
= NULL
, type
, f
;
9059 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
9060 name
= DECL_NAME (TYPE_NAME (orig_type
));
9061 name
= build_decl (gimple_location (tcctx
->ctx
->stmt
),
9062 TYPE_DECL
, name
, type
);
9063 TYPE_NAME (type
) = name
;
9065 for (f
= TYPE_FIELDS (orig_type
); f
; f
= TREE_CHAIN (f
))
9067 tree new_f
= copy_node (f
);
9068 DECL_CONTEXT (new_f
) = type
;
9069 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &tcctx
->cb
);
9070 TREE_CHAIN (new_f
) = new_fields
;
9071 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
9072 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
9073 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
9076 *pointer_map_insert (tcctx
->cb
.decl_map
, f
) = new_f
;
9078 TYPE_FIELDS (type
) = nreverse (new_fields
);
9083 /* Create task copyfn. */
9086 create_task_copyfn (gimple task_stmt
, omp_context
*ctx
)
9088 struct function
*child_cfun
;
9089 tree child_fn
, t
, c
, src
, dst
, f
, sf
, arg
, sarg
, decl
;
9090 tree record_type
, srecord_type
, bind
, list
;
9091 bool record_needs_remap
= false, srecord_needs_remap
= false;
9093 struct omp_taskcopy_context tcctx
;
9094 struct gimplify_ctx gctx
;
9095 location_t loc
= gimple_location (task_stmt
);
9097 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
9098 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
9099 gcc_assert (child_cfun
->cfg
== NULL
);
9100 DECL_SAVED_TREE (child_fn
) = alloc_stmt_list ();
9102 /* Reset DECL_CONTEXT on function arguments. */
9103 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
9104 DECL_CONTEXT (t
) = child_fn
;
9106 /* Populate the function. */
9107 push_gimplify_context (&gctx
);
9108 push_cfun (child_cfun
);
9110 bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
9111 TREE_SIDE_EFFECTS (bind
) = 1;
9113 DECL_SAVED_TREE (child_fn
) = bind
;
9114 DECL_SOURCE_LOCATION (child_fn
) = gimple_location (task_stmt
);
9116 /* Remap src and dst argument types if needed. */
9117 record_type
= ctx
->record_type
;
9118 srecord_type
= ctx
->srecord_type
;
9119 for (f
= TYPE_FIELDS (record_type
); f
; f
= DECL_CHAIN (f
))
9120 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
9122 record_needs_remap
= true;
9125 for (f
= TYPE_FIELDS (srecord_type
); f
; f
= DECL_CHAIN (f
))
9126 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
9128 srecord_needs_remap
= true;
9132 if (record_needs_remap
|| srecord_needs_remap
)
9134 memset (&tcctx
, '\0', sizeof (tcctx
));
9135 tcctx
.cb
.src_fn
= ctx
->cb
.src_fn
;
9136 tcctx
.cb
.dst_fn
= child_fn
;
9137 tcctx
.cb
.src_node
= cgraph_get_node (tcctx
.cb
.src_fn
);
9138 gcc_checking_assert (tcctx
.cb
.src_node
);
9139 tcctx
.cb
.dst_node
= tcctx
.cb
.src_node
;
9140 tcctx
.cb
.src_cfun
= ctx
->cb
.src_cfun
;
9141 tcctx
.cb
.copy_decl
= task_copyfn_copy_decl
;
9142 tcctx
.cb
.eh_lp_nr
= 0;
9143 tcctx
.cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
9144 tcctx
.cb
.decl_map
= pointer_map_create ();
9147 if (record_needs_remap
)
9148 record_type
= task_copyfn_remap_type (&tcctx
, record_type
);
9149 if (srecord_needs_remap
)
9150 srecord_type
= task_copyfn_remap_type (&tcctx
, srecord_type
);
9153 tcctx
.cb
.decl_map
= NULL
;
9155 arg
= DECL_ARGUMENTS (child_fn
);
9156 TREE_TYPE (arg
) = build_pointer_type (record_type
);
9157 sarg
= DECL_CHAIN (arg
);
9158 TREE_TYPE (sarg
) = build_pointer_type (srecord_type
);
9160 /* First pass: initialize temporaries used in record_type and srecord_type
9161 sizes and field offsets. */
9162 if (tcctx
.cb
.decl_map
)
9163 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
9164 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
9168 decl
= OMP_CLAUSE_DECL (c
);
9169 p
= (tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, decl
);
9172 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
9173 sf
= (tree
) n
->value
;
9174 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
9175 src
= build_simple_mem_ref_loc (loc
, sarg
);
9176 src
= omp_build_component_ref (src
, sf
);
9177 t
= build2 (MODIFY_EXPR
, TREE_TYPE (*p
), *p
, src
);
9178 append_to_statement_list (t
, &list
);
9181 /* Second pass: copy shared var pointers and copy construct non-VLA
9182 firstprivate vars. */
9183 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
9184 switch (OMP_CLAUSE_CODE (c
))
9186 case OMP_CLAUSE_SHARED
:
9187 decl
= OMP_CLAUSE_DECL (c
);
9188 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
9191 f
= (tree
) n
->value
;
9192 if (tcctx
.cb
.decl_map
)
9193 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
9194 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
9195 sf
= (tree
) n
->value
;
9196 if (tcctx
.cb
.decl_map
)
9197 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
9198 src
= build_simple_mem_ref_loc (loc
, sarg
);
9199 src
= omp_build_component_ref (src
, sf
);
9200 dst
= build_simple_mem_ref_loc (loc
, arg
);
9201 dst
= omp_build_component_ref (dst
, f
);
9202 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
9203 append_to_statement_list (t
, &list
);
9205 case OMP_CLAUSE_FIRSTPRIVATE
:
9206 decl
= OMP_CLAUSE_DECL (c
);
9207 if (is_variable_sized (decl
))
9209 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
9212 f
= (tree
) n
->value
;
9213 if (tcctx
.cb
.decl_map
)
9214 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
9215 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
9218 sf
= (tree
) n
->value
;
9219 if (tcctx
.cb
.decl_map
)
9220 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
9221 src
= build_simple_mem_ref_loc (loc
, sarg
);
9222 src
= omp_build_component_ref (src
, sf
);
9223 if (use_pointer_for_field (decl
, NULL
) || is_reference (decl
))
9224 src
= build_simple_mem_ref_loc (loc
, src
);
9228 dst
= build_simple_mem_ref_loc (loc
, arg
);
9229 dst
= omp_build_component_ref (dst
, f
);
9230 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
9231 append_to_statement_list (t
, &list
);
9233 case OMP_CLAUSE_PRIVATE
:
9234 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
9236 decl
= OMP_CLAUSE_DECL (c
);
9237 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
9238 f
= (tree
) n
->value
;
9239 if (tcctx
.cb
.decl_map
)
9240 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
9241 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
9244 sf
= (tree
) n
->value
;
9245 if (tcctx
.cb
.decl_map
)
9246 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
9247 src
= build_simple_mem_ref_loc (loc
, sarg
);
9248 src
= omp_build_component_ref (src
, sf
);
9249 if (use_pointer_for_field (decl
, NULL
))
9250 src
= build_simple_mem_ref_loc (loc
, src
);
9254 dst
= build_simple_mem_ref_loc (loc
, arg
);
9255 dst
= omp_build_component_ref (dst
, f
);
9256 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
9257 append_to_statement_list (t
, &list
);
9263 /* Last pass: handle VLA firstprivates. */
9264 if (tcctx
.cb
.decl_map
)
9265 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
9266 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
9270 decl
= OMP_CLAUSE_DECL (c
);
9271 if (!is_variable_sized (decl
))
9273 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
9276 f
= (tree
) n
->value
;
9277 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
9278 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl
));
9279 ind
= DECL_VALUE_EXPR (decl
);
9280 gcc_assert (TREE_CODE (ind
) == INDIRECT_REF
);
9281 gcc_assert (DECL_P (TREE_OPERAND (ind
, 0)));
9282 n
= splay_tree_lookup (ctx
->sfield_map
,
9283 (splay_tree_key
) TREE_OPERAND (ind
, 0));
9284 sf
= (tree
) n
->value
;
9285 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
9286 src
= build_simple_mem_ref_loc (loc
, sarg
);
9287 src
= omp_build_component_ref (src
, sf
);
9288 src
= build_simple_mem_ref_loc (loc
, src
);
9289 dst
= build_simple_mem_ref_loc (loc
, arg
);
9290 dst
= omp_build_component_ref (dst
, f
);
9291 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
9292 append_to_statement_list (t
, &list
);
9293 n
= splay_tree_lookup (ctx
->field_map
,
9294 (splay_tree_key
) TREE_OPERAND (ind
, 0));
9295 df
= (tree
) n
->value
;
9296 df
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, df
);
9297 ptr
= build_simple_mem_ref_loc (loc
, arg
);
9298 ptr
= omp_build_component_ref (ptr
, df
);
9299 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ptr
), ptr
,
9300 build_fold_addr_expr_loc (loc
, dst
));
9301 append_to_statement_list (t
, &list
);
9304 t
= build1 (RETURN_EXPR
, void_type_node
, NULL
);
9305 append_to_statement_list (t
, &list
);
9307 if (tcctx
.cb
.decl_map
)
9308 pointer_map_destroy (tcctx
.cb
.decl_map
);
9309 pop_gimplify_context (NULL
);
9310 BIND_EXPR_BODY (bind
) = list
;
9315 lower_depend_clauses (gimple stmt
, gimple_seq
*iseq
, gimple_seq
*oseq
)
9319 size_t n_in
= 0, n_out
= 0, idx
= 2, i
;
9321 clauses
= find_omp_clause (gimple_omp_task_clauses (stmt
),
9323 gcc_assert (clauses
);
9324 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
9325 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
)
9326 switch (OMP_CLAUSE_DEPEND_KIND (c
))
9328 case OMP_CLAUSE_DEPEND_IN
:
9331 case OMP_CLAUSE_DEPEND_OUT
:
9332 case OMP_CLAUSE_DEPEND_INOUT
:
9338 tree type
= build_array_type_nelts (ptr_type_node
, n_in
+ n_out
+ 2);
9339 tree array
= create_tmp_var (type
, NULL
);
9340 tree r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (0), NULL_TREE
,
9342 g
= gimple_build_assign (r
, build_int_cst (ptr_type_node
, n_in
+ n_out
));
9343 gimple_seq_add_stmt (iseq
, g
);
9344 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (1), NULL_TREE
,
9346 g
= gimple_build_assign (r
, build_int_cst (ptr_type_node
, n_out
));
9347 gimple_seq_add_stmt (iseq
, g
);
9348 for (i
= 0; i
< 2; i
++)
9350 if ((i
? n_in
: n_out
) == 0)
9352 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
9353 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_DEPEND
9354 && ((OMP_CLAUSE_DEPEND_KIND (c
) != OMP_CLAUSE_DEPEND_IN
) ^ i
))
9356 tree t
= OMP_CLAUSE_DECL (c
);
9357 t
= fold_convert (ptr_type_node
, t
);
9358 gimplify_expr (&t
, iseq
, NULL
, is_gimple_val
, fb_rvalue
);
9359 r
= build4 (ARRAY_REF
, ptr_type_node
, array
, size_int (idx
++),
9360 NULL_TREE
, NULL_TREE
);
9361 g
= gimple_build_assign (r
, t
);
9362 gimple_seq_add_stmt (iseq
, g
);
9365 tree
*p
= gimple_omp_task_clauses_ptr (stmt
);
9366 c
= build_omp_clause (UNKNOWN_LOCATION
, OMP_CLAUSE_DEPEND
);
9367 OMP_CLAUSE_DECL (c
) = build_fold_addr_expr (array
);
9368 OMP_CLAUSE_CHAIN (c
) = *p
;
9370 tree clobber
= build_constructor (type
, NULL
);
9371 TREE_THIS_VOLATILE (clobber
) = 1;
9372 g
= gimple_build_assign (array
, clobber
);
9373 gimple_seq_add_stmt (oseq
, g
);
9376 /* Lower the OpenMP parallel or task directive in the current statement
9377 in GSI_P. CTX holds context information for the directive. */
9380 lower_omp_taskreg (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
9384 gimple stmt
= gsi_stmt (*gsi_p
);
9385 gimple par_bind
, bind
, dep_bind
= NULL
;
9386 gimple_seq par_body
, olist
, ilist
, par_olist
, par_rlist
, par_ilist
, new_body
;
9387 struct gimplify_ctx gctx
, dep_gctx
;
9388 location_t loc
= gimple_location (stmt
);
9390 clauses
= gimple_omp_taskreg_clauses (stmt
);
9391 par_bind
= gimple_seq_first_stmt (gimple_omp_body (stmt
));
9392 par_body
= gimple_bind_body (par_bind
);
9393 child_fn
= ctx
->cb
.dst_fn
;
9394 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
9395 && !gimple_omp_parallel_combined_p (stmt
))
9397 struct walk_stmt_info wi
;
9400 memset (&wi
, 0, sizeof (wi
));
9403 walk_gimple_seq (par_body
, check_combined_parallel
, NULL
, &wi
);
9405 gimple_omp_parallel_set_combined_p (stmt
, true);
9407 gimple_seq dep_ilist
= NULL
;
9408 gimple_seq dep_olist
= NULL
;
9409 if (gimple_code (stmt
) == GIMPLE_OMP_TASK
9410 && find_omp_clause (clauses
, OMP_CLAUSE_DEPEND
))
9412 push_gimplify_context (&dep_gctx
);
9413 dep_bind
= gimple_build_bind (NULL
, NULL
, make_node (BLOCK
));
9414 lower_depend_clauses (stmt
, &dep_ilist
, &dep_olist
);
9417 if (ctx
->srecord_type
)
9418 create_task_copyfn (stmt
, ctx
);
9420 push_gimplify_context (&gctx
);
9425 lower_rec_input_clauses (clauses
, &par_ilist
, &par_olist
, ctx
, NULL
);
9426 lower_omp (&par_body
, ctx
);
9427 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
)
9428 lower_reduction_clauses (clauses
, &par_rlist
, ctx
);
9430 /* Declare all the variables created by mapping and the variables
9431 declared in the scope of the parallel body. */
9432 record_vars_into (ctx
->block_vars
, child_fn
);
9433 record_vars_into (gimple_bind_vars (par_bind
), child_fn
);
9435 if (ctx
->record_type
)
9438 = create_tmp_var (ctx
->srecord_type
? ctx
->srecord_type
9439 : ctx
->record_type
, ".omp_data_o");
9440 DECL_NAMELESS (ctx
->sender_decl
) = 1;
9441 TREE_ADDRESSABLE (ctx
->sender_decl
) = 1;
9442 gimple_omp_taskreg_set_data_arg (stmt
, ctx
->sender_decl
);
9447 lower_send_clauses (clauses
, &ilist
, &olist
, ctx
);
9448 lower_send_shared_vars (&ilist
, &olist
, ctx
);
9450 if (ctx
->record_type
)
9452 tree clobber
= build_constructor (TREE_TYPE (ctx
->sender_decl
), NULL
);
9453 TREE_THIS_VOLATILE (clobber
) = 1;
9454 gimple_seq_add_stmt (&olist
, gimple_build_assign (ctx
->sender_decl
,
9458 /* Once all the expansions are done, sequence all the different
9459 fragments inside gimple_omp_body. */
9463 if (ctx
->record_type
)
9465 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
9466 /* fixup_child_record_type might have changed receiver_decl's type. */
9467 t
= fold_convert_loc (loc
, TREE_TYPE (ctx
->receiver_decl
), t
);
9468 gimple_seq_add_stmt (&new_body
,
9469 gimple_build_assign (ctx
->receiver_decl
, t
));
9472 gimple_seq_add_seq (&new_body
, par_ilist
);
9473 gimple_seq_add_seq (&new_body
, par_body
);
9474 gimple_seq_add_seq (&new_body
, par_rlist
);
9475 if (ctx
->cancellable
)
9476 gimple_seq_add_stmt (&new_body
, gimple_build_label (ctx
->cancel_label
));
9477 gimple_seq_add_seq (&new_body
, par_olist
);
9478 new_body
= maybe_catch_exception (new_body
);
9479 gimple_seq_add_stmt (&new_body
, gimple_build_omp_return (false));
9480 gimple_omp_set_body (stmt
, new_body
);
9482 bind
= gimple_build_bind (NULL
, NULL
, gimple_bind_block (par_bind
));
9483 gsi_replace (gsi_p
, dep_bind
? dep_bind
: bind
, true);
9484 gimple_bind_add_seq (bind
, ilist
);
9485 gimple_bind_add_stmt (bind
, stmt
);
9486 gimple_bind_add_seq (bind
, olist
);
9488 pop_gimplify_context (NULL
);
9492 gimple_bind_add_seq (dep_bind
, dep_ilist
);
9493 gimple_bind_add_stmt (dep_bind
, bind
);
9494 gimple_bind_add_seq (dep_bind
, dep_olist
);
9495 pop_gimplify_context (dep_bind
);
9499 /* Lower the OpenMP target directive in the current statement
9500 in GSI_P. CTX holds context information for the directive. */
9503 lower_omp_target (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
9506 tree child_fn
, t
, c
;
9507 gimple stmt
= gsi_stmt (*gsi_p
);
9508 gimple tgt_bind
= NULL
, bind
;
9509 gimple_seq tgt_body
= NULL
, olist
, ilist
, new_body
;
9510 struct gimplify_ctx gctx
;
9511 location_t loc
= gimple_location (stmt
);
9512 int kind
= gimple_omp_target_kind (stmt
);
9513 unsigned int map_cnt
= 0;
9515 clauses
= gimple_omp_target_clauses (stmt
);
9516 if (kind
== GF_OMP_TARGET_KIND_REGION
)
9518 tgt_bind
= gimple_seq_first_stmt (gimple_omp_body (stmt
));
9519 tgt_body
= gimple_bind_body (tgt_bind
);
9521 else if (kind
== GF_OMP_TARGET_KIND_DATA
)
9522 tgt_body
= gimple_omp_body (stmt
);
9523 child_fn
= ctx
->cb
.dst_fn
;
9525 push_gimplify_context (&gctx
);
9527 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
9528 switch (OMP_CLAUSE_CODE (c
))
9534 case OMP_CLAUSE_MAP
:
9536 case OMP_CLAUSE_FROM
:
9537 var
= OMP_CLAUSE_DECL (c
);
9540 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_MAP
9541 || !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c
))
9547 && TREE_CODE (DECL_SIZE (var
)) != INTEGER_CST
)
9549 tree var2
= DECL_VALUE_EXPR (var
);
9550 gcc_assert (TREE_CODE (var2
) == INDIRECT_REF
);
9551 var2
= TREE_OPERAND (var2
, 0);
9552 gcc_assert (DECL_P (var2
));
9556 if (!maybe_lookup_field (var
, ctx
))
9559 if (kind
== GF_OMP_TARGET_KIND_REGION
)
9561 x
= build_receiver_ref (var
, true, ctx
);
9562 tree new_var
= lookup_decl (var
, ctx
);
9563 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
9564 && OMP_CLAUSE_MAP_KIND (c
) == OMP_CLAUSE_MAP_POINTER
9565 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c
)
9566 && TREE_CODE (TREE_TYPE (var
)) == ARRAY_TYPE
)
9567 x
= build_simple_mem_ref (x
);
9568 SET_DECL_VALUE_EXPR (new_var
, x
);
9569 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
9574 if (kind
== GF_OMP_TARGET_KIND_REGION
)
9576 target_nesting_level
++;
9577 lower_omp (&tgt_body
, ctx
);
9578 target_nesting_level
--;
9580 else if (kind
== GF_OMP_TARGET_KIND_DATA
)
9581 lower_omp (&tgt_body
, ctx
);
9583 if (kind
== GF_OMP_TARGET_KIND_REGION
)
9585 /* Declare all the variables created by mapping and the variables
9586 declared in the scope of the target body. */
9587 record_vars_into (ctx
->block_vars
, child_fn
);
9588 record_vars_into (gimple_bind_vars (tgt_bind
), child_fn
);
9593 if (ctx
->record_type
)
9596 = create_tmp_var (ctx
->record_type
, ".omp_data_arr");
9597 DECL_NAMELESS (ctx
->sender_decl
) = 1;
9598 TREE_ADDRESSABLE (ctx
->sender_decl
) = 1;
9599 t
= make_tree_vec (3);
9600 TREE_VEC_ELT (t
, 0) = ctx
->sender_decl
;
9602 = create_tmp_var (build_array_type_nelts (size_type_node
, map_cnt
),
9604 DECL_NAMELESS (TREE_VEC_ELT (t
, 1)) = 1;
9605 TREE_ADDRESSABLE (TREE_VEC_ELT (t
, 1)) = 1;
9606 TREE_STATIC (TREE_VEC_ELT (t
, 1)) = 1;
9608 = create_tmp_var (build_array_type_nelts (unsigned_char_type_node
,
9611 DECL_NAMELESS (TREE_VEC_ELT (t
, 2)) = 1;
9612 TREE_ADDRESSABLE (TREE_VEC_ELT (t
, 2)) = 1;
9613 TREE_STATIC (TREE_VEC_ELT (t
, 2)) = 1;
9614 gimple_omp_target_set_data_arg (stmt
, t
);
9616 vec
<constructor_elt
, va_gc
> *vsize
;
9617 vec
<constructor_elt
, va_gc
> *vkind
;
9618 vec_alloc (vsize
, map_cnt
);
9619 vec_alloc (vkind
, map_cnt
);
9620 unsigned int map_idx
= 0;
9622 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
9623 switch (OMP_CLAUSE_CODE (c
))
9629 case OMP_CLAUSE_MAP
:
9631 case OMP_CLAUSE_FROM
:
9633 ovar
= OMP_CLAUSE_DECL (c
);
9636 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
9637 && OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c
))
9639 gcc_checking_assert (OMP_CLAUSE_DECL (OMP_CLAUSE_CHAIN (c
))
9640 == get_base_address (ovar
));
9641 nc
= OMP_CLAUSE_CHAIN (c
);
9642 ovar
= OMP_CLAUSE_DECL (nc
);
9646 tree x
= build_sender_ref (ovar
, ctx
);
9648 = build_fold_addr_expr_with_type (ovar
, ptr_type_node
);
9649 gimplify_assign (x
, v
, &ilist
);
9655 if (DECL_SIZE (ovar
)
9656 && TREE_CODE (DECL_SIZE (ovar
)) != INTEGER_CST
)
9658 tree ovar2
= DECL_VALUE_EXPR (ovar
);
9659 gcc_assert (TREE_CODE (ovar2
) == INDIRECT_REF
);
9660 ovar2
= TREE_OPERAND (ovar2
, 0);
9661 gcc_assert (DECL_P (ovar2
));
9664 if (!maybe_lookup_field (ovar
, ctx
))
9670 tree var
= lookup_decl_in_outer_ctx (ovar
, ctx
);
9671 tree x
= build_sender_ref (ovar
, ctx
);
9672 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_MAP
9673 && OMP_CLAUSE_MAP_KIND (c
) == OMP_CLAUSE_MAP_POINTER
9674 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c
)
9675 && TREE_CODE (TREE_TYPE (ovar
)) == ARRAY_TYPE
)
9677 gcc_assert (kind
== GF_OMP_TARGET_KIND_REGION
);
9679 = create_tmp_var (TREE_TYPE (TREE_TYPE (x
)), NULL
);
9680 mark_addressable (avar
);
9681 gimplify_assign (avar
, build_fold_addr_expr (var
), &ilist
);
9682 avar
= build_fold_addr_expr (avar
);
9683 gimplify_assign (x
, avar
, &ilist
);
9685 else if (is_gimple_reg (var
))
9687 gcc_assert (kind
== GF_OMP_TARGET_KIND_REGION
);
9688 tree avar
= create_tmp_var (TREE_TYPE (var
), NULL
);
9689 mark_addressable (avar
);
9690 if (OMP_CLAUSE_MAP_KIND (c
) != OMP_CLAUSE_MAP_ALLOC
9691 && OMP_CLAUSE_MAP_KIND (c
) != OMP_CLAUSE_MAP_FROM
)
9692 gimplify_assign (avar
, var
, &ilist
);
9693 avar
= build_fold_addr_expr (avar
);
9694 gimplify_assign (x
, avar
, &ilist
);
9695 if ((OMP_CLAUSE_MAP_KIND (c
) == OMP_CLAUSE_MAP_FROM
9696 || OMP_CLAUSE_MAP_KIND (c
) == OMP_CLAUSE_MAP_TOFROM
)
9697 && !TYPE_READONLY (TREE_TYPE (var
)))
9699 x
= build_sender_ref (ovar
, ctx
);
9700 x
= build_simple_mem_ref (x
);
9701 gimplify_assign (var
, x
, &olist
);
9706 var
= build_fold_addr_expr (var
);
9707 gimplify_assign (x
, var
, &ilist
);
9710 tree s
= OMP_CLAUSE_SIZE (c
);
9712 s
= TYPE_SIZE_UNIT (TREE_TYPE (ovar
));
9713 s
= fold_convert (size_type_node
, s
);
9714 tree purpose
= size_int (map_idx
++);
9715 CONSTRUCTOR_APPEND_ELT (vsize
, purpose
, s
);
9716 if (TREE_CODE (s
) != INTEGER_CST
)
9717 TREE_STATIC (TREE_VEC_ELT (t
, 1)) = 0;
9719 unsigned char tkind
= 0;
9720 switch (OMP_CLAUSE_CODE (c
))
9722 case OMP_CLAUSE_MAP
:
9723 tkind
= OMP_CLAUSE_MAP_KIND (c
);
9726 tkind
= OMP_CLAUSE_MAP_TO
;
9728 case OMP_CLAUSE_FROM
:
9729 tkind
= OMP_CLAUSE_MAP_FROM
;
9734 unsigned int talign
= TYPE_ALIGN_UNIT (TREE_TYPE (ovar
));
9735 if (DECL_P (ovar
) && DECL_ALIGN_UNIT (ovar
) > talign
)
9736 talign
= DECL_ALIGN_UNIT (ovar
);
9737 talign
= ceil_log2 (talign
);
9738 tkind
|= talign
<< 3;
9739 CONSTRUCTOR_APPEND_ELT (vkind
, purpose
,
9740 build_int_cst (unsigned_char_type_node
,
9746 gcc_assert (map_idx
== map_cnt
);
9748 DECL_INITIAL (TREE_VEC_ELT (t
, 1))
9749 = build_constructor (TREE_TYPE (TREE_VEC_ELT (t
, 1)), vsize
);
9750 DECL_INITIAL (TREE_VEC_ELT (t
, 2))
9751 = build_constructor (TREE_TYPE (TREE_VEC_ELT (t
, 2)), vkind
);
9752 if (!TREE_STATIC (TREE_VEC_ELT (t
, 1)))
9754 gimple_seq initlist
= NULL
;
9755 force_gimple_operand (build1 (DECL_EXPR
, void_type_node
,
9756 TREE_VEC_ELT (t
, 1)),
9757 &initlist
, true, NULL_TREE
);
9758 gimple_seq_add_seq (&ilist
, initlist
);
9761 tree clobber
= build_constructor (ctx
->record_type
, NULL
);
9762 TREE_THIS_VOLATILE (clobber
) = 1;
9763 gimple_seq_add_stmt (&olist
, gimple_build_assign (ctx
->sender_decl
,
9767 /* Once all the expansions are done, sequence all the different
9768 fragments inside gimple_omp_body. */
9772 if (ctx
->record_type
&& kind
== GF_OMP_TARGET_KIND_REGION
)
9774 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
9775 /* fixup_child_record_type might have changed receiver_decl's type. */
9776 t
= fold_convert_loc (loc
, TREE_TYPE (ctx
->receiver_decl
), t
);
9777 gimple_seq_add_stmt (&new_body
,
9778 gimple_build_assign (ctx
->receiver_decl
, t
));
9781 if (kind
== GF_OMP_TARGET_KIND_REGION
)
9783 gimple_seq_add_seq (&new_body
, tgt_body
);
9784 new_body
= maybe_catch_exception (new_body
);
9786 else if (kind
== GF_OMP_TARGET_KIND_DATA
)
9787 new_body
= tgt_body
;
9788 if (kind
!= GF_OMP_TARGET_KIND_UPDATE
)
9790 gimple_seq_add_stmt (&new_body
, gimple_build_omp_return (false));
9791 gimple_omp_set_body (stmt
, new_body
);
9794 bind
= gimple_build_bind (NULL
, NULL
,
9795 tgt_bind
? gimple_bind_block (tgt_bind
)
9797 gsi_replace (gsi_p
, bind
, true);
9798 gimple_bind_add_seq (bind
, ilist
);
9799 gimple_bind_add_stmt (bind
, stmt
);
9800 gimple_bind_add_seq (bind
, olist
);
9802 pop_gimplify_context (NULL
);
9805 /* Expand code for an OpenMP teams directive. */
9808 lower_omp_teams (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
9810 gimple teams_stmt
= gsi_stmt (*gsi_p
);
9811 struct gimplify_ctx gctx
;
9812 push_gimplify_context (&gctx
);
9814 tree block
= make_node (BLOCK
);
9815 gimple bind
= gimple_build_bind (NULL
, NULL
, block
);
9816 gsi_replace (gsi_p
, bind
, true);
9817 gimple_seq bind_body
= NULL
;
9818 gimple_seq dlist
= NULL
;
9819 gimple_seq olist
= NULL
;
9821 tree num_teams
= find_omp_clause (gimple_omp_teams_clauses (teams_stmt
),
9822 OMP_CLAUSE_NUM_TEAMS
);
9823 if (num_teams
== NULL_TREE
)
9824 num_teams
= build_int_cst (unsigned_type_node
, 0);
9827 num_teams
= OMP_CLAUSE_NUM_TEAMS_EXPR (num_teams
);
9828 num_teams
= fold_convert (unsigned_type_node
, num_teams
);
9829 gimplify_expr (&num_teams
, &bind_body
, NULL
, is_gimple_val
, fb_rvalue
);
9831 tree thread_limit
= find_omp_clause (gimple_omp_teams_clauses (teams_stmt
),
9832 OMP_CLAUSE_THREAD_LIMIT
);
9833 if (thread_limit
== NULL_TREE
)
9834 thread_limit
= build_int_cst (unsigned_type_node
, 0);
9837 thread_limit
= OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit
);
9838 thread_limit
= fold_convert (unsigned_type_node
, thread_limit
);
9839 gimplify_expr (&thread_limit
, &bind_body
, NULL
, is_gimple_val
,
9843 lower_rec_input_clauses (gimple_omp_teams_clauses (teams_stmt
),
9844 &bind_body
, &dlist
, ctx
, NULL
);
9845 lower_omp (gimple_omp_body_ptr (teams_stmt
), ctx
);
9846 lower_reduction_clauses (gimple_omp_teams_clauses (teams_stmt
), &olist
, ctx
);
9847 gimple_seq_add_stmt (&bind_body
, teams_stmt
);
9849 location_t loc
= gimple_location (teams_stmt
);
9850 tree decl
= builtin_decl_explicit (BUILT_IN_GOMP_TEAMS
);
9851 gimple call
= gimple_build_call (decl
, 2, num_teams
, thread_limit
);
9852 gimple_set_location (call
, loc
);
9853 gimple_seq_add_stmt (&bind_body
, call
);
9855 gimple_seq_add_seq (&bind_body
, gimple_omp_body (teams_stmt
));
9856 gimple_omp_set_body (teams_stmt
, NULL
);
9857 gimple_seq_add_seq (&bind_body
, olist
);
9858 gimple_seq_add_seq (&bind_body
, dlist
);
9859 gimple_seq_add_stmt (&bind_body
, gimple_build_omp_return (true));
9860 gimple_bind_set_body (bind
, bind_body
);
9862 pop_gimplify_context (bind
);
9864 gimple_bind_append_vars (bind
, ctx
->block_vars
);
9865 BLOCK_VARS (block
) = ctx
->block_vars
;
9866 if (BLOCK_VARS (block
))
9867 TREE_USED (block
) = 1;
9871 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
9872 regimplified. If DATA is non-NULL, lower_omp_1 is outside
9873 of OpenMP context, but with task_shared_vars set. */
9876 lower_omp_regimplify_p (tree
*tp
, int *walk_subtrees
,
9881 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
9882 if (TREE_CODE (t
) == VAR_DECL
&& data
== NULL
&& DECL_HAS_VALUE_EXPR_P (t
))
9885 if (task_shared_vars
9887 && bitmap_bit_p (task_shared_vars
, DECL_UID (t
)))
9890 /* If a global variable has been privatized, TREE_CONSTANT on
9891 ADDR_EXPR might be wrong. */
9892 if (data
== NULL
&& TREE_CODE (t
) == ADDR_EXPR
)
9893 recompute_tree_invariant_for_addr_expr (t
);
9895 *walk_subtrees
= !TYPE_P (t
) && !DECL_P (t
);
9900 lower_omp_1 (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
9902 gimple stmt
= gsi_stmt (*gsi_p
);
9903 struct walk_stmt_info wi
;
9905 if (gimple_has_location (stmt
))
9906 input_location
= gimple_location (stmt
);
9908 if (task_shared_vars
)
9909 memset (&wi
, '\0', sizeof (wi
));
9911 /* If we have issued syntax errors, avoid doing any heavy lifting.
9912 Just replace the OpenMP directives with a NOP to avoid
9913 confusing RTL expansion. */
9914 if (seen_error () && is_gimple_omp (stmt
))
9916 gsi_replace (gsi_p
, gimple_build_nop (), true);
9920 switch (gimple_code (stmt
))
9923 if ((ctx
|| task_shared_vars
)
9924 && (walk_tree (gimple_cond_lhs_ptr (stmt
), lower_omp_regimplify_p
,
9925 ctx
? NULL
: &wi
, NULL
)
9926 || walk_tree (gimple_cond_rhs_ptr (stmt
), lower_omp_regimplify_p
,
9927 ctx
? NULL
: &wi
, NULL
)))
9928 gimple_regimplify_operands (stmt
, gsi_p
);
9931 lower_omp (gimple_catch_handler_ptr (stmt
), ctx
);
9933 case GIMPLE_EH_FILTER
:
9934 lower_omp (gimple_eh_filter_failure_ptr (stmt
), ctx
);
9937 lower_omp (gimple_try_eval_ptr (stmt
), ctx
);
9938 lower_omp (gimple_try_cleanup_ptr (stmt
), ctx
);
9940 case GIMPLE_TRANSACTION
:
9941 lower_omp (gimple_transaction_body_ptr (stmt
), ctx
);
9944 lower_omp (gimple_bind_body_ptr (stmt
), ctx
);
9946 case GIMPLE_OMP_PARALLEL
:
9947 case GIMPLE_OMP_TASK
:
9948 ctx
= maybe_lookup_ctx (stmt
);
9950 if (ctx
->cancellable
)
9951 ctx
->cancel_label
= create_artificial_label (UNKNOWN_LOCATION
);
9952 lower_omp_taskreg (gsi_p
, ctx
);
9954 case GIMPLE_OMP_FOR
:
9955 ctx
= maybe_lookup_ctx (stmt
);
9957 if (ctx
->cancellable
)
9958 ctx
->cancel_label
= create_artificial_label (UNKNOWN_LOCATION
);
9959 lower_omp_for (gsi_p
, ctx
);
9961 case GIMPLE_OMP_SECTIONS
:
9962 ctx
= maybe_lookup_ctx (stmt
);
9964 if (ctx
->cancellable
)
9965 ctx
->cancel_label
= create_artificial_label (UNKNOWN_LOCATION
);
9966 lower_omp_sections (gsi_p
, ctx
);
9968 case GIMPLE_OMP_SINGLE
:
9969 ctx
= maybe_lookup_ctx (stmt
);
9971 lower_omp_single (gsi_p
, ctx
);
9973 case GIMPLE_OMP_MASTER
:
9974 ctx
= maybe_lookup_ctx (stmt
);
9976 lower_omp_master (gsi_p
, ctx
);
9978 case GIMPLE_OMP_TASKGROUP
:
9979 ctx
= maybe_lookup_ctx (stmt
);
9981 lower_omp_taskgroup (gsi_p
, ctx
);
9983 case GIMPLE_OMP_ORDERED
:
9984 ctx
= maybe_lookup_ctx (stmt
);
9986 lower_omp_ordered (gsi_p
, ctx
);
9988 case GIMPLE_OMP_CRITICAL
:
9989 ctx
= maybe_lookup_ctx (stmt
);
9991 lower_omp_critical (gsi_p
, ctx
);
9993 case GIMPLE_OMP_ATOMIC_LOAD
:
9994 if ((ctx
|| task_shared_vars
)
9995 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt
),
9996 lower_omp_regimplify_p
, ctx
? NULL
: &wi
, NULL
))
9997 gimple_regimplify_operands (stmt
, gsi_p
);
9999 case GIMPLE_OMP_TARGET
:
10000 ctx
= maybe_lookup_ctx (stmt
);
10002 lower_omp_target (gsi_p
, ctx
);
10004 case GIMPLE_OMP_TEAMS
:
10005 ctx
= maybe_lookup_ctx (stmt
);
10007 lower_omp_teams (gsi_p
, ctx
);
10011 fndecl
= gimple_call_fndecl (stmt
);
10013 && DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
)
10014 switch (DECL_FUNCTION_CODE (fndecl
))
10016 case BUILT_IN_GOMP_BARRIER
:
10020 case BUILT_IN_GOMP_CANCEL
:
10021 case BUILT_IN_GOMP_CANCELLATION_POINT
:
10024 if (gimple_code (cctx
->stmt
) == GIMPLE_OMP_SECTION
)
10025 cctx
= cctx
->outer
;
10026 gcc_assert (gimple_call_lhs (stmt
) == NULL_TREE
);
10027 if (!cctx
->cancellable
)
10029 if (DECL_FUNCTION_CODE (fndecl
)
10030 == BUILT_IN_GOMP_CANCELLATION_POINT
)
10032 stmt
= gimple_build_nop ();
10033 gsi_replace (gsi_p
, stmt
, false);
10038 lhs
= create_tmp_var (boolean_type_node
, NULL
);
10039 if (DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_GOMP_BARRIER
)
10041 fndecl
= builtin_decl_explicit (BUILT_IN_GOMP_BARRIER_CANCEL
);
10042 gimple_call_set_fndecl (stmt
, fndecl
);
10043 gimple_call_set_fntype (stmt
, TREE_TYPE (fndecl
));
10045 gimple_call_set_lhs (stmt
, lhs
);
10046 tree fallthru_label
;
10047 fallthru_label
= create_artificial_label (UNKNOWN_LOCATION
);
10049 g
= gimple_build_label (fallthru_label
);
10050 gsi_insert_after (gsi_p
, g
, GSI_SAME_STMT
);
10051 g
= gimple_build_cond (NE_EXPR
, lhs
, boolean_false_node
,
10052 cctx
->cancel_label
, fallthru_label
);
10053 gsi_insert_after (gsi_p
, g
, GSI_SAME_STMT
);
10060 if ((ctx
|| task_shared_vars
)
10061 && walk_gimple_op (stmt
, lower_omp_regimplify_p
,
10063 gimple_regimplify_operands (stmt
, gsi_p
);
10069 lower_omp (gimple_seq
*body
, omp_context
*ctx
)
10071 location_t saved_location
= input_location
;
10072 gimple_stmt_iterator gsi
;
10073 for (gsi
= gsi_start (*body
); !gsi_end_p (gsi
); gsi_next (&gsi
))
10074 lower_omp_1 (&gsi
, ctx
);
10075 /* Inside target region we haven't called fold_stmt during gimplification,
10076 because it can break code by adding decl references that weren't in the
10077 source. Call fold_stmt now. */
10078 if (target_nesting_level
)
10079 for (gsi
= gsi_start (*body
); !gsi_end_p (gsi
); gsi_next (&gsi
))
10081 input_location
= saved_location
;
10084 /* Main entry point. */
10086 static unsigned int
10087 execute_lower_omp (void)
10091 /* This pass always runs, to provide PROP_gimple_lomp.
10092 But there is nothing to do unless -fopenmp is given. */
10093 if (flag_openmp
== 0 && flag_openmp_simd
== 0 && flag_enable_cilkplus
== 0)
10096 all_contexts
= splay_tree_new (splay_tree_compare_pointers
, 0,
10097 delete_omp_context
);
10099 body
= gimple_body (current_function_decl
);
10100 scan_omp (&body
, NULL
);
10101 gcc_assert (taskreg_nesting_level
== 0);
10103 if (all_contexts
->root
)
10105 struct gimplify_ctx gctx
;
10107 if (task_shared_vars
)
10108 push_gimplify_context (&gctx
);
10109 lower_omp (&body
, NULL
);
10110 if (task_shared_vars
)
10111 pop_gimplify_context (NULL
);
10116 splay_tree_delete (all_contexts
);
10117 all_contexts
= NULL
;
10119 BITMAP_FREE (task_shared_vars
);
10125 const pass_data pass_data_lower_omp
=
10127 GIMPLE_PASS
, /* type */
10128 "omplower", /* name */
10129 OPTGROUP_NONE
, /* optinfo_flags */
10130 false, /* has_gate */
10131 true, /* has_execute */
10132 TV_NONE
, /* tv_id */
10133 PROP_gimple_any
, /* properties_required */
10134 PROP_gimple_lomp
, /* properties_provided */
10135 0, /* properties_destroyed */
10136 0, /* todo_flags_start */
10137 0, /* todo_flags_finish */
10140 class pass_lower_omp
: public gimple_opt_pass
10143 pass_lower_omp (gcc::context
*ctxt
)
10144 : gimple_opt_pass (pass_data_lower_omp
, ctxt
)
10147 /* opt_pass methods: */
10148 unsigned int execute () { return execute_lower_omp (); }
10150 }; // class pass_lower_omp
10152 } // anon namespace
10155 make_pass_lower_omp (gcc::context
*ctxt
)
10157 return new pass_lower_omp (ctxt
);
10160 /* The following is a utility to diagnose OpenMP structured block violations.
10161 It is not part of the "omplower" pass, as that's invoked too late. It
10162 should be invoked by the respective front ends after gimplification. */
10164 static splay_tree all_labels
;
10166 /* Check for mismatched contexts and generate an error if needed. Return
10167 true if an error is detected. */
10170 diagnose_sb_0 (gimple_stmt_iterator
*gsi_p
,
10171 gimple branch_ctx
, gimple label_ctx
)
10173 if (label_ctx
== branch_ctx
)
10178 Previously we kept track of the label's entire context in diagnose_sb_[12]
10179 so we could traverse it and issue a correct "exit" or "enter" error
10180 message upon a structured block violation.
10182 We built the context by building a list with tree_cons'ing, but there is
10183 no easy counterpart in gimple tuples. It seems like far too much work
10184 for issuing exit/enter error messages. If someone really misses the
10185 distinct error message... patches welcome.
10189 /* Try to avoid confusing the user by producing and error message
10190 with correct "exit" or "enter" verbiage. We prefer "exit"
10191 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
10192 if (branch_ctx
== NULL
)
10198 if (TREE_VALUE (label_ctx
) == branch_ctx
)
10203 label_ctx
= TREE_CHAIN (label_ctx
);
10208 error ("invalid exit from OpenMP structured block");
10210 error ("invalid entry to OpenMP structured block");
10213 bool cilkplus_block
= false;
10214 if (flag_enable_cilkplus
)
10217 && gimple_code (branch_ctx
) == GIMPLE_OMP_FOR
10218 && gimple_omp_for_kind (branch_ctx
) == GF_OMP_FOR_KIND_CILKSIMD
)
10219 || (gimple_code (label_ctx
) == GIMPLE_OMP_FOR
10220 && gimple_omp_for_kind (label_ctx
) == GF_OMP_FOR_KIND_CILKSIMD
))
10221 cilkplus_block
= true;
10224 /* If it's obvious we have an invalid entry, be specific about the error. */
10225 if (branch_ctx
== NULL
)
10227 if (cilkplus_block
)
10228 error ("invalid entry to Cilk Plus structured block");
10230 error ("invalid entry to OpenMP structured block");
10234 /* Otherwise, be vague and lazy, but efficient. */
10235 if (cilkplus_block
)
10236 error ("invalid branch to/from a Cilk Plus structured block");
10238 error ("invalid branch to/from an OpenMP structured block");
10241 gsi_replace (gsi_p
, gimple_build_nop (), false);
10245 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
10246 where each label is found. */
10249 diagnose_sb_1 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
10250 struct walk_stmt_info
*wi
)
10252 gimple context
= (gimple
) wi
->info
;
10253 gimple inner_context
;
10254 gimple stmt
= gsi_stmt (*gsi_p
);
10256 *handled_ops_p
= true;
10258 switch (gimple_code (stmt
))
10262 case GIMPLE_OMP_PARALLEL
:
10263 case GIMPLE_OMP_TASK
:
10264 case GIMPLE_OMP_SECTIONS
:
10265 case GIMPLE_OMP_SINGLE
:
10266 case GIMPLE_OMP_SECTION
:
10267 case GIMPLE_OMP_MASTER
:
10268 case GIMPLE_OMP_ORDERED
:
10269 case GIMPLE_OMP_CRITICAL
:
10270 case GIMPLE_OMP_TARGET
:
10271 case GIMPLE_OMP_TEAMS
:
10272 case GIMPLE_OMP_TASKGROUP
:
10273 /* The minimal context here is just the current OMP construct. */
10274 inner_context
= stmt
;
10275 wi
->info
= inner_context
;
10276 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
10277 wi
->info
= context
;
10280 case GIMPLE_OMP_FOR
:
10281 inner_context
= stmt
;
10282 wi
->info
= inner_context
;
10283 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
10285 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
10286 diagnose_sb_1
, NULL
, wi
);
10287 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
10288 wi
->info
= context
;
10292 splay_tree_insert (all_labels
, (splay_tree_key
) gimple_label_label (stmt
),
10293 (splay_tree_value
) context
);
10303 /* Pass 2: Check each branch and see if its context differs from that of
10304 the destination label's context. */
10307 diagnose_sb_2 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
10308 struct walk_stmt_info
*wi
)
10310 gimple context
= (gimple
) wi
->info
;
10312 gimple stmt
= gsi_stmt (*gsi_p
);
10314 *handled_ops_p
= true;
10316 switch (gimple_code (stmt
))
10320 case GIMPLE_OMP_PARALLEL
:
10321 case GIMPLE_OMP_TASK
:
10322 case GIMPLE_OMP_SECTIONS
:
10323 case GIMPLE_OMP_SINGLE
:
10324 case GIMPLE_OMP_SECTION
:
10325 case GIMPLE_OMP_MASTER
:
10326 case GIMPLE_OMP_ORDERED
:
10327 case GIMPLE_OMP_CRITICAL
:
10328 case GIMPLE_OMP_TARGET
:
10329 case GIMPLE_OMP_TEAMS
:
10330 case GIMPLE_OMP_TASKGROUP
:
10332 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt
), diagnose_sb_2
, NULL
, wi
);
10333 wi
->info
= context
;
10336 case GIMPLE_OMP_FOR
:
10338 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
10340 walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt
),
10341 diagnose_sb_2
, NULL
, wi
);
10342 walk_gimple_seq_mod (gimple_omp_body_ptr (stmt
), diagnose_sb_2
, NULL
, wi
);
10343 wi
->info
= context
;
10348 tree lab
= gimple_cond_true_label (stmt
);
10351 n
= splay_tree_lookup (all_labels
,
10352 (splay_tree_key
) lab
);
10353 diagnose_sb_0 (gsi_p
, context
,
10354 n
? (gimple
) n
->value
: NULL
);
10356 lab
= gimple_cond_false_label (stmt
);
10359 n
= splay_tree_lookup (all_labels
,
10360 (splay_tree_key
) lab
);
10361 diagnose_sb_0 (gsi_p
, context
,
10362 n
? (gimple
) n
->value
: NULL
);
10369 tree lab
= gimple_goto_dest (stmt
);
10370 if (TREE_CODE (lab
) != LABEL_DECL
)
10373 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
10374 diagnose_sb_0 (gsi_p
, context
, n
? (gimple
) n
->value
: NULL
);
10378 case GIMPLE_SWITCH
:
10381 for (i
= 0; i
< gimple_switch_num_labels (stmt
); ++i
)
10383 tree lab
= CASE_LABEL (gimple_switch_label (stmt
, i
));
10384 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
10385 if (n
&& diagnose_sb_0 (gsi_p
, context
, (gimple
) n
->value
))
10391 case GIMPLE_RETURN
:
10392 diagnose_sb_0 (gsi_p
, context
, NULL
);
10402 /* Called from tree-cfg.c::make_edges to create cfg edges for all GIMPLE_OMP
10405 make_gimple_omp_edges (basic_block bb
, struct omp_region
**region
)
10407 gimple last
= last_stmt (bb
);
10408 enum gimple_code code
= gimple_code (last
);
10409 struct omp_region
*cur_region
= *region
;
10410 bool fallthru
= false;
10414 case GIMPLE_OMP_PARALLEL
:
10415 case GIMPLE_OMP_TASK
:
10416 case GIMPLE_OMP_FOR
:
10417 case GIMPLE_OMP_SINGLE
:
10418 case GIMPLE_OMP_TEAMS
:
10419 case GIMPLE_OMP_MASTER
:
10420 case GIMPLE_OMP_TASKGROUP
:
10421 case GIMPLE_OMP_ORDERED
:
10422 case GIMPLE_OMP_CRITICAL
:
10423 case GIMPLE_OMP_SECTION
:
10424 cur_region
= new_omp_region (bb
, code
, cur_region
);
10428 case GIMPLE_OMP_TARGET
:
10429 cur_region
= new_omp_region (bb
, code
, cur_region
);
10431 if (gimple_omp_target_kind (last
) == GF_OMP_TARGET_KIND_UPDATE
)
10432 cur_region
= cur_region
->outer
;
10435 case GIMPLE_OMP_SECTIONS
:
10436 cur_region
= new_omp_region (bb
, code
, cur_region
);
10440 case GIMPLE_OMP_SECTIONS_SWITCH
:
10444 case GIMPLE_OMP_ATOMIC_LOAD
:
10445 case GIMPLE_OMP_ATOMIC_STORE
:
10449 case GIMPLE_OMP_RETURN
:
10450 /* In the case of a GIMPLE_OMP_SECTION, the edge will go
10451 somewhere other than the next block. This will be
10453 cur_region
->exit
= bb
;
10454 fallthru
= cur_region
->type
!= GIMPLE_OMP_SECTION
;
10455 cur_region
= cur_region
->outer
;
10458 case GIMPLE_OMP_CONTINUE
:
10459 cur_region
->cont
= bb
;
10460 switch (cur_region
->type
)
10462 case GIMPLE_OMP_FOR
:
10463 /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
10464 succs edges as abnormal to prevent splitting
10466 single_succ_edge (cur_region
->entry
)->flags
|= EDGE_ABNORMAL
;
10467 /* Make the loopback edge. */
10468 make_edge (bb
, single_succ (cur_region
->entry
),
10471 /* Create an edge from GIMPLE_OMP_FOR to exit, which
10472 corresponds to the case that the body of the loop
10473 is not executed at all. */
10474 make_edge (cur_region
->entry
, bb
->next_bb
, EDGE_ABNORMAL
);
10475 make_edge (bb
, bb
->next_bb
, EDGE_FALLTHRU
| EDGE_ABNORMAL
);
10479 case GIMPLE_OMP_SECTIONS
:
10480 /* Wire up the edges into and out of the nested sections. */
10482 basic_block switch_bb
= single_succ (cur_region
->entry
);
10484 struct omp_region
*i
;
10485 for (i
= cur_region
->inner
; i
; i
= i
->next
)
10487 gcc_assert (i
->type
== GIMPLE_OMP_SECTION
);
10488 make_edge (switch_bb
, i
->entry
, 0);
10489 make_edge (i
->exit
, bb
, EDGE_FALLTHRU
);
10492 /* Make the loopback edge to the block with
10493 GIMPLE_OMP_SECTIONS_SWITCH. */
10494 make_edge (bb
, switch_bb
, 0);
10496 /* Make the edge from the switch to exit. */
10497 make_edge (switch_bb
, bb
->next_bb
, 0);
10503 gcc_unreachable ();
10508 gcc_unreachable ();
10511 if (*region
!= cur_region
)
10512 *region
= cur_region
;
10517 static unsigned int
10518 diagnose_omp_structured_block_errors (void)
10520 struct walk_stmt_info wi
;
10521 gimple_seq body
= gimple_body (current_function_decl
);
10523 all_labels
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
10525 memset (&wi
, 0, sizeof (wi
));
10526 walk_gimple_seq (body
, diagnose_sb_1
, NULL
, &wi
);
10528 memset (&wi
, 0, sizeof (wi
));
10529 wi
.want_locations
= true;
10530 walk_gimple_seq_mod (&body
, diagnose_sb_2
, NULL
, &wi
);
10532 gimple_set_body (current_function_decl
, body
);
10534 splay_tree_delete (all_labels
);
10541 gate_diagnose_omp_blocks (void)
10543 return flag_openmp
|| flag_enable_cilkplus
;
10548 const pass_data pass_data_diagnose_omp_blocks
=
10550 GIMPLE_PASS
, /* type */
10551 "*diagnose_omp_blocks", /* name */
10552 OPTGROUP_NONE
, /* optinfo_flags */
10553 true, /* has_gate */
10554 true, /* has_execute */
10555 TV_NONE
, /* tv_id */
10556 PROP_gimple_any
, /* properties_required */
10557 0, /* properties_provided */
10558 0, /* properties_destroyed */
10559 0, /* todo_flags_start */
10560 0, /* todo_flags_finish */
10563 class pass_diagnose_omp_blocks
: public gimple_opt_pass
10566 pass_diagnose_omp_blocks (gcc::context
*ctxt
)
10567 : gimple_opt_pass (pass_data_diagnose_omp_blocks
, ctxt
)
10570 /* opt_pass methods: */
10571 bool gate () { return gate_diagnose_omp_blocks (); }
10572 unsigned int execute () {
10573 return diagnose_omp_structured_block_errors ();
10576 }; // class pass_diagnose_omp_blocks
10578 } // anon namespace
10581 make_pass_diagnose_omp_blocks (gcc::context
*ctxt
)
10583 return new pass_diagnose_omp_blocks (ctxt
);
10586 #include "gt-omp-low.h"