1 /* Expansion pass for OMP directives. Outlines regions of certain OMP
2 directives to separate functions, converts others into explicit calls to the
3 runtime library (libgomp) and so forth
5 Copyright (C) 2005-2025 Free Software Foundation, Inc.
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
33 #include "tree-pass.h"
37 #include "pretty-print.h"
38 #include "diagnostic-core.h"
39 #include "fold-const.h"
40 #include "stor-layout.h"
42 #include "internal-fn.h"
44 #include "gimple-iterator.h"
45 #include "gimplify-me.h"
46 #include "gimple-walk.h"
48 #include "tree-into-ssa.h"
50 #include "splay-tree.h"
52 #include "omp-general.h"
53 #include "omp-offload.h"
54 #include "tree-cfgcleanup.h"
55 #include "alloc-pool.h"
56 #include "symbol-summary.h"
57 #include "gomp-constants.h"
58 #include "gimple-pretty-print.h"
59 #include "stringpool.h"
64 /* OMP region information. Every parallel and workshare
65 directive is enclosed between two markers, the OMP_* directive
66 and a corresponding GIMPLE_OMP_RETURN statement. */
70 /* The enclosing region. */
71 struct omp_region
*outer
;
73 /* First child region. */
74 struct omp_region
*inner
;
76 /* Next peer region. */
77 struct omp_region
*next
;
79 /* Block containing the omp directive as its last stmt. */
82 /* Block containing the GIMPLE_OMP_RETURN as its last stmt. */
85 /* Block containing the GIMPLE_OMP_CONTINUE as its last stmt. */
88 /* If this is a combined parallel+workshare region, this is a list
89 of additional arguments needed by the combined parallel+workshare
91 vec
<tree
, va_gc
> *ws_args
;
93 /* The code for the omp directive of this region. */
94 enum gimple_code type
;
96 /* Schedule kind, only used for GIMPLE_OMP_FOR type regions. */
97 enum omp_clause_schedule_kind sched_kind
;
99 /* Schedule modifiers. */
100 unsigned char sched_modifiers
;
102 /* True if this is a combined parallel+workshare region. */
103 bool is_combined_parallel
;
105 /* Copy of fd.lastprivate_conditional != 0. */
106 bool has_lastprivate_conditional
;
108 /* The ordered stmt if type is GIMPLE_OMP_ORDERED and it has
110 gomp_ordered
*ord_stmt
;
113 static struct omp_region
*root_omp_region
;
114 static bool omp_any_child_fn_dumped
;
116 static void expand_omp_build_assign (gimple_stmt_iterator
*, tree
, tree
,
118 static gphi
*find_phi_with_arg_on_edge (tree
, edge
);
119 static void expand_omp (struct omp_region
*region
);
121 /* Return true if REGION is a combined parallel+workshare region. */
124 is_combined_parallel (struct omp_region
*region
)
126 return region
->is_combined_parallel
;
129 /* Return true is REGION is or is contained within an offload region. */
132 is_in_offload_region (struct omp_region
*region
)
134 gimple
*entry_stmt
= last_nondebug_stmt (region
->entry
);
135 if (is_gimple_omp (entry_stmt
)
136 && is_gimple_omp_offloaded (entry_stmt
))
138 else if (region
->outer
)
139 return is_in_offload_region (region
->outer
);
141 return (lookup_attribute ("omp declare target",
142 DECL_ATTRIBUTES (current_function_decl
))
146 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
147 is the immediate dominator of PAR_ENTRY_BB, return true if there
148 are no data dependencies that would prevent expanding the parallel
149 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
151 When expanding a combined parallel+workshare region, the call to
152 the child function may need additional arguments in the case of
153 GIMPLE_OMP_FOR regions. In some cases, these arguments are
154 computed out of variables passed in from the parent to the child
155 via 'struct .omp_data_s'. For instance:
157 #pragma omp parallel for schedule (guided, i * 4)
162 # BLOCK 2 (PAR_ENTRY_BB)
164 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
166 # BLOCK 3 (WS_ENTRY_BB)
167 .omp_data_i = &.omp_data_o;
168 D.1667 = .omp_data_i->i;
170 #pragma omp for schedule (guided, D.1598)
172 When we outline the parallel region, the call to the child function
173 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
174 that value is computed *after* the call site. So, in principle we
175 cannot do the transformation.
177 To see whether the code in WS_ENTRY_BB blocks the combined
178 parallel+workshare call, we collect all the variables used in the
179 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
180 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
183 FIXME. If we had the SSA form built at this point, we could merely
184 hoist the code in block 3 into block 2 and be done with it. But at
185 this point we don't have dataflow information and though we could
186 hack something up here, it is really not worth the aggravation. */
189 workshare_safe_to_combine_p (basic_block ws_entry_bb
)
191 struct omp_for_data fd
;
192 gimple
*ws_stmt
= last_nondebug_stmt (ws_entry_bb
);
194 if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
197 gcc_assert (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
);
198 if (gimple_omp_for_kind (ws_stmt
) != GF_OMP_FOR_KIND_FOR
)
201 omp_extract_for_data (as_a
<gomp_for
*> (ws_stmt
), &fd
, NULL
);
203 if (fd
.collapse
> 1 && TREE_CODE (fd
.loop
.n2
) != INTEGER_CST
)
205 if (fd
.iter_type
!= long_integer_type_node
)
208 /* FIXME. We give up too easily here. If any of these arguments
209 are not constants, they will likely involve variables that have
210 been mapped into fields of .omp_data_s for sharing with the child
211 function. With appropriate data flow, it would be possible to
213 if (!is_gimple_min_invariant (fd
.loop
.n1
)
214 || !is_gimple_min_invariant (fd
.loop
.n2
)
215 || !is_gimple_min_invariant (fd
.loop
.step
)
216 || (fd
.chunk_size
&& !is_gimple_min_invariant (fd
.chunk_size
)))
222 /* Adjust CHUNK_SIZE from SCHEDULE clause, depending on simd modifier
223 presence (SIMD_SCHEDULE). */
226 omp_adjust_chunk_size (tree chunk_size
, bool simd_schedule
, bool offload
)
228 if (!simd_schedule
|| integer_zerop (chunk_size
))
232 tree type
= TREE_TYPE (chunk_size
);
236 cfun
->curr_properties
&= ~PROP_gimple_lomp_dev
;
237 vf
= build_call_expr_internal_loc (UNKNOWN_LOCATION
, IFN_GOMP_MAX_VF
,
238 unsigned_type_node
, 0);
239 vf
= fold_convert (type
, vf
);
243 poly_uint64 vf_num
= omp_max_vf (false);
244 if (known_eq (vf_num
, 1U))
246 vf
= build_int_cst (type
, vf_num
);
249 tree vf_minus_one
= fold_build2 (MINUS_EXPR
, type
, vf
,
250 build_int_cst (type
, 1));
251 tree negative_vf
= fold_build1 (NEGATE_EXPR
, type
, vf
);
252 chunk_size
= fold_build2 (PLUS_EXPR
, type
, chunk_size
, vf_minus_one
);
253 return fold_build2 (BIT_AND_EXPR
, type
, chunk_size
, negative_vf
);
256 /* Collect additional arguments needed to emit a combined
257 parallel+workshare call. WS_STMT is the workshare directive being
260 static vec
<tree
, va_gc
> *
261 get_ws_args_for (gimple
*par_stmt
, gimple
*ws_stmt
, bool offload
)
264 location_t loc
= gimple_location (ws_stmt
);
265 vec
<tree
, va_gc
> *ws_args
;
267 if (gomp_for
*for_stmt
= dyn_cast
<gomp_for
*> (ws_stmt
))
269 struct omp_for_data fd
;
272 omp_extract_for_data (for_stmt
, &fd
, NULL
);
276 if (gimple_omp_for_combined_into_p (for_stmt
))
279 = omp_find_clause (gimple_omp_parallel_clauses (par_stmt
),
280 OMP_CLAUSE__LOOPTEMP_
);
282 n1
= OMP_CLAUSE_DECL (innerc
);
283 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
284 OMP_CLAUSE__LOOPTEMP_
);
286 n2
= OMP_CLAUSE_DECL (innerc
);
289 vec_alloc (ws_args
, 3 + (fd
.chunk_size
!= 0));
291 t
= fold_convert_loc (loc
, long_integer_type_node
, n1
);
292 ws_args
->quick_push (t
);
294 t
= fold_convert_loc (loc
, long_integer_type_node
, n2
);
295 ws_args
->quick_push (t
);
297 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.step
);
298 ws_args
->quick_push (t
);
302 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.chunk_size
);
303 t
= omp_adjust_chunk_size (t
, fd
.simd_schedule
, offload
);
304 ws_args
->quick_push (t
);
309 else if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
311 /* Number of sections is equal to the number of edges from the
312 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
313 the exit of the sections region. */
314 basic_block bb
= single_succ (gimple_bb (ws_stmt
));
315 t
= build_int_cst (unsigned_type_node
, EDGE_COUNT (bb
->succs
) - 1);
316 vec_alloc (ws_args
, 1);
317 ws_args
->quick_push (t
);
324 /* Discover whether REGION is a combined parallel+workshare region. */
327 determine_parallel_type (struct omp_region
*region
)
329 basic_block par_entry_bb
, par_exit_bb
;
330 basic_block ws_entry_bb
, ws_exit_bb
;
332 if (region
== NULL
|| region
->inner
== NULL
333 || region
->exit
== NULL
|| region
->inner
->exit
== NULL
334 || region
->inner
->cont
== NULL
)
337 /* We only support parallel+for and parallel+sections. */
338 if (region
->type
!= GIMPLE_OMP_PARALLEL
339 || (region
->inner
->type
!= GIMPLE_OMP_FOR
340 && region
->inner
->type
!= GIMPLE_OMP_SECTIONS
))
343 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
344 WS_EXIT_BB -> PAR_EXIT_BB. */
345 par_entry_bb
= region
->entry
;
346 par_exit_bb
= region
->exit
;
347 ws_entry_bb
= region
->inner
->entry
;
348 ws_exit_bb
= region
->inner
->exit
;
350 /* Give up for task reductions on the parallel, while it is implementable,
351 adding another big set of APIs or slowing down the normal paths is
354 = gimple_omp_parallel_clauses (last_nondebug_stmt (par_entry_bb
));
355 if (omp_find_clause (pclauses
, OMP_CLAUSE__REDUCTEMP_
))
358 if (single_succ (par_entry_bb
) == ws_entry_bb
359 && single_succ (ws_exit_bb
) == par_exit_bb
360 && workshare_safe_to_combine_p (ws_entry_bb
)
361 && (gimple_omp_parallel_combined_p (last_nondebug_stmt (par_entry_bb
))
362 || (last_and_only_stmt (ws_entry_bb
)
363 && last_and_only_stmt (par_exit_bb
))))
365 gimple
*par_stmt
= last_nondebug_stmt (par_entry_bb
);
366 gimple
*ws_stmt
= last_nondebug_stmt (ws_entry_bb
);
368 if (region
->inner
->type
== GIMPLE_OMP_FOR
)
370 /* If this is a combined parallel loop, we need to determine
371 whether or not to use the combined library calls. There
372 are two cases where we do not apply the transformation:
373 static loops and any kind of ordered loop. In the first
374 case, we already open code the loop so there is no need
375 to do anything else. In the latter case, the combined
376 parallel loop call would still need extra synchronization
377 to implement ordered semantics, so there would not be any
378 gain in using the combined call. */
379 tree clauses
= gimple_omp_for_clauses (ws_stmt
);
380 tree c
= omp_find_clause (clauses
, OMP_CLAUSE_SCHEDULE
);
382 || ((OMP_CLAUSE_SCHEDULE_KIND (c
) & OMP_CLAUSE_SCHEDULE_MASK
)
383 == OMP_CLAUSE_SCHEDULE_STATIC
)
384 || omp_find_clause (clauses
, OMP_CLAUSE_ORDERED
)
385 || omp_find_clause (clauses
, OMP_CLAUSE__REDUCTEMP_
)
386 || ((c
= omp_find_clause (clauses
, OMP_CLAUSE__CONDTEMP_
))
387 && POINTER_TYPE_P (TREE_TYPE (OMP_CLAUSE_DECL (c
)))))
390 else if (region
->inner
->type
== GIMPLE_OMP_SECTIONS
391 && (omp_find_clause (gimple_omp_sections_clauses (ws_stmt
),
392 OMP_CLAUSE__REDUCTEMP_
)
393 || omp_find_clause (gimple_omp_sections_clauses (ws_stmt
),
394 OMP_CLAUSE__CONDTEMP_
)))
397 region
->is_combined_parallel
= true;
398 region
->inner
->is_combined_parallel
= true;
399 region
->ws_args
= get_ws_args_for (par_stmt
, ws_stmt
,
400 is_in_offload_region (region
));
404 /* Debugging dumps for parallel regions. */
405 void dump_omp_region (FILE *, struct omp_region
*, int);
406 void debug_omp_region (struct omp_region
*);
407 void debug_all_omp_regions (void);
409 /* Dump the parallel region tree rooted at REGION. */
412 dump_omp_region (FILE *file
, struct omp_region
*region
, int indent
)
414 fprintf (file
, "%*sbb %d: %s\n", indent
, "", region
->entry
->index
,
415 gimple_code_name
[region
->type
]);
418 dump_omp_region (file
, region
->inner
, indent
+ 4);
422 fprintf (file
, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent
, "",
423 region
->cont
->index
);
427 fprintf (file
, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent
, "",
428 region
->exit
->index
);
430 fprintf (file
, "%*s[no exit marker]\n", indent
, "");
433 dump_omp_region (file
, region
->next
, indent
);
437 debug_omp_region (struct omp_region
*region
)
439 dump_omp_region (stderr
, region
, 0);
443 debug_all_omp_regions (void)
445 dump_omp_region (stderr
, root_omp_region
, 0);
448 /* Create a new parallel region starting at STMT inside region PARENT. */
450 static struct omp_region
*
451 new_omp_region (basic_block bb
, enum gimple_code type
,
452 struct omp_region
*parent
)
454 struct omp_region
*region
= XCNEW (struct omp_region
);
456 region
->outer
= parent
;
462 /* This is a nested region. Add it to the list of inner
463 regions in PARENT. */
464 region
->next
= parent
->inner
;
465 parent
->inner
= region
;
469 /* This is a toplevel region. Add it to the list of toplevel
470 regions in ROOT_OMP_REGION. */
471 region
->next
= root_omp_region
;
472 root_omp_region
= region
;
478 /* Release the memory associated with the region tree rooted at REGION. */
481 free_omp_region_1 (struct omp_region
*region
)
483 struct omp_region
*i
, *n
;
485 for (i
= region
->inner
; i
; i
= n
)
488 free_omp_region_1 (i
);
494 /* Release the memory for the entire omp region tree. */
497 omp_free_regions (void)
499 struct omp_region
*r
, *n
;
500 for (r
= root_omp_region
; r
; r
= n
)
503 free_omp_region_1 (r
);
505 root_omp_region
= NULL
;
508 /* A convenience function to build an empty GIMPLE_COND with just the
512 gimple_build_cond_empty (tree cond
)
514 enum tree_code pred_code
;
517 gimple_cond_get_ops_from_tree (cond
, &pred_code
, &lhs
, &rhs
);
518 return gimple_build_cond (pred_code
, lhs
, rhs
, NULL_TREE
, NULL_TREE
);
521 /* Change DECL_CONTEXT of CHILD_FNDECL to that of the parent function.
522 Add CHILD_FNDECL to decl chain of the supercontext of the block
523 ENTRY_BLOCK - this is the block which originally contained the
524 code from which CHILD_FNDECL was created.
526 Together, these actions ensure that the debug info for the outlined
527 function will be emitted with the correct lexical scope. */
530 adjust_context_and_scope (struct omp_region
*region
, tree entry_block
,
533 tree parent_fndecl
= NULL_TREE
;
535 /* OMP expansion expands inner regions before outer ones, so if
536 we e.g. have explicit task region nested in parallel region, when
537 expanding the task region current_function_decl will be the original
538 source function, but we actually want to use as context the child
539 function of the parallel. */
540 for (region
= region
->outer
;
541 region
&& parent_fndecl
== NULL_TREE
; region
= region
->outer
)
542 switch (region
->type
)
544 case GIMPLE_OMP_PARALLEL
:
545 case GIMPLE_OMP_TASK
:
546 case GIMPLE_OMP_TEAMS
:
547 entry_stmt
= last_nondebug_stmt (region
->entry
);
548 parent_fndecl
= gimple_omp_taskreg_child_fn (entry_stmt
);
550 case GIMPLE_OMP_TARGET
:
551 entry_stmt
= last_nondebug_stmt (region
->entry
);
553 = gimple_omp_target_child_fn (as_a
<gomp_target
*> (entry_stmt
));
559 if (parent_fndecl
== NULL_TREE
)
560 parent_fndecl
= current_function_decl
;
561 DECL_CONTEXT (child_fndecl
) = parent_fndecl
;
563 if (entry_block
!= NULL_TREE
&& TREE_CODE (entry_block
) == BLOCK
)
565 tree b
= BLOCK_SUPERCONTEXT (entry_block
);
566 if (TREE_CODE (b
) == BLOCK
)
568 DECL_CHAIN (child_fndecl
) = BLOCK_VARS (b
);
569 BLOCK_VARS (b
) = child_fndecl
;
574 /* Build the function calls to GOMP_parallel etc to actually
575 generate the parallel operation. REGION is the parallel region
576 being expanded. BB is the block where to insert the code. WS_ARGS
577 will be set if this is a call to a combined parallel+workshare
578 construct, it contains the list of additional arguments needed by
579 the workshare construct. */
582 expand_parallel_call (struct omp_region
*region
, basic_block bb
,
583 gomp_parallel
*entry_stmt
,
584 vec
<tree
, va_gc
> *ws_args
)
586 tree t
, t1
, t2
, val
, cond
, c
, clauses
, flags
;
587 gimple_stmt_iterator gsi
;
589 enum built_in_function start_ix
;
591 location_t clause_loc
;
592 vec
<tree
, va_gc
> *args
;
594 clauses
= gimple_omp_parallel_clauses (entry_stmt
);
596 /* Determine what flavor of GOMP_parallel we will be
598 start_ix
= BUILT_IN_GOMP_PARALLEL
;
599 tree rtmp
= omp_find_clause (clauses
, OMP_CLAUSE__REDUCTEMP_
);
601 start_ix
= BUILT_IN_GOMP_PARALLEL_REDUCTIONS
;
602 else if (is_combined_parallel (region
))
604 switch (region
->inner
->type
)
607 gcc_assert (region
->inner
->sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
608 switch (region
->inner
->sched_kind
)
610 case OMP_CLAUSE_SCHEDULE_RUNTIME
:
611 /* For lastprivate(conditional:), our implementation
612 requires monotonic behavior. */
613 if (region
->inner
->has_lastprivate_conditional
!= 0)
615 else if ((region
->inner
->sched_modifiers
616 & OMP_CLAUSE_SCHEDULE_NONMONOTONIC
) != 0)
618 else if ((region
->inner
->sched_modifiers
619 & OMP_CLAUSE_SCHEDULE_MONOTONIC
) == 0)
624 case OMP_CLAUSE_SCHEDULE_DYNAMIC
:
625 case OMP_CLAUSE_SCHEDULE_GUIDED
:
626 if ((region
->inner
->sched_modifiers
627 & OMP_CLAUSE_SCHEDULE_MONOTONIC
) == 0
628 && !region
->inner
->has_lastprivate_conditional
)
630 start_ix2
= 3 + region
->inner
->sched_kind
;
635 start_ix2
= region
->inner
->sched_kind
;
638 start_ix2
+= (int) BUILT_IN_GOMP_PARALLEL_LOOP_STATIC
;
639 start_ix
= (enum built_in_function
) start_ix2
;
641 case GIMPLE_OMP_SECTIONS
:
642 start_ix
= BUILT_IN_GOMP_PARALLEL_SECTIONS
;
649 /* By default, the value of NUM_THREADS is zero (selected at run time)
650 and there is no conditional. */
652 val
= build_int_cst (unsigned_type_node
, 0);
653 flags
= build_int_cst (unsigned_type_node
, 0);
655 c
= omp_find_clause (clauses
, OMP_CLAUSE_IF
);
657 cond
= OMP_CLAUSE_IF_EXPR (c
);
659 c
= omp_find_clause (clauses
, OMP_CLAUSE_NUM_THREADS
);
662 val
= OMP_CLAUSE_NUM_THREADS_EXPR (c
);
663 clause_loc
= OMP_CLAUSE_LOCATION (c
);
666 clause_loc
= gimple_location (entry_stmt
);
668 c
= omp_find_clause (clauses
, OMP_CLAUSE_PROC_BIND
);
670 flags
= build_int_cst (unsigned_type_node
, OMP_CLAUSE_PROC_BIND_KIND (c
));
672 /* Ensure 'val' is of the correct type. */
673 val
= fold_convert_loc (clause_loc
, unsigned_type_node
, val
);
675 /* If we found the clause 'if (cond)', build either
676 (cond != 0) or (cond ? val : 1u). */
679 cond
= gimple_boolify (cond
);
681 if (integer_zerop (val
))
682 val
= fold_build2_loc (clause_loc
,
683 EQ_EXPR
, unsigned_type_node
, cond
,
684 build_int_cst (TREE_TYPE (cond
), 0));
687 basic_block cond_bb
, then_bb
, else_bb
;
688 edge e
, e_then
, e_else
;
689 tree tmp_then
, tmp_else
, tmp_join
, tmp_var
;
691 tmp_var
= create_tmp_var (TREE_TYPE (val
));
692 if (gimple_in_ssa_p (cfun
))
694 tmp_then
= make_ssa_name (tmp_var
);
695 tmp_else
= make_ssa_name (tmp_var
);
696 tmp_join
= make_ssa_name (tmp_var
);
705 e
= split_block_after_labels (bb
);
710 then_bb
= create_empty_bb (cond_bb
);
711 else_bb
= create_empty_bb (then_bb
);
712 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
713 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
715 stmt
= gimple_build_cond_empty (cond
);
716 gsi
= gsi_start_bb (cond_bb
);
717 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
719 gsi
= gsi_start_bb (then_bb
);
720 expand_omp_build_assign (&gsi
, tmp_then
, val
, true);
722 gsi
= gsi_start_bb (else_bb
);
723 expand_omp_build_assign (&gsi
, tmp_else
,
724 build_int_cst (unsigned_type_node
, 1),
727 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
728 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
729 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
730 add_bb_to_loop (else_bb
, cond_bb
->loop_father
);
731 e_then
= make_edge (then_bb
, bb
, EDGE_FALLTHRU
);
732 e_else
= make_edge (else_bb
, bb
, EDGE_FALLTHRU
);
734 if (gimple_in_ssa_p (cfun
))
736 gphi
*phi
= create_phi_node (tmp_join
, bb
);
737 add_phi_arg (phi
, tmp_then
, e_then
, UNKNOWN_LOCATION
);
738 add_phi_arg (phi
, tmp_else
, e_else
, UNKNOWN_LOCATION
);
744 gsi
= gsi_start_bb (bb
);
745 val
= force_gimple_operand_gsi (&gsi
, val
, true, NULL_TREE
,
746 false, GSI_CONTINUE_LINKING
);
749 gsi
= gsi_last_nondebug_bb (bb
);
750 t
= gimple_omp_parallel_data_arg (entry_stmt
);
752 t1
= null_pointer_node
;
754 t1
= build_fold_addr_expr (t
);
755 tree child_fndecl
= gimple_omp_parallel_child_fn (entry_stmt
);
756 t2
= build_fold_addr_expr (child_fndecl
);
758 vec_alloc (args
, 4 + vec_safe_length (ws_args
));
759 args
->quick_push (t2
);
760 args
->quick_push (t1
);
761 args
->quick_push (val
);
763 args
->splice (*ws_args
);
764 args
->quick_push (flags
);
766 t
= build_call_expr_loc_vec (UNKNOWN_LOCATION
,
767 builtin_decl_explicit (start_ix
), args
);
771 tree type
= TREE_TYPE (OMP_CLAUSE_DECL (rtmp
));
772 t
= build2 (MODIFY_EXPR
, type
, OMP_CLAUSE_DECL (rtmp
),
774 fold_convert (pointer_sized_int_node
, t
)));
776 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
777 false, GSI_CONTINUE_LINKING
);
780 /* Build the function call to GOMP_task to actually
781 generate the task operation. BB is the block where to insert the code. */
784 expand_task_call (struct omp_region
*region
, basic_block bb
,
785 gomp_task
*entry_stmt
)
788 gimple_stmt_iterator gsi
;
789 location_t loc
= gimple_location (entry_stmt
);
791 tree clauses
= gimple_omp_task_clauses (entry_stmt
);
793 tree ifc
= omp_find_clause (clauses
, OMP_CLAUSE_IF
);
794 tree untied
= omp_find_clause (clauses
, OMP_CLAUSE_UNTIED
);
795 tree mergeable
= omp_find_clause (clauses
, OMP_CLAUSE_MERGEABLE
);
796 tree depend
= omp_find_clause (clauses
, OMP_CLAUSE_DEPEND
);
797 tree finalc
= omp_find_clause (clauses
, OMP_CLAUSE_FINAL
);
798 tree priority
= omp_find_clause (clauses
, OMP_CLAUSE_PRIORITY
);
799 tree detach
= omp_find_clause (clauses
, OMP_CLAUSE_DETACH
);
802 = (untied
? GOMP_TASK_FLAG_UNTIED
: 0)
803 | (mergeable
? GOMP_TASK_FLAG_MERGEABLE
: 0)
804 | (depend
? GOMP_TASK_FLAG_DEPEND
: 0);
806 bool taskloop_p
= gimple_omp_task_taskloop_p (entry_stmt
);
807 tree startvar
= NULL_TREE
, endvar
= NULL_TREE
, step
= NULL_TREE
;
808 tree num_tasks
= NULL_TREE
;
812 gimple
*g
= last_nondebug_stmt (region
->outer
->entry
);
813 gcc_assert (gimple_code (g
) == GIMPLE_OMP_FOR
814 && gimple_omp_for_kind (g
) == GF_OMP_FOR_KIND_TASKLOOP
);
815 struct omp_for_data fd
;
816 omp_extract_for_data (as_a
<gomp_for
*> (g
), &fd
, NULL
);
817 startvar
= omp_find_clause (clauses
, OMP_CLAUSE__LOOPTEMP_
);
818 endvar
= omp_find_clause (OMP_CLAUSE_CHAIN (startvar
),
819 OMP_CLAUSE__LOOPTEMP_
);
820 startvar
= OMP_CLAUSE_DECL (startvar
);
821 endvar
= OMP_CLAUSE_DECL (endvar
);
822 step
= fold_convert_loc (loc
, fd
.iter_type
, fd
.loop
.step
);
823 if (fd
.loop
.cond_code
== LT_EXPR
)
824 iflags
|= GOMP_TASK_FLAG_UP
;
825 tree tclauses
= gimple_omp_for_clauses (g
);
826 num_tasks
= omp_find_clause (tclauses
, OMP_CLAUSE_NUM_TASKS
);
829 if (OMP_CLAUSE_NUM_TASKS_STRICT (num_tasks
))
830 iflags
|= GOMP_TASK_FLAG_STRICT
;
831 num_tasks
= OMP_CLAUSE_NUM_TASKS_EXPR (num_tasks
);
835 num_tasks
= omp_find_clause (tclauses
, OMP_CLAUSE_GRAINSIZE
);
838 iflags
|= GOMP_TASK_FLAG_GRAINSIZE
;
839 if (OMP_CLAUSE_GRAINSIZE_STRICT (num_tasks
))
840 iflags
|= GOMP_TASK_FLAG_STRICT
;
841 num_tasks
= OMP_CLAUSE_GRAINSIZE_EXPR (num_tasks
);
844 num_tasks
= integer_zero_node
;
846 num_tasks
= fold_convert_loc (loc
, long_integer_type_node
, num_tasks
);
847 if (ifc
== NULL_TREE
)
848 iflags
|= GOMP_TASK_FLAG_IF
;
849 if (omp_find_clause (tclauses
, OMP_CLAUSE_NOGROUP
))
850 iflags
|= GOMP_TASK_FLAG_NOGROUP
;
851 ull
= fd
.iter_type
== long_long_unsigned_type_node
;
852 if (omp_find_clause (clauses
, OMP_CLAUSE_REDUCTION
))
853 iflags
|= GOMP_TASK_FLAG_REDUCTION
;
858 iflags
|= GOMP_TASK_FLAG_PRIORITY
;
860 iflags
|= GOMP_TASK_FLAG_DETACH
;
863 tree flags
= build_int_cst (unsigned_type_node
, iflags
);
865 tree cond
= boolean_true_node
;
870 tree t
= gimple_boolify (OMP_CLAUSE_IF_EXPR (ifc
));
871 t
= fold_build3_loc (loc
, COND_EXPR
, unsigned_type_node
, t
,
872 build_int_cst (unsigned_type_node
,
874 build_int_cst (unsigned_type_node
, 0));
875 flags
= fold_build2_loc (loc
, PLUS_EXPR
, unsigned_type_node
,
879 cond
= gimple_boolify (OMP_CLAUSE_IF_EXPR (ifc
));
884 tree t
= gimple_boolify (OMP_CLAUSE_FINAL_EXPR (finalc
));
885 t
= fold_build3_loc (loc
, COND_EXPR
, unsigned_type_node
, t
,
886 build_int_cst (unsigned_type_node
,
887 GOMP_TASK_FLAG_FINAL
),
888 build_int_cst (unsigned_type_node
, 0));
889 flags
= fold_build2_loc (loc
, PLUS_EXPR
, unsigned_type_node
, flags
, t
);
892 depend
= OMP_CLAUSE_DECL (depend
);
894 depend
= build_int_cst (ptr_type_node
, 0);
896 priority
= fold_convert (integer_type_node
,
897 OMP_CLAUSE_PRIORITY_EXPR (priority
));
899 priority
= integer_zero_node
;
901 gsi
= gsi_last_nondebug_bb (bb
);
904 ? build_fold_addr_expr (OMP_CLAUSE_DECL (detach
))
905 : null_pointer_node
);
907 tree t
= gimple_omp_task_data_arg (entry_stmt
);
909 t2
= null_pointer_node
;
911 t2
= build_fold_addr_expr_loc (loc
, t
);
912 t1
= build_fold_addr_expr_loc (loc
, gimple_omp_task_child_fn (entry_stmt
));
913 t
= gimple_omp_task_copy_fn (entry_stmt
);
915 t3
= null_pointer_node
;
917 t3
= build_fold_addr_expr_loc (loc
, t
);
920 t
= build_call_expr (ull
921 ? builtin_decl_explicit (BUILT_IN_GOMP_TASKLOOP_ULL
)
922 : builtin_decl_explicit (BUILT_IN_GOMP_TASKLOOP
),
924 gimple_omp_task_arg_size (entry_stmt
),
925 gimple_omp_task_arg_align (entry_stmt
), flags
,
926 num_tasks
, priority
, startvar
, endvar
, step
);
928 t
= build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_TASK
),
930 gimple_omp_task_arg_size (entry_stmt
),
931 gimple_omp_task_arg_align (entry_stmt
), cond
, flags
,
932 depend
, priority
, detach
);
934 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
935 false, GSI_CONTINUE_LINKING
);
938 /* Build the function call to GOMP_taskwait_depend to actually
939 generate the taskwait operation. BB is the block where to insert the
943 expand_taskwait_call (basic_block bb
, gomp_task
*entry_stmt
)
945 tree clauses
= gimple_omp_task_clauses (entry_stmt
);
946 tree depend
= omp_find_clause (clauses
, OMP_CLAUSE_DEPEND
);
947 if (depend
== NULL_TREE
)
950 depend
= OMP_CLAUSE_DECL (depend
);
952 bool nowait
= omp_find_clause (clauses
, OMP_CLAUSE_NOWAIT
) != NULL_TREE
;
953 gimple_stmt_iterator gsi
= gsi_last_nondebug_bb (bb
);
954 enum built_in_function f
= (nowait
955 ? BUILT_IN_GOMP_TASKWAIT_DEPEND_NOWAIT
956 : BUILT_IN_GOMP_TASKWAIT_DEPEND
);
957 tree t
= build_call_expr (builtin_decl_explicit (f
), 1, depend
);
959 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
960 false, GSI_CONTINUE_LINKING
);
963 /* Build the function call to GOMP_teams_reg to actually
964 generate the host teams operation. REGION is the teams region
965 being expanded. BB is the block where to insert the code. */
968 expand_teams_call (basic_block bb
, gomp_teams
*entry_stmt
)
970 tree clauses
= gimple_omp_teams_clauses (entry_stmt
);
971 tree num_teams
= omp_find_clause (clauses
, OMP_CLAUSE_NUM_TEAMS
);
972 if (num_teams
== NULL_TREE
)
973 num_teams
= build_int_cst (unsigned_type_node
, 0);
976 num_teams
= OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (num_teams
);
977 num_teams
= fold_convert (unsigned_type_node
, num_teams
);
979 tree thread_limit
= omp_find_clause (clauses
, OMP_CLAUSE_THREAD_LIMIT
);
980 if (thread_limit
== NULL_TREE
)
981 thread_limit
= build_int_cst (unsigned_type_node
, 0);
984 thread_limit
= OMP_CLAUSE_THREAD_LIMIT_EXPR (thread_limit
);
985 thread_limit
= fold_convert (unsigned_type_node
, thread_limit
);
988 gimple_stmt_iterator gsi
= gsi_last_nondebug_bb (bb
);
989 tree t
= gimple_omp_teams_data_arg (entry_stmt
), t1
;
991 t1
= null_pointer_node
;
993 t1
= build_fold_addr_expr (t
);
994 tree child_fndecl
= gimple_omp_teams_child_fn (entry_stmt
);
995 tree t2
= build_fold_addr_expr (child_fndecl
);
997 vec
<tree
, va_gc
> *args
;
999 args
->quick_push (t2
);
1000 args
->quick_push (t1
);
1001 args
->quick_push (num_teams
);
1002 args
->quick_push (thread_limit
);
1003 /* For future extensibility. */
1004 args
->quick_push (build_zero_cst (unsigned_type_node
));
1006 t
= build_call_expr_loc_vec (UNKNOWN_LOCATION
,
1007 builtin_decl_explicit (BUILT_IN_GOMP_TEAMS_REG
),
1010 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
1011 false, GSI_CONTINUE_LINKING
);
1014 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
1017 vec2chain (vec
<tree
, va_gc
> *v
)
1019 tree chain
= NULL_TREE
, t
;
1022 FOR_EACH_VEC_SAFE_ELT_REVERSE (v
, ix
, t
)
1024 DECL_CHAIN (t
) = chain
;
1031 /* Remove barriers in REGION->EXIT's block. Note that this is only
1032 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
1033 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
1034 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
1038 remove_exit_barrier (struct omp_region
*region
)
1040 gimple_stmt_iterator gsi
;
1041 basic_block exit_bb
;
1045 int any_addressable_vars
= -1;
1047 exit_bb
= region
->exit
;
1049 /* If the parallel region doesn't return, we don't have REGION->EXIT
1054 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
1055 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
1056 statements that can appear in between are extremely limited -- no
1057 memory operations at all. Here, we allow nothing at all, so the
1058 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
1059 gsi
= gsi_last_nondebug_bb (exit_bb
);
1060 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
1061 gsi_prev_nondebug (&gsi
);
1062 if (!gsi_end_p (gsi
) && gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
1065 FOR_EACH_EDGE (e
, ei
, exit_bb
->preds
)
1067 gsi
= gsi_last_nondebug_bb (e
->src
);
1068 if (gsi_end_p (gsi
))
1070 stmt
= gsi_stmt (gsi
);
1071 if (gimple_code (stmt
) == GIMPLE_OMP_RETURN
1072 && !gimple_omp_return_nowait_p (stmt
))
1074 /* OpenMP 3.0 tasks unfortunately prevent this optimization
1075 in many cases. If there could be tasks queued, the barrier
1076 might be needed to let the tasks run before some local
1077 variable of the parallel that the task uses as shared
1078 runs out of scope. The task can be spawned either
1079 from within current function (this would be easy to check)
1080 or from some function it calls and gets passed an address
1081 of such a variable. */
1082 if (any_addressable_vars
< 0)
1084 gomp_parallel
*parallel_stmt
1085 = as_a
<gomp_parallel
*> (last_nondebug_stmt (region
->entry
));
1086 tree child_fun
= gimple_omp_parallel_child_fn (parallel_stmt
);
1087 tree local_decls
, block
, decl
;
1090 any_addressable_vars
= 0;
1091 FOR_EACH_LOCAL_DECL (DECL_STRUCT_FUNCTION (child_fun
), ix
, decl
)
1092 if (TREE_ADDRESSABLE (decl
))
1094 any_addressable_vars
= 1;
1097 for (block
= gimple_block (stmt
);
1098 !any_addressable_vars
1100 && TREE_CODE (block
) == BLOCK
;
1101 block
= BLOCK_SUPERCONTEXT (block
))
1103 for (local_decls
= BLOCK_VARS (block
);
1105 local_decls
= DECL_CHAIN (local_decls
))
1106 if (TREE_ADDRESSABLE (local_decls
))
1108 any_addressable_vars
= 1;
1111 if (block
== gimple_block (parallel_stmt
))
1115 if (!any_addressable_vars
)
1116 gimple_omp_return_set_nowait (stmt
);
1122 remove_exit_barriers (struct omp_region
*region
)
1124 if (region
->type
== GIMPLE_OMP_PARALLEL
)
1125 remove_exit_barrier (region
);
1129 region
= region
->inner
;
1130 remove_exit_barriers (region
);
1131 while (region
->next
)
1133 region
= region
->next
;
1134 remove_exit_barriers (region
);
1139 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
1140 calls. These can't be declared as const functions, but
1141 within one parallel body they are constant, so they can be
1142 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
1143 which are declared const. Similarly for task body, except
1144 that in untied task omp_get_thread_num () can change at any task
1145 scheduling point. */
1148 optimize_omp_library_calls (gimple
*entry_stmt
)
1151 gimple_stmt_iterator gsi
;
1152 tree thr_num_tree
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
1153 tree thr_num_id
= DECL_ASSEMBLER_NAME (thr_num_tree
);
1154 tree num_thr_tree
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
1155 tree num_thr_id
= DECL_ASSEMBLER_NAME (num_thr_tree
);
1156 bool untied_task
= (gimple_code (entry_stmt
) == GIMPLE_OMP_TASK
1157 && omp_find_clause (gimple_omp_task_clauses (entry_stmt
),
1158 OMP_CLAUSE_UNTIED
) != NULL
);
1160 FOR_EACH_BB_FN (bb
, cfun
)
1161 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1163 gimple
*call
= gsi_stmt (gsi
);
1166 if (is_gimple_call (call
)
1167 && (decl
= gimple_call_fndecl (call
))
1168 && DECL_EXTERNAL (decl
)
1169 && TREE_PUBLIC (decl
)
1170 && DECL_INITIAL (decl
) == NULL
)
1174 if (DECL_NAME (decl
) == thr_num_id
)
1176 /* In #pragma omp task untied omp_get_thread_num () can change
1177 during the execution of the task region. */
1180 built_in
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
1182 else if (DECL_NAME (decl
) == num_thr_id
)
1183 built_in
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
1187 if (DECL_ASSEMBLER_NAME (decl
) != DECL_ASSEMBLER_NAME (built_in
)
1188 || gimple_call_num_args (call
) != 0)
1191 if (flag_exceptions
&& !TREE_NOTHROW (decl
))
1194 if (TREE_CODE (TREE_TYPE (decl
)) != FUNCTION_TYPE
1195 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl
)),
1196 TREE_TYPE (TREE_TYPE (built_in
))))
1199 gimple_call_set_fndecl (call
, built_in
);
1204 /* Callback for expand_omp_build_assign. Return non-NULL if *tp needs to be
1208 expand_omp_regimplify_p (tree
*tp
, int *walk_subtrees
, void *)
1212 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
1213 if (VAR_P (t
) && DECL_HAS_VALUE_EXPR_P (t
))
1216 if (TREE_CODE (t
) == ADDR_EXPR
)
1217 recompute_tree_invariant_for_addr_expr (t
);
1219 *walk_subtrees
= !TYPE_P (t
) && !DECL_P (t
);
1223 /* Prepend or append TO = FROM assignment before or after *GSI_P. */
1226 expand_omp_build_assign (gimple_stmt_iterator
*gsi_p
, tree to
, tree from
,
1229 bool simple_p
= DECL_P (to
) && TREE_ADDRESSABLE (to
);
1230 from
= force_gimple_operand_gsi (gsi_p
, from
, simple_p
, NULL_TREE
,
1231 !after
, after
? GSI_CONTINUE_LINKING
1233 gimple
*stmt
= gimple_build_assign (to
, from
);
1235 gsi_insert_after (gsi_p
, stmt
, GSI_CONTINUE_LINKING
);
1237 gsi_insert_before (gsi_p
, stmt
, GSI_SAME_STMT
);
1238 if (walk_tree (&from
, expand_omp_regimplify_p
, NULL
, NULL
)
1239 || walk_tree (&to
, expand_omp_regimplify_p
, NULL
, NULL
))
1241 gimple_stmt_iterator gsi
= gsi_for_stmt (stmt
);
1242 gimple_regimplify_operands (stmt
, &gsi
);
1246 /* Prepend or append LHS CODE RHS condition before or after *GSI_P. */
1249 expand_omp_build_cond (gimple_stmt_iterator
*gsi_p
, enum tree_code code
,
1250 tree lhs
, tree rhs
, bool after
= false)
1252 gcond
*cond_stmt
= gimple_build_cond (code
, lhs
, rhs
, NULL_TREE
, NULL_TREE
);
1254 gsi_insert_after (gsi_p
, cond_stmt
, GSI_CONTINUE_LINKING
);
1256 gsi_insert_before (gsi_p
, cond_stmt
, GSI_SAME_STMT
);
1257 if (walk_tree (gimple_cond_lhs_ptr (cond_stmt
), expand_omp_regimplify_p
,
1259 || walk_tree (gimple_cond_rhs_ptr (cond_stmt
), expand_omp_regimplify_p
,
1262 gimple_stmt_iterator gsi
= gsi_for_stmt (cond_stmt
);
1263 gimple_regimplify_operands (cond_stmt
, &gsi
);
1268 /* Expand the OpenMP parallel or task directive starting at REGION. */
1271 expand_omp_taskreg (struct omp_region
*region
)
1273 basic_block entry_bb
, exit_bb
, new_bb
;
1274 struct function
*child_cfun
;
1275 tree child_fn
, block
, t
;
1276 gimple_stmt_iterator gsi
;
1277 gimple
*entry_stmt
, *stmt
;
1279 vec
<tree
, va_gc
> *ws_args
;
1281 entry_stmt
= last_nondebug_stmt (region
->entry
);
1282 if (gimple_code (entry_stmt
) == GIMPLE_OMP_TASK
1283 && gimple_omp_task_taskwait_p (entry_stmt
))
1285 new_bb
= region
->entry
;
1286 gsi
= gsi_last_nondebug_bb (region
->entry
);
1287 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_TASK
);
1288 gsi_remove (&gsi
, true);
1289 expand_taskwait_call (new_bb
, as_a
<gomp_task
*> (entry_stmt
));
1293 child_fn
= gimple_omp_taskreg_child_fn (entry_stmt
);
1294 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
1296 entry_bb
= region
->entry
;
1297 if (gimple_code (entry_stmt
) == GIMPLE_OMP_TASK
)
1298 exit_bb
= region
->cont
;
1300 exit_bb
= region
->exit
;
1302 if (is_combined_parallel (region
))
1303 ws_args
= region
->ws_args
;
1307 if (child_cfun
->cfg
)
1309 /* Due to inlining, it may happen that we have already outlined
1310 the region, in which case all we need to do is make the
1311 sub-graph unreachable and emit the parallel call. */
1312 edge entry_succ_e
, exit_succ_e
;
1314 entry_succ_e
= single_succ_edge (entry_bb
);
1316 gsi
= gsi_last_nondebug_bb (entry_bb
);
1317 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_PARALLEL
1318 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_TASK
1319 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_TEAMS
);
1320 gsi_remove (&gsi
, true);
1325 exit_succ_e
= single_succ_edge (exit_bb
);
1326 make_edge (new_bb
, exit_succ_e
->dest
, EDGE_FALLTHRU
);
1328 remove_edge_and_dominated_blocks (entry_succ_e
);
1332 unsigned srcidx
, dstidx
, num
;
1334 /* If the parallel region needs data sent from the parent
1335 function, then the very first statement (except possible
1336 tree profile counter updates) of the parallel body
1337 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
1338 &.OMP_DATA_O is passed as an argument to the child function,
1339 we need to replace it with the argument as seen by the child
1342 In most cases, this will end up being the identity assignment
1343 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
1344 a function call that has been inlined, the original PARM_DECL
1345 .OMP_DATA_I may have been converted into a different local
1346 variable. In which case, we need to keep the assignment. */
1347 if (gimple_omp_taskreg_data_arg (entry_stmt
))
1349 basic_block entry_succ_bb
1350 = single_succ_p (entry_bb
) ? single_succ (entry_bb
)
1351 : FALLTHRU_EDGE (entry_bb
)->dest
;
1353 gimple
*parcopy_stmt
= NULL
;
1355 for (gsi
= gsi_start_bb (entry_succ_bb
); ; gsi_next (&gsi
))
1359 gcc_assert (!gsi_end_p (gsi
));
1360 stmt
= gsi_stmt (gsi
);
1361 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
1364 if (gimple_num_ops (stmt
) == 2)
1366 tree arg
= gimple_assign_rhs1 (stmt
);
1368 /* We're ignore the subcode because we're
1369 effectively doing a STRIP_NOPS. */
1371 if (TREE_CODE (arg
) == ADDR_EXPR
1372 && (TREE_OPERAND (arg
, 0)
1373 == gimple_omp_taskreg_data_arg (entry_stmt
)))
1375 parcopy_stmt
= stmt
;
1381 gcc_assert (parcopy_stmt
!= NULL
);
1382 arg
= DECL_ARGUMENTS (child_fn
);
1384 if (!gimple_in_ssa_p (cfun
))
1386 if (gimple_assign_lhs (parcopy_stmt
) == arg
)
1387 gsi_remove (&gsi
, true);
1390 /* ?? Is setting the subcode really necessary ?? */
1391 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (arg
));
1392 gimple_assign_set_rhs1 (parcopy_stmt
, arg
);
1397 tree lhs
= gimple_assign_lhs (parcopy_stmt
);
1398 gcc_assert (SSA_NAME_VAR (lhs
) == arg
);
1399 /* We'd like to set the rhs to the default def in the child_fn,
1400 but it's too early to create ssa names in the child_fn.
1401 Instead, we set the rhs to the parm. In
1402 move_sese_region_to_fn, we introduce a default def for the
1403 parm, map the parm to it's default def, and once we encounter
1404 this stmt, replace the parm with the default def. */
1405 gimple_assign_set_rhs1 (parcopy_stmt
, arg
);
1406 update_stmt (parcopy_stmt
);
1410 /* Declare local variables needed in CHILD_CFUN. */
1411 block
= DECL_INITIAL (child_fn
);
1412 BLOCK_VARS (block
) = vec2chain (child_cfun
->local_decls
);
1413 /* The gimplifier could record temporaries in parallel/task block
1414 rather than in containing function's local_decls chain,
1415 which would mean cgraph missed finalizing them. Do it now. */
1416 for (t
= BLOCK_VARS (block
); t
; t
= DECL_CHAIN (t
))
1417 if (VAR_P (t
) && TREE_STATIC (t
) && !DECL_EXTERNAL (t
))
1418 varpool_node::finalize_decl (t
);
1419 DECL_SAVED_TREE (child_fn
) = NULL
;
1420 /* We'll create a CFG for child_fn, so no gimple body is needed. */
1421 gimple_set_body (child_fn
, NULL
);
1422 TREE_USED (block
) = 1;
1424 /* Reset DECL_CONTEXT on function arguments. */
1425 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
1426 DECL_CONTEXT (t
) = child_fn
;
1428 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
1429 so that it can be moved to the child function. */
1430 gsi
= gsi_last_nondebug_bb (entry_bb
);
1431 stmt
= gsi_stmt (gsi
);
1432 gcc_assert (stmt
&& (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
1433 || gimple_code (stmt
) == GIMPLE_OMP_TASK
1434 || gimple_code (stmt
) == GIMPLE_OMP_TEAMS
));
1435 e
= split_block (entry_bb
, stmt
);
1436 gsi_remove (&gsi
, true);
1439 if (gimple_code (entry_stmt
) != GIMPLE_OMP_TASK
)
1440 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
1443 e2
= make_edge (e
->src
, BRANCH_EDGE (entry_bb
)->dest
, EDGE_ABNORMAL
);
1444 gcc_assert (e2
->dest
== region
->exit
);
1445 remove_edge (BRANCH_EDGE (entry_bb
));
1446 set_immediate_dominator (CDI_DOMINATORS
, e2
->dest
, e
->src
);
1447 gsi
= gsi_last_nondebug_bb (region
->exit
);
1448 gcc_assert (!gsi_end_p (gsi
)
1449 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
1450 gsi_remove (&gsi
, true);
1453 /* Convert GIMPLE_OMP_{RETURN,CONTINUE} into a RETURN_EXPR. */
1456 gsi
= gsi_last_nondebug_bb (exit_bb
);
1457 gcc_assert (!gsi_end_p (gsi
)
1458 && (gimple_code (gsi_stmt (gsi
))
1459 == (e2
? GIMPLE_OMP_CONTINUE
: GIMPLE_OMP_RETURN
)));
1460 stmt
= gimple_build_return (NULL
);
1461 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
1462 gsi_remove (&gsi
, true);
1465 /* Move the parallel region into CHILD_CFUN. */
1467 if (gimple_in_ssa_p (cfun
))
1469 init_tree_ssa (child_cfun
);
1470 init_ssa_operands (child_cfun
);
1471 child_cfun
->gimple_df
->in_ssa_p
= true;
1475 block
= gimple_block (entry_stmt
);
1477 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
, block
);
1479 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
1482 basic_block dest_bb
= e2
->dest
;
1484 make_edge (new_bb
, dest_bb
, EDGE_FALLTHRU
);
1486 set_immediate_dominator (CDI_DOMINATORS
, dest_bb
, new_bb
);
1488 /* When the OMP expansion process cannot guarantee an up-to-date
1489 loop tree arrange for the child function to fixup loops. */
1490 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
1491 child_cfun
->x_current_loops
->state
|= LOOPS_NEED_FIXUP
;
1493 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
1494 num
= vec_safe_length (child_cfun
->local_decls
);
1495 for (srcidx
= 0, dstidx
= 0; srcidx
< num
; srcidx
++)
1497 t
= (*child_cfun
->local_decls
)[srcidx
];
1498 if (DECL_CONTEXT (t
) == cfun
->decl
)
1500 if (srcidx
!= dstidx
)
1501 (*child_cfun
->local_decls
)[dstidx
] = t
;
1505 vec_safe_truncate (child_cfun
->local_decls
, dstidx
);
1507 /* Inform the callgraph about the new function. */
1508 child_cfun
->curr_properties
= cfun
->curr_properties
;
1509 child_cfun
->has_simduid_loops
|= cfun
->has_simduid_loops
;
1510 child_cfun
->has_force_vectorize_loops
|= cfun
->has_force_vectorize_loops
;
1511 cgraph_node
*node
= cgraph_node::get_create (child_fn
);
1512 node
->parallelized_function
= 1;
1513 node
->has_omp_variant_constructs
1514 |= cgraph_node::get (cfun
->decl
)->has_omp_variant_constructs
;
1515 cgraph_node::add_new_function (child_fn
, true);
1517 bool need_asm
= DECL_ASSEMBLER_NAME_SET_P (current_function_decl
)
1518 && !DECL_ASSEMBLER_NAME_SET_P (child_fn
);
1520 /* Fix the callgraph edges for child_cfun. Those for cfun will be
1521 fixed in a following pass. */
1522 push_cfun (child_cfun
);
1524 assign_assembler_name_if_needed (child_fn
);
1527 optimize_omp_library_calls (entry_stmt
);
1528 update_max_bb_count ();
1529 cgraph_edge::rebuild_edges ();
1531 /* Some EH regions might become dead, see PR34608. If
1532 pass_cleanup_cfg isn't the first pass to happen with the
1533 new child, these dead EH edges might cause problems.
1534 Clean them up now. */
1535 if (flag_exceptions
)
1538 bool changed
= false;
1540 FOR_EACH_BB_FN (bb
, cfun
)
1541 changed
|= gimple_purge_dead_eh_edges (bb
);
1543 cleanup_tree_cfg ();
1545 if (gimple_in_ssa_p (cfun
))
1546 update_ssa (TODO_update_ssa
);
1547 if (flag_checking
&& !loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
1548 verify_loop_structure ();
1551 if (dump_file
&& !gimple_in_ssa_p (cfun
))
1553 omp_any_child_fn_dumped
= true;
1554 dump_function_header (dump_file
, child_fn
, dump_flags
);
1555 dump_function_to_file (child_fn
, dump_file
, dump_flags
);
1559 adjust_context_and_scope (region
, gimple_block (entry_stmt
), child_fn
);
1561 if (gimple_code (entry_stmt
) == GIMPLE_OMP_PARALLEL
)
1562 expand_parallel_call (region
, new_bb
,
1563 as_a
<gomp_parallel
*> (entry_stmt
), ws_args
);
1564 else if (gimple_code (entry_stmt
) == GIMPLE_OMP_TEAMS
)
1565 expand_teams_call (new_bb
, as_a
<gomp_teams
*> (entry_stmt
));
1567 expand_task_call (region
, new_bb
, as_a
<gomp_task
*> (entry_stmt
));
1570 /* Information about members of an OpenACC collapsed loop nest. */
1572 struct oacc_collapse
1574 tree base
; /* Base value. */
1575 tree iters
; /* Number of steps. */
1576 tree step
; /* Step size. */
1577 tree tile
; /* Tile increment (if tiled). */
1578 tree outer
; /* Tile iterator var. */
1581 /* Helper for expand_oacc_for. Determine collapsed loop information.
1582 Fill in COUNTS array. Emit any initialization code before GSI.
1583 Return the calculated outer loop bound of BOUND_TYPE. */
1586 expand_oacc_collapse_init (const struct omp_for_data
*fd
,
1587 gimple_stmt_iterator
*gsi
,
1588 oacc_collapse
*counts
, tree diff_type
,
1589 tree bound_type
, location_t loc
)
1591 tree tiling
= fd
->tiling
;
1592 tree total
= build_int_cst (bound_type
, 1);
1595 gcc_assert (integer_onep (fd
->loop
.step
));
1596 gcc_assert (integer_zerop (fd
->loop
.n1
));
1598 /* When tiling, the first operand of the tile clause applies to the
1599 innermost loop, and we work outwards from there. Seems
1600 backwards, but whatever. */
1601 for (ix
= fd
->collapse
; ix
--;)
1603 const omp_for_data_loop
*loop
= &fd
->loops
[ix
];
1605 tree iter_type
= TREE_TYPE (loop
->v
);
1606 tree plus_type
= iter_type
;
1608 gcc_assert (loop
->cond_code
== LT_EXPR
|| loop
->cond_code
== GT_EXPR
);
1610 if (POINTER_TYPE_P (iter_type
))
1611 plus_type
= sizetype
;
1615 tree num
= build_int_cst (integer_type_node
, fd
->collapse
);
1616 tree loop_no
= build_int_cst (integer_type_node
, ix
);
1617 tree tile
= TREE_VALUE (tiling
);
1619 = gimple_build_call_internal (IFN_GOACC_TILE
, 5, num
, loop_no
, tile
,
1620 /* gwv-outer=*/integer_zero_node
,
1621 /* gwv-inner=*/integer_zero_node
);
1623 counts
[ix
].outer
= create_tmp_var (iter_type
, ".outer");
1624 counts
[ix
].tile
= create_tmp_var (diff_type
, ".tile");
1625 gimple_call_set_lhs (call
, counts
[ix
].tile
);
1626 gimple_set_location (call
, loc
);
1627 gsi_insert_before (gsi
, call
, GSI_SAME_STMT
);
1629 tiling
= TREE_CHAIN (tiling
);
1633 counts
[ix
].tile
= NULL
;
1634 counts
[ix
].outer
= loop
->v
;
1639 tree s
= loop
->step
;
1640 bool up
= loop
->cond_code
== LT_EXPR
;
1641 tree dir
= build_int_cst (diff_type
, up
? +1 : -1);
1645 b
= force_gimple_operand_gsi (gsi
, b
, true, NULL_TREE
,
1646 true, GSI_SAME_STMT
);
1647 e
= force_gimple_operand_gsi (gsi
, e
, true, NULL_TREE
,
1648 true, GSI_SAME_STMT
);
1650 /* Convert the step, avoiding possible unsigned->signed overflow. */
1651 negating
= !up
&& TYPE_UNSIGNED (TREE_TYPE (s
));
1653 s
= fold_build1 (NEGATE_EXPR
, TREE_TYPE (s
), s
);
1654 s
= fold_convert (diff_type
, s
);
1656 s
= fold_build1 (NEGATE_EXPR
, diff_type
, s
);
1657 s
= force_gimple_operand_gsi (gsi
, s
, true, NULL_TREE
,
1658 true, GSI_SAME_STMT
);
1660 /* Determine the range, avoiding possible unsigned->signed overflow. */
1661 negating
= !up
&& TYPE_UNSIGNED (iter_type
);
1662 expr
= fold_build2 (MINUS_EXPR
, plus_type
,
1663 fold_convert (plus_type
, negating
? b
: e
),
1664 fold_convert (plus_type
, negating
? e
: b
));
1665 expr
= fold_convert (diff_type
, expr
);
1667 expr
= fold_build1 (NEGATE_EXPR
, diff_type
, expr
);
1668 tree range
= force_gimple_operand_gsi
1669 (gsi
, expr
, true, NULL_TREE
, true, GSI_SAME_STMT
);
1671 /* Determine number of iterations. */
1672 expr
= fold_build2 (MINUS_EXPR
, diff_type
, range
, dir
);
1673 expr
= fold_build2 (PLUS_EXPR
, diff_type
, expr
, s
);
1674 expr
= fold_build2 (TRUNC_DIV_EXPR
, diff_type
, expr
, s
);
1676 tree iters
= force_gimple_operand_gsi (gsi
, expr
, true, NULL_TREE
,
1677 true, GSI_SAME_STMT
);
1679 counts
[ix
].base
= b
;
1680 counts
[ix
].iters
= iters
;
1681 counts
[ix
].step
= s
;
1683 total
= fold_build2 (MULT_EXPR
, bound_type
, total
,
1684 fold_convert (bound_type
, iters
));
1690 /* Emit initializers for collapsed loop members. INNER is true if
1691 this is for the element loop of a TILE. IVAR is the outer
1692 loop iteration variable, from which collapsed loop iteration values
1693 are calculated. COUNTS array has been initialized by
1694 expand_oacc_collapse_inits. */
1697 expand_oacc_collapse_vars (const struct omp_for_data
*fd
, bool inner
,
1698 gimple_stmt_iterator
*gsi
,
1699 const oacc_collapse
*counts
, tree ivar
,
1702 tree ivar_type
= TREE_TYPE (ivar
);
1704 /* The most rapidly changing iteration variable is the innermost
1706 for (int ix
= fd
->collapse
; ix
--;)
1708 const omp_for_data_loop
*loop
= &fd
->loops
[ix
];
1709 const oacc_collapse
*collapse
= &counts
[ix
];
1710 tree v
= inner
? loop
->v
: collapse
->outer
;
1711 tree iter_type
= TREE_TYPE (v
);
1712 tree plus_type
= iter_type
;
1713 enum tree_code plus_code
= PLUS_EXPR
;
1716 if (POINTER_TYPE_P (iter_type
))
1718 plus_code
= POINTER_PLUS_EXPR
;
1719 plus_type
= sizetype
;
1725 tree mod
= fold_convert (ivar_type
, collapse
->iters
);
1726 ivar
= fold_build2 (TRUNC_DIV_EXPR
, ivar_type
, expr
, mod
);
1727 expr
= fold_build2 (TRUNC_MOD_EXPR
, ivar_type
, expr
, mod
);
1728 ivar
= force_gimple_operand_gsi (gsi
, ivar
, true, NULL_TREE
,
1729 true, GSI_SAME_STMT
);
1732 expr
= fold_build2 (MULT_EXPR
, diff_type
, fold_convert (diff_type
, expr
),
1733 fold_convert (diff_type
, collapse
->step
));
1734 expr
= fold_build2 (plus_code
, iter_type
,
1735 inner
? collapse
->outer
: collapse
->base
,
1736 fold_convert (plus_type
, expr
));
1737 expr
= force_gimple_operand_gsi (gsi
, expr
, false, NULL_TREE
,
1738 true, GSI_SAME_STMT
);
1739 gassign
*ass
= gimple_build_assign (v
, expr
);
1740 gsi_insert_before (gsi
, ass
, GSI_SAME_STMT
);
1744 /* Helper function for expand_omp_{for_*,simd}. If this is the outermost
1745 of the combined collapse > 1 loop constructs, generate code like:
1746 if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
1751 count3 = (adj + N32 - N31) / STEP3;
1752 if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
1757 count2 = (adj + N22 - N21) / STEP2;
1758 if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
1763 count1 = (adj + N12 - N11) / STEP1;
1764 count = count1 * count2 * count3;
1765 Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
1767 and set ZERO_ITER_BB to that bb. If this isn't the outermost
1768 of the combined loop constructs, just initialize COUNTS array
1769 from the _looptemp_ clauses. For loop nests with non-rectangular
1770 loops, do this only for the rectangular loops. Then pick
1771 the loops which reference outer vars in their bound expressions
1772 and the loops which they refer to and for this sub-nest compute
1773 number of iterations. For triangular loops use Faulhaber's formula,
1774 otherwise as a fallback, compute by iterating the loops.
1775 If e.g. the sub-nest is
1776 for (I = N11; I COND1 N12; I += STEP1)
1777 for (J = M21 * I + N21; J COND2 M22 * I + N22; J += STEP2)
1778 for (K = M31 * J + N31; K COND3 M32 * J + N32; K += STEP3)
1781 for (tmpi = N11; tmpi COND1 N12; tmpi += STEP1)
1782 for (tmpj = M21 * tmpi + N21;
1783 tmpj COND2 M22 * tmpi + N22; tmpj += STEP2)
1785 int tmpk1 = M31 * tmpj + N31;
1786 int tmpk2 = M32 * tmpj + N32;
1787 if (tmpk1 COND3 tmpk2)
1793 COUNT += (adj + tmpk2 - tmpk1) / STEP3;
1796 and finally multiply the counts of the rectangular loops not
1797 in the sub-nest with COUNT. Also, as counts[fd->last_nonrect]
1798 store number of iterations of the loops from fd->first_nonrect
1799 to fd->last_nonrect inclusive, i.e. the above COUNT multiplied
1800 by the counts of rectangular loops not referenced in any non-rectangular
1801 loops sandwitched in between those. */
1803 /* NOTE: It *could* be better to moosh all of the BBs together,
1804 creating one larger BB with all the computation and the unexpected
1805 jump at the end. I.e.
1807 bool zero3, zero2, zero1, zero;
1810 count3 = (N32 - N31) /[cl] STEP3;
1812 count2 = (N22 - N21) /[cl] STEP2;
1814 count1 = (N12 - N11) /[cl] STEP1;
1815 zero = zero3 || zero2 || zero1;
1816 count = count1 * count2 * count3;
1817 if (__builtin_expect(zero, false)) goto zero_iter_bb;
1819 After all, we expect the zero=false, and thus we expect to have to
1820 evaluate all of the comparison expressions, so short-circuiting
1821 oughtn't be a win. Since the condition isn't protecting a
1822 denominator, we're not concerned about divide-by-zero, so we can
1823 fully evaluate count even if a numerator turned out to be wrong.
1825 It seems like putting this all together would create much better
1826 scheduling opportunities, and less pressure on the chip's branch
1830 expand_omp_for_init_counts (struct omp_for_data
*fd
, gimple_stmt_iterator
*gsi
,
1831 basic_block
&entry_bb
, tree
*counts
,
1832 basic_block
&zero_iter1_bb
, int &first_zero_iter1
,
1833 basic_block
&zero_iter2_bb
, int &first_zero_iter2
,
1834 basic_block
&l2_dom_bb
)
1836 tree t
, type
= TREE_TYPE (fd
->loop
.v
);
1840 /* Collapsed loops need work for expansion into SSA form. */
1841 gcc_assert (!gimple_in_ssa_p (cfun
));
1843 if (gimple_omp_for_combined_into_p (fd
->for_stmt
)
1844 && TREE_CODE (fd
->loop
.n2
) != INTEGER_CST
)
1846 gcc_assert (fd
->ordered
== 0);
1847 /* First two _looptemp_ clauses are for istart/iend, counts[0]
1848 isn't supposed to be handled, as the inner loop doesn't
1850 tree innerc
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
1851 OMP_CLAUSE__LOOPTEMP_
);
1852 gcc_assert (innerc
);
1853 for (i
= 0; i
< fd
->collapse
; i
++)
1855 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
1856 OMP_CLAUSE__LOOPTEMP_
);
1857 gcc_assert (innerc
);
1859 counts
[i
] = OMP_CLAUSE_DECL (innerc
);
1861 counts
[0] = NULL_TREE
;
1864 && fd
->last_nonrect
== fd
->first_nonrect
+ 1
1865 && !TYPE_UNSIGNED (TREE_TYPE (fd
->loops
[fd
->last_nonrect
].v
)))
1868 for (i
= 0; i
< 4; i
++)
1870 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
1871 OMP_CLAUSE__LOOPTEMP_
);
1872 gcc_assert (innerc
);
1873 c
[i
] = OMP_CLAUSE_DECL (innerc
);
1876 fd
->first_inner_iterations
= c
[1];
1883 for (i
= fd
->collapse
; i
< fd
->ordered
; i
++)
1885 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
1886 counts
[i
] = NULL_TREE
;
1887 t
= fold_binary (fd
->loops
[i
].cond_code
, boolean_type_node
,
1888 fold_convert (itype
, fd
->loops
[i
].n1
),
1889 fold_convert (itype
, fd
->loops
[i
].n2
));
1890 if (t
&& integer_zerop (t
))
1892 for (i
= fd
->collapse
; i
< fd
->ordered
; i
++)
1893 counts
[i
] = build_int_cst (type
, 0);
1897 bool rect_count_seen
= false;
1898 for (i
= 0; i
< (fd
->ordered
? fd
->ordered
: fd
->collapse
); i
++)
1900 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
1902 if (i
>= fd
->collapse
&& counts
[i
])
1906 /* Skip loops that use outer iterators in their expressions
1907 during this phase. */
1908 if (fd
->loops
[i
].m1
|| fd
->loops
[i
].m2
)
1910 counts
[i
] = build_zero_cst (type
);
1914 if ((SSA_VAR_P (fd
->loop
.n2
) || i
>= fd
->collapse
)
1915 && ((t
= fold_binary (fd
->loops
[i
].cond_code
, boolean_type_node
,
1916 fold_convert (itype
, fd
->loops
[i
].n1
),
1917 fold_convert (itype
, fd
->loops
[i
].n2
)))
1918 == NULL_TREE
|| !integer_onep (t
)))
1922 n1
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n1
));
1923 n1
= force_gimple_operand_gsi (gsi
, n1
, true, NULL_TREE
,
1924 true, GSI_SAME_STMT
);
1925 n2
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
1926 n2
= force_gimple_operand_gsi (gsi
, n2
, true, NULL_TREE
,
1927 true, GSI_SAME_STMT
);
1928 cond_stmt
= expand_omp_build_cond (gsi
, fd
->loops
[i
].cond_code
,
1930 e
= split_block (entry_bb
, cond_stmt
);
1931 basic_block
&zero_iter_bb
1932 = i
< fd
->collapse
? zero_iter1_bb
: zero_iter2_bb
;
1933 int &first_zero_iter
1934 = i
< fd
->collapse
? first_zero_iter1
: first_zero_iter2
;
1935 if (zero_iter_bb
== NULL
)
1937 gassign
*assign_stmt
;
1938 first_zero_iter
= i
;
1939 zero_iter_bb
= create_empty_bb (entry_bb
);
1940 add_bb_to_loop (zero_iter_bb
, entry_bb
->loop_father
);
1941 *gsi
= gsi_after_labels (zero_iter_bb
);
1942 if (i
< fd
->collapse
)
1943 assign_stmt
= gimple_build_assign (fd
->loop
.n2
,
1944 build_zero_cst (type
));
1947 counts
[i
] = create_tmp_reg (type
, ".count");
1949 = gimple_build_assign (counts
[i
], build_zero_cst (type
));
1951 gsi_insert_before (gsi
, assign_stmt
, GSI_SAME_STMT
);
1952 set_immediate_dominator (CDI_DOMINATORS
, zero_iter_bb
,
1955 ne
= make_edge (entry_bb
, zero_iter_bb
, EDGE_FALSE_VALUE
);
1956 ne
->probability
= profile_probability::very_unlikely ();
1957 e
->flags
= EDGE_TRUE_VALUE
;
1958 e
->probability
= ne
->probability
.invert ();
1959 if (l2_dom_bb
== NULL
)
1960 l2_dom_bb
= entry_bb
;
1962 *gsi
= gsi_last_nondebug_bb (entry_bb
);
1965 if (POINTER_TYPE_P (itype
))
1966 itype
= signed_type_for (itype
);
1967 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
== LT_EXPR
1969 t
= fold_build2 (PLUS_EXPR
, itype
,
1970 fold_convert (itype
, fd
->loops
[i
].step
), t
);
1971 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
1972 fold_convert (itype
, fd
->loops
[i
].n2
));
1973 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
1974 fold_convert (itype
, fd
->loops
[i
].n1
));
1975 /* ?? We could probably use CEIL_DIV_EXPR instead of
1976 TRUNC_DIV_EXPR and adjusting by hand. Unless we can't
1977 generate the same code in the end because generically we
1978 don't know that the values involved must be negative for
1980 if (TYPE_UNSIGNED (itype
) && fd
->loops
[i
].cond_code
== GT_EXPR
)
1981 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
1982 fold_build1 (NEGATE_EXPR
, itype
, t
),
1983 fold_build1 (NEGATE_EXPR
, itype
,
1984 fold_convert (itype
,
1985 fd
->loops
[i
].step
)));
1987 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
,
1988 fold_convert (itype
, fd
->loops
[i
].step
));
1989 t
= fold_convert (type
, t
);
1990 if (TREE_CODE (t
) == INTEGER_CST
)
1994 if (i
< fd
->collapse
|| i
!= first_zero_iter2
)
1995 counts
[i
] = create_tmp_reg (type
, ".count");
1996 expand_omp_build_assign (gsi
, counts
[i
], t
);
1998 if (SSA_VAR_P (fd
->loop
.n2
) && i
< fd
->collapse
)
2000 if (fd
->non_rect
&& i
>= fd
->first_nonrect
&& i
<= fd
->last_nonrect
)
2002 if (!rect_count_seen
)
2005 rect_count_seen
= true;
2008 t
= fold_build2 (MULT_EXPR
, type
, fd
->loop
.n2
, counts
[i
]);
2009 expand_omp_build_assign (gsi
, fd
->loop
.n2
, t
);
2012 if (fd
->non_rect
&& SSA_VAR_P (fd
->loop
.n2
))
2014 gcc_assert (fd
->last_nonrect
!= -1);
2016 counts
[fd
->last_nonrect
] = create_tmp_reg (type
, ".count");
2017 expand_omp_build_assign (gsi
, counts
[fd
->last_nonrect
],
2018 build_zero_cst (type
));
2019 for (i
= fd
->first_nonrect
+ 1; i
< fd
->last_nonrect
; i
++)
2022 || fd
->loops
[i
].non_rect_referenced
)
2024 if (i
== fd
->last_nonrect
2025 && fd
->loops
[i
].outer
== fd
->last_nonrect
- fd
->first_nonrect
2026 && !POINTER_TYPE_P (TREE_TYPE (fd
->loops
[i
].v
))
2027 && !TYPE_UNSIGNED (TREE_TYPE (fd
->loops
[i
].v
)))
2029 int o
= fd
->first_nonrect
;
2030 tree itype
= TREE_TYPE (fd
->loops
[o
].v
);
2031 tree n1o
= create_tmp_reg (itype
, ".n1o");
2032 t
= fold_convert (itype
, unshare_expr (fd
->loops
[o
].n1
));
2033 expand_omp_build_assign (gsi
, n1o
, t
);
2034 tree n2o
= create_tmp_reg (itype
, ".n2o");
2035 t
= fold_convert (itype
, unshare_expr (fd
->loops
[o
].n2
));
2036 expand_omp_build_assign (gsi
, n2o
, t
);
2037 if (fd
->loops
[i
].m1
&& fd
->loops
[i
].m2
)
2038 t
= fold_build2 (MINUS_EXPR
, itype
, unshare_expr (fd
->loops
[i
].m2
),
2039 unshare_expr (fd
->loops
[i
].m1
));
2040 else if (fd
->loops
[i
].m1
)
2041 t
= fold_build1 (NEGATE_EXPR
, itype
,
2042 unshare_expr (fd
->loops
[i
].m1
));
2044 t
= unshare_expr (fd
->loops
[i
].m2
);
2046 = force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
,
2047 true, GSI_SAME_STMT
);
2049 gimple_stmt_iterator gsi2
= *gsi
;
2051 e
= split_block (entry_bb
, gsi_stmt (gsi2
));
2052 e
= split_block (e
->dest
, (gimple
*) NULL
);
2053 basic_block bb1
= e
->src
;
2055 *gsi
= gsi_after_labels (entry_bb
);
2057 gsi2
= gsi_after_labels (bb1
);
2058 tree ostep
= fold_convert (itype
, fd
->loops
[o
].step
);
2059 t
= build_int_cst (itype
, (fd
->loops
[o
].cond_code
2060 == LT_EXPR
? -1 : 1));
2061 t
= fold_build2 (PLUS_EXPR
, itype
, ostep
, t
);
2062 t
= fold_build2 (PLUS_EXPR
, itype
, t
, n2o
);
2063 t
= fold_build2 (MINUS_EXPR
, itype
, t
, n1o
);
2064 if (TYPE_UNSIGNED (itype
)
2065 && fd
->loops
[o
].cond_code
== GT_EXPR
)
2066 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
2067 fold_build1 (NEGATE_EXPR
, itype
, t
),
2068 fold_build1 (NEGATE_EXPR
, itype
, ostep
));
2070 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, ostep
);
2072 = force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2073 true, GSI_SAME_STMT
);
2074 t
= fold_build2 (MINUS_EXPR
, itype
, outer_niters
,
2075 build_one_cst (itype
));
2076 t
= fold_build2 (MULT_EXPR
, itype
, t
, ostep
);
2077 t
= fold_build2 (PLUS_EXPR
, itype
, n1o
, t
);
2078 tree last
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2079 true, GSI_SAME_STMT
);
2080 tree n1
, n2
, n1e
, n2e
;
2081 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n1
));
2082 if (fd
->loops
[i
].m1
)
2084 n1
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m1
));
2085 n1
= fold_build2 (MULT_EXPR
, itype
, n1o
, n1
);
2086 n1
= fold_build2 (PLUS_EXPR
, itype
, n1
, t
);
2090 n1
= force_gimple_operand_gsi (&gsi2
, n1
, true, NULL_TREE
,
2091 true, GSI_SAME_STMT
);
2092 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
2093 if (fd
->loops
[i
].m2
)
2095 n2
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m2
));
2096 n2
= fold_build2 (MULT_EXPR
, itype
, n1o
, n2
);
2097 n2
= fold_build2 (PLUS_EXPR
, itype
, n2
, t
);
2101 n2
= force_gimple_operand_gsi (&gsi2
, n2
, true, NULL_TREE
,
2102 true, GSI_SAME_STMT
);
2103 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n1
));
2104 if (fd
->loops
[i
].m1
)
2106 n1e
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m1
));
2107 n1e
= fold_build2 (MULT_EXPR
, itype
, last
, n1e
);
2108 n1e
= fold_build2 (PLUS_EXPR
, itype
, n1e
, t
);
2112 n1e
= force_gimple_operand_gsi (&gsi2
, n1e
, true, NULL_TREE
,
2113 true, GSI_SAME_STMT
);
2114 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
2115 if (fd
->loops
[i
].m2
)
2117 n2e
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m2
));
2118 n2e
= fold_build2 (MULT_EXPR
, itype
, last
, n2e
);
2119 n2e
= fold_build2 (PLUS_EXPR
, itype
, n2e
, t
);
2123 n2e
= force_gimple_operand_gsi (&gsi2
, n2e
, true, NULL_TREE
,
2124 true, GSI_SAME_STMT
);
2126 = expand_omp_build_cond (&gsi2
, fd
->loops
[i
].cond_code
,
2128 e
= split_block (bb1
, cond_stmt
);
2129 e
->flags
= EDGE_TRUE_VALUE
;
2130 e
->probability
= profile_probability::likely ().guessed ();
2131 basic_block bb2
= e
->dest
;
2132 gsi2
= gsi_after_labels (bb2
);
2134 cond_stmt
= expand_omp_build_cond (&gsi2
, fd
->loops
[i
].cond_code
,
2136 e
= split_block (bb2
, cond_stmt
);
2137 e
->flags
= EDGE_TRUE_VALUE
;
2138 e
->probability
= profile_probability::likely ().guessed ();
2139 gsi2
= gsi_after_labels (e
->dest
);
2141 tree step
= fold_convert (itype
, fd
->loops
[i
].step
);
2142 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
2143 == LT_EXPR
? -1 : 1));
2144 t
= fold_build2 (PLUS_EXPR
, itype
, step
, t
);
2145 t
= fold_build2 (PLUS_EXPR
, itype
, t
, n2
);
2146 t
= fold_build2 (MINUS_EXPR
, itype
, t
, n1
);
2147 if (TYPE_UNSIGNED (itype
)
2148 && fd
->loops
[i
].cond_code
== GT_EXPR
)
2149 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
2150 fold_build1 (NEGATE_EXPR
, itype
, t
),
2151 fold_build1 (NEGATE_EXPR
, itype
, step
));
2153 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
2154 tree first_inner_iterations
2155 = force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2156 true, GSI_SAME_STMT
);
2157 t
= fold_build2 (MULT_EXPR
, itype
, m2minusm1
, ostep
);
2158 if (TYPE_UNSIGNED (itype
)
2159 && fd
->loops
[i
].cond_code
== GT_EXPR
)
2160 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
2161 fold_build1 (NEGATE_EXPR
, itype
, t
),
2162 fold_build1 (NEGATE_EXPR
, itype
, step
));
2164 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
2166 = force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2167 true, GSI_SAME_STMT
);
2168 t
= fold_build2 (MINUS_EXPR
, itype
, outer_niters
,
2169 build_one_cst (itype
));
2170 t
= fold_build2 (MULT_EXPR
, itype
, t
, outer_niters
);
2171 t
= fold_build2 (RSHIFT_EXPR
, itype
, t
, integer_one_node
);
2172 t
= fold_build2 (MULT_EXPR
, itype
, factor
, t
);
2173 t
= fold_build2 (PLUS_EXPR
, itype
,
2174 fold_build2 (MULT_EXPR
, itype
, outer_niters
,
2175 first_inner_iterations
), t
);
2176 expand_omp_build_assign (&gsi2
, counts
[fd
->last_nonrect
],
2177 fold_convert (type
, t
));
2179 basic_block bb3
= create_empty_bb (bb1
);
2180 add_bb_to_loop (bb3
, bb1
->loop_father
);
2182 e
= make_edge (bb1
, bb3
, EDGE_FALSE_VALUE
);
2183 e
->probability
= profile_probability::unlikely ().guessed ();
2185 gsi2
= gsi_after_labels (bb3
);
2186 cond_stmt
= expand_omp_build_cond (&gsi2
, fd
->loops
[i
].cond_code
,
2188 e
= split_block (bb3
, cond_stmt
);
2189 e
->flags
= EDGE_TRUE_VALUE
;
2190 e
->probability
= profile_probability::likely ().guessed ();
2191 basic_block bb4
= e
->dest
;
2193 ne
= make_edge (bb3
, entry_bb
, EDGE_FALSE_VALUE
);
2194 ne
->probability
= e
->probability
.invert ();
2196 basic_block bb5
= create_empty_bb (bb2
);
2197 add_bb_to_loop (bb5
, bb2
->loop_father
);
2199 ne
= make_edge (bb2
, bb5
, EDGE_FALSE_VALUE
);
2200 ne
->probability
= profile_probability::unlikely ().guessed ();
2202 for (int j
= 0; j
< 2; j
++)
2204 gsi2
= gsi_after_labels (j
? bb5
: bb4
);
2205 t
= fold_build2 (MINUS_EXPR
, itype
,
2206 unshare_expr (fd
->loops
[i
].n1
),
2207 unshare_expr (fd
->loops
[i
].n2
));
2208 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, m2minusm1
);
2210 = force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2211 true, GSI_SAME_STMT
);
2212 t
= fold_build2 (MINUS_EXPR
, itype
, tem
, n1o
);
2213 t
= fold_build2 (TRUNC_MOD_EXPR
, itype
, t
, ostep
);
2214 t
= fold_build2 (MINUS_EXPR
, itype
, tem
, t
);
2215 tem
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2216 true, GSI_SAME_STMT
);
2217 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n1
));
2218 if (fd
->loops
[i
].m1
)
2220 n1
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m1
));
2221 n1
= fold_build2 (MULT_EXPR
, itype
, tem
, n1
);
2222 n1
= fold_build2 (PLUS_EXPR
, itype
, n1
, t
);
2226 n1
= force_gimple_operand_gsi (&gsi2
, n1
, true, NULL_TREE
,
2227 true, GSI_SAME_STMT
);
2228 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
2229 if (fd
->loops
[i
].m2
)
2231 n2
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m2
));
2232 n2
= fold_build2 (MULT_EXPR
, itype
, tem
, n2
);
2233 n2
= fold_build2 (PLUS_EXPR
, itype
, n2
, t
);
2237 n2
= force_gimple_operand_gsi (&gsi2
, n2
, true, NULL_TREE
,
2238 true, GSI_SAME_STMT
);
2239 expand_omp_build_assign (&gsi2
, j
? n2o
: n1o
, tem
);
2241 cond_stmt
= expand_omp_build_cond (&gsi2
, fd
->loops
[i
].cond_code
,
2243 e
= split_block (gsi_bb (gsi2
), cond_stmt
);
2244 e
->flags
= j
? EDGE_TRUE_VALUE
: EDGE_FALSE_VALUE
;
2245 e
->probability
= profile_probability::unlikely ().guessed ();
2246 ne
= make_edge (e
->src
, bb1
,
2247 j
? EDGE_FALSE_VALUE
: EDGE_TRUE_VALUE
);
2248 ne
->probability
= e
->probability
.invert ();
2249 gsi2
= gsi_after_labels (e
->dest
);
2251 t
= fold_build2 (PLUS_EXPR
, itype
, tem
, ostep
);
2252 expand_omp_build_assign (&gsi2
, j
? n2o
: n1o
, t
);
2254 make_edge (e
->dest
, bb1
, EDGE_FALLTHRU
);
2257 set_immediate_dominator (CDI_DOMINATORS
, bb3
, bb1
);
2258 set_immediate_dominator (CDI_DOMINATORS
, bb5
, bb2
);
2259 set_immediate_dominator (CDI_DOMINATORS
, entry_bb
, bb1
);
2261 if (fd
->first_nonrect
+ 1 == fd
->last_nonrect
)
2263 fd
->first_inner_iterations
= first_inner_iterations
;
2264 fd
->factor
= factor
;
2270 /* Fallback implementation. Evaluate the loops with m1/m2
2271 non-NULL as well as their outer loops at runtime using temporaries
2272 instead of the original iteration variables, and in the
2273 body just bump the counter. */
2274 gimple_stmt_iterator gsi2
= *gsi
;
2276 e
= split_block (entry_bb
, gsi_stmt (gsi2
));
2277 e
= split_block (e
->dest
, (gimple
*) NULL
);
2278 basic_block cur_bb
= e
->src
;
2279 basic_block next_bb
= e
->dest
;
2281 *gsi
= gsi_after_labels (entry_bb
);
2283 tree
*vs
= XALLOCAVEC (tree
, fd
->last_nonrect
);
2284 memset (vs
, 0, fd
->last_nonrect
* sizeof (tree
));
2286 for (i
= 0; i
<= fd
->last_nonrect
; i
++)
2288 if (fd
->loops
[i
].m1
== NULL_TREE
2289 && fd
->loops
[i
].m2
== NULL_TREE
2290 && !fd
->loops
[i
].non_rect_referenced
)
2293 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
2295 gsi2
= gsi_after_labels (cur_bb
);
2297 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n1
));
2298 if (fd
->loops
[i
].m1
== NULL_TREE
)
2300 else if (POINTER_TYPE_P (itype
))
2302 gcc_assert (integer_onep (fd
->loops
[i
].m1
));
2303 t
= unshare_expr (fd
->loops
[i
].n1
);
2304 n1
= fold_build_pointer_plus (vs
[i
- fd
->loops
[i
].outer
], t
);
2308 n1
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m1
));
2309 n1
= fold_build2 (MULT_EXPR
, itype
,
2310 vs
[i
- fd
->loops
[i
].outer
], n1
);
2311 n1
= fold_build2 (PLUS_EXPR
, itype
, n1
, t
);
2313 n1
= force_gimple_operand_gsi (&gsi2
, n1
, true, NULL_TREE
,
2314 true, GSI_SAME_STMT
);
2315 if (i
< fd
->last_nonrect
)
2317 vs
[i
] = create_tmp_reg (itype
, ".it");
2318 expand_omp_build_assign (&gsi2
, vs
[i
], n1
);
2320 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
2321 if (fd
->loops
[i
].m2
== NULL_TREE
)
2323 else if (POINTER_TYPE_P (itype
))
2325 gcc_assert (integer_onep (fd
->loops
[i
].m2
));
2326 t
= unshare_expr (fd
->loops
[i
].n2
);
2327 n2
= fold_build_pointer_plus (vs
[i
- fd
->loops
[i
].outer
], t
);
2331 n2
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m2
));
2332 n2
= fold_build2 (MULT_EXPR
, itype
,
2333 vs
[i
- fd
->loops
[i
].outer
], n2
);
2334 n2
= fold_build2 (PLUS_EXPR
, itype
, n2
, t
);
2336 n2
= force_gimple_operand_gsi (&gsi2
, n2
, true, NULL_TREE
,
2337 true, GSI_SAME_STMT
);
2338 if (POINTER_TYPE_P (itype
))
2339 itype
= signed_type_for (itype
);
2340 if (i
== fd
->last_nonrect
)
2343 = expand_omp_build_cond (&gsi2
, fd
->loops
[i
].cond_code
,
2345 e
= split_block (cur_bb
, cond_stmt
);
2346 e
->flags
= EDGE_TRUE_VALUE
;
2347 ne
= make_edge (cur_bb
, next_bb
, EDGE_FALSE_VALUE
);
2348 e
->probability
= profile_probability::likely ().guessed ();
2349 ne
->probability
= e
->probability
.invert ();
2350 gsi2
= gsi_after_labels (e
->dest
);
2352 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
== LT_EXPR
2354 t
= fold_build2 (PLUS_EXPR
, itype
,
2355 fold_convert (itype
, fd
->loops
[i
].step
), t
);
2356 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
2357 fold_convert (itype
, n2
));
2358 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
2359 fold_convert (itype
, n1
));
2360 tree step
= fold_convert (itype
, fd
->loops
[i
].step
);
2361 if (TYPE_UNSIGNED (itype
)
2362 && fd
->loops
[i
].cond_code
== GT_EXPR
)
2363 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
2364 fold_build1 (NEGATE_EXPR
, itype
, t
),
2365 fold_build1 (NEGATE_EXPR
, itype
, step
));
2367 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
2368 t
= fold_convert (type
, t
);
2369 t
= fold_build2 (PLUS_EXPR
, type
,
2370 counts
[fd
->last_nonrect
], t
);
2371 t
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2372 true, GSI_SAME_STMT
);
2373 expand_omp_build_assign (&gsi2
, counts
[fd
->last_nonrect
], t
);
2374 e
= make_edge (e
->dest
, next_bb
, EDGE_FALLTHRU
);
2375 set_immediate_dominator (CDI_DOMINATORS
, next_bb
, cur_bb
);
2378 e
= split_block (cur_bb
, last_nondebug_stmt (cur_bb
));
2380 basic_block new_cur_bb
= create_empty_bb (cur_bb
);
2381 add_bb_to_loop (new_cur_bb
, cur_bb
->loop_father
);
2383 gsi2
= gsi_after_labels (e
->dest
);
2384 tree step
= fold_convert (itype
,
2385 unshare_expr (fd
->loops
[i
].step
));
2386 if (POINTER_TYPE_P (TREE_TYPE (vs
[i
])))
2387 t
= fold_build_pointer_plus (vs
[i
], step
);
2389 t
= fold_build2 (PLUS_EXPR
, itype
, vs
[i
], step
);
2390 t
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2391 true, GSI_SAME_STMT
);
2392 expand_omp_build_assign (&gsi2
, vs
[i
], t
);
2394 ne
= split_block (e
->dest
, last_nondebug_stmt (e
->dest
));
2395 gsi2
= gsi_after_labels (ne
->dest
);
2397 expand_omp_build_cond (&gsi2
, fd
->loops
[i
].cond_code
, vs
[i
], n2
);
2399 if (next_bb
== entry_bb
)
2401 e3
= find_edge (ne
->dest
, next_bb
);
2402 e3
->flags
= EDGE_FALSE_VALUE
;
2405 e3
= make_edge (ne
->dest
, next_bb
, EDGE_FALSE_VALUE
);
2406 e4
= make_edge (ne
->dest
, new_cur_bb
, EDGE_TRUE_VALUE
);
2407 e4
->probability
= profile_probability::likely ().guessed ();
2408 e3
->probability
= e4
->probability
.invert ();
2409 basic_block esrc
= e
->src
;
2410 make_edge (e
->src
, ne
->dest
, EDGE_FALLTHRU
);
2411 cur_bb
= new_cur_bb
;
2412 basic_block latch_bb
= next_bb
;
2415 set_immediate_dominator (CDI_DOMINATORS
, ne
->dest
, esrc
);
2416 set_immediate_dominator (CDI_DOMINATORS
, latch_bb
, ne
->dest
);
2417 set_immediate_dominator (CDI_DOMINATORS
, cur_bb
, ne
->dest
);
2421 for (i
= fd
->first_nonrect
; i
< fd
->last_nonrect
; i
++)
2422 if (!fd
->loops
[i
].non_rect_referenced
2423 && fd
->loops
[i
].m1
== NULL_TREE
2424 && fd
->loops
[i
].m2
== NULL_TREE
)
2429 t
= fold_build2 (MULT_EXPR
, type
, t
, counts
[i
]);
2433 t
= fold_build2 (MULT_EXPR
, type
, counts
[fd
->last_nonrect
], t
);
2434 expand_omp_build_assign (gsi
, counts
[fd
->last_nonrect
], t
);
2436 if (!rect_count_seen
)
2437 t
= counts
[fd
->last_nonrect
];
2439 t
= fold_build2 (MULT_EXPR
, type
, fd
->loop
.n2
,
2440 counts
[fd
->last_nonrect
]);
2441 expand_omp_build_assign (gsi
, fd
->loop
.n2
, t
);
2443 else if (fd
->non_rect
)
2445 tree t
= fd
->loop
.n2
;
2446 gcc_assert (TREE_CODE (t
) == INTEGER_CST
);
2447 int non_rect_referenced
= 0, non_rect
= 0;
2448 for (i
= 0; i
< fd
->collapse
; i
++)
2450 if ((i
< fd
->first_nonrect
|| i
> fd
->last_nonrect
)
2451 && !integer_zerop (counts
[i
]))
2452 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, t
, counts
[i
]);
2453 if (fd
->loops
[i
].non_rect_referenced
)
2454 non_rect_referenced
++;
2455 if (fd
->loops
[i
].m1
|| fd
->loops
[i
].m2
)
2458 gcc_assert (non_rect
== 1 && non_rect_referenced
== 1);
2459 counts
[fd
->last_nonrect
] = t
;
2463 /* Helper function for expand_omp_{for_*,simd}. Generate code like:
2465 V3 = N31 + (T % count3) * STEP3;
2467 V2 = N21 + (T % count2) * STEP2;
2469 V1 = N11 + T * STEP1;
2470 if this loop doesn't have an inner loop construct combined with it.
2471 If it does have an inner loop construct combined with it and the
2472 iteration count isn't known constant, store values from counts array
2473 into its _looptemp_ temporaries instead.
2474 For non-rectangular loops (between fd->first_nonrect and fd->last_nonrect
2475 inclusive), use the count of all those loops together, and either
2476 find quadratic etc. equation roots, or as a fallback, do:
2478 for (tmpi = N11; tmpi COND1 N12; tmpi += STEP1)
2479 for (tmpj = M21 * tmpi + N21;
2480 tmpj COND2 M22 * tmpi + N22; tmpj += STEP2)
2482 int tmpk1 = M31 * tmpj + N31;
2483 int tmpk2 = M32 * tmpj + N32;
2484 if (tmpk1 COND3 tmpk2)
2490 int temp = (adj + tmpk2 - tmpk1) / STEP3;
2491 if (COUNT + temp > T)
2495 V3 = tmpk1 + (T - COUNT) * STEP3;
2503 but for optional innermost or outermost rectangular loops that aren't
2504 referenced by other loop expressions keep doing the division/modulo. */
2507 expand_omp_for_init_vars (struct omp_for_data
*fd
, gimple_stmt_iterator
*gsi
,
2508 tree
*counts
, tree
*nonrect_bounds
,
2509 gimple
*inner_stmt
, tree startvar
)
2512 if (gimple_omp_for_combined_p (fd
->for_stmt
))
2514 /* If fd->loop.n2 is constant, then no propagation of the counts
2515 is needed, they are constant. */
2516 if (TREE_CODE (fd
->loop
.n2
) == INTEGER_CST
)
2519 tree clauses
= gimple_code (inner_stmt
) != GIMPLE_OMP_FOR
2520 ? gimple_omp_taskreg_clauses (inner_stmt
)
2521 : gimple_omp_for_clauses (inner_stmt
);
2522 /* First two _looptemp_ clauses are for istart/iend, counts[0]
2523 isn't supposed to be handled, as the inner loop doesn't
2525 tree innerc
= omp_find_clause (clauses
, OMP_CLAUSE__LOOPTEMP_
);
2526 gcc_assert (innerc
);
2529 && fd
->last_nonrect
== fd
->first_nonrect
+ 1
2530 && !TYPE_UNSIGNED (TREE_TYPE (fd
->loops
[fd
->last_nonrect
].v
)))
2532 for (i
= 0; i
< fd
->collapse
+ count
; i
++)
2534 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
2535 OMP_CLAUSE__LOOPTEMP_
);
2536 gcc_assert (innerc
);
2539 tree tem
= OMP_CLAUSE_DECL (innerc
);
2541 if (i
< fd
->collapse
)
2544 switch (i
- fd
->collapse
)
2546 case 0: t
= counts
[0]; break;
2547 case 1: t
= fd
->first_inner_iterations
; break;
2548 case 2: t
= fd
->factor
; break;
2549 case 3: t
= fd
->adjn1
; break;
2550 default: gcc_unreachable ();
2552 t
= fold_convert (TREE_TYPE (tem
), t
);
2553 t
= force_gimple_operand_gsi (gsi
, t
, false, NULL_TREE
,
2554 false, GSI_CONTINUE_LINKING
);
2555 gassign
*stmt
= gimple_build_assign (tem
, t
);
2556 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
2562 tree type
= TREE_TYPE (fd
->loop
.v
);
2563 tree tem
= create_tmp_reg (type
, ".tem");
2564 gassign
*stmt
= gimple_build_assign (tem
, startvar
);
2565 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
2567 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
2569 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
), itype
, t
;
2571 if (POINTER_TYPE_P (vtype
))
2572 itype
= signed_type_for (vtype
);
2573 if (i
!= 0 && (i
!= fd
->last_nonrect
|| fd
->first_nonrect
))
2574 t
= fold_build2 (TRUNC_MOD_EXPR
, type
, tem
, counts
[i
]);
2577 if (i
== fd
->last_nonrect
)
2579 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
,
2580 false, GSI_CONTINUE_LINKING
);
2582 tree idx
= create_tmp_reg (type
, ".count");
2583 expand_omp_build_assign (gsi
, idx
,
2584 build_zero_cst (type
), true);
2585 basic_block bb_triang
= NULL
, bb_triang_dom
= NULL
;
2586 if (fd
->first_nonrect
+ 1 == fd
->last_nonrect
2587 && (TREE_CODE (fd
->loop
.n2
) == INTEGER_CST
2588 || fd
->first_inner_iterations
)
2589 && (optab_handler (sqrt_optab
, TYPE_MODE (double_type_node
))
2590 != CODE_FOR_nothing
)
2591 && !integer_zerop (fd
->loop
.n2
))
2593 tree outer_n1
= fd
->adjn1
? fd
->adjn1
: fd
->loops
[i
- 1].n1
;
2594 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
2595 tree first_inner_iterations
= fd
->first_inner_iterations
;
2596 tree factor
= fd
->factor
;
2598 = expand_omp_build_cond (gsi
, NE_EXPR
, factor
,
2599 build_zero_cst (TREE_TYPE (factor
)),
2601 edge e
= split_block (gsi_bb (*gsi
), cond_stmt
);
2602 basic_block bb0
= e
->src
;
2603 e
->flags
= EDGE_TRUE_VALUE
;
2604 e
->probability
= profile_probability::likely ();
2605 bb_triang_dom
= bb0
;
2606 *gsi
= gsi_after_labels (e
->dest
);
2607 tree slltype
= long_long_integer_type_node
;
2608 tree ulltype
= long_long_unsigned_type_node
;
2609 tree stopvalull
= fold_convert (ulltype
, stopval
);
2611 = force_gimple_operand_gsi (gsi
, stopvalull
, true, NULL_TREE
,
2612 false, GSI_CONTINUE_LINKING
);
2613 first_inner_iterations
2614 = fold_convert (slltype
, first_inner_iterations
);
2615 first_inner_iterations
2616 = force_gimple_operand_gsi (gsi
, first_inner_iterations
, true,
2618 GSI_CONTINUE_LINKING
);
2619 factor
= fold_convert (slltype
, factor
);
2621 = force_gimple_operand_gsi (gsi
, factor
, true, NULL_TREE
,
2622 false, GSI_CONTINUE_LINKING
);
2623 tree first_inner_iterationsd
2624 = fold_build1 (FLOAT_EXPR
, double_type_node
,
2625 first_inner_iterations
);
2626 first_inner_iterationsd
2627 = force_gimple_operand_gsi (gsi
, first_inner_iterationsd
, true,
2629 GSI_CONTINUE_LINKING
);
2630 tree factord
= fold_build1 (FLOAT_EXPR
, double_type_node
,
2632 factord
= force_gimple_operand_gsi (gsi
, factord
, true,
2634 GSI_CONTINUE_LINKING
);
2635 tree stopvald
= fold_build1 (FLOAT_EXPR
, double_type_node
,
2637 stopvald
= force_gimple_operand_gsi (gsi
, stopvald
, true,
2639 GSI_CONTINUE_LINKING
);
2640 /* Temporarily disable flag_rounding_math, values will be
2641 decimal numbers divided by 2 and worst case imprecisions
2642 due to too large values ought to be caught later by the
2643 checks for fallback. */
2644 int save_flag_rounding_math
= flag_rounding_math
;
2645 flag_rounding_math
= 0;
2646 t
= fold_build2 (RDIV_EXPR
, double_type_node
, factord
,
2647 build_real (double_type_node
, dconst2
));
2648 tree t3
= fold_build2 (MINUS_EXPR
, double_type_node
,
2649 first_inner_iterationsd
, t
);
2650 t3
= force_gimple_operand_gsi (gsi
, t3
, true, NULL_TREE
, false,
2651 GSI_CONTINUE_LINKING
);
2652 t
= fold_build2 (MULT_EXPR
, double_type_node
, factord
,
2653 build_real (double_type_node
, dconst2
));
2654 t
= fold_build2 (MULT_EXPR
, double_type_node
, t
, stopvald
);
2655 t
= fold_build2 (PLUS_EXPR
, double_type_node
, t
,
2656 fold_build2 (MULT_EXPR
, double_type_node
,
2658 flag_rounding_math
= save_flag_rounding_math
;
2659 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, false,
2660 GSI_CONTINUE_LINKING
);
2662 && cfun
->can_throw_non_call_exceptions
2663 && operation_could_trap_p (LT_EXPR
, true, false, NULL_TREE
))
2665 tree tem
= fold_build2 (LT_EXPR
, boolean_type_node
, t
,
2666 build_zero_cst (double_type_node
));
2667 tem
= force_gimple_operand_gsi (gsi
, tem
, true, NULL_TREE
,
2668 false, GSI_CONTINUE_LINKING
);
2669 cond_stmt
= gimple_build_cond (NE_EXPR
, tem
,
2671 NULL_TREE
, NULL_TREE
);
2675 = gimple_build_cond (LT_EXPR
, t
,
2676 build_zero_cst (double_type_node
),
2677 NULL_TREE
, NULL_TREE
);
2678 gsi_insert_after (gsi
, cond_stmt
, GSI_CONTINUE_LINKING
);
2679 e
= split_block (gsi_bb (*gsi
), cond_stmt
);
2680 basic_block bb1
= e
->src
;
2681 e
->flags
= EDGE_FALSE_VALUE
;
2682 e
->probability
= profile_probability::very_likely ();
2683 *gsi
= gsi_after_labels (e
->dest
);
2684 gcall
*call
= gimple_build_call_internal (IFN_SQRT
, 1, t
);
2685 tree sqrtr
= create_tmp_var (double_type_node
);
2686 gimple_call_set_lhs (call
, sqrtr
);
2687 gsi_insert_after (gsi
, call
, GSI_CONTINUE_LINKING
);
2688 t
= fold_build2 (MINUS_EXPR
, double_type_node
, sqrtr
, t3
);
2689 t
= fold_build2 (RDIV_EXPR
, double_type_node
, t
, factord
);
2690 t
= fold_build1 (FIX_TRUNC_EXPR
, ulltype
, t
);
2691 tree c
= create_tmp_var (ulltype
);
2692 tree d
= create_tmp_var (ulltype
);
2693 expand_omp_build_assign (gsi
, c
, t
, true);
2694 t
= fold_build2 (MINUS_EXPR
, ulltype
, c
,
2695 build_one_cst (ulltype
));
2696 t
= fold_build2 (MULT_EXPR
, ulltype
, c
, t
);
2697 t
= fold_build2 (RSHIFT_EXPR
, ulltype
, t
, integer_one_node
);
2698 t
= fold_build2 (MULT_EXPR
, ulltype
,
2699 fold_convert (ulltype
, fd
->factor
), t
);
2701 = fold_build2 (MULT_EXPR
, ulltype
, c
,
2702 fold_convert (ulltype
,
2703 fd
->first_inner_iterations
));
2704 t
= fold_build2 (PLUS_EXPR
, ulltype
, t
, t2
);
2705 expand_omp_build_assign (gsi
, d
, t
, true);
2706 t
= fold_build2 (MULT_EXPR
, ulltype
,
2707 fold_convert (ulltype
, fd
->factor
), c
);
2708 t
= fold_build2 (PLUS_EXPR
, ulltype
,
2709 t
, fold_convert (ulltype
,
2710 fd
->first_inner_iterations
));
2711 t2
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, false,
2712 GSI_CONTINUE_LINKING
);
2713 cond_stmt
= gimple_build_cond (GE_EXPR
, stopvalull
, d
,
2714 NULL_TREE
, NULL_TREE
);
2715 gsi_insert_after (gsi
, cond_stmt
, GSI_CONTINUE_LINKING
);
2716 e
= split_block (gsi_bb (*gsi
), cond_stmt
);
2717 basic_block bb2
= e
->src
;
2718 e
->flags
= EDGE_TRUE_VALUE
;
2719 e
->probability
= profile_probability::very_likely ();
2720 *gsi
= gsi_after_labels (e
->dest
);
2721 t
= fold_build2 (PLUS_EXPR
, ulltype
, d
, t2
);
2722 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, false,
2723 GSI_CONTINUE_LINKING
);
2724 cond_stmt
= gimple_build_cond (GE_EXPR
, stopvalull
, t
,
2725 NULL_TREE
, NULL_TREE
);
2726 gsi_insert_after (gsi
, cond_stmt
, GSI_CONTINUE_LINKING
);
2727 e
= split_block (gsi_bb (*gsi
), cond_stmt
);
2728 basic_block bb3
= e
->src
;
2729 e
->flags
= EDGE_FALSE_VALUE
;
2730 e
->probability
= profile_probability::very_likely ();
2731 *gsi
= gsi_after_labels (e
->dest
);
2732 t
= fold_convert (itype
, c
);
2733 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loops
[i
- 1].step
);
2734 t
= fold_build2 (PLUS_EXPR
, itype
, outer_n1
, t
);
2735 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
, false,
2736 GSI_CONTINUE_LINKING
);
2737 expand_omp_build_assign (gsi
, fd
->loops
[i
- 1].v
, t
, true);
2738 t2
= fold_build2 (MINUS_EXPR
, ulltype
, stopvalull
, d
);
2739 t2
= fold_convert (itype
, t2
);
2740 t2
= fold_build2 (MULT_EXPR
, itype
, t2
, fd
->loops
[i
].step
);
2741 t2
= fold_build2 (PLUS_EXPR
, itype
, t2
, fd
->loops
[i
].n1
);
2742 if (fd
->loops
[i
].m1
)
2744 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loops
[i
].m1
);
2745 t2
= fold_build2 (PLUS_EXPR
, itype
, t2
, t
);
2747 expand_omp_build_assign (gsi
, fd
->loops
[i
].v
, t2
, true);
2748 e
= split_block (gsi_bb (*gsi
), gsi_stmt (*gsi
));
2750 *gsi
= gsi_after_labels (e
->dest
);
2752 e
= make_edge (bb1
, gsi_bb (*gsi
), EDGE_TRUE_VALUE
);
2753 e
->probability
= profile_probability::very_unlikely ();
2754 e
= make_edge (bb2
, gsi_bb (*gsi
), EDGE_FALSE_VALUE
);
2755 e
->probability
= profile_probability::very_unlikely ();
2756 e
= make_edge (bb3
, gsi_bb (*gsi
), EDGE_TRUE_VALUE
);
2757 e
->probability
= profile_probability::very_unlikely ();
2759 basic_block bb4
= create_empty_bb (bb0
);
2760 add_bb_to_loop (bb4
, bb0
->loop_father
);
2761 e
= make_edge (bb0
, bb4
, EDGE_FALSE_VALUE
);
2762 e
->probability
= profile_probability::unlikely ();
2763 make_edge (bb4
, gsi_bb (*gsi
), EDGE_FALLTHRU
);
2764 set_immediate_dominator (CDI_DOMINATORS
, bb4
, bb0
);
2765 set_immediate_dominator (CDI_DOMINATORS
, gsi_bb (*gsi
), bb0
);
2766 gimple_stmt_iterator gsi2
= gsi_after_labels (bb4
);
2767 t2
= fold_build2 (TRUNC_DIV_EXPR
, type
,
2768 counts
[i
], counts
[i
- 1]);
2769 t2
= force_gimple_operand_gsi (&gsi2
, t2
, true, NULL_TREE
, false,
2770 GSI_CONTINUE_LINKING
);
2771 t
= fold_build2 (TRUNC_MOD_EXPR
, type
, stopval
, t2
);
2772 t2
= fold_build2 (TRUNC_DIV_EXPR
, type
, stopval
, t2
);
2773 t
= fold_convert (itype
, t
);
2774 t2
= fold_convert (itype
, t2
);
2775 t
= fold_build2 (MULT_EXPR
, itype
, t
,
2776 fold_convert (itype
, fd
->loops
[i
].step
));
2777 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[i
].n1
, t
);
2778 t2
= fold_build2 (MULT_EXPR
, itype
, t2
,
2779 fold_convert (itype
, fd
->loops
[i
- 1].step
));
2780 t2
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[i
- 1].n1
, t2
);
2781 t2
= force_gimple_operand_gsi (&gsi2
, t2
, false, NULL_TREE
,
2782 false, GSI_CONTINUE_LINKING
);
2783 stmt
= gimple_build_assign (fd
->loops
[i
- 1].v
, t2
);
2784 gsi_insert_after (&gsi2
, stmt
, GSI_CONTINUE_LINKING
);
2785 if (fd
->loops
[i
].m1
)
2787 t2
= fold_build2 (MULT_EXPR
, itype
, fd
->loops
[i
].m1
,
2788 fd
->loops
[i
- 1].v
);
2789 t
= fold_build2 (PLUS_EXPR
, itype
, t
, t2
);
2791 t
= force_gimple_operand_gsi (&gsi2
, t
, false, NULL_TREE
,
2792 false, GSI_CONTINUE_LINKING
);
2793 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
2794 gsi_insert_after (&gsi2
, stmt
, GSI_CONTINUE_LINKING
);
2796 /* Fallback implementation. Evaluate the loops in between
2797 (inclusive) fd->first_nonrect and fd->last_nonrect at
2798 runtime unsing temporaries instead of the original iteration
2799 variables, in the body just bump the counter and compare
2800 with the desired value. */
2801 gimple_stmt_iterator gsi2
= *gsi
;
2802 basic_block entry_bb
= gsi_bb (gsi2
);
2803 edge e
= split_block (entry_bb
, gsi_stmt (gsi2
));
2804 e
= split_block (e
->dest
, (gimple
*) NULL
);
2805 basic_block dom_bb
= NULL
;
2806 basic_block cur_bb
= e
->src
;
2807 basic_block next_bb
= e
->dest
;
2809 *gsi
= gsi_after_labels (entry_bb
);
2811 tree
*vs
= XALLOCAVEC (tree
, fd
->last_nonrect
);
2812 tree n1
= NULL_TREE
, n2
= NULL_TREE
;
2813 memset (vs
, 0, fd
->last_nonrect
* sizeof (tree
));
2815 for (int j
= fd
->first_nonrect
; j
<= fd
->last_nonrect
; j
++)
2817 tree itype
= TREE_TYPE (fd
->loops
[j
].v
);
2818 bool rect_p
= (fd
->loops
[j
].m1
== NULL_TREE
2819 && fd
->loops
[j
].m2
== NULL_TREE
2820 && !fd
->loops
[j
].non_rect_referenced
);
2821 gsi2
= gsi_after_labels (cur_bb
);
2822 t
= fold_convert (itype
, unshare_expr (fd
->loops
[j
].n1
));
2823 if (fd
->loops
[j
].m1
== NULL_TREE
)
2824 n1
= rect_p
? build_zero_cst (type
) : t
;
2825 else if (POINTER_TYPE_P (itype
))
2827 gcc_assert (integer_onep (fd
->loops
[j
].m1
));
2828 t
= unshare_expr (fd
->loops
[j
].n1
);
2829 n1
= fold_build_pointer_plus (vs
[j
- fd
->loops
[j
].outer
], t
);
2833 n1
= fold_convert (itype
, unshare_expr (fd
->loops
[j
].m1
));
2834 n1
= fold_build2 (MULT_EXPR
, itype
,
2835 vs
[j
- fd
->loops
[j
].outer
], n1
);
2836 n1
= fold_build2 (PLUS_EXPR
, itype
, n1
, t
);
2838 n1
= force_gimple_operand_gsi (&gsi2
, n1
, true, NULL_TREE
,
2839 true, GSI_SAME_STMT
);
2840 if (j
< fd
->last_nonrect
)
2842 vs
[j
] = create_tmp_reg (rect_p
? type
: itype
, ".it");
2843 expand_omp_build_assign (&gsi2
, vs
[j
], n1
);
2845 t
= fold_convert (itype
, unshare_expr (fd
->loops
[j
].n2
));
2846 if (fd
->loops
[j
].m2
== NULL_TREE
)
2847 n2
= rect_p
? counts
[j
] : t
;
2848 else if (POINTER_TYPE_P (itype
))
2850 gcc_assert (integer_onep (fd
->loops
[j
].m2
));
2851 t
= unshare_expr (fd
->loops
[j
].n2
);
2852 n2
= fold_build_pointer_plus (vs
[j
- fd
->loops
[j
].outer
], t
);
2856 n2
= fold_convert (itype
, unshare_expr (fd
->loops
[j
].m2
));
2857 n2
= fold_build2 (MULT_EXPR
, itype
,
2858 vs
[j
- fd
->loops
[j
].outer
], n2
);
2859 n2
= fold_build2 (PLUS_EXPR
, itype
, n2
, t
);
2861 n2
= force_gimple_operand_gsi (&gsi2
, n2
, true, NULL_TREE
,
2862 true, GSI_SAME_STMT
);
2863 if (POINTER_TYPE_P (itype
))
2864 itype
= signed_type_for (itype
);
2865 if (j
== fd
->last_nonrect
)
2868 = expand_omp_build_cond (&gsi2
, fd
->loops
[i
].cond_code
,
2870 e
= split_block (cur_bb
, cond_stmt
);
2871 e
->flags
= EDGE_TRUE_VALUE
;
2872 edge ne
= make_edge (cur_bb
, next_bb
, EDGE_FALSE_VALUE
);
2873 e
->probability
= profile_probability::likely ().guessed ();
2874 ne
->probability
= e
->probability
.invert ();
2875 gsi2
= gsi_after_labels (e
->dest
);
2877 t
= build_int_cst (itype
, (fd
->loops
[j
].cond_code
== LT_EXPR
2879 t
= fold_build2 (PLUS_EXPR
, itype
,
2880 fold_convert (itype
, fd
->loops
[j
].step
), t
);
2881 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
2882 fold_convert (itype
, n2
));
2883 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
2884 fold_convert (itype
, n1
));
2885 tree step
= fold_convert (itype
, fd
->loops
[j
].step
);
2886 if (TYPE_UNSIGNED (itype
)
2887 && fd
->loops
[j
].cond_code
== GT_EXPR
)
2888 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
2889 fold_build1 (NEGATE_EXPR
, itype
, t
),
2890 fold_build1 (NEGATE_EXPR
, itype
, step
));
2892 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
2893 t
= fold_convert (type
, t
);
2894 t
= fold_build2 (PLUS_EXPR
, type
, idx
, t
);
2895 t
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2896 true, GSI_SAME_STMT
);
2897 e
= make_edge (e
->dest
, next_bb
, EDGE_FALLTHRU
);
2898 set_immediate_dominator (CDI_DOMINATORS
, next_bb
, cur_bb
);
2900 = gimple_build_cond (LE_EXPR
, t
, stopval
, NULL_TREE
,
2902 gsi_insert_before (&gsi2
, cond_stmt
, GSI_SAME_STMT
);
2903 e
= split_block (gsi_bb (gsi2
), cond_stmt
);
2904 e
->flags
= EDGE_TRUE_VALUE
;
2905 e
->probability
= profile_probability::likely ().guessed ();
2906 ne
= make_edge (e
->src
, entry_bb
, EDGE_FALSE_VALUE
);
2907 ne
->probability
= e
->probability
.invert ();
2908 gsi2
= gsi_after_labels (e
->dest
);
2909 expand_omp_build_assign (&gsi2
, idx
, t
);
2910 set_immediate_dominator (CDI_DOMINATORS
, entry_bb
, dom_bb
);
2913 e
= split_block (cur_bb
, last_nondebug_stmt (cur_bb
));
2915 basic_block new_cur_bb
= create_empty_bb (cur_bb
);
2916 add_bb_to_loop (new_cur_bb
, cur_bb
->loop_father
);
2918 gsi2
= gsi_after_labels (e
->dest
);
2920 t
= fold_build2 (PLUS_EXPR
, type
, vs
[j
],
2921 build_one_cst (type
));
2925 = fold_convert (itype
, unshare_expr (fd
->loops
[j
].step
));
2926 if (POINTER_TYPE_P (vtype
))
2927 t
= fold_build_pointer_plus (vs
[j
], step
);
2929 t
= fold_build2 (PLUS_EXPR
, itype
, vs
[j
], step
);
2931 t
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
2932 true, GSI_SAME_STMT
);
2933 expand_omp_build_assign (&gsi2
, vs
[j
], t
);
2935 edge ne
= split_block (e
->dest
, last_nondebug_stmt (e
->dest
));
2936 gsi2
= gsi_after_labels (ne
->dest
);
2939 if (next_bb
== entry_bb
)
2940 /* No need to actually check the outermost condition. */
2942 = gimple_build_cond (EQ_EXPR
, boolean_true_node
,
2944 NULL_TREE
, NULL_TREE
);
2947 = gimple_build_cond (rect_p
? LT_EXPR
2948 : fd
->loops
[j
].cond_code
,
2949 vs
[j
], n2
, NULL_TREE
, NULL_TREE
);
2950 gsi_insert_before (&gsi2
, cond_stmt
, GSI_SAME_STMT
);
2952 if (next_bb
== entry_bb
)
2954 e3
= find_edge (ne
->dest
, next_bb
);
2955 e3
->flags
= EDGE_FALSE_VALUE
;
2959 e3
= make_edge (ne
->dest
, next_bb
, EDGE_FALSE_VALUE
);
2960 e4
= make_edge (ne
->dest
, new_cur_bb
, EDGE_TRUE_VALUE
);
2961 e4
->probability
= profile_probability::likely ().guessed ();
2962 e3
->probability
= e4
->probability
.invert ();
2963 basic_block esrc
= e
->src
;
2964 make_edge (e
->src
, ne
->dest
, EDGE_FALLTHRU
);
2965 cur_bb
= new_cur_bb
;
2966 basic_block latch_bb
= next_bb
;
2969 set_immediate_dominator (CDI_DOMINATORS
, ne
->dest
, esrc
);
2970 set_immediate_dominator (CDI_DOMINATORS
, latch_bb
, ne
->dest
);
2971 set_immediate_dominator (CDI_DOMINATORS
, cur_bb
, ne
->dest
);
2973 for (int j
= fd
->last_nonrect
; j
>= fd
->first_nonrect
; j
--)
2975 tree vtype
= TREE_TYPE (fd
->loops
[j
].v
);
2977 if (POINTER_TYPE_P (itype
))
2978 itype
= signed_type_for (itype
);
2979 bool rect_p
= (fd
->loops
[j
].m1
== NULL_TREE
2980 && fd
->loops
[j
].m2
== NULL_TREE
2981 && !fd
->loops
[j
].non_rect_referenced
);
2982 if (j
== fd
->last_nonrect
)
2984 t
= fold_build2 (MINUS_EXPR
, type
, stopval
, idx
);
2985 t
= fold_convert (itype
, t
);
2987 = fold_convert (itype
, unshare_expr (fd
->loops
[j
].step
));
2988 t
= fold_build2 (MULT_EXPR
, itype
, t
, t2
);
2989 if (POINTER_TYPE_P (vtype
))
2990 t
= fold_build_pointer_plus (n1
, t
);
2992 t
= fold_build2 (PLUS_EXPR
, itype
, n1
, t
);
2996 t
= fold_convert (itype
, vs
[j
]);
2997 t
= fold_build2 (MULT_EXPR
, itype
, t
,
2998 fold_convert (itype
, fd
->loops
[j
].step
));
2999 if (POINTER_TYPE_P (vtype
))
3000 t
= fold_build_pointer_plus (fd
->loops
[j
].n1
, t
);
3002 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[j
].n1
, t
);
3006 t
= force_gimple_operand_gsi (gsi
, t
, false,
3009 stmt
= gimple_build_assign (fd
->loops
[j
].v
, t
);
3010 gsi_insert_before (gsi
, stmt
, GSI_SAME_STMT
);
3012 if (gsi_end_p (*gsi
))
3013 *gsi
= gsi_last_bb (gsi_bb (*gsi
));
3018 e
= split_block (gsi_bb (*gsi
), gsi_stmt (*gsi
));
3019 make_edge (bb_triang
, e
->dest
, EDGE_FALLTHRU
);
3020 *gsi
= gsi_after_labels (e
->dest
);
3021 if (!gsi_end_p (*gsi
))
3022 gsi_insert_before (gsi
, gimple_build_nop (), GSI_NEW_STMT
);
3023 set_immediate_dominator (CDI_DOMINATORS
, e
->dest
, bb_triang_dom
);
3028 t
= fold_convert (itype
, t
);
3029 t
= fold_build2 (MULT_EXPR
, itype
, t
,
3030 fold_convert (itype
, fd
->loops
[i
].step
));
3031 if (POINTER_TYPE_P (vtype
))
3032 t
= fold_build_pointer_plus (fd
->loops
[i
].n1
, t
);
3034 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[i
].n1
, t
);
3035 t
= force_gimple_operand_gsi (gsi
, t
,
3036 DECL_P (fd
->loops
[i
].v
)
3037 && TREE_ADDRESSABLE (fd
->loops
[i
].v
),
3039 GSI_CONTINUE_LINKING
);
3040 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
3041 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
3043 if (i
!= 0 && (i
!= fd
->last_nonrect
|| fd
->first_nonrect
))
3045 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, tem
, counts
[i
]);
3046 t
= force_gimple_operand_gsi (gsi
, t
, false, NULL_TREE
,
3047 false, GSI_CONTINUE_LINKING
);
3048 stmt
= gimple_build_assign (tem
, t
);
3049 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
3051 if (i
== fd
->last_nonrect
)
3052 i
= fd
->first_nonrect
;
3055 for (i
= 0; i
<= fd
->last_nonrect
; i
++)
3056 if (fd
->loops
[i
].m2
)
3058 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
3061 if (POINTER_TYPE_P (itype
))
3063 gcc_assert (integer_onep (fd
->loops
[i
].m2
));
3064 t
= fold_build_pointer_plus (fd
->loops
[i
- fd
->loops
[i
].outer
].v
,
3065 unshare_expr (fd
->loops
[i
].n2
));
3069 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].m2
));
3070 t
= fold_build2 (MULT_EXPR
, itype
,
3071 fd
->loops
[i
- fd
->loops
[i
].outer
].v
, t
);
3072 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
3073 fold_convert (itype
,
3074 unshare_expr (fd
->loops
[i
].n2
)));
3076 nonrect_bounds
[i
] = create_tmp_reg (itype
, ".bound");
3077 t
= force_gimple_operand_gsi (gsi
, t
, false,
3079 GSI_CONTINUE_LINKING
);
3080 stmt
= gimple_build_assign (nonrect_bounds
[i
], t
);
3081 gsi_insert_after (gsi
, stmt
, GSI_CONTINUE_LINKING
);
3085 /* Helper function for expand_omp_for_*. Generate code like:
3088 if (V3 cond3 N32) goto BODY_BB; else goto L11;
3092 if (V2 cond2 N22) goto BODY_BB; else goto L12;
3097 For non-rectangular loops, use temporaries stored in nonrect_bounds
3098 for the upper bounds if M?2 multiplier is present. Given e.g.
3099 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3100 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3101 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3102 for (V4 = N41 + M41 * V2; V4 cond4 N42 + M42 * V2; V4 += STEP4)
3106 if (V4 cond4 NONRECT_BOUND4) goto BODY_BB; else goto L11;
3108 V4 = N41 + M41 * V2; // This can be left out if the loop
3109 // refers to the immediate parent loop
3111 if (V3 cond3 N32) goto BODY_BB; else goto L12;
3115 if (V2 cond2 N22) goto L120; else goto L13;
3117 V4 = N41 + M41 * V2;
3118 NONRECT_BOUND4 = N42 + M42 * V2;
3119 if (V4 cond4 NONRECT_BOUND4) goto BODY_BB; else goto L12;
3126 extract_omp_for_update_vars (struct omp_for_data
*fd
, tree
*nonrect_bounds
,
3127 basic_block cont_bb
, basic_block body_bb
)
3129 basic_block last_bb
, bb
, collapse_bb
= NULL
;
3131 gimple_stmt_iterator gsi
;
3137 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
3139 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
);
3141 bb
= create_empty_bb (last_bb
);
3142 add_bb_to_loop (bb
, last_bb
->loop_father
);
3143 gsi
= gsi_start_bb (bb
);
3145 if (i
< fd
->collapse
- 1)
3147 e
= make_edge (last_bb
, bb
, EDGE_FALSE_VALUE
);
3148 e
->probability
= profile_probability::guessed_always () / 8;
3150 struct omp_for_data_loop
*l
= &fd
->loops
[i
+ 1];
3151 if (l
->m1
== NULL_TREE
|| l
->outer
!= 1)
3156 if (POINTER_TYPE_P (TREE_TYPE (l
->v
)))
3157 t
= fold_build_pointer_plus (fd
->loops
[i
+ 1 - l
->outer
].v
,
3162 = fold_build2 (MULT_EXPR
, TREE_TYPE (t
),
3163 fd
->loops
[i
+ 1 - l
->outer
].v
, l
->m1
);
3164 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t2
, t
);
3167 t
= force_gimple_operand_gsi (&gsi
, t
,
3169 && TREE_ADDRESSABLE (l
->v
),
3171 GSI_CONTINUE_LINKING
);
3172 stmt
= gimple_build_assign (l
->v
, t
);
3173 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3179 set_immediate_dominator (CDI_DOMINATORS
, bb
, last_bb
);
3181 if (POINTER_TYPE_P (vtype
))
3182 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, fd
->loops
[i
].step
);
3184 t
= fold_build2 (PLUS_EXPR
, vtype
, fd
->loops
[i
].v
, fd
->loops
[i
].step
);
3185 t
= force_gimple_operand_gsi (&gsi
, t
,
3186 DECL_P (fd
->loops
[i
].v
)
3187 && TREE_ADDRESSABLE (fd
->loops
[i
].v
),
3188 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
3189 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
3190 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3192 if (fd
->loops
[i
].non_rect_referenced
)
3194 basic_block update_bb
= NULL
, prev_bb
= NULL
;
3195 for (int j
= i
+ 1; j
<= fd
->last_nonrect
; j
++)
3196 if (j
- fd
->loops
[j
].outer
== i
)
3199 struct omp_for_data_loop
*l
= &fd
->loops
[j
];
3200 basic_block this_bb
= create_empty_bb (last_bb
);
3201 add_bb_to_loop (this_bb
, last_bb
->loop_father
);
3202 gimple_stmt_iterator gsi2
= gsi_start_bb (this_bb
);
3205 e
= make_edge (prev_bb
, this_bb
, EDGE_TRUE_VALUE
);
3207 = profile_probability::guessed_always ().apply_scale (7,
3209 set_immediate_dominator (CDI_DOMINATORS
, this_bb
, prev_bb
);
3213 if (POINTER_TYPE_P (TREE_TYPE (l
->v
)))
3214 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, l
->n1
);
3217 t
= fold_build2 (MULT_EXPR
, TREE_TYPE (l
->m1
), l
->m1
,
3219 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (l
->v
),
3222 n1
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
3224 GSI_CONTINUE_LINKING
);
3225 stmt
= gimple_build_assign (l
->v
, n1
);
3226 gsi_insert_after (&gsi2
, stmt
, GSI_CONTINUE_LINKING
);
3230 n1
= force_gimple_operand_gsi (&gsi2
, l
->n1
, true,
3232 GSI_CONTINUE_LINKING
);
3235 if (POINTER_TYPE_P (TREE_TYPE (l
->v
)))
3236 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, l
->n2
);
3239 t
= fold_build2 (MULT_EXPR
, TREE_TYPE (l
->m2
), l
->m2
,
3241 t
= fold_build2 (PLUS_EXPR
,
3242 TREE_TYPE (nonrect_bounds
[j
]),
3243 t
, unshare_expr (l
->n2
));
3245 n2
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
3247 GSI_CONTINUE_LINKING
);
3248 stmt
= gimple_build_assign (nonrect_bounds
[j
], n2
);
3249 gsi_insert_after (&gsi2
, stmt
, GSI_CONTINUE_LINKING
);
3250 n2
= nonrect_bounds
[j
];
3253 n2
= force_gimple_operand_gsi (&gsi2
, unshare_expr (l
->n2
),
3254 true, NULL_TREE
, false,
3255 GSI_CONTINUE_LINKING
);
3257 = gimple_build_cond (l
->cond_code
, n1
, n2
,
3258 NULL_TREE
, NULL_TREE
);
3259 gsi_insert_after (&gsi2
, cond_stmt
, GSI_CONTINUE_LINKING
);
3260 if (update_bb
== NULL
)
3261 update_bb
= this_bb
;
3262 e
= make_edge (this_bb
, bb
, EDGE_FALSE_VALUE
);
3263 e
->probability
= profile_probability::guessed_always () / 8;
3264 if (prev_bb
== NULL
)
3265 set_immediate_dominator (CDI_DOMINATORS
, this_bb
, bb
);
3268 e
= make_edge (prev_bb
, body_bb
, EDGE_TRUE_VALUE
);
3270 = profile_probability::guessed_always ().apply_scale (7, 8);
3271 body_bb
= update_bb
;
3276 if (fd
->loops
[i
].m2
)
3277 t
= nonrect_bounds
[i
];
3279 t
= unshare_expr (fd
->loops
[i
].n2
);
3280 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3281 false, GSI_CONTINUE_LINKING
);
3282 tree v
= fd
->loops
[i
].v
;
3283 if (DECL_P (v
) && TREE_ADDRESSABLE (v
))
3284 v
= force_gimple_operand_gsi (&gsi
, v
, true, NULL_TREE
,
3285 false, GSI_CONTINUE_LINKING
);
3286 t
= fold_build2 (fd
->loops
[i
].cond_code
, boolean_type_node
, v
, t
);
3287 stmt
= gimple_build_cond_empty (t
);
3288 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3289 if (walk_tree (gimple_cond_lhs_ptr (as_a
<gcond
*> (stmt
)),
3290 expand_omp_regimplify_p
, NULL
, NULL
)
3291 || walk_tree (gimple_cond_rhs_ptr (as_a
<gcond
*> (stmt
)),
3292 expand_omp_regimplify_p
, NULL
, NULL
))
3293 gimple_regimplify_operands (stmt
, &gsi
);
3294 e
= make_edge (bb
, body_bb
, EDGE_TRUE_VALUE
);
3295 e
->probability
= profile_probability::guessed_always ().apply_scale (7, 8);
3298 make_edge (bb
, body_bb
, EDGE_FALLTHRU
);
3299 set_immediate_dominator (CDI_DOMINATORS
, bb
, last_bb
);
3306 /* Expand #pragma omp ordered depend(source). */
3309 expand_omp_ordered_source (gimple_stmt_iterator
*gsi
, struct omp_for_data
*fd
,
3310 tree
*counts
, location_t loc
)
3312 enum built_in_function source_ix
3313 = fd
->iter_type
== long_integer_type_node
3314 ? BUILT_IN_GOMP_DOACROSS_POST
: BUILT_IN_GOMP_DOACROSS_ULL_POST
;
3316 = gimple_build_call (builtin_decl_explicit (source_ix
), 1,
3317 build_fold_addr_expr (counts
[fd
->ordered
]));
3318 gimple_set_location (g
, loc
);
3319 gsi_insert_before (gsi
, g
, GSI_SAME_STMT
);
3322 /* Expand a single depend from #pragma omp ordered depend(sink:...). */
3325 expand_omp_ordered_sink (gimple_stmt_iterator
*gsi
, struct omp_for_data
*fd
,
3326 tree
*counts
, tree c
, location_t loc
,
3327 basic_block cont_bb
)
3329 auto_vec
<tree
, 10> args
;
3330 enum built_in_function sink_ix
3331 = fd
->iter_type
== long_integer_type_node
3332 ? BUILT_IN_GOMP_DOACROSS_WAIT
: BUILT_IN_GOMP_DOACROSS_ULL_WAIT
;
3333 tree t
, off
, coff
= NULL_TREE
, deps
= OMP_CLAUSE_DECL (c
), cond
= NULL_TREE
;
3335 gimple_stmt_iterator gsi2
= *gsi
;
3336 bool warned_step
= false;
3340 /* Handle doacross(sink: omp_cur_iteration - 1). */
3342 edge e1
= split_block (gsi_bb (gsi2
), gsi_stmt (gsi2
));
3343 edge e2
= split_block_after_labels (e1
->dest
);
3344 gsi2
= gsi_after_labels (e1
->dest
);
3345 *gsi
= gsi_last_bb (e1
->src
);
3346 gimple_stmt_iterator gsi3
= *gsi
;
3348 if (counts
[fd
->collapse
- 1])
3350 gcc_assert (fd
->collapse
== 1);
3351 t
= counts
[fd
->collapse
- 1];
3353 else if (fd
->collapse
> 1)
3357 t
= fold_build2 (MINUS_EXPR
, TREE_TYPE (fd
->loops
[0].v
),
3358 fd
->loops
[0].v
, fd
->loops
[0].n1
);
3359 t
= fold_convert (fd
->iter_type
, t
);
3362 t
= force_gimple_operand_gsi (gsi
, t
, true, NULL_TREE
,
3363 false, GSI_CONTINUE_LINKING
);
3364 gsi_insert_after (gsi
, gimple_build_cond (NE_EXPR
, t
,
3365 build_zero_cst (TREE_TYPE (t
)),
3366 NULL_TREE
, NULL_TREE
),
3369 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
,
3370 build_minus_one_cst (TREE_TYPE (t
)));
3371 t
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
3372 true, GSI_SAME_STMT
);
3374 for (i
= fd
->collapse
; i
< fd
->ordered
; i
++)
3376 t
= counts
[fd
->ordered
+ 2 + (i
- fd
->collapse
)];
3377 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
,
3378 build_minus_one_cst (TREE_TYPE (t
)));
3379 t
= fold_convert (fd
->iter_type
, t
);
3380 t
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
3381 true, GSI_SAME_STMT
);
3385 gimple
*g
= gimple_build_call_vec (builtin_decl_explicit (sink_ix
),
3387 gimple_set_location (g
, loc
);
3388 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
3390 edge e3
= make_edge (e1
->src
, e2
->dest
, EDGE_FALSE_VALUE
);
3391 e3
->probability
= profile_probability::guessed_always () / 8;
3392 e1
->probability
= e3
->probability
.invert ();
3393 e1
->flags
= EDGE_TRUE_VALUE
;
3394 set_immediate_dominator (CDI_DOMINATORS
, e2
->dest
, e1
->src
);
3396 if (fd
->ordered
> fd
->collapse
&& cont_bb
)
3398 if (counts
[fd
->ordered
+ 1] == NULL_TREE
)
3399 counts
[fd
->ordered
+ 1]
3400 = create_tmp_var (boolean_type_node
, ".first");
3403 if (gsi_end_p (gsi3
))
3404 e4
= split_block_after_labels (e1
->src
);
3408 e4
= split_block (gsi_bb (gsi3
), gsi_stmt (gsi3
));
3410 gsi3
= gsi_last_bb (e4
->src
);
3412 gsi_insert_after (&gsi3
,
3413 gimple_build_cond (NE_EXPR
,
3414 counts
[fd
->ordered
+ 1],
3416 NULL_TREE
, NULL_TREE
),
3419 edge e5
= make_edge (e4
->src
, e2
->dest
, EDGE_FALSE_VALUE
);
3420 e4
->probability
= profile_probability::guessed_always () / 8;
3421 e5
->probability
= e4
->probability
.invert ();
3422 e4
->flags
= EDGE_TRUE_VALUE
;
3423 set_immediate_dominator (CDI_DOMINATORS
, e2
->dest
, e4
->src
);
3426 *gsi
= gsi_after_labels (e2
->dest
);
3429 for (i
= 0; i
< fd
->ordered
; i
++)
3431 tree step
= NULL_TREE
;
3432 off
= TREE_PURPOSE (deps
);
3433 if (TREE_CODE (off
) == TRUNC_DIV_EXPR
)
3435 step
= TREE_OPERAND (off
, 1);
3436 off
= TREE_OPERAND (off
, 0);
3438 if (!integer_zerop (off
))
3440 gcc_assert (fd
->loops
[i
].cond_code
== LT_EXPR
3441 || fd
->loops
[i
].cond_code
== GT_EXPR
);
3442 bool forward
= fd
->loops
[i
].cond_code
== LT_EXPR
;
3445 /* Non-simple Fortran DO loops. If step is variable,
3446 we don't know at compile even the direction, so can't
3448 if (TREE_CODE (step
) != INTEGER_CST
)
3450 forward
= tree_int_cst_sgn (step
) != -1;
3452 if (forward
^ OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps
))
3453 warning_at (loc
, OPT_Wopenmp
,
3454 "%qs clause with %<sink%> modifier "
3455 "waiting for lexically later iteration",
3456 OMP_CLAUSE_DOACROSS_DEPEND (c
)
3457 ? "depend" : "doacross");
3460 deps
= TREE_CHAIN (deps
);
3462 /* If all offsets corresponding to the collapsed loops are zero,
3463 this depend clause can be ignored. FIXME: but there is still a
3464 flush needed. We need to emit one __sync_synchronize () for it
3465 though (perhaps conditionally)? Solve this together with the
3466 conservative dependence folding optimization.
3467 if (i >= fd->collapse)
3470 deps
= OMP_CLAUSE_DECL (c
);
3472 edge e1
= split_block (gsi_bb (gsi2
), gsi_stmt (gsi2
));
3473 edge e2
= split_block_after_labels (e1
->dest
);
3475 gsi2
= gsi_after_labels (e1
->dest
);
3476 *gsi
= gsi_last_bb (e1
->src
);
3477 for (i
= 0; i
< fd
->ordered
; i
++)
3479 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
3480 tree step
= NULL_TREE
;
3481 tree orig_off
= NULL_TREE
;
3482 if (POINTER_TYPE_P (itype
))
3485 deps
= TREE_CHAIN (deps
);
3486 off
= TREE_PURPOSE (deps
);
3487 if (TREE_CODE (off
) == TRUNC_DIV_EXPR
)
3489 step
= TREE_OPERAND (off
, 1);
3490 off
= TREE_OPERAND (off
, 0);
3491 gcc_assert (fd
->loops
[i
].cond_code
== LT_EXPR
3492 && integer_onep (fd
->loops
[i
].step
)
3493 && !POINTER_TYPE_P (TREE_TYPE (fd
->loops
[i
].v
)));
3495 tree s
= fold_convert_loc (loc
, itype
, step
? step
: fd
->loops
[i
].step
);
3498 off
= fold_convert_loc (loc
, itype
, off
);
3500 off
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
, off
, s
);
3503 if (integer_zerop (off
))
3504 t
= boolean_true_node
;
3508 tree co
= fold_convert_loc (loc
, itype
, off
);
3509 if (POINTER_TYPE_P (TREE_TYPE (fd
->loops
[i
].v
)))
3511 if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps
))
3512 co
= fold_build1_loc (loc
, NEGATE_EXPR
, itype
, co
);
3513 a
= fold_build2_loc (loc
, POINTER_PLUS_EXPR
,
3514 TREE_TYPE (fd
->loops
[i
].v
), fd
->loops
[i
].v
,
3517 else if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps
))
3518 a
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (fd
->loops
[i
].v
),
3519 fd
->loops
[i
].v
, co
);
3521 a
= fold_build2_loc (loc
, PLUS_EXPR
, TREE_TYPE (fd
->loops
[i
].v
),
3522 fd
->loops
[i
].v
, co
);
3526 if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps
))
3527 t1
= fold_build2_loc (loc
, GE_EXPR
, boolean_type_node
, a
,
3530 t1
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
, a
,
3532 if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps
))
3533 t2
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
, a
,
3536 t2
= fold_build2_loc (loc
, GE_EXPR
, boolean_type_node
, a
,
3538 t
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
,
3539 step
, build_int_cst (TREE_TYPE (step
), 0));
3540 if (TREE_CODE (step
) != INTEGER_CST
)
3542 t1
= unshare_expr (t1
);
3543 t1
= force_gimple_operand_gsi (gsi
, t1
, true, NULL_TREE
,
3544 false, GSI_CONTINUE_LINKING
);
3545 t2
= unshare_expr (t2
);
3546 t2
= force_gimple_operand_gsi (gsi
, t2
, true, NULL_TREE
,
3547 false, GSI_CONTINUE_LINKING
);
3549 t
= fold_build3_loc (loc
, COND_EXPR
, boolean_type_node
,
3552 else if (fd
->loops
[i
].cond_code
== LT_EXPR
)
3554 if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps
))
3555 t
= fold_build2_loc (loc
, GE_EXPR
, boolean_type_node
, a
,
3558 t
= fold_build2_loc (loc
, LT_EXPR
, boolean_type_node
, a
,
3561 else if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps
))
3562 t
= fold_build2_loc (loc
, GT_EXPR
, boolean_type_node
, a
,
3565 t
= fold_build2_loc (loc
, LE_EXPR
, boolean_type_node
, a
,
3569 cond
= fold_build2_loc (loc
, BIT_AND_EXPR
, boolean_type_node
, cond
, t
);
3573 off
= fold_convert_loc (loc
, itype
, off
);
3576 || (fd
->loops
[i
].cond_code
== LT_EXPR
3577 ? !integer_onep (fd
->loops
[i
].step
)
3578 : !integer_minus_onep (fd
->loops
[i
].step
)))
3580 if (step
== NULL_TREE
3581 && TYPE_UNSIGNED (itype
)
3582 && fd
->loops
[i
].cond_code
== GT_EXPR
)
3583 t
= fold_build2_loc (loc
, TRUNC_MOD_EXPR
, itype
, off
,
3584 fold_build1_loc (loc
, NEGATE_EXPR
, itype
,
3587 t
= fold_build2_loc (loc
, TRUNC_MOD_EXPR
, itype
,
3588 orig_off
? orig_off
: off
, s
);
3589 t
= fold_build2_loc (loc
, EQ_EXPR
, boolean_type_node
, t
,
3590 build_int_cst (itype
, 0));
3591 if (integer_zerop (t
) && !warned_step
)
3593 warning_at (loc
, OPT_Wopenmp
,
3594 "%qs clause with %<sink%> modifier refers to "
3595 "iteration never in the iteration space",
3596 OMP_CLAUSE_DOACROSS_DEPEND (c
)
3597 ? "depend" : "doacross");
3600 cond
= fold_build2_loc (loc
, BIT_AND_EXPR
, boolean_type_node
,
3604 if (i
<= fd
->collapse
- 1 && fd
->collapse
> 1)
3610 t
= fold_build2_loc (loc
, MINUS_EXPR
, TREE_TYPE (fd
->loops
[i
].v
),
3611 fd
->loops
[i
].v
, fd
->loops
[i
].n1
);
3612 t
= fold_convert_loc (loc
, fd
->iter_type
, t
);
3615 /* We have divided off by step already earlier. */;
3616 else if (TYPE_UNSIGNED (itype
) && fd
->loops
[i
].cond_code
== GT_EXPR
)
3617 off
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
, off
,
3618 fold_build1_loc (loc
, NEGATE_EXPR
, itype
,
3621 off
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
, off
, s
);
3622 if (OMP_CLAUSE_DOACROSS_SINK_NEGATIVE (deps
))
3623 off
= fold_build1_loc (loc
, NEGATE_EXPR
, itype
, off
);
3624 off
= fold_convert_loc (loc
, fd
->iter_type
, off
);
3625 if (i
<= fd
->collapse
- 1 && fd
->collapse
> 1)
3628 off
= fold_build2_loc (loc
, PLUS_EXPR
, fd
->iter_type
, coff
,
3630 if (i
< fd
->collapse
- 1)
3632 coff
= fold_build2_loc (loc
, MULT_EXPR
, fd
->iter_type
, off
,
3637 off
= unshare_expr (off
);
3638 t
= fold_build2_loc (loc
, PLUS_EXPR
, fd
->iter_type
, t
, off
);
3639 t
= force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
3640 true, GSI_SAME_STMT
);
3643 gimple
*g
= gimple_build_call_vec (builtin_decl_explicit (sink_ix
), args
);
3644 gimple_set_location (g
, loc
);
3645 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
3647 cond
= unshare_expr (cond
);
3648 cond
= force_gimple_operand_gsi (gsi
, cond
, true, NULL_TREE
, false,
3649 GSI_CONTINUE_LINKING
);
3650 gsi_insert_after (gsi
, gimple_build_cond_empty (cond
), GSI_NEW_STMT
);
3651 edge e3
= make_edge (e1
->src
, e2
->dest
, EDGE_FALSE_VALUE
);
3652 e3
->probability
= profile_probability::guessed_always () / 8;
3653 e1
->probability
= e3
->probability
.invert ();
3654 e1
->flags
= EDGE_TRUE_VALUE
;
3655 set_immediate_dominator (CDI_DOMINATORS
, e2
->dest
, e1
->src
);
3657 *gsi
= gsi_after_labels (e2
->dest
);
3660 /* Expand all #pragma omp ordered depend(source) and
3661 #pragma omp ordered depend(sink:...) constructs in the current
3662 #pragma omp for ordered(n) region. */
3665 expand_omp_ordered_source_sink (struct omp_region
*region
,
3666 struct omp_for_data
*fd
, tree
*counts
,
3667 basic_block cont_bb
)
3669 struct omp_region
*inner
;
3671 for (i
= fd
->collapse
- 1; i
< fd
->ordered
; i
++)
3672 if (i
== fd
->collapse
- 1 && fd
->collapse
> 1)
3673 counts
[i
] = NULL_TREE
;
3674 else if (i
>= fd
->collapse
&& !cont_bb
)
3675 counts
[i
] = build_zero_cst (fd
->iter_type
);
3676 else if (!POINTER_TYPE_P (TREE_TYPE (fd
->loops
[i
].v
))
3677 && integer_onep (fd
->loops
[i
].step
))
3678 counts
[i
] = NULL_TREE
;
3680 counts
[i
] = create_tmp_var (fd
->iter_type
, ".orditer");
3682 = build_array_type_nelts (fd
->iter_type
, fd
->ordered
- fd
->collapse
+ 1);
3683 counts
[fd
->ordered
] = create_tmp_var (atype
, ".orditera");
3684 TREE_ADDRESSABLE (counts
[fd
->ordered
]) = 1;
3685 counts
[fd
->ordered
+ 1] = NULL_TREE
;
3687 for (inner
= region
->inner
; inner
; inner
= inner
->next
)
3688 if (inner
->type
== GIMPLE_OMP_ORDERED
)
3690 gomp_ordered
*ord_stmt
= inner
->ord_stmt
;
3691 gimple_stmt_iterator gsi
= gsi_for_stmt (ord_stmt
);
3692 location_t loc
= gimple_location (ord_stmt
);
3694 for (c
= gimple_omp_ordered_clauses (ord_stmt
);
3695 c
; c
= OMP_CLAUSE_CHAIN (c
))
3696 if (OMP_CLAUSE_DOACROSS_KIND (c
) == OMP_CLAUSE_DOACROSS_SOURCE
)
3699 expand_omp_ordered_source (&gsi
, fd
, counts
, loc
);
3700 for (c
= gimple_omp_ordered_clauses (ord_stmt
);
3701 c
; c
= OMP_CLAUSE_CHAIN (c
))
3702 if (OMP_CLAUSE_DOACROSS_KIND (c
) == OMP_CLAUSE_DOACROSS_SINK
)
3703 expand_omp_ordered_sink (&gsi
, fd
, counts
, c
, loc
, cont_bb
);
3704 gsi_remove (&gsi
, true);
3708 /* Wrap the body into fd->ordered - fd->collapse loops that aren't
3712 expand_omp_for_ordered_loops (struct omp_for_data
*fd
, tree
*counts
,
3713 basic_block cont_bb
, basic_block body_bb
,
3714 basic_block l0_bb
, bool ordered_lastprivate
)
3716 if (fd
->ordered
== fd
->collapse
)
3721 gimple_stmt_iterator gsi
= gsi_after_labels (body_bb
);
3722 for (int i
= fd
->collapse
; i
< fd
->ordered
; i
++)
3724 tree type
= TREE_TYPE (fd
->loops
[i
].v
);
3725 tree n1
= fold_convert (type
, fd
->loops
[i
].n1
);
3726 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
, n1
);
3727 tree aref
= build4 (ARRAY_REF
, fd
->iter_type
, counts
[fd
->ordered
],
3728 size_int (i
- fd
->collapse
+ 1),
3729 NULL_TREE
, NULL_TREE
);
3730 expand_omp_build_assign (&gsi
, aref
, build_zero_cst (fd
->iter_type
));
3735 for (int i
= fd
->ordered
- 1; i
>= fd
->collapse
; i
--)
3737 tree t
, type
= TREE_TYPE (fd
->loops
[i
].v
);
3738 gimple_stmt_iterator gsi
= gsi_after_labels (body_bb
);
3739 if (counts
[fd
->ordered
+ 1] && i
== fd
->collapse
)
3740 expand_omp_build_assign (&gsi
, counts
[fd
->ordered
+ 1],
3742 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
,
3743 fold_convert (type
, fd
->loops
[i
].n1
));
3745 expand_omp_build_assign (&gsi
, counts
[i
],
3746 build_zero_cst (fd
->iter_type
));
3747 tree aref
= build4 (ARRAY_REF
, fd
->iter_type
, counts
[fd
->ordered
],
3748 size_int (i
- fd
->collapse
+ 1),
3749 NULL_TREE
, NULL_TREE
);
3750 expand_omp_build_assign (&gsi
, aref
, build_zero_cst (fd
->iter_type
));
3751 if (!gsi_end_p (gsi
))
3754 gsi
= gsi_last_bb (body_bb
);
3755 edge e1
= split_block (body_bb
, gsi_stmt (gsi
));
3756 basic_block new_body
= e1
->dest
;
3757 if (body_bb
== cont_bb
)
3760 basic_block new_header
;
3761 if (EDGE_COUNT (cont_bb
->preds
) > 0)
3763 gsi
= gsi_last_bb (cont_bb
);
3764 if (POINTER_TYPE_P (type
))
3765 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, fd
->loops
[i
].step
);
3767 t
= fold_build2 (PLUS_EXPR
, type
, fd
->loops
[i
].v
,
3768 fold_convert (type
, fd
->loops
[i
].step
));
3769 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
, t
);
3772 t
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, counts
[i
],
3773 build_int_cst (fd
->iter_type
, 1));
3774 expand_omp_build_assign (&gsi
, counts
[i
], t
);
3779 t
= fold_build2 (MINUS_EXPR
, TREE_TYPE (fd
->loops
[i
].v
),
3780 fd
->loops
[i
].v
, fd
->loops
[i
].n1
);
3781 t
= fold_convert (fd
->iter_type
, t
);
3782 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3783 true, GSI_SAME_STMT
);
3785 aref
= build4 (ARRAY_REF
, fd
->iter_type
, counts
[fd
->ordered
],
3786 size_int (i
- fd
->collapse
+ 1),
3787 NULL_TREE
, NULL_TREE
);
3788 expand_omp_build_assign (&gsi
, aref
, t
);
3789 if (counts
[fd
->ordered
+ 1] && i
== fd
->ordered
- 1)
3790 expand_omp_build_assign (&gsi
, counts
[fd
->ordered
+ 1],
3791 boolean_false_node
);
3793 e2
= split_block (cont_bb
, gsi_stmt (gsi
));
3794 new_header
= e2
->dest
;
3797 new_header
= cont_bb
;
3798 gsi
= gsi_after_labels (new_header
);
3799 tree v
= force_gimple_operand_gsi (&gsi
, fd
->loops
[i
].v
, true, NULL_TREE
,
3800 true, GSI_SAME_STMT
);
3802 = force_gimple_operand_gsi (&gsi
, fold_convert (type
, fd
->loops
[i
].n2
),
3803 true, NULL_TREE
, true, GSI_SAME_STMT
);
3804 t
= build2 (fd
->loops
[i
].cond_code
, boolean_type_node
, v
, n2
);
3805 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_NEW_STMT
);
3806 edge e3
= split_block (new_header
, gsi_stmt (gsi
));
3809 make_edge (body_bb
, new_header
, EDGE_FALLTHRU
);
3810 e3
->flags
= EDGE_FALSE_VALUE
;
3811 e3
->probability
= profile_probability::guessed_always () / 8;
3812 e1
= make_edge (new_header
, new_body
, EDGE_TRUE_VALUE
);
3813 e1
->probability
= e3
->probability
.invert ();
3815 set_immediate_dominator (CDI_DOMINATORS
, new_header
, body_bb
);
3816 set_immediate_dominator (CDI_DOMINATORS
, new_body
, new_header
);
3820 class loop
*loop
= alloc_loop ();
3821 loop
->header
= new_header
;
3822 loop
->latch
= e2
->src
;
3823 add_loop (loop
, l0_bb
->loop_father
);
3827 /* If there are any lastprivate clauses and it is possible some loops
3828 might have zero iterations, ensure all the decls are initialized,
3829 otherwise we could crash evaluating C++ class iterators with lastprivate
3831 bool need_inits
= false;
3832 for (int i
= fd
->collapse
; ordered_lastprivate
&& i
< fd
->ordered
; i
++)
3835 tree type
= TREE_TYPE (fd
->loops
[i
].v
);
3836 gimple_stmt_iterator gsi
= gsi_after_labels (body_bb
);
3837 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
,
3838 fold_convert (type
, fd
->loops
[i
].n1
));
3842 tree type
= TREE_TYPE (fd
->loops
[i
].v
);
3843 tree this_cond
= fold_build2 (fd
->loops
[i
].cond_code
,
3845 fold_convert (type
, fd
->loops
[i
].n1
),
3846 fold_convert (type
, fd
->loops
[i
].n2
));
3847 if (!integer_onep (this_cond
))
3854 /* A subroutine of expand_omp_for. Generate code for a parallel
3855 loop with any schedule. Given parameters:
3857 for (V = N1; V cond N2; V += STEP) BODY;
3859 where COND is "<" or ">", we generate pseudocode
3861 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3862 if (more) goto L0; else goto L3;
3869 if (V cond iend) goto L1; else goto L2;
3871 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3874 If this is a combined omp parallel loop, instead of the call to
3875 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3876 If this is gimple_omp_for_combined_p loop, then instead of assigning
3877 V and iend in L0 we assign the first two _looptemp_ clause decls of the
3878 inner GIMPLE_OMP_FOR and V += STEP; and
3879 if (V cond iend) goto L1; else goto L2; are removed.
3881 For collapsed loops, given parameters:
3883 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3884 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3885 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3888 we generate pseudocode
3890 if (__builtin_expect (N32 cond3 N31, 0)) goto Z0;
3895 count3 = (adj + N32 - N31) / STEP3;
3896 if (__builtin_expect (N22 cond2 N21, 0)) goto Z0;
3901 count2 = (adj + N22 - N21) / STEP2;
3902 if (__builtin_expect (N12 cond1 N11, 0)) goto Z0;
3907 count1 = (adj + N12 - N11) / STEP1;
3908 count = count1 * count2 * count3;
3913 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3914 if (more) goto L0; else goto L3;
3918 V3 = N31 + (T % count3) * STEP3;
3920 V2 = N21 + (T % count2) * STEP2;
3922 V1 = N11 + T * STEP1;
3927 if (V < iend) goto L10; else goto L2;
3930 if (V3 cond3 N32) goto L1; else goto L11;
3934 if (V2 cond2 N22) goto L1; else goto L12;
3940 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3946 expand_omp_for_generic (struct omp_region
*region
,
3947 struct omp_for_data
*fd
,
3948 enum built_in_function start_fn
,
3949 enum built_in_function next_fn
,
3953 tree type
, istart0
, iend0
, iend
;
3954 tree t
, vmain
, vback
, bias
= NULL_TREE
;
3955 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
, collapse_bb
;
3956 basic_block l2_bb
= NULL
, l3_bb
= NULL
;
3957 gimple_stmt_iterator gsi
;
3958 gassign
*assign_stmt
;
3959 bool in_combined_parallel
= is_combined_parallel (region
);
3960 bool broken_loop
= region
->cont
== NULL
;
3962 tree
*counts
= NULL
;
3964 bool ordered_lastprivate
= false;
3965 bool offload
= is_in_offload_region (region
);
3967 gcc_assert (!broken_loop
|| !in_combined_parallel
);
3968 gcc_assert (fd
->iter_type
== long_integer_type_node
3969 || !in_combined_parallel
);
3971 entry_bb
= region
->entry
;
3972 cont_bb
= region
->cont
;
3974 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
3975 gcc_assert (broken_loop
3976 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
3977 l0_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
3978 l1_bb
= single_succ (l0_bb
);
3981 l2_bb
= create_empty_bb (cont_bb
);
3982 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l1_bb
3983 || (single_succ_edge (BRANCH_EDGE (cont_bb
)->dest
)->dest
3985 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
3989 l3_bb
= BRANCH_EDGE (entry_bb
)->dest
;
3990 exit_bb
= region
->exit
;
3992 gsi
= gsi_last_nondebug_bb (entry_bb
);
3994 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
3996 && omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
3997 OMP_CLAUSE_LASTPRIVATE
))
3998 ordered_lastprivate
= false;
3999 tree reductions
= NULL_TREE
;
4000 tree mem
= NULL_TREE
, cond_var
= NULL_TREE
, condtemp
= NULL_TREE
;
4001 tree memv
= NULL_TREE
;
4002 if (fd
->lastprivate_conditional
)
4004 tree c
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
4005 OMP_CLAUSE__CONDTEMP_
);
4006 if (fd
->have_pointer_condtemp
)
4007 condtemp
= OMP_CLAUSE_DECL (c
);
4008 c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
), OMP_CLAUSE__CONDTEMP_
);
4009 cond_var
= OMP_CLAUSE_DECL (c
);
4013 if (fd
->have_reductemp
)
4015 tree c
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
4016 OMP_CLAUSE__REDUCTEMP_
);
4017 reductions
= OMP_CLAUSE_DECL (c
);
4018 gcc_assert (TREE_CODE (reductions
) == SSA_NAME
);
4019 gimple
*g
= SSA_NAME_DEF_STMT (reductions
);
4020 reductions
= gimple_assign_rhs1 (g
);
4021 OMP_CLAUSE_DECL (c
) = reductions
;
4022 entry_bb
= gimple_bb (g
);
4023 edge e
= split_block (entry_bb
, g
);
4024 if (region
->entry
== entry_bb
)
4025 region
->entry
= e
->dest
;
4026 gsi
= gsi_last_bb (entry_bb
);
4029 reductions
= null_pointer_node
;
4030 if (fd
->have_pointer_condtemp
)
4032 tree type
= TREE_TYPE (condtemp
);
4033 memv
= create_tmp_var (type
);
4034 TREE_ADDRESSABLE (memv
) = 1;
4035 unsigned HOST_WIDE_INT sz
4036 = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type
)));
4037 sz
*= fd
->lastprivate_conditional
;
4038 expand_omp_build_assign (&gsi
, memv
, build_int_cst (type
, sz
),
4040 mem
= build_fold_addr_expr (memv
);
4043 mem
= null_pointer_node
;
4045 if (fd
->collapse
> 1 || fd
->ordered
)
4047 int first_zero_iter1
= -1, first_zero_iter2
= -1;
4048 basic_block zero_iter1_bb
= NULL
, zero_iter2_bb
= NULL
, l2_dom_bb
= NULL
;
4050 counts
= XALLOCAVEC (tree
, fd
->ordered
4052 + (fd
->ordered
- fd
->collapse
)
4054 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
4055 zero_iter1_bb
, first_zero_iter1
,
4056 zero_iter2_bb
, first_zero_iter2
, l2_dom_bb
);
4060 /* Some counts[i] vars might be uninitialized if
4061 some loop has zero iterations. But the body shouldn't
4062 be executed in that case, so just avoid uninit warnings. */
4063 for (i
= first_zero_iter1
;
4064 i
< (fd
->ordered
? fd
->ordered
: fd
->collapse
); i
++)
4065 if (SSA_VAR_P (counts
[i
]))
4066 suppress_warning (counts
[i
], OPT_Wuninitialized
);
4068 e
= split_block (entry_bb
, gsi_stmt (gsi
));
4070 make_edge (zero_iter1_bb
, entry_bb
, EDGE_FALLTHRU
);
4071 gsi
= gsi_last_nondebug_bb (entry_bb
);
4072 set_immediate_dominator (CDI_DOMINATORS
, entry_bb
,
4073 get_immediate_dominator (CDI_DOMINATORS
,
4078 /* Some counts[i] vars might be uninitialized if
4079 some loop has zero iterations. But the body shouldn't
4080 be executed in that case, so just avoid uninit warnings. */
4081 for (i
= first_zero_iter2
; i
< fd
->ordered
; i
++)
4082 if (SSA_VAR_P (counts
[i
]))
4083 suppress_warning (counts
[i
], OPT_Wuninitialized
);
4085 make_edge (zero_iter2_bb
, entry_bb
, EDGE_FALLTHRU
);
4089 e
= split_block (entry_bb
, gsi_stmt (gsi
));
4091 make_edge (zero_iter2_bb
, entry_bb
, EDGE_FALLTHRU
);
4092 gsi
= gsi_last_nondebug_bb (entry_bb
);
4093 set_immediate_dominator (CDI_DOMINATORS
, entry_bb
,
4094 get_immediate_dominator
4095 (CDI_DOMINATORS
, zero_iter2_bb
));
4098 if (fd
->collapse
== 1)
4100 counts
[0] = fd
->loop
.n2
;
4101 fd
->loop
= fd
->loops
[0];
4105 type
= TREE_TYPE (fd
->loop
.v
);
4106 istart0
= create_tmp_var (fd
->iter_type
, ".istart0");
4107 iend0
= create_tmp_var (fd
->iter_type
, ".iend0");
4108 TREE_ADDRESSABLE (istart0
) = 1;
4109 TREE_ADDRESSABLE (iend0
) = 1;
4111 /* See if we need to bias by LLONG_MIN. */
4112 if (fd
->iter_type
== long_long_unsigned_type_node
4113 && (TREE_CODE (type
) == INTEGER_TYPE
|| TREE_CODE (type
) == BITINT_TYPE
)
4114 && !TYPE_UNSIGNED (type
)
4115 && fd
->ordered
== 0)
4119 if (fd
->loop
.cond_code
== LT_EXPR
)
4122 n2
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
4126 n1
= fold_build2 (MINUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
4129 if (TREE_CODE (n1
) != INTEGER_CST
4130 || TREE_CODE (n2
) != INTEGER_CST
4131 || ((tree_int_cst_sgn (n1
) < 0) ^ (tree_int_cst_sgn (n2
) < 0)))
4132 bias
= fold_convert (fd
->iter_type
, TYPE_MIN_VALUE (type
));
4135 gimple_stmt_iterator gsif
= gsi
;
4138 tree arr
= NULL_TREE
;
4139 if (in_combined_parallel
)
4141 gcc_assert (fd
->ordered
== 0);
4142 /* In a combined parallel loop, emit a call to
4143 GOMP_loop_foo_next. */
4144 t
= build_call_expr (builtin_decl_explicit (next_fn
), 2,
4145 build_fold_addr_expr (istart0
),
4146 build_fold_addr_expr (iend0
));
4150 tree t0
, t1
, t2
, t3
, t4
;
4151 /* If this is not a combined parallel loop, emit a call to
4152 GOMP_loop_foo_start in ENTRY_BB. */
4153 t4
= build_fold_addr_expr (iend0
);
4154 t3
= build_fold_addr_expr (istart0
);
4157 t0
= build_int_cst (unsigned_type_node
,
4158 fd
->ordered
- fd
->collapse
+ 1);
4159 arr
= create_tmp_var (build_array_type_nelts (fd
->iter_type
,
4161 - fd
->collapse
+ 1),
4163 DECL_NAMELESS (arr
) = 1;
4164 TREE_ADDRESSABLE (arr
) = 1;
4165 TREE_STATIC (arr
) = 1;
4166 vec
<constructor_elt
, va_gc
> *v
;
4167 vec_alloc (v
, fd
->ordered
- fd
->collapse
+ 1);
4170 for (idx
= 0; idx
< fd
->ordered
- fd
->collapse
+ 1; idx
++)
4173 if (idx
== 0 && fd
->collapse
> 1)
4176 c
= counts
[idx
+ fd
->collapse
- 1];
4177 tree purpose
= size_int (idx
);
4178 CONSTRUCTOR_APPEND_ELT (v
, purpose
, c
);
4179 if (TREE_CODE (c
) != INTEGER_CST
)
4180 TREE_STATIC (arr
) = 0;
4183 DECL_INITIAL (arr
) = build_constructor (TREE_TYPE (arr
), v
);
4184 if (!TREE_STATIC (arr
))
4185 force_gimple_operand_gsi (&gsi
, build1 (DECL_EXPR
,
4186 void_type_node
, arr
),
4187 true, NULL_TREE
, true, GSI_SAME_STMT
);
4188 t1
= build_fold_addr_expr (arr
);
4193 t2
= fold_convert (fd
->iter_type
, fd
->loop
.step
);
4196 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
4199 = omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
4200 OMP_CLAUSE__LOOPTEMP_
);
4201 gcc_assert (innerc
);
4202 t0
= OMP_CLAUSE_DECL (innerc
);
4203 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
4204 OMP_CLAUSE__LOOPTEMP_
);
4205 gcc_assert (innerc
);
4206 t1
= OMP_CLAUSE_DECL (innerc
);
4208 if (POINTER_TYPE_P (TREE_TYPE (t0
))
4209 && TYPE_PRECISION (TREE_TYPE (t0
))
4210 != TYPE_PRECISION (fd
->iter_type
))
4212 /* Avoid casting pointers to integer of a different size. */
4213 tree itype
= signed_type_for (type
);
4214 t1
= fold_convert (fd
->iter_type
, fold_convert (itype
, t1
));
4215 t0
= fold_convert (fd
->iter_type
, fold_convert (itype
, t0
));
4219 t1
= fold_convert (fd
->iter_type
, t1
);
4220 t0
= fold_convert (fd
->iter_type
, t0
);
4224 t1
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t1
, bias
);
4225 t0
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t0
, bias
);
4228 if (fd
->iter_type
== long_integer_type_node
|| fd
->ordered
)
4232 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
4233 t
= omp_adjust_chunk_size (t
, fd
->simd_schedule
, offload
);
4237 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4238 8, t0
, t1
, sched_arg
, t
, t3
, t4
,
4241 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4242 9, t0
, t1
, t2
, sched_arg
, t
, t3
, t4
,
4245 else if (fd
->ordered
)
4246 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4247 5, t0
, t1
, t
, t3
, t4
);
4249 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4250 6, t0
, t1
, t2
, t
, t3
, t4
);
4252 else if (fd
->ordered
)
4253 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4256 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4257 5, t0
, t1
, t2
, t3
, t4
);
4265 /* The GOMP_loop_ull_*start functions have additional boolean
4266 argument, true for < loops and false for > loops.
4267 In Fortran, the C bool type can be different from
4268 boolean_type_node. */
4269 bfn_decl
= builtin_decl_explicit (start_fn
);
4270 c_bool_type
= TREE_TYPE (TREE_TYPE (bfn_decl
));
4271 t5
= build_int_cst (c_bool_type
,
4272 fd
->loop
.cond_code
== LT_EXPR
? 1 : 0);
4275 tree bfn_decl
= builtin_decl_explicit (start_fn
);
4276 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
4277 t
= omp_adjust_chunk_size (t
, fd
->simd_schedule
, offload
);
4279 t
= build_call_expr (bfn_decl
, 10, t5
, t0
, t1
, t2
, sched_arg
,
4280 t
, t3
, t4
, reductions
, mem
);
4282 t
= build_call_expr (bfn_decl
, 7, t5
, t0
, t1
, t2
, t
, t3
, t4
);
4285 t
= build_call_expr (builtin_decl_explicit (start_fn
),
4286 6, t5
, t0
, t1
, t2
, t3
, t4
);
4289 if (TREE_TYPE (t
) != boolean_type_node
)
4290 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
4291 t
, build_int_cst (TREE_TYPE (t
), 0));
4292 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4293 true, GSI_SAME_STMT
);
4294 if (arr
&& !TREE_STATIC (arr
))
4296 tree clobber
= build_clobber (TREE_TYPE (arr
));
4297 gsi_insert_before (&gsi
, gimple_build_assign (arr
, clobber
),
4300 if (fd
->have_pointer_condtemp
)
4301 expand_omp_build_assign (&gsi
, condtemp
, memv
, false);
4302 if (fd
->have_reductemp
)
4304 gimple
*g
= gsi_stmt (gsi
);
4305 gsi_remove (&gsi
, true);
4306 release_ssa_name (gimple_assign_lhs (g
));
4308 entry_bb
= region
->entry
;
4309 gsi
= gsi_last_nondebug_bb (entry_bb
);
4311 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4313 gsi_insert_after (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4315 /* Remove the GIMPLE_OMP_FOR statement. */
4316 gsi_remove (&gsi
, true);
4318 if (gsi_end_p (gsif
))
4319 gsif
= gsi_after_labels (gsi_bb (gsif
));
4322 /* Iteration setup for sequential loop goes in L0_BB. */
4323 tree startvar
= fd
->loop
.v
;
4324 tree endvar
= NULL_TREE
;
4326 if (gimple_omp_for_combined_p (fd
->for_stmt
))
4328 gcc_assert (gimple_code (inner_stmt
) == GIMPLE_OMP_FOR
4329 && gimple_omp_for_kind (inner_stmt
)
4330 == GF_OMP_FOR_KIND_SIMD
);
4331 tree innerc
= omp_find_clause (gimple_omp_for_clauses (inner_stmt
),
4332 OMP_CLAUSE__LOOPTEMP_
);
4333 gcc_assert (innerc
);
4334 startvar
= OMP_CLAUSE_DECL (innerc
);
4335 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
4336 OMP_CLAUSE__LOOPTEMP_
);
4337 gcc_assert (innerc
);
4338 endvar
= OMP_CLAUSE_DECL (innerc
);
4341 gsi
= gsi_start_bb (l0_bb
);
4343 if (fd
->ordered
&& fd
->collapse
== 1)
4344 t
= fold_build2 (MULT_EXPR
, fd
->iter_type
, t
,
4345 fold_convert (fd
->iter_type
, fd
->loop
.step
));
4347 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
4348 if (fd
->ordered
&& fd
->collapse
== 1)
4350 if (POINTER_TYPE_P (TREE_TYPE (startvar
)))
4351 t
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (startvar
),
4352 fd
->loop
.n1
, fold_convert (sizetype
, t
));
4355 t
= fold_convert (TREE_TYPE (startvar
), t
);
4356 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (startvar
),
4362 if (POINTER_TYPE_P (TREE_TYPE (startvar
)))
4363 t
= fold_convert (signed_type_for (TREE_TYPE (startvar
)), t
);
4364 t
= fold_convert (TREE_TYPE (startvar
), t
);
4366 t
= force_gimple_operand_gsi (&gsi
, t
,
4368 && TREE_ADDRESSABLE (startvar
),
4369 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
4370 assign_stmt
= gimple_build_assign (startvar
, t
);
4371 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
4374 tree itype
= TREE_TYPE (cond_var
);
4375 /* For lastprivate(conditional:) itervar, we need some iteration
4376 counter that starts at unsigned non-zero and increases.
4377 Prefer as few IVs as possible, so if we can use startvar
4378 itself, use that, or startvar + constant (those would be
4379 incremented with step), and as last resort use the s0 + 1
4380 incremented by 1. */
4381 if ((fd
->ordered
&& fd
->collapse
== 1)
4383 || POINTER_TYPE_P (type
)
4384 || TREE_CODE (fd
->loop
.n1
) != INTEGER_CST
4385 || fd
->loop
.cond_code
!= LT_EXPR
)
4386 t
= fold_build2 (PLUS_EXPR
, itype
, fold_convert (itype
, istart0
),
4387 build_int_cst (itype
, 1));
4388 else if (tree_int_cst_sgn (fd
->loop
.n1
) == 1)
4389 t
= fold_convert (itype
, t
);
4392 tree c
= fold_convert (itype
, fd
->loop
.n1
);
4393 c
= fold_build2 (MINUS_EXPR
, itype
, build_int_cst (itype
, 1), c
);
4394 t
= fold_build2 (PLUS_EXPR
, itype
, fold_convert (itype
, t
), c
);
4396 t
= force_gimple_operand_gsi (&gsi
, t
, false,
4397 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
4398 assign_stmt
= gimple_build_assign (cond_var
, t
);
4399 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
4403 if (fd
->ordered
&& fd
->collapse
== 1)
4404 t
= fold_build2 (MULT_EXPR
, fd
->iter_type
, t
,
4405 fold_convert (fd
->iter_type
, fd
->loop
.step
));
4407 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
4408 if (fd
->ordered
&& fd
->collapse
== 1)
4410 if (POINTER_TYPE_P (TREE_TYPE (startvar
)))
4411 t
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (startvar
),
4412 fd
->loop
.n1
, fold_convert (sizetype
, t
));
4415 t
= fold_convert (TREE_TYPE (startvar
), t
);
4416 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (startvar
),
4422 if (POINTER_TYPE_P (TREE_TYPE (startvar
)))
4423 t
= fold_convert (signed_type_for (TREE_TYPE (startvar
)), t
);
4424 t
= fold_convert (TREE_TYPE (startvar
), t
);
4426 iend
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4427 false, GSI_CONTINUE_LINKING
);
4430 assign_stmt
= gimple_build_assign (endvar
, iend
);
4431 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
4432 if (useless_type_conversion_p (TREE_TYPE (fd
->loop
.v
), TREE_TYPE (iend
)))
4433 assign_stmt
= gimple_build_assign (fd
->loop
.v
, iend
);
4435 assign_stmt
= gimple_build_assign (fd
->loop
.v
, NOP_EXPR
, iend
);
4436 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
4438 /* Handle linear clause adjustments. */
4439 tree itercnt
= NULL_TREE
;
4440 if (gimple_omp_for_kind (fd
->for_stmt
) == GF_OMP_FOR_KIND_FOR
)
4441 for (tree c
= gimple_omp_for_clauses (fd
->for_stmt
);
4442 c
; c
= OMP_CLAUSE_CHAIN (c
))
4443 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
4444 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
4446 tree d
= OMP_CLAUSE_DECL (c
);
4447 tree t
= d
, a
, dest
;
4448 if (omp_privatize_by_reference (t
))
4449 t
= build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c
), t
);
4450 tree type
= TREE_TYPE (t
);
4451 if (POINTER_TYPE_P (type
))
4453 dest
= unshare_expr (t
);
4454 tree v
= create_tmp_var (TREE_TYPE (t
), NULL
);
4455 expand_omp_build_assign (&gsif
, v
, t
);
4456 if (itercnt
== NULL_TREE
)
4459 tree n1
= fd
->loop
.n1
;
4460 if (POINTER_TYPE_P (TREE_TYPE (itercnt
)))
4463 = fold_convert (signed_type_for (TREE_TYPE (itercnt
)),
4465 n1
= fold_convert (TREE_TYPE (itercnt
), n1
);
4467 itercnt
= fold_build2 (MINUS_EXPR
, TREE_TYPE (itercnt
),
4469 itercnt
= fold_build2 (EXACT_DIV_EXPR
, TREE_TYPE (itercnt
),
4470 itercnt
, fd
->loop
.step
);
4471 itercnt
= force_gimple_operand_gsi (&gsi
, itercnt
, true,
4473 GSI_CONTINUE_LINKING
);
4475 a
= fold_build2 (MULT_EXPR
, type
,
4476 fold_convert (type
, itercnt
),
4477 fold_convert (type
, OMP_CLAUSE_LINEAR_STEP (c
)));
4478 t
= fold_build2 (type
== TREE_TYPE (t
) ? PLUS_EXPR
4479 : POINTER_PLUS_EXPR
, TREE_TYPE (t
), v
, a
);
4480 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4481 false, GSI_CONTINUE_LINKING
);
4482 expand_omp_build_assign (&gsi
, dest
, t
, true);
4484 if (fd
->collapse
> 1)
4485 expand_omp_for_init_vars (fd
, &gsi
, counts
, NULL
, inner_stmt
, startvar
);
4489 /* Until now, counts array contained number of iterations or
4490 variable containing it for ith loop. From now on, we usually need
4491 those counts only for collapsed loops, and only for the 2nd
4492 till the last collapsed one. Move those one element earlier,
4493 we'll use counts[fd->collapse - 1] for the first source/sink
4494 iteration counter and so on and counts[fd->ordered]
4495 as the array holding the current counter values for
4496 depend(source). For doacross(sink:omp_cur_iteration - 1) we need
4497 the counts from fd->collapse to fd->ordered - 1; make a copy of
4498 those to counts[fd->ordered + 2] and onwards.
4499 counts[fd->ordered + 1] can be a flag whether it is the first
4500 iteration with a new collapsed counter (used only if
4501 fd->ordered > fd->collapse). */
4502 if (fd
->ordered
> fd
->collapse
)
4503 memcpy (counts
+ fd
->ordered
+ 2, counts
+ fd
->collapse
,
4504 (fd
->ordered
- fd
->collapse
) * sizeof (counts
[0]));
4505 if (fd
->collapse
> 1)
4506 memmove (counts
, counts
+ 1, (fd
->collapse
- 1) * sizeof (counts
[0]));
4510 for (i
= fd
->collapse
; i
< fd
->ordered
; i
++)
4512 tree type
= TREE_TYPE (fd
->loops
[i
].v
);
4514 = fold_build2 (fd
->loops
[i
].cond_code
, boolean_type_node
,
4515 fold_convert (type
, fd
->loops
[i
].n1
),
4516 fold_convert (type
, fd
->loops
[i
].n2
));
4517 if (!integer_onep (this_cond
))
4520 if (i
< fd
->ordered
)
4522 if (entry_bb
->loop_father
!= l0_bb
->loop_father
)
4524 remove_bb_from_loops (l0_bb
);
4525 add_bb_to_loop (l0_bb
, entry_bb
->loop_father
);
4526 gcc_assert (single_succ (l0_bb
) == l1_bb
);
4529 = create_empty_bb (EXIT_BLOCK_PTR_FOR_FN (cfun
)->prev_bb
);
4530 add_bb_to_loop (cont_bb
, l0_bb
->loop_father
);
4531 gimple_stmt_iterator gsi
= gsi_after_labels (cont_bb
);
4532 gimple
*g
= gimple_build_omp_continue (fd
->loop
.v
, fd
->loop
.v
);
4533 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
4534 make_edge (cont_bb
, l3_bb
, EDGE_FALLTHRU
);
4535 make_edge (cont_bb
, l1_bb
, 0);
4536 l2_bb
= create_empty_bb (cont_bb
);
4537 broken_loop
= false;
4540 expand_omp_ordered_source_sink (region
, fd
, counts
, cont_bb
);
4541 cont_bb
= expand_omp_for_ordered_loops (fd
, counts
, cont_bb
, l1_bb
,
4542 l0_bb
, ordered_lastprivate
);
4543 if (counts
[fd
->collapse
- 1])
4545 gcc_assert (fd
->collapse
== 1);
4546 gsi
= gsi_last_bb (l0_bb
);
4547 expand_omp_build_assign (&gsi
, counts
[fd
->collapse
- 1],
4551 gsi
= gsi_last_bb (cont_bb
);
4552 t
= fold_build2 (PLUS_EXPR
, fd
->iter_type
,
4553 counts
[fd
->collapse
- 1],
4554 build_int_cst (fd
->iter_type
, 1));
4555 expand_omp_build_assign (&gsi
, counts
[fd
->collapse
- 1], t
);
4556 tree aref
= build4 (ARRAY_REF
, fd
->iter_type
,
4557 counts
[fd
->ordered
], size_zero_node
,
4558 NULL_TREE
, NULL_TREE
);
4559 expand_omp_build_assign (&gsi
, aref
, counts
[fd
->collapse
- 1]);
4561 t
= counts
[fd
->collapse
- 1];
4563 else if (fd
->collapse
> 1)
4567 t
= fold_build2 (MINUS_EXPR
, TREE_TYPE (fd
->loops
[0].v
),
4568 fd
->loops
[0].v
, fd
->loops
[0].n1
);
4569 t
= fold_convert (fd
->iter_type
, t
);
4571 gsi
= gsi_last_bb (l0_bb
);
4572 tree aref
= build4 (ARRAY_REF
, fd
->iter_type
, counts
[fd
->ordered
],
4573 size_zero_node
, NULL_TREE
, NULL_TREE
);
4574 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4575 false, GSI_CONTINUE_LINKING
);
4576 expand_omp_build_assign (&gsi
, aref
, t
, true);
4581 /* Code to control the increment and predicate for the sequential
4582 loop goes in the CONT_BB. */
4583 gsi
= gsi_last_nondebug_bb (cont_bb
);
4584 gomp_continue
*cont_stmt
= as_a
<gomp_continue
*> (gsi_stmt (gsi
));
4585 gcc_assert (gimple_code (cont_stmt
) == GIMPLE_OMP_CONTINUE
);
4586 vmain
= gimple_omp_continue_control_use (cont_stmt
);
4587 vback
= gimple_omp_continue_control_def (cont_stmt
);
4591 tree itype
= TREE_TYPE (cond_var
);
4593 if ((fd
->ordered
&& fd
->collapse
== 1)
4595 || POINTER_TYPE_P (type
)
4596 || TREE_CODE (fd
->loop
.n1
) != INTEGER_CST
4597 || fd
->loop
.cond_code
!= LT_EXPR
)
4598 t2
= build_int_cst (itype
, 1);
4600 t2
= fold_convert (itype
, fd
->loop
.step
);
4601 t2
= fold_build2 (PLUS_EXPR
, itype
, cond_var
, t2
);
4602 t2
= force_gimple_operand_gsi (&gsi
, t2
, false,
4603 NULL_TREE
, true, GSI_SAME_STMT
);
4604 assign_stmt
= gimple_build_assign (cond_var
, t2
);
4605 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
4608 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
4610 if (POINTER_TYPE_P (type
))
4611 t
= fold_build_pointer_plus (vmain
, fd
->loop
.step
);
4613 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
4614 t
= force_gimple_operand_gsi (&gsi
, t
,
4616 && TREE_ADDRESSABLE (vback
),
4617 NULL_TREE
, true, GSI_SAME_STMT
);
4618 assign_stmt
= gimple_build_assign (vback
, t
);
4619 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
4621 if (fd
->ordered
&& counts
[fd
->collapse
- 1] == NULL_TREE
)
4624 if (fd
->collapse
> 1)
4628 tem
= fold_build2 (MINUS_EXPR
, TREE_TYPE (fd
->loops
[0].v
),
4629 fd
->loops
[0].v
, fd
->loops
[0].n1
);
4630 tem
= fold_convert (fd
->iter_type
, tem
);
4632 tree aref
= build4 (ARRAY_REF
, fd
->iter_type
,
4633 counts
[fd
->ordered
], size_zero_node
,
4634 NULL_TREE
, NULL_TREE
);
4635 tem
= force_gimple_operand_gsi (&gsi
, tem
, true, NULL_TREE
,
4636 true, GSI_SAME_STMT
);
4637 expand_omp_build_assign (&gsi
, aref
, tem
);
4640 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
4641 DECL_P (vback
) && TREE_ADDRESSABLE (vback
) ? t
: vback
,
4643 gcond
*cond_stmt
= gimple_build_cond_empty (t
);
4644 gsi_insert_before (&gsi
, cond_stmt
, GSI_SAME_STMT
);
4647 /* Remove GIMPLE_OMP_CONTINUE. */
4648 gsi_remove (&gsi
, true);
4650 if (fd
->collapse
> 1 && !gimple_omp_for_combined_p (fd
->for_stmt
))
4651 collapse_bb
= extract_omp_for_update_vars (fd
, NULL
, cont_bb
, l1_bb
);
4653 /* Emit code to get the next parallel iteration in L2_BB. */
4654 gsi
= gsi_start_bb (l2_bb
);
4656 t
= build_call_expr (builtin_decl_explicit (next_fn
), 2,
4657 build_fold_addr_expr (istart0
),
4658 build_fold_addr_expr (iend0
));
4659 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4660 false, GSI_CONTINUE_LINKING
);
4661 if (TREE_TYPE (t
) != boolean_type_node
)
4662 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
4663 t
, build_int_cst (TREE_TYPE (t
), 0));
4664 gcond
*cond_stmt
= gimple_build_cond_empty (t
);
4665 gsi_insert_after (&gsi
, cond_stmt
, GSI_CONTINUE_LINKING
);
4668 /* Add the loop cleanup function. */
4669 gsi
= gsi_last_nondebug_bb (exit_bb
);
4670 if (gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4671 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT
);
4672 else if (gimple_omp_return_lhs (gsi_stmt (gsi
)))
4673 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL
);
4675 t
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END
);
4676 gcall
*call_stmt
= gimple_build_call (t
, 0);
4679 tree arr
= counts
[fd
->ordered
];
4680 tree clobber
= build_clobber (TREE_TYPE (arr
));
4681 gsi_insert_after (&gsi
, gimple_build_assign (arr
, clobber
),
4684 if (gimple_omp_return_lhs (gsi_stmt (gsi
)))
4686 gimple_call_set_lhs (call_stmt
, gimple_omp_return_lhs (gsi_stmt (gsi
)));
4687 if (fd
->have_reductemp
)
4689 gimple
*g
= gimple_build_assign (reductions
, NOP_EXPR
,
4690 gimple_call_lhs (call_stmt
));
4691 gsi_insert_after (&gsi
, g
, GSI_SAME_STMT
);
4694 gsi_insert_after (&gsi
, call_stmt
, GSI_SAME_STMT
);
4695 gsi_remove (&gsi
, true);
4697 /* Connect the new blocks. */
4698 find_edge (entry_bb
, l0_bb
)->flags
= EDGE_TRUE_VALUE
;
4699 find_edge (entry_bb
, l3_bb
)->flags
= EDGE_FALSE_VALUE
;
4705 e
= find_edge (cont_bb
, l3_bb
);
4706 ne
= make_edge (l2_bb
, l3_bb
, EDGE_FALSE_VALUE
);
4708 phis
= phi_nodes (l3_bb
);
4709 for (gsi
= gsi_start (phis
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4711 gimple
*phi
= gsi_stmt (gsi
);
4712 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, ne
),
4713 PHI_ARG_DEF_FROM_EDGE (phi
, e
));
4717 make_edge (cont_bb
, l2_bb
, EDGE_FALSE_VALUE
);
4718 e
= find_edge (cont_bb
, l1_bb
);
4721 e
= BRANCH_EDGE (cont_bb
);
4722 gcc_assert (single_succ (e
->dest
) == l1_bb
);
4724 if (gimple_omp_for_combined_p (fd
->for_stmt
))
4729 else if (fd
->collapse
> 1)
4732 e
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
4735 e
->flags
= EDGE_TRUE_VALUE
;
4738 e
->probability
= profile_probability::guessed_always ().apply_scale (7, 8);
4739 find_edge (cont_bb
, l2_bb
)->probability
= e
->probability
.invert ();
4743 e
= find_edge (cont_bb
, l2_bb
);
4744 e
->flags
= EDGE_FALLTHRU
;
4746 make_edge (l2_bb
, l0_bb
, EDGE_TRUE_VALUE
);
4748 if (gimple_in_ssa_p (cfun
))
4750 /* Add phis to the outer loop that connect to the phis in the inner,
4751 original loop, and move the loop entry value of the inner phi to
4752 the loop entry value of the outer phi. */
4754 for (psi
= gsi_start_phis (l3_bb
); !gsi_end_p (psi
); gsi_next (&psi
))
4758 gphi
*exit_phi
= psi
.phi ();
4760 if (virtual_operand_p (gimple_phi_result (exit_phi
)))
4763 edge l2_to_l3
= find_edge (l2_bb
, l3_bb
);
4764 tree exit_res
= PHI_ARG_DEF_FROM_EDGE (exit_phi
, l2_to_l3
);
4766 basic_block latch
= BRANCH_EDGE (cont_bb
)->dest
;
4767 edge latch_to_l1
= find_edge (latch
, l1_bb
);
4769 = find_phi_with_arg_on_edge (exit_res
, latch_to_l1
);
4771 tree t
= gimple_phi_result (exit_phi
);
4772 tree new_res
= copy_ssa_name (t
, NULL
);
4773 nphi
= create_phi_node (new_res
, l0_bb
);
4775 edge l0_to_l1
= find_edge (l0_bb
, l1_bb
);
4776 t
= PHI_ARG_DEF_FROM_EDGE (inner_phi
, l0_to_l1
);
4777 locus
= gimple_phi_arg_location_from_edge (inner_phi
, l0_to_l1
);
4778 edge entry_to_l0
= find_edge (entry_bb
, l0_bb
);
4779 add_phi_arg (nphi
, t
, entry_to_l0
, locus
);
4781 edge l2_to_l0
= find_edge (l2_bb
, l0_bb
);
4782 add_phi_arg (nphi
, exit_res
, l2_to_l0
, UNKNOWN_LOCATION
);
4784 add_phi_arg (inner_phi
, new_res
, l0_to_l1
, UNKNOWN_LOCATION
);
4788 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
,
4789 recompute_dominator (CDI_DOMINATORS
, l2_bb
));
4790 set_immediate_dominator (CDI_DOMINATORS
, l3_bb
,
4791 recompute_dominator (CDI_DOMINATORS
, l3_bb
));
4792 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
,
4793 recompute_dominator (CDI_DOMINATORS
, l0_bb
));
4794 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
,
4795 recompute_dominator (CDI_DOMINATORS
, l1_bb
));
4797 /* We enter expand_omp_for_generic with a loop. This original loop may
4798 have its own loop struct, or it may be part of an outer loop struct
4799 (which may be the fake loop). */
4800 class loop
*outer_loop
= entry_bb
->loop_father
;
4801 bool orig_loop_has_loop_struct
= l1_bb
->loop_father
!= outer_loop
;
4803 add_bb_to_loop (l2_bb
, outer_loop
);
4805 /* We've added a new loop around the original loop. Allocate the
4806 corresponding loop struct. */
4807 class loop
*new_loop
= alloc_loop ();
4808 new_loop
->header
= l0_bb
;
4809 new_loop
->latch
= l2_bb
;
4810 add_loop (new_loop
, outer_loop
);
4812 /* Allocate a loop structure for the original loop unless we already
4814 if (!orig_loop_has_loop_struct
4815 && !gimple_omp_for_combined_p (fd
->for_stmt
))
4817 class loop
*orig_loop
= alloc_loop ();
4818 orig_loop
->header
= l1_bb
;
4819 /* The loop may have multiple latches. */
4820 add_loop (orig_loop
, new_loop
);
4825 /* Helper function for expand_omp_for_static_nochunk. If PTR is NULL,
4826 compute needed allocation size. If !ALLOC of team allocations,
4827 if ALLOC of thread allocation. SZ is the initial needed size for
4828 other purposes, ALLOC_ALIGN guaranteed alignment of allocation in bytes,
4829 CNT number of elements of each array, for !ALLOC this is
4830 omp_get_num_threads (), for ALLOC number of iterations handled by the
4831 current thread. If PTR is non-NULL, it is the start of the allocation
4832 and this routine shall assign to OMP_CLAUSE_DECL (c) of those _scantemp_
4833 clauses pointers to the corresponding arrays. */
4836 expand_omp_scantemp_alloc (tree clauses
, tree ptr
, unsigned HOST_WIDE_INT sz
,
4837 unsigned HOST_WIDE_INT alloc_align
, tree cnt
,
4838 gimple_stmt_iterator
*gsi
, bool alloc
)
4840 tree eltsz
= NULL_TREE
;
4841 unsigned HOST_WIDE_INT preval
= 0;
4843 ptr
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ptr
),
4844 ptr
, size_int (sz
));
4845 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
4846 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE__SCANTEMP_
4847 && !OMP_CLAUSE__SCANTEMP__CONTROL (c
)
4848 && (!OMP_CLAUSE__SCANTEMP__ALLOC (c
)) != alloc
)
4850 tree pointee_type
= TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
4851 unsigned HOST_WIDE_INT al
= TYPE_ALIGN_UNIT (pointee_type
);
4852 if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (pointee_type
)))
4854 unsigned HOST_WIDE_INT szl
4855 = tree_to_uhwi (TYPE_SIZE_UNIT (pointee_type
));
4856 szl
= least_bit_hwi (szl
);
4860 if (ptr
== NULL_TREE
)
4862 if (eltsz
== NULL_TREE
)
4863 eltsz
= TYPE_SIZE_UNIT (pointee_type
);
4865 eltsz
= size_binop (PLUS_EXPR
, eltsz
,
4866 TYPE_SIZE_UNIT (pointee_type
));
4868 if (preval
== 0 && al
<= alloc_align
)
4870 unsigned HOST_WIDE_INT diff
= ROUND_UP (sz
, al
) - sz
;
4873 ptr
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ptr
),
4874 ptr
, size_int (diff
));
4876 else if (al
> preval
)
4880 ptr
= fold_convert (pointer_sized_int_node
, ptr
);
4881 ptr
= fold_build2 (PLUS_EXPR
, pointer_sized_int_node
, ptr
,
4882 build_int_cst (pointer_sized_int_node
,
4884 ptr
= fold_build2 (BIT_AND_EXPR
, pointer_sized_int_node
, ptr
,
4885 build_int_cst (pointer_sized_int_node
,
4886 -(HOST_WIDE_INT
) al
));
4887 ptr
= fold_convert (ptr_type_node
, ptr
);
4892 if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (pointee_type
)))
4898 expand_omp_build_assign (gsi
, OMP_CLAUSE_DECL (c
), ptr
, false);
4899 ptr
= OMP_CLAUSE_DECL (c
);
4900 ptr
= fold_build2 (POINTER_PLUS_EXPR
, TREE_TYPE (ptr
), ptr
,
4901 size_binop (MULT_EXPR
, cnt
,
4902 TYPE_SIZE_UNIT (pointee_type
)));
4906 if (ptr
== NULL_TREE
)
4908 eltsz
= size_binop (MULT_EXPR
, eltsz
, cnt
);
4910 eltsz
= size_binop (PLUS_EXPR
, eltsz
, size_int (sz
));
4917 /* Return the last _looptemp_ clause if one has been created for
4918 lastprivate on distribute parallel for{, simd} or taskloop.
4919 FD is the loop data and INNERC should be the second _looptemp_
4920 clause (the one holding the end of the range).
4921 This is followed by collapse - 1 _looptemp_ clauses for the
4922 counts[1] and up, and for triangular loops followed by 4
4923 further _looptemp_ clauses (one for counts[0], one first_inner_iterations,
4924 one factor and one adjn1). After this there is optionally one
4925 _looptemp_ clause that this function returns. */
4928 find_lastprivate_looptemp (struct omp_for_data
*fd
, tree innerc
)
4930 gcc_assert (innerc
);
4931 int count
= fd
->collapse
- 1;
4933 && fd
->last_nonrect
== fd
->first_nonrect
+ 1
4934 && !TYPE_UNSIGNED (TREE_TYPE (fd
->loops
[fd
->last_nonrect
].v
)))
4936 for (int i
= 0; i
< count
; i
++)
4938 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
4939 OMP_CLAUSE__LOOPTEMP_
);
4940 gcc_assert (innerc
);
4942 return omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
4943 OMP_CLAUSE__LOOPTEMP_
);
4946 /* A subroutine of expand_omp_for. Generate code for a parallel
4947 loop with static schedule and no specified chunk size. Given
4950 for (V = N1; V cond N2; V += STEP) BODY;
4952 where COND is "<" or ">", we generate pseudocode
4954 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
4959 if ((__typeof (V)) -1 > 0 && cond is >)
4960 n = -(adj + N2 - N1) / -STEP;
4962 n = (adj + N2 - N1) / STEP;
4965 if (threadid < tt) goto L3; else goto L4;
4970 s0 = q * threadid + tt;
4973 if (s0 >= e0) goto L2; else goto L0;
4979 if (V cond e) goto L1;
4984 expand_omp_for_static_nochunk (struct omp_region
*region
,
4985 struct omp_for_data
*fd
,
4988 tree n
, q
, s0
, e0
, e
, t
, tt
, nthreads
= NULL_TREE
, threadid
;
4989 tree type
, itype
, vmain
, vback
;
4990 basic_block entry_bb
, second_bb
, third_bb
, exit_bb
, seq_start_bb
;
4991 basic_block body_bb
, cont_bb
, collapse_bb
= NULL
;
4992 basic_block fin_bb
, fourth_bb
= NULL
, fifth_bb
= NULL
, sixth_bb
= NULL
;
4993 basic_block exit1_bb
= NULL
, exit2_bb
= NULL
, exit3_bb
= NULL
;
4994 gimple_stmt_iterator gsi
, gsip
;
4996 bool broken_loop
= region
->cont
== NULL
;
4997 tree
*counts
= NULL
;
4999 tree reductions
= NULL_TREE
;
5000 tree cond_var
= NULL_TREE
, condtemp
= NULL_TREE
;
5002 itype
= type
= TREE_TYPE (fd
->loop
.v
);
5003 if (POINTER_TYPE_P (type
))
5004 itype
= signed_type_for (type
);
5006 entry_bb
= region
->entry
;
5007 cont_bb
= region
->cont
;
5008 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
5009 fin_bb
= BRANCH_EDGE (entry_bb
)->dest
;
5010 gcc_assert (broken_loop
5011 || (fin_bb
== FALLTHRU_EDGE (cont_bb
)->dest
));
5012 seq_start_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
5013 body_bb
= single_succ (seq_start_bb
);
5016 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
5017 || single_succ (BRANCH_EDGE (cont_bb
)->dest
) == body_bb
);
5018 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
5020 exit_bb
= region
->exit
;
5022 /* Iteration space partitioning goes in ENTRY_BB. */
5023 gsi
= gsi_last_nondebug_bb (entry_bb
);
5024 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
5028 if (fd
->collapse
> 1)
5030 int first_zero_iter
= -1, dummy
= -1;
5031 basic_block l2_dom_bb
= NULL
, dummy_bb
= NULL
;
5033 counts
= XALLOCAVEC (tree
, fd
->collapse
);
5034 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
5035 fin_bb
, first_zero_iter
,
5036 dummy_bb
, dummy
, l2_dom_bb
);
5039 else if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
5040 t
= integer_one_node
;
5042 t
= fold_binary (fd
->loop
.cond_code
, boolean_type_node
,
5043 fold_convert (type
, fd
->loop
.n1
),
5044 fold_convert (type
, fd
->loop
.n2
));
5045 if (fd
->collapse
== 1
5046 && TYPE_UNSIGNED (type
)
5047 && (t
== NULL_TREE
|| !integer_onep (t
)))
5049 n1
= fold_convert (type
, unshare_expr (fd
->loop
.n1
));
5050 n1
= force_gimple_operand_gsi (&gsi
, n1
, true, NULL_TREE
,
5051 true, GSI_SAME_STMT
);
5052 n2
= fold_convert (type
, unshare_expr (fd
->loop
.n2
));
5053 n2
= force_gimple_operand_gsi (&gsi
, n2
, true, NULL_TREE
,
5054 true, GSI_SAME_STMT
);
5055 gcond
*cond_stmt
= expand_omp_build_cond (&gsi
, fd
->loop
.cond_code
,
5057 ep
= split_block (entry_bb
, cond_stmt
);
5058 ep
->flags
= EDGE_TRUE_VALUE
;
5059 entry_bb
= ep
->dest
;
5060 ep
->probability
= profile_probability::very_likely ();
5061 ep
= make_edge (ep
->src
, fin_bb
, EDGE_FALSE_VALUE
);
5062 ep
->probability
= profile_probability::very_unlikely ();
5063 if (gimple_in_ssa_p (cfun
))
5065 int dest_idx
= find_edge (entry_bb
, fin_bb
)->dest_idx
;
5066 for (gphi_iterator gpi
= gsi_start_phis (fin_bb
);
5067 !gsi_end_p (gpi
); gsi_next (&gpi
))
5069 gphi
*phi
= gpi
.phi ();
5070 add_phi_arg (phi
, gimple_phi_arg_def (phi
, dest_idx
),
5071 ep
, UNKNOWN_LOCATION
);
5074 gsi
= gsi_last_bb (entry_bb
);
5077 if (fd
->lastprivate_conditional
)
5079 tree clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
5080 tree c
= omp_find_clause (clauses
, OMP_CLAUSE__CONDTEMP_
);
5081 if (fd
->have_pointer_condtemp
)
5082 condtemp
= OMP_CLAUSE_DECL (c
);
5083 c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
), OMP_CLAUSE__CONDTEMP_
);
5084 cond_var
= OMP_CLAUSE_DECL (c
);
5086 if (fd
->have_reductemp
5087 /* For scan, we don't want to reinitialize condtemp before the
5089 || (fd
->have_pointer_condtemp
&& !fd
->have_scantemp
)
5090 || fd
->have_nonctrl_scantemp
)
5092 tree t1
= build_int_cst (long_integer_type_node
, 0);
5093 tree t2
= build_int_cst (long_integer_type_node
, 1);
5094 tree t3
= build_int_cstu (long_integer_type_node
,
5095 (HOST_WIDE_INT_1U
<< 31) + 1);
5096 tree clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
5097 gimple_stmt_iterator gsi2
= gsi_none ();
5099 tree mem
= null_pointer_node
, memv
= NULL_TREE
;
5100 unsigned HOST_WIDE_INT condtemp_sz
= 0;
5101 unsigned HOST_WIDE_INT alloc_align
= 0;
5102 if (fd
->have_reductemp
)
5104 gcc_assert (!fd
->have_nonctrl_scantemp
);
5105 tree c
= omp_find_clause (clauses
, OMP_CLAUSE__REDUCTEMP_
);
5106 reductions
= OMP_CLAUSE_DECL (c
);
5107 gcc_assert (TREE_CODE (reductions
) == SSA_NAME
);
5108 g
= SSA_NAME_DEF_STMT (reductions
);
5109 reductions
= gimple_assign_rhs1 (g
);
5110 OMP_CLAUSE_DECL (c
) = reductions
;
5111 gsi2
= gsi_for_stmt (g
);
5115 if (gsi_end_p (gsip
))
5116 gsi2
= gsi_after_labels (region
->entry
);
5119 reductions
= null_pointer_node
;
5121 if (fd
->have_pointer_condtemp
|| fd
->have_nonctrl_scantemp
)
5124 if (fd
->have_pointer_condtemp
)
5125 type
= TREE_TYPE (condtemp
);
5127 type
= ptr_type_node
;
5128 memv
= create_tmp_var (type
);
5129 TREE_ADDRESSABLE (memv
) = 1;
5130 unsigned HOST_WIDE_INT sz
= 0;
5131 tree size
= NULL_TREE
;
5132 if (fd
->have_pointer_condtemp
)
5134 sz
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type
)));
5135 sz
*= fd
->lastprivate_conditional
;
5138 if (fd
->have_nonctrl_scantemp
)
5140 nthreads
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
5141 gimple
*g
= gimple_build_call (nthreads
, 0);
5142 nthreads
= create_tmp_var (integer_type_node
);
5143 gimple_call_set_lhs (g
, nthreads
);
5144 gsi_insert_before (&gsi2
, g
, GSI_SAME_STMT
);
5145 nthreads
= fold_convert (sizetype
, nthreads
);
5146 alloc_align
= TYPE_ALIGN_UNIT (long_long_integer_type_node
);
5147 size
= expand_omp_scantemp_alloc (clauses
, NULL_TREE
, sz
,
5148 alloc_align
, nthreads
, NULL
,
5150 size
= fold_convert (type
, size
);
5153 size
= build_int_cst (type
, sz
);
5154 expand_omp_build_assign (&gsi2
, memv
, size
, false);
5155 mem
= build_fold_addr_expr (memv
);
5158 = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_LOOP_START
),
5159 9, t1
, t2
, t2
, t3
, t1
, null_pointer_node
,
5160 null_pointer_node
, reductions
, mem
);
5161 force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
5162 true, GSI_SAME_STMT
);
5163 if (fd
->have_pointer_condtemp
)
5164 expand_omp_build_assign (&gsi2
, condtemp
, memv
, false);
5165 if (fd
->have_nonctrl_scantemp
)
5167 tree ptr
= fd
->have_pointer_condtemp
? condtemp
: memv
;
5168 expand_omp_scantemp_alloc (clauses
, ptr
, condtemp_sz
,
5169 alloc_align
, nthreads
, &gsi2
, false);
5171 if (fd
->have_reductemp
)
5173 gsi_remove (&gsi2
, true);
5174 release_ssa_name (gimple_assign_lhs (g
));
5177 switch (gimple_omp_for_kind (fd
->for_stmt
))
5179 case GF_OMP_FOR_KIND_FOR
:
5180 nthreads
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
5181 threadid
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
5183 case GF_OMP_FOR_KIND_DISTRIBUTE
:
5184 nthreads
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS
);
5185 threadid
= builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM
);
5190 nthreads
= build_call_expr (nthreads
, 0);
5191 nthreads
= fold_convert (itype
, nthreads
);
5192 nthreads
= force_gimple_operand_gsi (&gsi
, nthreads
, true, NULL_TREE
,
5193 true, GSI_SAME_STMT
);
5194 threadid
= build_call_expr (threadid
, 0);
5195 threadid
= fold_convert (itype
, threadid
);
5196 threadid
= force_gimple_operand_gsi (&gsi
, threadid
, true, NULL_TREE
,
5197 true, GSI_SAME_STMT
);
5201 step
= fd
->loop
.step
;
5202 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
5204 tree innerc
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
5205 OMP_CLAUSE__LOOPTEMP_
);
5206 gcc_assert (innerc
);
5207 n1
= OMP_CLAUSE_DECL (innerc
);
5208 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
5209 OMP_CLAUSE__LOOPTEMP_
);
5210 gcc_assert (innerc
);
5211 n2
= OMP_CLAUSE_DECL (innerc
);
5213 n1
= force_gimple_operand_gsi (&gsi
, fold_convert (type
, n1
),
5214 true, NULL_TREE
, true, GSI_SAME_STMT
);
5215 n2
= force_gimple_operand_gsi (&gsi
, fold_convert (itype
, n2
),
5216 true, NULL_TREE
, true, GSI_SAME_STMT
);
5217 step
= force_gimple_operand_gsi (&gsi
, fold_convert (itype
, step
),
5218 true, NULL_TREE
, true, GSI_SAME_STMT
);
5220 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
5221 t
= fold_build2 (PLUS_EXPR
, itype
, step
, t
);
5222 t
= fold_build2 (PLUS_EXPR
, itype
, t
, n2
);
5223 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, n1
));
5224 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
5225 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
5226 fold_build1 (NEGATE_EXPR
, itype
, t
),
5227 fold_build1 (NEGATE_EXPR
, itype
, step
));
5229 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
5230 t
= fold_convert (itype
, t
);
5231 n
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5233 q
= create_tmp_reg (itype
, "q");
5234 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, n
, nthreads
);
5235 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, true, GSI_SAME_STMT
);
5236 gsi_insert_before (&gsi
, gimple_build_assign (q
, t
), GSI_SAME_STMT
);
5238 tt
= create_tmp_reg (itype
, "tt");
5239 t
= fold_build2 (TRUNC_MOD_EXPR
, itype
, n
, nthreads
);
5240 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, true, GSI_SAME_STMT
);
5241 gsi_insert_before (&gsi
, gimple_build_assign (tt
, t
), GSI_SAME_STMT
);
5243 t
= build2 (LT_EXPR
, boolean_type_node
, threadid
, tt
);
5244 gcond
*cond_stmt
= gimple_build_cond_empty (t
);
5245 gsi_insert_before (&gsi
, cond_stmt
, GSI_SAME_STMT
);
5247 second_bb
= split_block (entry_bb
, cond_stmt
)->dest
;
5248 gsi
= gsi_last_nondebug_bb (second_bb
);
5249 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
5251 gsi_insert_before (&gsi
, gimple_build_assign (tt
, build_int_cst (itype
, 0)),
5253 gassign
*assign_stmt
5254 = gimple_build_assign (q
, PLUS_EXPR
, q
, build_int_cst (itype
, 1));
5255 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
5257 third_bb
= split_block (second_bb
, assign_stmt
)->dest
;
5258 gsi
= gsi_last_nondebug_bb (third_bb
);
5259 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
5261 if (fd
->have_nonctrl_scantemp
)
5263 tree clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
5264 tree controlp
= NULL_TREE
, controlb
= NULL_TREE
;
5265 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
5266 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE__SCANTEMP_
5267 && OMP_CLAUSE__SCANTEMP__CONTROL (c
))
5269 if (TREE_TYPE (OMP_CLAUSE_DECL (c
)) == boolean_type_node
)
5270 controlb
= OMP_CLAUSE_DECL (c
);
5272 controlp
= OMP_CLAUSE_DECL (c
);
5273 if (controlb
&& controlp
)
5276 gcc_assert (controlp
&& controlb
);
5277 tree cnt
= create_tmp_var (sizetype
);
5278 gimple
*g
= gimple_build_assign (cnt
, NOP_EXPR
, q
);
5279 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5280 unsigned HOST_WIDE_INT alloc_align
= TYPE_ALIGN_UNIT (ptr_type_node
);
5281 tree sz
= expand_omp_scantemp_alloc (clauses
, NULL_TREE
, 0,
5282 alloc_align
, cnt
, NULL
, true);
5283 tree size
= create_tmp_var (sizetype
);
5284 expand_omp_build_assign (&gsi
, size
, sz
, false);
5285 tree cmp
= fold_build2 (GT_EXPR
, boolean_type_node
,
5286 size
, size_int (16384));
5287 expand_omp_build_assign (&gsi
, controlb
, cmp
);
5288 g
= gimple_build_cond (NE_EXPR
, controlb
, boolean_false_node
,
5289 NULL_TREE
, NULL_TREE
);
5290 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5291 fourth_bb
= split_block (third_bb
, g
)->dest
;
5292 gsi
= gsi_last_nondebug_bb (fourth_bb
);
5293 /* FIXME: Once we have allocators, this should use allocator. */
5294 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_MALLOC
), 1, size
);
5295 gimple_call_set_lhs (g
, controlp
);
5296 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5297 expand_omp_scantemp_alloc (clauses
, controlp
, 0, alloc_align
, cnt
,
5301 fifth_bb
= split_block (fourth_bb
, g
)->dest
;
5302 gsi
= gsi_last_nondebug_bb (fifth_bb
);
5304 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_SAVE
), 0);
5305 gimple_call_set_lhs (g
, controlp
);
5306 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5307 tree alloca_decl
= builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN
);
5308 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
5309 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE__SCANTEMP_
5310 && OMP_CLAUSE__SCANTEMP__ALLOC (c
))
5312 tree tmp
= create_tmp_var (sizetype
);
5313 tree pointee_type
= TREE_TYPE (TREE_TYPE (OMP_CLAUSE_DECL (c
)));
5314 g
= gimple_build_assign (tmp
, MULT_EXPR
, cnt
,
5315 TYPE_SIZE_UNIT (pointee_type
));
5316 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5317 g
= gimple_build_call (alloca_decl
, 2, tmp
,
5318 size_int (TYPE_ALIGN (pointee_type
)));
5319 gimple_call_set_lhs (g
, OMP_CLAUSE_DECL (c
));
5320 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5323 sixth_bb
= split_block (fifth_bb
, g
)->dest
;
5324 gsi
= gsi_last_nondebug_bb (sixth_bb
);
5327 t
= build2 (MULT_EXPR
, itype
, q
, threadid
);
5328 t
= build2 (PLUS_EXPR
, itype
, t
, tt
);
5329 s0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5331 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, q
);
5332 e0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5334 t
= build2 (GE_EXPR
, boolean_type_node
, s0
, e0
);
5335 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
5337 /* Remove the GIMPLE_OMP_FOR statement. */
5338 gsi_remove (&gsi
, true);
5340 /* Setup code for sequential iteration goes in SEQ_START_BB. */
5341 gsi
= gsi_start_bb (seq_start_bb
);
5343 tree startvar
= fd
->loop
.v
;
5344 tree endvar
= NULL_TREE
;
5346 if (gimple_omp_for_combined_p (fd
->for_stmt
))
5348 tree clauses
= gimple_code (inner_stmt
) == GIMPLE_OMP_PARALLEL
5349 ? gimple_omp_parallel_clauses (inner_stmt
)
5350 : gimple_omp_for_clauses (inner_stmt
);
5351 tree innerc
= omp_find_clause (clauses
, OMP_CLAUSE__LOOPTEMP_
);
5352 gcc_assert (innerc
);
5353 startvar
= OMP_CLAUSE_DECL (innerc
);
5354 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
5355 OMP_CLAUSE__LOOPTEMP_
);
5356 gcc_assert (innerc
);
5357 endvar
= OMP_CLAUSE_DECL (innerc
);
5358 if (fd
->collapse
> 1 && TREE_CODE (fd
->loop
.n2
) != INTEGER_CST
5359 && gimple_omp_for_kind (fd
->for_stmt
) == GF_OMP_FOR_KIND_DISTRIBUTE
)
5361 innerc
= find_lastprivate_looptemp (fd
, innerc
);
5364 /* If needed (distribute parallel for with lastprivate),
5365 propagate down the total number of iterations. */
5366 tree t
= fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (innerc
)),
5368 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, false,
5369 GSI_CONTINUE_LINKING
);
5370 assign_stmt
= gimple_build_assign (OMP_CLAUSE_DECL (innerc
), t
);
5371 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
5375 t
= fold_convert (itype
, s0
);
5376 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
5377 if (POINTER_TYPE_P (type
))
5379 t
= fold_build_pointer_plus (n1
, t
);
5380 if (!POINTER_TYPE_P (TREE_TYPE (startvar
))
5381 && TYPE_PRECISION (TREE_TYPE (startvar
)) > TYPE_PRECISION (type
))
5382 t
= fold_convert (signed_type_for (type
), t
);
5385 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
5386 t
= fold_convert (TREE_TYPE (startvar
), t
);
5387 t
= force_gimple_operand_gsi (&gsi
, t
,
5389 && TREE_ADDRESSABLE (startvar
),
5390 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
5391 assign_stmt
= gimple_build_assign (startvar
, t
);
5392 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
5395 tree itype
= TREE_TYPE (cond_var
);
5396 /* For lastprivate(conditional:) itervar, we need some iteration
5397 counter that starts at unsigned non-zero and increases.
5398 Prefer as few IVs as possible, so if we can use startvar
5399 itself, use that, or startvar + constant (those would be
5400 incremented with step), and as last resort use the s0 + 1
5401 incremented by 1. */
5402 if (POINTER_TYPE_P (type
)
5403 || TREE_CODE (n1
) != INTEGER_CST
5404 || fd
->loop
.cond_code
!= LT_EXPR
)
5405 t
= fold_build2 (PLUS_EXPR
, itype
, fold_convert (itype
, s0
),
5406 build_int_cst (itype
, 1));
5407 else if (tree_int_cst_sgn (n1
) == 1)
5408 t
= fold_convert (itype
, t
);
5411 tree c
= fold_convert (itype
, n1
);
5412 c
= fold_build2 (MINUS_EXPR
, itype
, build_int_cst (itype
, 1), c
);
5413 t
= fold_build2 (PLUS_EXPR
, itype
, fold_convert (itype
, t
), c
);
5415 t
= force_gimple_operand_gsi (&gsi
, t
, false,
5416 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
5417 assign_stmt
= gimple_build_assign (cond_var
, t
);
5418 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
5421 t
= fold_convert (itype
, e0
);
5422 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
5423 if (POINTER_TYPE_P (type
))
5425 t
= fold_build_pointer_plus (n1
, t
);
5426 if (!POINTER_TYPE_P (TREE_TYPE (startvar
))
5427 && TYPE_PRECISION (TREE_TYPE (startvar
)) > TYPE_PRECISION (type
))
5428 t
= fold_convert (signed_type_for (type
), t
);
5431 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
5432 t
= fold_convert (TREE_TYPE (startvar
), t
);
5433 e
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5434 false, GSI_CONTINUE_LINKING
);
5437 assign_stmt
= gimple_build_assign (endvar
, e
);
5438 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
5439 if (useless_type_conversion_p (TREE_TYPE (fd
->loop
.v
), TREE_TYPE (e
)))
5440 assign_stmt
= gimple_build_assign (fd
->loop
.v
, e
);
5442 assign_stmt
= gimple_build_assign (fd
->loop
.v
, NOP_EXPR
, e
);
5443 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
5445 /* Handle linear clause adjustments. */
5446 tree itercnt
= NULL_TREE
;
5447 tree
*nonrect_bounds
= NULL
;
5448 if (gimple_omp_for_kind (fd
->for_stmt
) == GF_OMP_FOR_KIND_FOR
)
5449 for (tree c
= gimple_omp_for_clauses (fd
->for_stmt
);
5450 c
; c
= OMP_CLAUSE_CHAIN (c
))
5451 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
5452 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
5454 tree d
= OMP_CLAUSE_DECL (c
);
5455 tree t
= d
, a
, dest
;
5456 if (omp_privatize_by_reference (t
))
5457 t
= build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c
), t
);
5458 if (itercnt
== NULL_TREE
)
5460 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
5462 itercnt
= fold_build2 (MINUS_EXPR
, itype
,
5463 fold_convert (itype
, n1
),
5464 fold_convert (itype
, fd
->loop
.n1
));
5465 itercnt
= fold_build2 (EXACT_DIV_EXPR
, itype
, itercnt
, step
);
5466 itercnt
= fold_build2 (PLUS_EXPR
, itype
, itercnt
, s0
);
5467 itercnt
= force_gimple_operand_gsi (&gsi
, itercnt
, true,
5469 GSI_CONTINUE_LINKING
);
5474 tree type
= TREE_TYPE (t
);
5475 if (POINTER_TYPE_P (type
))
5477 a
= fold_build2 (MULT_EXPR
, type
,
5478 fold_convert (type
, itercnt
),
5479 fold_convert (type
, OMP_CLAUSE_LINEAR_STEP (c
)));
5480 dest
= unshare_expr (t
);
5481 t
= fold_build2 (type
== TREE_TYPE (t
) ? PLUS_EXPR
5482 : POINTER_PLUS_EXPR
, TREE_TYPE (t
), t
, a
);
5483 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5484 false, GSI_CONTINUE_LINKING
);
5485 expand_omp_build_assign (&gsi
, dest
, t
, true);
5487 if (fd
->collapse
> 1)
5491 nonrect_bounds
= XALLOCAVEC (tree
, fd
->last_nonrect
+ 1);
5492 memset (nonrect_bounds
, 0, sizeof (tree
) * (fd
->last_nonrect
+ 1));
5494 expand_omp_for_init_vars (fd
, &gsi
, counts
, nonrect_bounds
, inner_stmt
,
5500 /* The code controlling the sequential loop replaces the
5501 GIMPLE_OMP_CONTINUE. */
5502 gsi
= gsi_last_nondebug_bb (cont_bb
);
5503 gomp_continue
*cont_stmt
= as_a
<gomp_continue
*> (gsi_stmt (gsi
));
5504 gcc_assert (gimple_code (cont_stmt
) == GIMPLE_OMP_CONTINUE
);
5505 vmain
= gimple_omp_continue_control_use (cont_stmt
);
5506 vback
= gimple_omp_continue_control_def (cont_stmt
);
5510 tree itype
= TREE_TYPE (cond_var
);
5512 if (POINTER_TYPE_P (type
)
5513 || TREE_CODE (n1
) != INTEGER_CST
5514 || fd
->loop
.cond_code
!= LT_EXPR
)
5515 t2
= build_int_cst (itype
, 1);
5517 t2
= fold_convert (itype
, step
);
5518 t2
= fold_build2 (PLUS_EXPR
, itype
, cond_var
, t2
);
5519 t2
= force_gimple_operand_gsi (&gsi
, t2
, false,
5520 NULL_TREE
, true, GSI_SAME_STMT
);
5521 assign_stmt
= gimple_build_assign (cond_var
, t2
);
5522 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
5525 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
5527 if (POINTER_TYPE_P (type
))
5528 t
= fold_build_pointer_plus (vmain
, step
);
5530 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, step
);
5531 t
= force_gimple_operand_gsi (&gsi
, t
,
5533 && TREE_ADDRESSABLE (vback
),
5534 NULL_TREE
, true, GSI_SAME_STMT
);
5535 assign_stmt
= gimple_build_assign (vback
, t
);
5536 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
5538 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
5539 DECL_P (vback
) && TREE_ADDRESSABLE (vback
)
5541 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
5544 /* Remove the GIMPLE_OMP_CONTINUE statement. */
5545 gsi_remove (&gsi
, true);
5547 if (fd
->collapse
> 1 && !gimple_omp_for_combined_p (fd
->for_stmt
))
5548 collapse_bb
= extract_omp_for_update_vars (fd
, nonrect_bounds
,
5552 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
5553 gsi
= gsi_last_nondebug_bb (exit_bb
);
5554 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
5556 t
= gimple_omp_return_lhs (gsi_stmt (gsi
));
5557 if (fd
->have_reductemp
5558 || ((fd
->have_pointer_condtemp
|| fd
->have_scantemp
)
5559 && !fd
->have_nonctrl_scantemp
))
5563 fn
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL
);
5565 fn
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END
);
5566 gcall
*g
= gimple_build_call (fn
, 0);
5569 gimple_call_set_lhs (g
, t
);
5570 if (fd
->have_reductemp
)
5571 gsi_insert_after (&gsi
, gimple_build_assign (reductions
,
5575 gsi_insert_after (&gsi
, g
, GSI_SAME_STMT
);
5578 gsi_insert_after (&gsi
, omp_build_barrier (t
), GSI_SAME_STMT
);
5580 else if ((fd
->have_pointer_condtemp
|| fd
->have_scantemp
)
5581 && !fd
->have_nonctrl_scantemp
)
5583 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT
);
5584 gcall
*g
= gimple_build_call (fn
, 0);
5585 gsi_insert_after (&gsi
, g
, GSI_SAME_STMT
);
5587 if (fd
->have_scantemp
&& !fd
->have_nonctrl_scantemp
)
5589 tree clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
5590 tree controlp
= NULL_TREE
, controlb
= NULL_TREE
;
5591 for (tree c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
5592 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE__SCANTEMP_
5593 && OMP_CLAUSE__SCANTEMP__CONTROL (c
))
5595 if (TREE_TYPE (OMP_CLAUSE_DECL (c
)) == boolean_type_node
)
5596 controlb
= OMP_CLAUSE_DECL (c
);
5598 controlp
= OMP_CLAUSE_DECL (c
);
5599 if (controlb
&& controlp
)
5602 gcc_assert (controlp
&& controlb
);
5603 gimple
*g
= gimple_build_cond (NE_EXPR
, controlb
, boolean_false_node
,
5604 NULL_TREE
, NULL_TREE
);
5605 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5606 exit1_bb
= split_block (exit_bb
, g
)->dest
;
5607 gsi
= gsi_after_labels (exit1_bb
);
5608 g
= gimple_build_call (builtin_decl_explicit (BUILT_IN_FREE
), 1,
5610 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5611 exit2_bb
= split_block (exit1_bb
, g
)->dest
;
5612 gsi
= gsi_after_labels (exit2_bb
);
5613 g
= gimple_build_call (builtin_decl_implicit (BUILT_IN_STACK_RESTORE
), 1,
5615 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
5616 exit3_bb
= split_block (exit2_bb
, g
)->dest
;
5617 gsi
= gsi_after_labels (exit3_bb
);
5619 gsi_remove (&gsi
, true);
5621 /* Connect all the blocks. */
5622 ep
= make_edge (entry_bb
, third_bb
, EDGE_FALSE_VALUE
);
5623 ep
->probability
= profile_probability::guessed_always ().apply_scale (3, 4);
5624 ep
= find_edge (entry_bb
, second_bb
);
5625 ep
->flags
= EDGE_TRUE_VALUE
;
5626 ep
->probability
= profile_probability::guessed_always () / 4;
5629 ep
= make_edge (third_bb
, fifth_bb
, EDGE_FALSE_VALUE
);
5630 ep
->probability
= profile_probability::guessed_always () / 2;
5631 ep
= find_edge (third_bb
, fourth_bb
);
5632 ep
->flags
= EDGE_TRUE_VALUE
;
5633 ep
->probability
= profile_probability::guessed_always () / 2;
5634 ep
= find_edge (fourth_bb
, fifth_bb
);
5635 redirect_edge_and_branch (ep
, sixth_bb
);
5638 sixth_bb
= third_bb
;
5639 find_edge (sixth_bb
, seq_start_bb
)->flags
= EDGE_FALSE_VALUE
;
5640 find_edge (sixth_bb
, fin_bb
)->flags
= EDGE_TRUE_VALUE
;
5643 ep
= make_edge (exit_bb
, exit2_bb
, EDGE_FALSE_VALUE
);
5644 ep
->probability
= profile_probability::guessed_always () / 2;
5645 ep
= find_edge (exit_bb
, exit1_bb
);
5646 ep
->flags
= EDGE_TRUE_VALUE
;
5647 ep
->probability
= profile_probability::guessed_always () / 2;
5648 ep
= find_edge (exit1_bb
, exit2_bb
);
5649 redirect_edge_and_branch (ep
, exit3_bb
);
5654 ep
= find_edge (cont_bb
, body_bb
);
5657 ep
= BRANCH_EDGE (cont_bb
);
5658 gcc_assert (single_succ (ep
->dest
) == body_bb
);
5660 if (gimple_omp_for_combined_p (fd
->for_stmt
))
5665 else if (fd
->collapse
> 1)
5668 ep
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
5671 ep
->flags
= EDGE_TRUE_VALUE
;
5672 find_edge (cont_bb
, fin_bb
)->flags
5673 = ep
? EDGE_FALSE_VALUE
: EDGE_FALLTHRU
;
5676 set_immediate_dominator (CDI_DOMINATORS
, second_bb
, entry_bb
);
5677 set_immediate_dominator (CDI_DOMINATORS
, third_bb
, entry_bb
);
5680 set_immediate_dominator (CDI_DOMINATORS
, fifth_bb
, third_bb
);
5681 set_immediate_dominator (CDI_DOMINATORS
, sixth_bb
, third_bb
);
5683 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
, sixth_bb
);
5685 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
5686 recompute_dominator (CDI_DOMINATORS
, body_bb
));
5687 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
5688 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
5691 set_immediate_dominator (CDI_DOMINATORS
, exit2_bb
, exit_bb
);
5692 set_immediate_dominator (CDI_DOMINATORS
, exit3_bb
, exit_bb
);
5695 class loop
*loop
= body_bb
->loop_father
;
5696 if (loop
!= entry_bb
->loop_father
)
5698 gcc_assert (broken_loop
|| loop
->header
== body_bb
);
5699 gcc_assert (broken_loop
5700 || loop
->latch
== region
->cont
5701 || single_pred (loop
->latch
) == region
->cont
);
5705 if (!broken_loop
&& !gimple_omp_for_combined_p (fd
->for_stmt
))
5707 loop
= alloc_loop ();
5708 loop
->header
= body_bb
;
5709 if (collapse_bb
== NULL
)
5710 loop
->latch
= cont_bb
;
5711 add_loop (loop
, body_bb
->loop_father
);
5715 /* Return phi in E->DEST with ARG on edge E. */
5718 find_phi_with_arg_on_edge (tree arg
, edge e
)
5720 basic_block bb
= e
->dest
;
5722 for (gphi_iterator gpi
= gsi_start_phis (bb
);
5726 gphi
*phi
= gpi
.phi ();
5727 if (PHI_ARG_DEF_FROM_EDGE (phi
, e
) == arg
)
5734 /* A subroutine of expand_omp_for. Generate code for a parallel
5735 loop with static schedule and a specified chunk size. Given
5738 for (V = N1; V cond N2; V += STEP) BODY;
5740 where COND is "<" or ">", we generate pseudocode
5742 if ((__typeof (V)) -1 > 0 && N2 cond N1) goto L2;
5747 if ((__typeof (V)) -1 > 0 && cond is >)
5748 n = -(adj + N2 - N1) / -STEP;
5750 n = (adj + N2 - N1) / STEP;
5752 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
5753 here so that V is defined
5754 if the loop is not entered
5756 s0 = (trip * nthreads + threadid) * CHUNK;
5757 e0 = min (s0 + CHUNK, n);
5758 if (s0 < n) goto L1; else goto L4;
5765 if (V cond e) goto L2; else goto L3;
5773 expand_omp_for_static_chunk (struct omp_region
*region
,
5774 struct omp_for_data
*fd
, gimple
*inner_stmt
)
5776 tree n
, s0
, e0
, e
, t
;
5777 tree trip_var
, trip_init
, trip_main
, trip_back
, nthreads
, threadid
;
5778 tree type
, itype
, vmain
, vback
, vextra
;
5779 basic_block entry_bb
, exit_bb
, body_bb
, seq_start_bb
, iter_part_bb
;
5780 basic_block trip_update_bb
= NULL
, cont_bb
, collapse_bb
= NULL
, fin_bb
;
5781 gimple_stmt_iterator gsi
, gsip
;
5783 bool broken_loop
= region
->cont
== NULL
;
5784 tree
*counts
= NULL
;
5786 tree reductions
= NULL_TREE
;
5787 tree cond_var
= NULL_TREE
, condtemp
= NULL_TREE
;
5789 itype
= type
= TREE_TYPE (fd
->loop
.v
);
5790 if (POINTER_TYPE_P (type
))
5791 itype
= signed_type_for (type
);
5793 entry_bb
= region
->entry
;
5794 se
= split_block (entry_bb
, last_nondebug_stmt (entry_bb
));
5796 iter_part_bb
= se
->dest
;
5797 cont_bb
= region
->cont
;
5798 gcc_assert (EDGE_COUNT (iter_part_bb
->succs
) == 2);
5799 fin_bb
= BRANCH_EDGE (iter_part_bb
)->dest
;
5800 gcc_assert (broken_loop
5801 || fin_bb
== FALLTHRU_EDGE (cont_bb
)->dest
);
5802 seq_start_bb
= split_edge (FALLTHRU_EDGE (iter_part_bb
));
5803 body_bb
= single_succ (seq_start_bb
);
5806 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
5807 || single_succ (BRANCH_EDGE (cont_bb
)->dest
) == body_bb
);
5808 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
5809 trip_update_bb
= split_edge (FALLTHRU_EDGE (cont_bb
));
5811 exit_bb
= region
->exit
;
5813 /* Trip and adjustment setup goes in ENTRY_BB. */
5814 gsi
= gsi_last_nondebug_bb (entry_bb
);
5815 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
5819 if (fd
->collapse
> 1)
5821 int first_zero_iter
= -1, dummy
= -1;
5822 basic_block l2_dom_bb
= NULL
, dummy_bb
= NULL
;
5824 counts
= XALLOCAVEC (tree
, fd
->collapse
);
5825 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
5826 fin_bb
, first_zero_iter
,
5827 dummy_bb
, dummy
, l2_dom_bb
);
5830 else if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
5831 t
= integer_one_node
;
5833 t
= fold_binary (fd
->loop
.cond_code
, boolean_type_node
,
5834 fold_convert (type
, fd
->loop
.n1
),
5835 fold_convert (type
, fd
->loop
.n2
));
5836 if (fd
->collapse
== 1
5837 && TYPE_UNSIGNED (type
)
5838 && (t
== NULL_TREE
|| !integer_onep (t
)))
5840 n1
= fold_convert (type
, unshare_expr (fd
->loop
.n1
));
5841 n1
= force_gimple_operand_gsi (&gsi
, n1
, true, NULL_TREE
,
5842 true, GSI_SAME_STMT
);
5843 n2
= fold_convert (type
, unshare_expr (fd
->loop
.n2
));
5844 n2
= force_gimple_operand_gsi (&gsi
, n2
, true, NULL_TREE
,
5845 true, GSI_SAME_STMT
);
5846 gcond
*cond_stmt
= expand_omp_build_cond (&gsi
, fd
->loop
.cond_code
,
5848 se
= split_block (entry_bb
, cond_stmt
);
5849 se
->flags
= EDGE_TRUE_VALUE
;
5850 entry_bb
= se
->dest
;
5851 se
->probability
= profile_probability::very_likely ();
5852 se
= make_edge (se
->src
, fin_bb
, EDGE_FALSE_VALUE
);
5853 se
->probability
= profile_probability::very_unlikely ();
5854 if (gimple_in_ssa_p (cfun
))
5856 int dest_idx
= find_edge (iter_part_bb
, fin_bb
)->dest_idx
;
5857 for (gphi_iterator gpi
= gsi_start_phis (fin_bb
);
5858 !gsi_end_p (gpi
); gsi_next (&gpi
))
5860 gphi
*phi
= gpi
.phi ();
5861 add_phi_arg (phi
, gimple_phi_arg_def (phi
, dest_idx
),
5862 se
, UNKNOWN_LOCATION
);
5865 gsi
= gsi_last_bb (entry_bb
);
5868 if (fd
->lastprivate_conditional
)
5870 tree clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
5871 tree c
= omp_find_clause (clauses
, OMP_CLAUSE__CONDTEMP_
);
5872 if (fd
->have_pointer_condtemp
)
5873 condtemp
= OMP_CLAUSE_DECL (c
);
5874 c
= omp_find_clause (OMP_CLAUSE_CHAIN (c
), OMP_CLAUSE__CONDTEMP_
);
5875 cond_var
= OMP_CLAUSE_DECL (c
);
5877 if (fd
->have_reductemp
|| fd
->have_pointer_condtemp
)
5879 tree t1
= build_int_cst (long_integer_type_node
, 0);
5880 tree t2
= build_int_cst (long_integer_type_node
, 1);
5881 tree t3
= build_int_cstu (long_integer_type_node
,
5882 (HOST_WIDE_INT_1U
<< 31) + 1);
5883 tree clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
5884 gimple_stmt_iterator gsi2
= gsi_none ();
5886 tree mem
= null_pointer_node
, memv
= NULL_TREE
;
5887 if (fd
->have_reductemp
)
5889 tree c
= omp_find_clause (clauses
, OMP_CLAUSE__REDUCTEMP_
);
5890 reductions
= OMP_CLAUSE_DECL (c
);
5891 gcc_assert (TREE_CODE (reductions
) == SSA_NAME
);
5892 g
= SSA_NAME_DEF_STMT (reductions
);
5893 reductions
= gimple_assign_rhs1 (g
);
5894 OMP_CLAUSE_DECL (c
) = reductions
;
5895 gsi2
= gsi_for_stmt (g
);
5899 if (gsi_end_p (gsip
))
5900 gsi2
= gsi_after_labels (region
->entry
);
5903 reductions
= null_pointer_node
;
5905 if (fd
->have_pointer_condtemp
)
5907 tree type
= TREE_TYPE (condtemp
);
5908 memv
= create_tmp_var (type
);
5909 TREE_ADDRESSABLE (memv
) = 1;
5910 unsigned HOST_WIDE_INT sz
5911 = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type
)));
5912 sz
*= fd
->lastprivate_conditional
;
5913 expand_omp_build_assign (&gsi2
, memv
, build_int_cst (type
, sz
),
5915 mem
= build_fold_addr_expr (memv
);
5918 = build_call_expr (builtin_decl_explicit (BUILT_IN_GOMP_LOOP_START
),
5919 9, t1
, t2
, t2
, t3
, t1
, null_pointer_node
,
5920 null_pointer_node
, reductions
, mem
);
5921 force_gimple_operand_gsi (&gsi2
, t
, true, NULL_TREE
,
5922 true, GSI_SAME_STMT
);
5923 if (fd
->have_pointer_condtemp
)
5924 expand_omp_build_assign (&gsi2
, condtemp
, memv
, false);
5925 if (fd
->have_reductemp
)
5927 gsi_remove (&gsi2
, true);
5928 release_ssa_name (gimple_assign_lhs (g
));
5931 switch (gimple_omp_for_kind (fd
->for_stmt
))
5933 case GF_OMP_FOR_KIND_FOR
:
5934 nthreads
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_THREADS
);
5935 threadid
= builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM
);
5937 case GF_OMP_FOR_KIND_DISTRIBUTE
:
5938 nthreads
= builtin_decl_explicit (BUILT_IN_OMP_GET_NUM_TEAMS
);
5939 threadid
= builtin_decl_explicit (BUILT_IN_OMP_GET_TEAM_NUM
);
5944 nthreads
= build_call_expr (nthreads
, 0);
5945 nthreads
= fold_convert (itype
, nthreads
);
5946 nthreads
= force_gimple_operand_gsi (&gsi
, nthreads
, true, NULL_TREE
,
5947 true, GSI_SAME_STMT
);
5948 threadid
= build_call_expr (threadid
, 0);
5949 threadid
= fold_convert (itype
, threadid
);
5950 threadid
= force_gimple_operand_gsi (&gsi
, threadid
, true, NULL_TREE
,
5951 true, GSI_SAME_STMT
);
5955 step
= fd
->loop
.step
;
5956 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
5958 tree innerc
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
5959 OMP_CLAUSE__LOOPTEMP_
);
5960 gcc_assert (innerc
);
5961 n1
= OMP_CLAUSE_DECL (innerc
);
5962 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
5963 OMP_CLAUSE__LOOPTEMP_
);
5964 gcc_assert (innerc
);
5965 n2
= OMP_CLAUSE_DECL (innerc
);
5967 n1
= force_gimple_operand_gsi (&gsi
, fold_convert (type
, n1
),
5968 true, NULL_TREE
, true, GSI_SAME_STMT
);
5969 n2
= force_gimple_operand_gsi (&gsi
, fold_convert (itype
, n2
),
5970 true, NULL_TREE
, true, GSI_SAME_STMT
);
5971 step
= force_gimple_operand_gsi (&gsi
, fold_convert (itype
, step
),
5972 true, NULL_TREE
, true, GSI_SAME_STMT
);
5973 tree chunk_size
= fold_convert (itype
, fd
->chunk_size
);
5974 chunk_size
= omp_adjust_chunk_size (chunk_size
, fd
->simd_schedule
,
5975 is_in_offload_region (region
));
5977 = force_gimple_operand_gsi (&gsi
, chunk_size
, true, NULL_TREE
, true,
5980 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
5981 t
= fold_build2 (PLUS_EXPR
, itype
, step
, t
);
5982 t
= fold_build2 (PLUS_EXPR
, itype
, t
, n2
);
5983 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, n1
));
5984 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
5985 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
5986 fold_build1 (NEGATE_EXPR
, itype
, t
),
5987 fold_build1 (NEGATE_EXPR
, itype
, step
));
5989 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
5990 t
= fold_convert (itype
, t
);
5991 n
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
5992 true, GSI_SAME_STMT
);
5994 trip_var
= create_tmp_reg (itype
, ".trip");
5995 if (gimple_in_ssa_p (cfun
))
5997 trip_init
= make_ssa_name (trip_var
);
5998 trip_main
= make_ssa_name (trip_var
);
5999 trip_back
= make_ssa_name (trip_var
);
6003 trip_init
= trip_var
;
6004 trip_main
= trip_var
;
6005 trip_back
= trip_var
;
6008 gassign
*assign_stmt
6009 = gimple_build_assign (trip_init
, build_int_cst (itype
, 0));
6010 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
6012 t
= fold_build2 (MULT_EXPR
, itype
, threadid
, chunk_size
);
6013 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
6014 if (POINTER_TYPE_P (type
))
6015 t
= fold_build_pointer_plus (n1
, t
);
6017 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
6018 vextra
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6019 true, GSI_SAME_STMT
);
6021 /* Remove the GIMPLE_OMP_FOR. */
6022 gsi_remove (&gsi
, true);
6024 gimple_stmt_iterator gsif
= gsi
;
6026 /* Iteration space partitioning goes in ITER_PART_BB. */
6027 gsi
= gsi_last_bb (iter_part_bb
);
6029 t
= fold_build2 (MULT_EXPR
, itype
, trip_main
, nthreads
);
6030 t
= fold_build2 (PLUS_EXPR
, itype
, t
, threadid
);
6031 t
= fold_build2 (MULT_EXPR
, itype
, t
, chunk_size
);
6032 s0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6033 false, GSI_CONTINUE_LINKING
);
6035 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, chunk_size
);
6036 t
= fold_build2 (MIN_EXPR
, itype
, t
, n
);
6037 e0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6038 false, GSI_CONTINUE_LINKING
);
6040 t
= build2 (LT_EXPR
, boolean_type_node
, s0
, n
);
6041 gsi_insert_after (&gsi
, gimple_build_cond_empty (t
), GSI_CONTINUE_LINKING
);
6043 /* Setup code for sequential iteration goes in SEQ_START_BB. */
6044 gsi
= gsi_start_bb (seq_start_bb
);
6046 tree startvar
= fd
->loop
.v
;
6047 tree endvar
= NULL_TREE
;
6049 if (gimple_omp_for_combined_p (fd
->for_stmt
))
6051 tree clauses
= gimple_code (inner_stmt
) == GIMPLE_OMP_PARALLEL
6052 ? gimple_omp_parallel_clauses (inner_stmt
)
6053 : gimple_omp_for_clauses (inner_stmt
);
6054 tree innerc
= omp_find_clause (clauses
, OMP_CLAUSE__LOOPTEMP_
);
6055 gcc_assert (innerc
);
6056 startvar
= OMP_CLAUSE_DECL (innerc
);
6057 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
6058 OMP_CLAUSE__LOOPTEMP_
);
6059 gcc_assert (innerc
);
6060 endvar
= OMP_CLAUSE_DECL (innerc
);
6061 if (fd
->collapse
> 1 && TREE_CODE (fd
->loop
.n2
) != INTEGER_CST
6062 && gimple_omp_for_kind (fd
->for_stmt
) == GF_OMP_FOR_KIND_DISTRIBUTE
)
6064 innerc
= find_lastprivate_looptemp (fd
, innerc
);
6067 /* If needed (distribute parallel for with lastprivate),
6068 propagate down the total number of iterations. */
6069 tree t
= fold_convert (TREE_TYPE (OMP_CLAUSE_DECL (innerc
)),
6071 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
, false,
6072 GSI_CONTINUE_LINKING
);
6073 assign_stmt
= gimple_build_assign (OMP_CLAUSE_DECL (innerc
), t
);
6074 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
6079 t
= fold_convert (itype
, s0
);
6080 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
6081 if (POINTER_TYPE_P (type
))
6083 t
= fold_build_pointer_plus (n1
, t
);
6084 if (!POINTER_TYPE_P (TREE_TYPE (startvar
))
6085 && TYPE_PRECISION (TREE_TYPE (startvar
)) > TYPE_PRECISION (type
))
6086 t
= fold_convert (signed_type_for (type
), t
);
6089 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
6090 t
= fold_convert (TREE_TYPE (startvar
), t
);
6091 t
= force_gimple_operand_gsi (&gsi
, t
,
6093 && TREE_ADDRESSABLE (startvar
),
6094 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
6095 assign_stmt
= gimple_build_assign (startvar
, t
);
6096 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
6099 tree itype
= TREE_TYPE (cond_var
);
6100 /* For lastprivate(conditional:) itervar, we need some iteration
6101 counter that starts at unsigned non-zero and increases.
6102 Prefer as few IVs as possible, so if we can use startvar
6103 itself, use that, or startvar + constant (those would be
6104 incremented with step), and as last resort use the s0 + 1
6105 incremented by 1. */
6106 if (POINTER_TYPE_P (type
)
6107 || TREE_CODE (n1
) != INTEGER_CST
6108 || fd
->loop
.cond_code
!= LT_EXPR
)
6109 t
= fold_build2 (PLUS_EXPR
, itype
, fold_convert (itype
, s0
),
6110 build_int_cst (itype
, 1));
6111 else if (tree_int_cst_sgn (n1
) == 1)
6112 t
= fold_convert (itype
, t
);
6115 tree c
= fold_convert (itype
, n1
);
6116 c
= fold_build2 (MINUS_EXPR
, itype
, build_int_cst (itype
, 1), c
);
6117 t
= fold_build2 (PLUS_EXPR
, itype
, fold_convert (itype
, t
), c
);
6119 t
= force_gimple_operand_gsi (&gsi
, t
, false,
6120 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
6121 assign_stmt
= gimple_build_assign (cond_var
, t
);
6122 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
6125 t
= fold_convert (itype
, e0
);
6126 t
= fold_build2 (MULT_EXPR
, itype
, t
, step
);
6127 if (POINTER_TYPE_P (type
))
6129 t
= fold_build_pointer_plus (n1
, t
);
6130 if (!POINTER_TYPE_P (TREE_TYPE (startvar
))
6131 && TYPE_PRECISION (TREE_TYPE (startvar
)) > TYPE_PRECISION (type
))
6132 t
= fold_convert (signed_type_for (type
), t
);
6135 t
= fold_build2 (PLUS_EXPR
, type
, t
, n1
);
6136 t
= fold_convert (TREE_TYPE (startvar
), t
);
6137 e
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6138 false, GSI_CONTINUE_LINKING
);
6141 assign_stmt
= gimple_build_assign (endvar
, e
);
6142 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
6143 if (useless_type_conversion_p (TREE_TYPE (fd
->loop
.v
), TREE_TYPE (e
)))
6144 assign_stmt
= gimple_build_assign (fd
->loop
.v
, e
);
6146 assign_stmt
= gimple_build_assign (fd
->loop
.v
, NOP_EXPR
, e
);
6147 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
6149 /* Handle linear clause adjustments. */
6150 tree itercnt
= NULL_TREE
, itercntbias
= NULL_TREE
;
6151 if (gimple_omp_for_kind (fd
->for_stmt
) == GF_OMP_FOR_KIND_FOR
)
6152 for (tree c
= gimple_omp_for_clauses (fd
->for_stmt
);
6153 c
; c
= OMP_CLAUSE_CHAIN (c
))
6154 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LINEAR
6155 && !OMP_CLAUSE_LINEAR_NO_COPYIN (c
))
6157 tree d
= OMP_CLAUSE_DECL (c
);
6158 tree t
= d
, a
, dest
;
6159 if (omp_privatize_by_reference (t
))
6160 t
= build_simple_mem_ref_loc (OMP_CLAUSE_LOCATION (c
), t
);
6161 tree type
= TREE_TYPE (t
);
6162 if (POINTER_TYPE_P (type
))
6164 dest
= unshare_expr (t
);
6165 tree v
= create_tmp_var (TREE_TYPE (t
), NULL
);
6166 expand_omp_build_assign (&gsif
, v
, t
);
6167 if (itercnt
== NULL_TREE
)
6169 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
6172 = fold_build2 (MINUS_EXPR
, itype
, fold_convert (itype
, n1
),
6173 fold_convert (itype
, fd
->loop
.n1
));
6174 itercntbias
= fold_build2 (EXACT_DIV_EXPR
, itype
,
6177 = force_gimple_operand_gsi (&gsif
, itercntbias
, true,
6180 itercnt
= fold_build2 (PLUS_EXPR
, itype
, itercntbias
, s0
);
6181 itercnt
= force_gimple_operand_gsi (&gsi
, itercnt
, true,
6183 GSI_CONTINUE_LINKING
);
6188 a
= fold_build2 (MULT_EXPR
, type
,
6189 fold_convert (type
, itercnt
),
6190 fold_convert (type
, OMP_CLAUSE_LINEAR_STEP (c
)));
6191 t
= fold_build2 (type
== TREE_TYPE (t
) ? PLUS_EXPR
6192 : POINTER_PLUS_EXPR
, TREE_TYPE (t
), v
, a
);
6193 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6194 false, GSI_CONTINUE_LINKING
);
6195 expand_omp_build_assign (&gsi
, dest
, t
, true);
6197 if (fd
->collapse
> 1)
6198 expand_omp_for_init_vars (fd
, &gsi
, counts
, NULL
, inner_stmt
, startvar
);
6202 /* The code controlling the sequential loop goes in CONT_BB,
6203 replacing the GIMPLE_OMP_CONTINUE. */
6204 gsi
= gsi_last_nondebug_bb (cont_bb
);
6205 gomp_continue
*cont_stmt
= as_a
<gomp_continue
*> (gsi_stmt (gsi
));
6206 vmain
= gimple_omp_continue_control_use (cont_stmt
);
6207 vback
= gimple_omp_continue_control_def (cont_stmt
);
6211 tree itype
= TREE_TYPE (cond_var
);
6213 if (POINTER_TYPE_P (type
)
6214 || TREE_CODE (n1
) != INTEGER_CST
6215 || fd
->loop
.cond_code
!= LT_EXPR
)
6216 t2
= build_int_cst (itype
, 1);
6218 t2
= fold_convert (itype
, step
);
6219 t2
= fold_build2 (PLUS_EXPR
, itype
, cond_var
, t2
);
6220 t2
= force_gimple_operand_gsi (&gsi
, t2
, false,
6221 NULL_TREE
, true, GSI_SAME_STMT
);
6222 assign_stmt
= gimple_build_assign (cond_var
, t2
);
6223 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
6226 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
6228 if (POINTER_TYPE_P (type
))
6229 t
= fold_build_pointer_plus (vmain
, step
);
6231 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, step
);
6232 if (DECL_P (vback
) && TREE_ADDRESSABLE (vback
))
6233 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6234 true, GSI_SAME_STMT
);
6235 assign_stmt
= gimple_build_assign (vback
, t
);
6236 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
6238 if (tree_int_cst_equal (fd
->chunk_size
, integer_one_node
))
6239 t
= build2 (EQ_EXPR
, boolean_type_node
,
6240 build_int_cst (itype
, 0),
6241 build_int_cst (itype
, 1));
6243 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
6244 DECL_P (vback
) && TREE_ADDRESSABLE (vback
)
6246 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
6249 /* Remove GIMPLE_OMP_CONTINUE. */
6250 gsi_remove (&gsi
, true);
6252 if (fd
->collapse
> 1 && !gimple_omp_for_combined_p (fd
->for_stmt
))
6253 collapse_bb
= extract_omp_for_update_vars (fd
, NULL
, cont_bb
, body_bb
);
6255 /* Trip update code goes into TRIP_UPDATE_BB. */
6256 gsi
= gsi_start_bb (trip_update_bb
);
6258 t
= build_int_cst (itype
, 1);
6259 t
= build2 (PLUS_EXPR
, itype
, trip_main
, t
);
6260 assign_stmt
= gimple_build_assign (trip_back
, t
);
6261 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
6264 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
6265 gsi
= gsi_last_nondebug_bb (exit_bb
);
6266 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
6268 t
= gimple_omp_return_lhs (gsi_stmt (gsi
));
6269 if (fd
->have_reductemp
|| fd
->have_pointer_condtemp
)
6273 fn
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_CANCEL
);
6275 fn
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END
);
6276 gcall
*g
= gimple_build_call (fn
, 0);
6279 gimple_call_set_lhs (g
, t
);
6280 if (fd
->have_reductemp
)
6281 gsi_insert_after (&gsi
, gimple_build_assign (reductions
,
6285 gsi_insert_after (&gsi
, g
, GSI_SAME_STMT
);
6288 gsi_insert_after (&gsi
, omp_build_barrier (t
), GSI_SAME_STMT
);
6290 else if (fd
->have_pointer_condtemp
)
6292 tree fn
= builtin_decl_explicit (BUILT_IN_GOMP_LOOP_END_NOWAIT
);
6293 gcall
*g
= gimple_build_call (fn
, 0);
6294 gsi_insert_after (&gsi
, g
, GSI_SAME_STMT
);
6296 gsi_remove (&gsi
, true);
6298 /* Connect the new blocks. */
6299 find_edge (iter_part_bb
, seq_start_bb
)->flags
= EDGE_TRUE_VALUE
;
6300 find_edge (iter_part_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
6304 se
= find_edge (cont_bb
, body_bb
);
6307 se
= BRANCH_EDGE (cont_bb
);
6308 gcc_assert (single_succ (se
->dest
) == body_bb
);
6310 if (gimple_omp_for_combined_p (fd
->for_stmt
))
6315 else if (fd
->collapse
> 1)
6318 se
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
6321 se
->flags
= EDGE_TRUE_VALUE
;
6322 find_edge (cont_bb
, trip_update_bb
)->flags
6323 = se
? EDGE_FALSE_VALUE
: EDGE_FALLTHRU
;
6325 redirect_edge_and_branch (single_succ_edge (trip_update_bb
),
6329 if (gimple_in_ssa_p (cfun
))
6337 gcc_assert (fd
->collapse
== 1 && !broken_loop
);
6339 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
6340 remove arguments of the phi nodes in fin_bb. We need to create
6341 appropriate phi nodes in iter_part_bb instead. */
6342 se
= find_edge (iter_part_bb
, fin_bb
);
6343 re
= single_succ_edge (trip_update_bb
);
6344 vec
<edge_var_map
> *head
= redirect_edge_var_map_vector (re
);
6345 ene
= single_succ_edge (entry_bb
);
6347 psi
= gsi_start_phis (fin_bb
);
6348 for (i
= 0; !gsi_end_p (psi
) && head
->iterate (i
, &vm
);
6349 gsi_next (&psi
), ++i
)
6355 if (operand_equal_p (gimple_phi_arg_def (phi
, 0),
6356 redirect_edge_var_map_def (vm
), 0))
6359 t
= gimple_phi_result (phi
);
6360 gcc_assert (t
== redirect_edge_var_map_result (vm
));
6362 if (!single_pred_p (fin_bb
))
6363 t
= copy_ssa_name (t
, phi
);
6365 nphi
= create_phi_node (t
, iter_part_bb
);
6367 t
= PHI_ARG_DEF_FROM_EDGE (phi
, se
);
6368 locus
= gimple_phi_arg_location_from_edge (phi
, se
);
6370 /* A special case -- fd->loop.v is not yet computed in
6371 iter_part_bb, we need to use vextra instead. */
6372 if (t
== fd
->loop
.v
)
6374 add_phi_arg (nphi
, t
, ene
, locus
);
6375 locus
= redirect_edge_var_map_location (vm
);
6376 tree back_arg
= redirect_edge_var_map_def (vm
);
6377 add_phi_arg (nphi
, back_arg
, re
, locus
);
6378 edge ce
= find_edge (cont_bb
, body_bb
);
6381 ce
= BRANCH_EDGE (cont_bb
);
6382 gcc_assert (single_succ (ce
->dest
) == body_bb
);
6383 ce
= single_succ_edge (ce
->dest
);
6385 gphi
*inner_loop_phi
= find_phi_with_arg_on_edge (back_arg
, ce
);
6386 gcc_assert (inner_loop_phi
!= NULL
);
6387 add_phi_arg (inner_loop_phi
, gimple_phi_result (nphi
),
6388 find_edge (seq_start_bb
, body_bb
), locus
);
6390 if (!single_pred_p (fin_bb
))
6391 add_phi_arg (phi
, gimple_phi_result (nphi
), se
, locus
);
6393 gcc_assert (gsi_end_p (psi
) && (head
== NULL
|| i
== head
->length ()));
6394 redirect_edge_var_map_clear (re
);
6395 if (single_pred_p (fin_bb
))
6398 psi
= gsi_start_phis (fin_bb
);
6399 if (gsi_end_p (psi
))
6401 remove_phi_node (&psi
, false);
6404 /* Make phi node for trip. */
6405 phi
= create_phi_node (trip_main
, iter_part_bb
);
6406 add_phi_arg (phi
, trip_back
, single_succ_edge (trip_update_bb
),
6408 add_phi_arg (phi
, trip_init
, single_succ_edge (entry_bb
),
6413 set_immediate_dominator (CDI_DOMINATORS
, trip_update_bb
, cont_bb
);
6414 set_immediate_dominator (CDI_DOMINATORS
, iter_part_bb
,
6415 recompute_dominator (CDI_DOMINATORS
, iter_part_bb
));
6416 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
6417 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
6418 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
,
6419 recompute_dominator (CDI_DOMINATORS
, seq_start_bb
));
6420 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
6421 recompute_dominator (CDI_DOMINATORS
, body_bb
));
6425 class loop
*loop
= body_bb
->loop_father
;
6426 class loop
*trip_loop
= alloc_loop ();
6427 trip_loop
->header
= iter_part_bb
;
6428 trip_loop
->latch
= trip_update_bb
;
6429 add_loop (trip_loop
, iter_part_bb
->loop_father
);
6431 if (loop
!= entry_bb
->loop_father
)
6433 gcc_assert (loop
->header
== body_bb
);
6434 gcc_assert (loop
->latch
== region
->cont
6435 || single_pred (loop
->latch
) == region
->cont
);
6436 trip_loop
->inner
= loop
;
6440 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
6442 loop
= alloc_loop ();
6443 loop
->header
= body_bb
;
6444 if (collapse_bb
== NULL
)
6445 loop
->latch
= cont_bb
;
6446 add_loop (loop
, trip_loop
);
6451 /* A subroutine of expand_omp_for. Generate code for a simd non-worksharing
6452 loop. Given parameters:
6454 for (V = N1; V cond N2; V += STEP) BODY;
6456 where COND is "<" or ">", we generate pseudocode
6464 if (V cond N2) goto L0; else goto L2;
6467 For collapsed loops, emit the outer loops as scalar
6468 and only try to vectorize the innermost loop. */
6471 expand_omp_simd (struct omp_region
*region
, struct omp_for_data
*fd
)
6474 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
, l2_bb
, l2_dom_bb
;
6475 gimple_stmt_iterator gsi
;
6478 bool broken_loop
= region
->cont
== NULL
;
6480 tree
*counts
= NULL
;
6482 int safelen_int
= INT_MAX
;
6483 bool dont_vectorize
= false;
6484 tree safelen
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6485 OMP_CLAUSE_SAFELEN
);
6486 tree simduid
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6487 OMP_CLAUSE__SIMDUID_
);
6488 tree ifc
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6490 tree simdlen
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6491 OMP_CLAUSE_SIMDLEN
);
6492 tree condtemp
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6493 OMP_CLAUSE__CONDTEMP_
);
6495 tree cond_var
= condtemp
? OMP_CLAUSE_DECL (condtemp
) : NULL_TREE
;
6500 safelen
= OMP_CLAUSE_SAFELEN_EXPR (safelen
);
6501 if (!poly_int_tree_p (safelen
, &val
))
6504 safelen_int
= MIN (constant_lower_bound (val
), INT_MAX
);
6505 if (safelen_int
== 1)
6508 if ((ifc
&& integer_zerop (OMP_CLAUSE_IF_EXPR (ifc
)))
6509 || (simdlen
&& integer_onep (OMP_CLAUSE_SIMDLEN_EXPR (simdlen
))))
6512 dont_vectorize
= true;
6514 type
= TREE_TYPE (fd
->loop
.v
);
6515 entry_bb
= region
->entry
;
6516 cont_bb
= region
->cont
;
6517 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
6518 gcc_assert (broken_loop
6519 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
6520 l0_bb
= FALLTHRU_EDGE (entry_bb
)->dest
;
6523 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l0_bb
);
6524 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
6525 l1_bb
= split_block (cont_bb
, last_nondebug_stmt (cont_bb
))->dest
;
6526 l2_bb
= BRANCH_EDGE (entry_bb
)->dest
;
6530 BRANCH_EDGE (entry_bb
)->flags
&= ~EDGE_ABNORMAL
;
6531 l1_bb
= split_edge (BRANCH_EDGE (entry_bb
));
6532 l2_bb
= single_succ (l1_bb
);
6534 exit_bb
= region
->exit
;
6537 gsi
= gsi_last_nondebug_bb (entry_bb
);
6539 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
6540 /* Not needed in SSA form right now. */
6541 gcc_assert (!gimple_in_ssa_p (cfun
));
6542 if (fd
->collapse
> 1
6543 && (gimple_omp_for_combined_into_p (fd
->for_stmt
)
6546 int first_zero_iter
= -1, dummy
= -1;
6547 basic_block zero_iter_bb
= l2_bb
, dummy_bb
= NULL
;
6549 counts
= XALLOCAVEC (tree
, fd
->collapse
);
6550 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
6551 zero_iter_bb
, first_zero_iter
,
6552 dummy_bb
, dummy
, l2_dom_bb
);
6554 if (l2_dom_bb
== NULL
)
6559 if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
6561 tree innerc
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6562 OMP_CLAUSE__LOOPTEMP_
);
6563 gcc_assert (innerc
);
6564 n1
= OMP_CLAUSE_DECL (innerc
);
6565 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
6566 OMP_CLAUSE__LOOPTEMP_
);
6567 gcc_assert (innerc
);
6568 n2
= OMP_CLAUSE_DECL (innerc
);
6570 tree step
= fd
->loop
.step
;
6571 tree orig_step
= step
; /* May be different from step if is_simt. */
6573 bool is_simt
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
6577 cfun
->curr_properties
&= ~PROP_gimple_lomp_dev
;
6578 is_simt
= safelen_int
> 1;
6580 tree simt_lane
= NULL_TREE
, simt_maxlane
= NULL_TREE
;
6583 simt_lane
= create_tmp_var (unsigned_type_node
);
6584 gimple
*g
= gimple_build_call_internal (IFN_GOMP_SIMT_LANE
, 0);
6585 gimple_call_set_lhs (g
, simt_lane
);
6586 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
6587 tree offset
= fold_build2 (MULT_EXPR
, TREE_TYPE (step
), step
,
6588 fold_convert (TREE_TYPE (step
), simt_lane
));
6589 n1
= fold_convert (type
, n1
);
6590 if (POINTER_TYPE_P (type
))
6591 n1
= fold_build_pointer_plus (n1
, offset
);
6593 n1
= fold_build2 (PLUS_EXPR
, type
, n1
, fold_convert (type
, offset
));
6595 /* Collapsed loops not handled for SIMT yet: limit to one lane only. */
6596 if (fd
->collapse
> 1)
6597 simt_maxlane
= build_one_cst (unsigned_type_node
);
6598 else if (safelen_int
< omp_max_simt_vf ())
6599 simt_maxlane
= build_int_cst (unsigned_type_node
, safelen_int
);
6601 = build_call_expr_internal_loc (UNKNOWN_LOCATION
, IFN_GOMP_SIMT_VF
,
6602 unsigned_type_node
, 0);
6604 vf
= fold_build2 (MIN_EXPR
, unsigned_type_node
, vf
, simt_maxlane
);
6605 vf
= fold_convert (TREE_TYPE (step
), vf
);
6606 step
= fold_build2 (MULT_EXPR
, TREE_TYPE (step
), step
, vf
);
6609 tree n2var
= NULL_TREE
;
6610 tree n2v
= NULL_TREE
;
6611 tree
*nonrect_bounds
= NULL
;
6612 tree min_arg1
= NULL_TREE
, min_arg2
= NULL_TREE
;
6613 if (fd
->collapse
> 1)
6615 if (broken_loop
|| gimple_omp_for_combined_into_p (fd
->for_stmt
))
6619 nonrect_bounds
= XALLOCAVEC (tree
, fd
->last_nonrect
+ 1);
6620 memset (nonrect_bounds
, 0,
6621 sizeof (tree
) * (fd
->last_nonrect
+ 1));
6623 expand_omp_build_assign (&gsi
, fd
->loop
.v
, fold_convert (type
, n1
));
6624 gcc_assert (entry_bb
== gsi_bb (gsi
));
6625 gcc_assert (fd
->for_stmt
== gsi_stmt (gsi
));
6627 entry_bb
= split_block (entry_bb
, gsi_stmt (gsi
))->dest
;
6628 expand_omp_for_init_vars (fd
, &gsi
, counts
, nonrect_bounds
,
6630 gsi
= gsi_for_stmt (fd
->for_stmt
);
6634 else if (gimple_omp_for_combined_into_p (fd
->for_stmt
))
6636 /* Compute in n2var the limit for the first innermost loop,
6637 i.e. fd->loop.v + MIN (n2 - fd->loop.v, cnt)
6638 where cnt is how many iterations would the loop have if
6639 all further iterations were assigned to the current task. */
6640 n2var
= create_tmp_var (type
);
6641 i
= fd
->collapse
- 1;
6642 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
6643 if (POINTER_TYPE_P (itype
))
6644 itype
= signed_type_for (itype
);
6645 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
== LT_EXPR
6647 t
= fold_build2 (PLUS_EXPR
, itype
,
6648 fold_convert (itype
, fd
->loops
[i
].step
), t
);
6649 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
6650 fold_convert (itype
, fd
->loops
[i
].n2
));
6651 if (fd
->loops
[i
].m2
)
6653 tree t2
= fold_convert (itype
,
6654 fd
->loops
[i
- fd
->loops
[i
].outer
].v
);
6655 tree t3
= fold_convert (itype
, fd
->loops
[i
].m2
);
6656 t2
= fold_build2 (MULT_EXPR
, TREE_TYPE (t
), t2
, t3
);
6657 t
= fold_build2 (PLUS_EXPR
, itype
, t
, t2
);
6659 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
6660 fold_convert (itype
, fd
->loops
[i
].v
));
6661 if (TYPE_UNSIGNED (itype
) && fd
->loops
[i
].cond_code
== GT_EXPR
)
6662 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
6663 fold_build1 (NEGATE_EXPR
, itype
, t
),
6664 fold_build1 (NEGATE_EXPR
, itype
,
6665 fold_convert (itype
,
6666 fd
->loops
[i
].step
)));
6668 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
,
6669 fold_convert (itype
, fd
->loops
[i
].step
));
6670 t
= fold_convert (type
, t
);
6671 tree t2
= fold_build2 (MINUS_EXPR
, type
, n2
, n1
);
6672 min_arg1
= create_tmp_var (type
);
6673 expand_omp_build_assign (&gsi
, min_arg1
, t2
);
6674 min_arg2
= create_tmp_var (type
);
6675 expand_omp_build_assign (&gsi
, min_arg2
, t
);
6679 if (TREE_CODE (n2
) == INTEGER_CST
)
6681 /* Indicate for lastprivate handling that at least one iteration
6682 has been performed, without wasting runtime. */
6683 if (integer_nonzerop (n2
))
6684 expand_omp_build_assign (&gsi
, fd
->loop
.v
,
6685 fold_convert (type
, n2
));
6687 /* Indicate that no iteration has been performed. */
6688 expand_omp_build_assign (&gsi
, fd
->loop
.v
,
6689 build_one_cst (type
));
6693 expand_omp_build_assign (&gsi
, fd
->loop
.v
,
6694 build_zero_cst (type
));
6695 expand_omp_build_assign (&gsi
, n2
, build_one_cst (type
));
6697 for (i
= 0; i
< fd
->collapse
; i
++)
6699 t
= fold_convert (TREE_TYPE (fd
->loops
[i
].v
), fd
->loops
[i
].n1
);
6700 if (fd
->loops
[i
].m1
)
6703 = fold_convert (TREE_TYPE (t
),
6704 fd
->loops
[i
- fd
->loops
[i
].outer
].v
);
6705 tree t3
= fold_convert (TREE_TYPE (t
), fd
->loops
[i
].m1
);
6706 t2
= fold_build2 (MULT_EXPR
, TREE_TYPE (t
), t2
, t3
);
6707 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, t2
);
6709 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
, t
);
6710 /* For normal non-combined collapsed loops just initialize
6711 the outermost iterator in the entry_bb. */
6718 expand_omp_build_assign (&gsi
, fd
->loop
.v
, fold_convert (type
, n1
));
6719 tree altv
= NULL_TREE
, altn2
= NULL_TREE
;
6720 if (fd
->collapse
== 1
6722 && TREE_CODE (orig_step
) != INTEGER_CST
)
6724 /* The vectorizer currently punts on loops with non-constant steps
6725 for the main IV (can't compute number of iterations and gives up
6726 because of that). As for OpenMP loops it is always possible to
6727 compute the number of iterations upfront, use an alternate IV
6728 as the loop iterator:
6729 altn2 = n1 < n2 ? (n2 - n1 + step - 1) / step : 0;
6730 for (i = n1, altv = 0; altv < altn2; altv++, i += step) */
6731 altv
= create_tmp_var (unsigned_type_for (TREE_TYPE (fd
->loops
[0].v
)));
6732 expand_omp_build_assign (&gsi
, altv
, build_zero_cst (TREE_TYPE (altv
)));
6733 tree itype
= TREE_TYPE (fd
->loop
.v
);
6734 if (POINTER_TYPE_P (itype
))
6735 itype
= signed_type_for (itype
);
6736 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
6737 t
= fold_build2 (PLUS_EXPR
, itype
,
6738 fold_convert (itype
, step
), t
);
6739 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fold_convert (itype
, n2
));
6740 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
6741 fold_convert (itype
, fd
->loop
.v
));
6742 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
6743 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
6744 fold_build1 (NEGATE_EXPR
, itype
, t
),
6745 fold_build1 (NEGATE_EXPR
, itype
,
6746 fold_convert (itype
, step
)));
6748 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
,
6749 fold_convert (itype
, step
));
6750 t
= fold_convert (TREE_TYPE (altv
), t
);
6751 altn2
= create_tmp_var (TREE_TYPE (altv
));
6752 expand_omp_build_assign (&gsi
, altn2
, t
);
6753 tree t2
= fold_convert (TREE_TYPE (fd
->loop
.v
), n2
);
6754 t2
= fold_build2 (fd
->loop
.cond_code
, boolean_type_node
, fd
->loop
.v
, t2
);
6755 t2
= force_gimple_operand_gsi (&gsi
, t2
, true, NULL_TREE
,
6756 true, GSI_SAME_STMT
);
6757 gassign
*g
= gimple_build_assign (altn2
, COND_EXPR
, t2
, altn2
,
6758 build_zero_cst (TREE_TYPE (altv
)));
6759 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
6761 else if (fd
->collapse
> 1
6763 && !gimple_omp_for_combined_into_p (fd
->for_stmt
)
6764 && TREE_CODE (fd
->loops
[fd
->collapse
- 1].step
) != INTEGER_CST
)
6766 altv
= create_tmp_var (unsigned_type_for (TREE_TYPE (fd
->loops
[0].v
)));
6767 altn2
= create_tmp_var (TREE_TYPE (altv
));
6771 if (POINTER_TYPE_P (type
)
6772 || TREE_CODE (n1
) != INTEGER_CST
6773 || fd
->loop
.cond_code
!= LT_EXPR
6774 || tree_int_cst_sgn (n1
) != 1)
6775 expand_omp_build_assign (&gsi
, cond_var
,
6776 build_one_cst (TREE_TYPE (cond_var
)));
6778 expand_omp_build_assign (&gsi
, cond_var
,
6779 fold_convert (TREE_TYPE (cond_var
), n1
));
6782 /* Remove the GIMPLE_OMP_FOR statement. */
6783 gsi_remove (&gsi
, true);
6787 /* Code to control the increment goes in the CONT_BB. */
6788 gsi
= gsi_last_nondebug_bb (cont_bb
);
6789 stmt
= gsi_stmt (gsi
);
6790 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
6792 if (fd
->collapse
== 1
6793 || gimple_omp_for_combined_into_p (fd
->for_stmt
))
6795 if (POINTER_TYPE_P (type
))
6796 t
= fold_build_pointer_plus (fd
->loop
.v
, step
);
6798 t
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.v
, step
);
6799 expand_omp_build_assign (&gsi
, fd
->loop
.v
, t
);
6801 else if (TREE_CODE (n2
) != INTEGER_CST
)
6802 expand_omp_build_assign (&gsi
, fd
->loop
.v
, build_one_cst (type
));
6805 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (altv
), altv
,
6806 build_one_cst (TREE_TYPE (altv
)));
6807 expand_omp_build_assign (&gsi
, altv
, t
);
6810 if (fd
->collapse
> 1)
6812 i
= fd
->collapse
- 1;
6813 if (POINTER_TYPE_P (TREE_TYPE (fd
->loops
[i
].v
)))
6814 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, fd
->loops
[i
].step
);
6817 t
= fold_convert (TREE_TYPE (fd
->loops
[i
].v
),
6819 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (fd
->loops
[i
].v
),
6822 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
, t
);
6826 if (POINTER_TYPE_P (type
)
6827 || TREE_CODE (n1
) != INTEGER_CST
6828 || fd
->loop
.cond_code
!= LT_EXPR
6829 || tree_int_cst_sgn (n1
) != 1)
6830 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (cond_var
), cond_var
,
6831 build_one_cst (TREE_TYPE (cond_var
)));
6833 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (cond_var
), cond_var
,
6834 fold_convert (TREE_TYPE (cond_var
), step
));
6835 expand_omp_build_assign (&gsi
, cond_var
, t
);
6838 /* Remove GIMPLE_OMP_CONTINUE. */
6839 gsi_remove (&gsi
, true);
6842 /* Emit the condition in L1_BB. */
6843 gsi
= gsi_start_bb (l1_bb
);
6846 t
= build2 (LT_EXPR
, boolean_type_node
, altv
, altn2
);
6847 else if (fd
->collapse
> 1
6848 && !gimple_omp_for_combined_into_p (fd
->for_stmt
)
6851 i
= fd
->collapse
- 1;
6852 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
6853 if (fd
->loops
[i
].m2
)
6854 t
= n2v
= create_tmp_var (itype
);
6856 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
6857 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6858 false, GSI_CONTINUE_LINKING
);
6859 tree v
= fd
->loops
[i
].v
;
6860 if (DECL_P (v
) && TREE_ADDRESSABLE (v
))
6861 v
= force_gimple_operand_gsi (&gsi
, v
, true, NULL_TREE
,
6862 false, GSI_CONTINUE_LINKING
);
6863 t
= build2 (fd
->loops
[i
].cond_code
, boolean_type_node
, v
, t
);
6867 if (fd
->collapse
> 1 && !broken_loop
)
6870 t
= fold_convert (type
, unshare_expr (n2
));
6871 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6872 false, GSI_CONTINUE_LINKING
);
6873 tree v
= fd
->loop
.v
;
6874 if (DECL_P (v
) && TREE_ADDRESSABLE (v
))
6875 v
= force_gimple_operand_gsi (&gsi
, v
, true, NULL_TREE
,
6876 false, GSI_CONTINUE_LINKING
);
6877 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, v
, t
);
6879 cond_stmt
= gimple_build_cond_empty (t
);
6880 gsi_insert_after (&gsi
, cond_stmt
, GSI_CONTINUE_LINKING
);
6881 if (walk_tree (gimple_cond_lhs_ptr (cond_stmt
), expand_omp_regimplify_p
,
6883 || walk_tree (gimple_cond_rhs_ptr (cond_stmt
), expand_omp_regimplify_p
,
6886 gsi
= gsi_for_stmt (cond_stmt
);
6887 gimple_regimplify_operands (cond_stmt
, &gsi
);
6890 /* Add 'V -= STEP * (SIMT_VF - 1)' after the loop. */
6893 gsi
= gsi_start_bb (l2_bb
);
6894 step
= fold_build2 (MINUS_EXPR
, TREE_TYPE (step
), orig_step
, step
);
6895 if (POINTER_TYPE_P (type
))
6896 t
= fold_build_pointer_plus (fd
->loop
.v
, step
);
6898 t
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.v
, step
);
6899 expand_omp_build_assign (&gsi
, fd
->loop
.v
, t
);
6902 /* Remove GIMPLE_OMP_RETURN. */
6903 gsi
= gsi_last_nondebug_bb (exit_bb
);
6904 gsi_remove (&gsi
, true);
6906 /* Connect the new blocks. */
6907 remove_edge (FALLTHRU_EDGE (entry_bb
));
6911 remove_edge (BRANCH_EDGE (entry_bb
));
6912 make_edge (entry_bb
, l1_bb
, EDGE_FALLTHRU
);
6914 e
= BRANCH_EDGE (l1_bb
);
6915 ne
= FALLTHRU_EDGE (l1_bb
);
6916 e
->flags
= EDGE_TRUE_VALUE
;
6920 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
6922 ne
= single_succ_edge (l1_bb
);
6923 e
= make_edge (l1_bb
, l0_bb
, EDGE_TRUE_VALUE
);
6926 ne
->flags
= EDGE_FALSE_VALUE
;
6927 e
->probability
= profile_probability::guessed_always ().apply_scale (7, 8);
6928 ne
->probability
= e
->probability
.invert ();
6930 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
, entry_bb
);
6931 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
, l1_bb
);
6935 cond_stmt
= gimple_build_cond (LT_EXPR
, simt_lane
, simt_maxlane
,
6936 NULL_TREE
, NULL_TREE
);
6937 gsi
= gsi_last_bb (entry_bb
);
6938 gsi_insert_after (&gsi
, cond_stmt
, GSI_NEW_STMT
);
6939 make_edge (entry_bb
, l2_bb
, EDGE_FALSE_VALUE
);
6940 FALLTHRU_EDGE (entry_bb
)->flags
= EDGE_TRUE_VALUE
;
6941 FALLTHRU_EDGE (entry_bb
)->probability
6942 = profile_probability::guessed_always ().apply_scale (7, 8);
6943 BRANCH_EDGE (entry_bb
)->probability
6944 = FALLTHRU_EDGE (entry_bb
)->probability
.invert ();
6945 l2_dom_bb
= entry_bb
;
6947 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
, l2_dom_bb
);
6949 if (!broken_loop
&& fd
->collapse
> 1)
6951 basic_block last_bb
= l1_bb
;
6952 basic_block init_bb
= NULL
;
6953 for (i
= fd
->collapse
- 2; i
>= 0; i
--)
6955 tree nextn2v
= NULL_TREE
;
6956 if (EDGE_SUCC (last_bb
, 0)->flags
& EDGE_FALSE_VALUE
)
6957 e
= EDGE_SUCC (last_bb
, 0);
6959 e
= EDGE_SUCC (last_bb
, 1);
6960 basic_block bb
= split_edge (e
);
6961 if (POINTER_TYPE_P (TREE_TYPE (fd
->loops
[i
].v
)))
6962 t
= fold_build_pointer_plus (fd
->loops
[i
].v
, fd
->loops
[i
].step
);
6965 t
= fold_convert (TREE_TYPE (fd
->loops
[i
].v
),
6967 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (fd
->loops
[i
].v
),
6970 gsi
= gsi_after_labels (bb
);
6971 expand_omp_build_assign (&gsi
, fd
->loops
[i
].v
, t
);
6973 bb
= split_block (bb
, last_nondebug_stmt (bb
))->dest
;
6974 gsi
= gsi_start_bb (bb
);
6975 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
6976 if (fd
->loops
[i
].m2
)
6977 t
= nextn2v
= create_tmp_var (itype
);
6979 t
= fold_convert (itype
, unshare_expr (fd
->loops
[i
].n2
));
6980 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
6981 false, GSI_CONTINUE_LINKING
);
6982 tree v
= fd
->loops
[i
].v
;
6983 if (DECL_P (v
) && TREE_ADDRESSABLE (v
))
6984 v
= force_gimple_operand_gsi (&gsi
, v
, true, NULL_TREE
,
6985 false, GSI_CONTINUE_LINKING
);
6986 t
= build2 (fd
->loops
[i
].cond_code
, boolean_type_node
, v
, t
);
6987 cond_stmt
= gimple_build_cond_empty (t
);
6988 gsi_insert_after (&gsi
, cond_stmt
, GSI_CONTINUE_LINKING
);
6989 if (walk_tree (gimple_cond_lhs_ptr (cond_stmt
),
6990 expand_omp_regimplify_p
, NULL
, NULL
)
6991 || walk_tree (gimple_cond_rhs_ptr (cond_stmt
),
6992 expand_omp_regimplify_p
, NULL
, NULL
))
6994 gsi
= gsi_for_stmt (cond_stmt
);
6995 gimple_regimplify_operands (cond_stmt
, &gsi
);
6997 ne
= single_succ_edge (bb
);
6998 ne
->flags
= EDGE_FALSE_VALUE
;
7000 init_bb
= create_empty_bb (bb
);
7001 set_immediate_dominator (CDI_DOMINATORS
, init_bb
, bb
);
7002 add_bb_to_loop (init_bb
, bb
->loop_father
);
7003 e
= make_edge (bb
, init_bb
, EDGE_TRUE_VALUE
);
7005 = profile_probability::guessed_always ().apply_scale (7, 8);
7006 ne
->probability
= e
->probability
.invert ();
7008 gsi
= gsi_after_labels (init_bb
);
7009 if (fd
->loops
[i
+ 1].m1
)
7011 tree t2
= fold_convert (TREE_TYPE (fd
->loops
[i
+ 1].v
),
7013 - fd
->loops
[i
+ 1].outer
].v
);
7014 if (POINTER_TYPE_P (TREE_TYPE (t2
)))
7015 t
= fold_build_pointer_plus (t2
, fd
->loops
[i
+ 1].n1
);
7018 t
= fold_convert (TREE_TYPE (fd
->loops
[i
+ 1].v
),
7019 fd
->loops
[i
+ 1].n1
);
7020 tree t3
= fold_convert (TREE_TYPE (t
), fd
->loops
[i
+ 1].m1
);
7021 t2
= fold_build2 (MULT_EXPR
, TREE_TYPE (t
), t2
, t3
);
7022 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, t2
);
7026 t
= fold_convert (TREE_TYPE (fd
->loops
[i
+ 1].v
),
7027 fd
->loops
[i
+ 1].n1
);
7028 expand_omp_build_assign (&gsi
, fd
->loops
[i
+ 1].v
, t
);
7029 if (fd
->loops
[i
+ 1].m2
)
7031 if (i
+ 2 == fd
->collapse
&& (n2var
|| altv
))
7033 gcc_assert (n2v
== NULL_TREE
);
7034 n2v
= create_tmp_var (TREE_TYPE (fd
->loops
[i
+ 1].v
));
7036 tree t2
= fold_convert (TREE_TYPE (fd
->loops
[i
+ 1].v
),
7038 - fd
->loops
[i
+ 1].outer
].v
);
7039 if (POINTER_TYPE_P (TREE_TYPE (t2
)))
7040 t
= fold_build_pointer_plus (t2
, fd
->loops
[i
+ 1].n2
);
7043 t
= fold_convert (TREE_TYPE (fd
->loops
[i
+ 1].v
),
7044 fd
->loops
[i
+ 1].n2
);
7045 tree t3
= fold_convert (TREE_TYPE (t
), fd
->loops
[i
+ 1].m2
);
7046 t2
= fold_build2 (MULT_EXPR
, TREE_TYPE (t
), t2
, t3
);
7047 t
= fold_build2 (PLUS_EXPR
, TREE_TYPE (t
), t
, t2
);
7049 expand_omp_build_assign (&gsi
, n2v
, t
);
7051 if (i
+ 2 == fd
->collapse
&& n2var
)
7053 /* For composite simd, n2 is the first iteration the current
7054 task shouldn't already handle, so we effectively want to use
7055 for (V3 = N31; V < N2 && V3 < N32; V++, V3 += STEP3)
7056 as the vectorized loop. Except the vectorizer will not
7057 vectorize that, so instead compute N2VAR as
7058 N2VAR = V + MIN (N2 - V, COUNTS3) and use
7059 for (V3 = N31; V < N2VAR; V++, V3 += STEP3)
7060 as the loop to vectorize. */
7061 tree t2
= fold_build2 (MINUS_EXPR
, type
, n2
, fd
->loop
.v
);
7062 if (fd
->loops
[i
+ 1].m1
|| fd
->loops
[i
+ 1].m2
)
7064 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
7065 if (POINTER_TYPE_P (itype
))
7066 itype
= signed_type_for (itype
);
7067 t
= build_int_cst (itype
, (fd
->loops
[i
+ 1].cond_code
7068 == LT_EXPR
? -1 : 1));
7069 t
= fold_build2 (PLUS_EXPR
, itype
,
7070 fold_convert (itype
,
7071 fd
->loops
[i
+ 1].step
), t
);
7072 if (fd
->loops
[i
+ 1].m2
== NULL_TREE
)
7073 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
7074 fold_convert (itype
,
7075 fd
->loops
[i
+ 1].n2
));
7076 else if (POINTER_TYPE_P (TREE_TYPE (n2v
)))
7078 t
= fold_build_pointer_plus (n2v
, t
);
7079 t
= fold_convert (itype
, t
);
7082 t
= fold_build2 (PLUS_EXPR
, itype
, t
, n2v
);
7083 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
7084 fold_convert (itype
, fd
->loops
[i
+ 1].v
));
7085 tree step
= fold_convert (itype
, fd
->loops
[i
+ 1].step
);
7086 if (TYPE_UNSIGNED (itype
)
7087 && fd
->loops
[i
+ 1].cond_code
== GT_EXPR
)
7088 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
7089 fold_build1 (NEGATE_EXPR
, itype
, t
),
7090 fold_build1 (NEGATE_EXPR
, itype
, step
));
7092 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
7093 t
= fold_convert (type
, t
);
7097 expand_omp_build_assign (&gsi
, min_arg1
, t2
);
7098 expand_omp_build_assign (&gsi
, min_arg2
, t
);
7099 e
= split_block (init_bb
, last_nondebug_stmt (init_bb
));
7100 gsi
= gsi_after_labels (e
->dest
);
7102 remove_edge (FALLTHRU_EDGE (entry_bb
));
7103 make_edge (entry_bb
, init_bb
, EDGE_FALLTHRU
);
7104 set_immediate_dominator (CDI_DOMINATORS
, init_bb
, entry_bb
);
7105 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
, init_bb
);
7106 t
= fold_build2 (MIN_EXPR
, type
, min_arg1
, min_arg2
);
7107 t
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.v
, t
);
7108 expand_omp_build_assign (&gsi
, n2var
, t
);
7110 if (i
+ 2 == fd
->collapse
&& altv
)
7112 /* The vectorizer currently punts on loops with non-constant
7113 steps for the main IV (can't compute number of iterations
7114 and gives up because of that). As for OpenMP loops it is
7115 always possible to compute the number of iterations upfront,
7116 use an alternate IV as the loop iterator. */
7117 expand_omp_build_assign (&gsi
, altv
,
7118 build_zero_cst (TREE_TYPE (altv
)));
7119 tree itype
= TREE_TYPE (fd
->loops
[i
+ 1].v
);
7120 if (POINTER_TYPE_P (itype
))
7121 itype
= signed_type_for (itype
);
7122 t
= build_int_cst (itype
, (fd
->loops
[i
+ 1].cond_code
== LT_EXPR
7124 t
= fold_build2 (PLUS_EXPR
, itype
,
7125 fold_convert (itype
, fd
->loops
[i
+ 1].step
), t
);
7126 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
7127 fold_convert (itype
,
7129 ? n2v
: fd
->loops
[i
+ 1].n2
));
7130 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
7131 fold_convert (itype
, fd
->loops
[i
+ 1].v
));
7132 tree step
= fold_convert (itype
, fd
->loops
[i
+ 1].step
);
7133 if (TYPE_UNSIGNED (itype
)
7134 && fd
->loops
[i
+ 1].cond_code
== GT_EXPR
)
7135 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
7136 fold_build1 (NEGATE_EXPR
, itype
, t
),
7137 fold_build1 (NEGATE_EXPR
, itype
, step
));
7139 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, step
);
7140 t
= fold_convert (TREE_TYPE (altv
), t
);
7141 expand_omp_build_assign (&gsi
, altn2
, t
);
7142 tree t2
= fold_convert (TREE_TYPE (fd
->loops
[i
+ 1].v
),
7144 ? n2v
: fd
->loops
[i
+ 1].n2
);
7145 t2
= fold_build2 (fd
->loops
[i
+ 1].cond_code
, boolean_type_node
,
7146 fd
->loops
[i
+ 1].v
, t2
);
7147 t2
= force_gimple_operand_gsi (&gsi
, t2
, true, NULL_TREE
,
7148 true, GSI_SAME_STMT
);
7150 = gimple_build_assign (altn2
, COND_EXPR
, t2
, altn2
,
7151 build_zero_cst (TREE_TYPE (altv
)));
7152 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
7156 make_edge (init_bb
, last_bb
, EDGE_FALLTHRU
);
7157 if (!gimple_omp_for_combined_into_p (fd
->for_stmt
))
7159 e
= find_edge (entry_bb
, last_bb
);
7160 redirect_edge_succ (e
, bb
);
7161 set_immediate_dominator (CDI_DOMINATORS
, bb
, entry_bb
);
7162 set_immediate_dominator (CDI_DOMINATORS
, last_bb
, init_bb
);
7170 class loop
*loop
= alloc_loop ();
7171 loop
->header
= l1_bb
;
7172 loop
->latch
= cont_bb
;
7173 add_loop (loop
, l1_bb
->loop_father
);
7174 loop
->safelen
= safelen_int
;
7177 loop
->simduid
= OMP_CLAUSE__SIMDUID__DECL (simduid
);
7178 cfun
->has_simduid_loops
= true;
7180 /* If not -fno-tree-loop-vectorize, hint that we want to vectorize
7182 if ((flag_tree_loop_vectorize
7183 || !OPTION_SET_P (flag_tree_loop_vectorize
))
7184 && flag_tree_loop_optimize
7185 && loop
->safelen
> 1)
7187 loop
->force_vectorize
= true;
7188 if (simdlen
&& tree_fits_uhwi_p (OMP_CLAUSE_SIMDLEN_EXPR (simdlen
)))
7190 unsigned HOST_WIDE_INT v
7191 = tree_to_uhwi (OMP_CLAUSE_SIMDLEN_EXPR (simdlen
));
7192 if (v
< INT_MAX
&& v
<= (unsigned HOST_WIDE_INT
) loop
->safelen
)
7195 cfun
->has_force_vectorize_loops
= true;
7197 else if (dont_vectorize
)
7198 loop
->dont_vectorize
= true;
7201 cfun
->has_simduid_loops
= true;
7204 /* Taskloop construct is represented after gimplification with
7205 two GIMPLE_OMP_FOR constructs with GIMPLE_OMP_TASK sandwiched
7206 in between them. This routine expands the outer GIMPLE_OMP_FOR,
7207 which should just compute all the needed loop temporaries
7208 for GIMPLE_OMP_TASK. */
7211 expand_omp_taskloop_for_outer (struct omp_region
*region
,
7212 struct omp_for_data
*fd
,
7215 tree type
, bias
= NULL_TREE
;
7216 basic_block entry_bb
, cont_bb
, exit_bb
;
7217 gimple_stmt_iterator gsi
;
7218 gassign
*assign_stmt
;
7219 tree
*counts
= NULL
;
7222 gcc_assert (inner_stmt
);
7223 gcc_assert (region
->cont
);
7224 gcc_assert (gimple_code (inner_stmt
) == GIMPLE_OMP_TASK
7225 && gimple_omp_task_taskloop_p (inner_stmt
));
7226 type
= TREE_TYPE (fd
->loop
.v
);
7228 /* See if we need to bias by LLONG_MIN. */
7229 if (fd
->iter_type
== long_long_unsigned_type_node
7230 && (TREE_CODE (type
) == INTEGER_TYPE
|| TREE_CODE (type
) == BITINT_TYPE
)
7231 && !TYPE_UNSIGNED (type
))
7235 if (fd
->loop
.cond_code
== LT_EXPR
)
7238 n2
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
7242 n1
= fold_build2 (MINUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
7245 if (TREE_CODE (n1
) != INTEGER_CST
7246 || TREE_CODE (n2
) != INTEGER_CST
7247 || ((tree_int_cst_sgn (n1
) < 0) ^ (tree_int_cst_sgn (n2
) < 0)))
7248 bias
= fold_convert (fd
->iter_type
, TYPE_MIN_VALUE (type
));
7251 entry_bb
= region
->entry
;
7252 cont_bb
= region
->cont
;
7253 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
7254 gcc_assert (BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
7255 exit_bb
= region
->exit
;
7257 gsi
= gsi_last_nondebug_bb (entry_bb
);
7258 gimple
*for_stmt
= gsi_stmt (gsi
);
7259 gcc_assert (gimple_code (for_stmt
) == GIMPLE_OMP_FOR
);
7260 if (fd
->collapse
> 1)
7262 int first_zero_iter
= -1, dummy
= -1;
7263 basic_block zero_iter_bb
= NULL
, dummy_bb
= NULL
, l2_dom_bb
= NULL
;
7265 counts
= XALLOCAVEC (tree
, fd
->collapse
);
7266 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
7267 zero_iter_bb
, first_zero_iter
,
7268 dummy_bb
, dummy
, l2_dom_bb
);
7272 /* Some counts[i] vars might be uninitialized if
7273 some loop has zero iterations. But the body shouldn't
7274 be executed in that case, so just avoid uninit warnings. */
7275 for (i
= first_zero_iter
; i
< fd
->collapse
; i
++)
7276 if (SSA_VAR_P (counts
[i
]))
7277 suppress_warning (counts
[i
], OPT_Wuninitialized
);
7279 edge e
= split_block (entry_bb
, gsi_stmt (gsi
));
7281 make_edge (zero_iter_bb
, entry_bb
, EDGE_FALLTHRU
);
7282 gsi
= gsi_last_bb (entry_bb
);
7283 set_immediate_dominator (CDI_DOMINATORS
, entry_bb
,
7284 get_immediate_dominator (CDI_DOMINATORS
,
7292 if (POINTER_TYPE_P (TREE_TYPE (t0
))
7293 && TYPE_PRECISION (TREE_TYPE (t0
))
7294 != TYPE_PRECISION (fd
->iter_type
))
7296 /* Avoid casting pointers to integer of a different size. */
7297 tree itype
= signed_type_for (type
);
7298 t1
= fold_convert (fd
->iter_type
, fold_convert (itype
, t1
));
7299 t0
= fold_convert (fd
->iter_type
, fold_convert (itype
, t0
));
7303 t1
= fold_convert (fd
->iter_type
, t1
);
7304 t0
= fold_convert (fd
->iter_type
, t0
);
7308 t1
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t1
, bias
);
7309 t0
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t0
, bias
);
7312 tree innerc
= omp_find_clause (gimple_omp_task_clauses (inner_stmt
),
7313 OMP_CLAUSE__LOOPTEMP_
);
7314 gcc_assert (innerc
);
7315 tree startvar
= OMP_CLAUSE_DECL (innerc
);
7316 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
), OMP_CLAUSE__LOOPTEMP_
);
7317 gcc_assert (innerc
);
7318 tree endvar
= OMP_CLAUSE_DECL (innerc
);
7319 if (fd
->collapse
> 1 && TREE_CODE (fd
->loop
.n2
) != INTEGER_CST
)
7321 innerc
= find_lastprivate_looptemp (fd
, innerc
);
7324 /* If needed (inner taskloop has lastprivate clause), propagate
7325 down the total number of iterations. */
7326 tree t
= force_gimple_operand_gsi (&gsi
, fd
->loop
.n2
, false,
7328 GSI_CONTINUE_LINKING
);
7329 assign_stmt
= gimple_build_assign (OMP_CLAUSE_DECL (innerc
), t
);
7330 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
7334 t0
= force_gimple_operand_gsi (&gsi
, t0
, false, NULL_TREE
, false,
7335 GSI_CONTINUE_LINKING
);
7336 assign_stmt
= gimple_build_assign (startvar
, t0
);
7337 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
7339 t1
= force_gimple_operand_gsi (&gsi
, t1
, false, NULL_TREE
, false,
7340 GSI_CONTINUE_LINKING
);
7341 assign_stmt
= gimple_build_assign (endvar
, t1
);
7342 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
7343 if (fd
->collapse
> 1)
7344 expand_omp_for_init_vars (fd
, &gsi
, counts
, NULL
, inner_stmt
, startvar
);
7346 /* Remove the GIMPLE_OMP_FOR statement. */
7347 gsi
= gsi_for_stmt (for_stmt
);
7348 gsi_remove (&gsi
, true);
7350 gsi
= gsi_last_nondebug_bb (cont_bb
);
7351 gsi_remove (&gsi
, true);
7353 gsi
= gsi_last_nondebug_bb (exit_bb
);
7354 gsi_remove (&gsi
, true);
7356 FALLTHRU_EDGE (entry_bb
)->probability
= profile_probability::always ();
7357 remove_edge (BRANCH_EDGE (entry_bb
));
7358 FALLTHRU_EDGE (cont_bb
)->probability
= profile_probability::always ();
7359 remove_edge (BRANCH_EDGE (cont_bb
));
7360 set_immediate_dominator (CDI_DOMINATORS
, exit_bb
, cont_bb
);
7361 set_immediate_dominator (CDI_DOMINATORS
, region
->entry
,
7362 recompute_dominator (CDI_DOMINATORS
, region
->entry
));
7365 /* Taskloop construct is represented after gimplification with
7366 two GIMPLE_OMP_FOR constructs with GIMPLE_OMP_TASK sandwiched
7367 in between them. This routine expands the inner GIMPLE_OMP_FOR.
7368 GOMP_taskloop{,_ull} function arranges for each task to be given just
7369 a single range of iterations. */
7372 expand_omp_taskloop_for_inner (struct omp_region
*region
,
7373 struct omp_for_data
*fd
,
7376 tree e
, t
, type
, itype
, vmain
, vback
, bias
= NULL_TREE
;
7377 basic_block entry_bb
, exit_bb
, body_bb
, cont_bb
, collapse_bb
= NULL
;
7379 gimple_stmt_iterator gsi
;
7381 bool broken_loop
= region
->cont
== NULL
;
7382 tree
*counts
= NULL
;
7385 itype
= type
= TREE_TYPE (fd
->loop
.v
);
7386 if (POINTER_TYPE_P (type
))
7387 itype
= signed_type_for (type
);
7389 /* See if we need to bias by LLONG_MIN. */
7390 if (fd
->iter_type
== long_long_unsigned_type_node
7391 && (TREE_CODE (type
) == INTEGER_TYPE
|| TREE_CODE (type
) == BITINT_TYPE
)
7392 && !TYPE_UNSIGNED (type
))
7396 if (fd
->loop
.cond_code
== LT_EXPR
)
7399 n2
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
7403 n1
= fold_build2 (MINUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
7406 if (TREE_CODE (n1
) != INTEGER_CST
7407 || TREE_CODE (n2
) != INTEGER_CST
7408 || ((tree_int_cst_sgn (n1
) < 0) ^ (tree_int_cst_sgn (n2
) < 0)))
7409 bias
= fold_convert (fd
->iter_type
, TYPE_MIN_VALUE (type
));
7412 entry_bb
= region
->entry
;
7413 cont_bb
= region
->cont
;
7414 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
7415 fin_bb
= BRANCH_EDGE (entry_bb
)->dest
;
7416 gcc_assert (broken_loop
7417 || (fin_bb
== FALLTHRU_EDGE (cont_bb
)->dest
));
7418 body_bb
= FALLTHRU_EDGE (entry_bb
)->dest
;
7421 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
7422 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
7424 exit_bb
= region
->exit
;
7426 /* Iteration space partitioning goes in ENTRY_BB. */
7427 gsi
= gsi_last_nondebug_bb (entry_bb
);
7428 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
7430 if (fd
->collapse
> 1)
7432 int first_zero_iter
= -1, dummy
= -1;
7433 basic_block l2_dom_bb
= NULL
, dummy_bb
= NULL
;
7435 counts
= XALLOCAVEC (tree
, fd
->collapse
);
7436 expand_omp_for_init_counts (fd
, &gsi
, entry_bb
, counts
,
7437 fin_bb
, first_zero_iter
,
7438 dummy_bb
, dummy
, l2_dom_bb
);
7442 t
= integer_one_node
;
7444 step
= fd
->loop
.step
;
7445 tree innerc
= omp_find_clause (gimple_omp_for_clauses (fd
->for_stmt
),
7446 OMP_CLAUSE__LOOPTEMP_
);
7447 gcc_assert (innerc
);
7448 n1
= OMP_CLAUSE_DECL (innerc
);
7449 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
), OMP_CLAUSE__LOOPTEMP_
);
7450 gcc_assert (innerc
);
7451 n2
= OMP_CLAUSE_DECL (innerc
);
7454 n1
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, n1
, bias
);
7455 n2
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, n2
, bias
);
7457 n1
= force_gimple_operand_gsi (&gsi
, fold_convert (type
, n1
),
7458 true, NULL_TREE
, true, GSI_SAME_STMT
);
7459 n2
= force_gimple_operand_gsi (&gsi
, fold_convert (itype
, n2
),
7460 true, NULL_TREE
, true, GSI_SAME_STMT
);
7461 step
= force_gimple_operand_gsi (&gsi
, fold_convert (itype
, step
),
7462 true, NULL_TREE
, true, GSI_SAME_STMT
);
7464 tree startvar
= fd
->loop
.v
;
7465 tree endvar
= NULL_TREE
;
7467 if (gimple_omp_for_combined_p (fd
->for_stmt
))
7469 tree clauses
= gimple_omp_for_clauses (inner_stmt
);
7470 tree innerc
= omp_find_clause (clauses
, OMP_CLAUSE__LOOPTEMP_
);
7471 gcc_assert (innerc
);
7472 startvar
= OMP_CLAUSE_DECL (innerc
);
7473 innerc
= omp_find_clause (OMP_CLAUSE_CHAIN (innerc
),
7474 OMP_CLAUSE__LOOPTEMP_
);
7475 gcc_assert (innerc
);
7476 endvar
= OMP_CLAUSE_DECL (innerc
);
7478 t
= fold_convert (TREE_TYPE (startvar
), n1
);
7479 t
= force_gimple_operand_gsi (&gsi
, t
,
7481 && TREE_ADDRESSABLE (startvar
),
7482 NULL_TREE
, false, GSI_CONTINUE_LINKING
);
7483 gimple
*assign_stmt
= gimple_build_assign (startvar
, t
);
7484 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
7486 t
= fold_convert (TREE_TYPE (startvar
), n2
);
7487 e
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
7488 false, GSI_CONTINUE_LINKING
);
7491 assign_stmt
= gimple_build_assign (endvar
, e
);
7492 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
7493 if (useless_type_conversion_p (TREE_TYPE (fd
->loop
.v
), TREE_TYPE (e
)))
7494 assign_stmt
= gimple_build_assign (fd
->loop
.v
, e
);
7496 assign_stmt
= gimple_build_assign (fd
->loop
.v
, NOP_EXPR
, e
);
7497 gsi_insert_after (&gsi
, assign_stmt
, GSI_CONTINUE_LINKING
);
7500 tree
*nonrect_bounds
= NULL
;
7501 if (fd
->collapse
> 1)
7505 nonrect_bounds
= XALLOCAVEC (tree
, fd
->last_nonrect
+ 1);
7506 memset (nonrect_bounds
, 0, sizeof (tree
) * (fd
->last_nonrect
+ 1));
7508 gcc_assert (gsi_bb (gsi
) == entry_bb
);
7509 expand_omp_for_init_vars (fd
, &gsi
, counts
, nonrect_bounds
, inner_stmt
,
7511 entry_bb
= gsi_bb (gsi
);
7516 /* The code controlling the sequential loop replaces the
7517 GIMPLE_OMP_CONTINUE. */
7518 gsi
= gsi_last_nondebug_bb (cont_bb
);
7519 gomp_continue
*cont_stmt
= as_a
<gomp_continue
*> (gsi_stmt (gsi
));
7520 gcc_assert (gimple_code (cont_stmt
) == GIMPLE_OMP_CONTINUE
);
7521 vmain
= gimple_omp_continue_control_use (cont_stmt
);
7522 vback
= gimple_omp_continue_control_def (cont_stmt
);
7524 if (!gimple_omp_for_combined_p (fd
->for_stmt
))
7526 if (POINTER_TYPE_P (type
))
7527 t
= fold_build_pointer_plus (vmain
, step
);
7529 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, step
);
7530 t
= force_gimple_operand_gsi (&gsi
, t
,
7532 && TREE_ADDRESSABLE (vback
),
7533 NULL_TREE
, true, GSI_SAME_STMT
);
7534 assign_stmt
= gimple_build_assign (vback
, t
);
7535 gsi_insert_before (&gsi
, assign_stmt
, GSI_SAME_STMT
);
7537 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
,
7538 DECL_P (vback
) && TREE_ADDRESSABLE (vback
)
7540 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
7543 /* Remove the GIMPLE_OMP_CONTINUE statement. */
7544 gsi_remove (&gsi
, true);
7546 if (fd
->collapse
> 1 && !gimple_omp_for_combined_p (fd
->for_stmt
))
7547 collapse_bb
= extract_omp_for_update_vars (fd
, nonrect_bounds
,
7551 /* Remove the GIMPLE_OMP_FOR statement. */
7552 gsi
= gsi_for_stmt (fd
->for_stmt
);
7553 gsi_remove (&gsi
, true);
7555 /* Remove the GIMPLE_OMP_RETURN statement. */
7556 gsi
= gsi_last_nondebug_bb (exit_bb
);
7557 gsi_remove (&gsi
, true);
7559 FALLTHRU_EDGE (entry_bb
)->probability
= profile_probability::always ();
7561 remove_edge (BRANCH_EDGE (entry_bb
));
7564 remove_edge_and_dominated_blocks (BRANCH_EDGE (entry_bb
));
7565 region
->outer
->cont
= NULL
;
7568 /* Connect all the blocks. */
7571 ep
= find_edge (cont_bb
, body_bb
);
7572 if (gimple_omp_for_combined_p (fd
->for_stmt
))
7577 else if (fd
->collapse
> 1)
7580 ep
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
7583 ep
->flags
= EDGE_TRUE_VALUE
;
7584 find_edge (cont_bb
, fin_bb
)->flags
7585 = ep
? EDGE_FALSE_VALUE
: EDGE_FALLTHRU
;
7588 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
7589 recompute_dominator (CDI_DOMINATORS
, body_bb
));
7591 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
7592 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
7594 if (!broken_loop
&& !gimple_omp_for_combined_p (fd
->for_stmt
))
7596 class loop
*loop
= alloc_loop ();
7597 loop
->header
= body_bb
;
7598 if (collapse_bb
== NULL
)
7599 loop
->latch
= cont_bb
;
7600 add_loop (loop
, body_bb
->loop_father
);
7604 /* A subroutine of expand_omp_for. Generate code for an OpenACC
7605 partitioned loop. The lowering here is abstracted, in that the
7606 loop parameters are passed through internal functions, which are
7607 further lowered by oacc_device_lower, once we get to the target
7608 compiler. The loop is of the form:
7610 for (V = B; V LTGT E; V += S) {BODY}
7612 where LTGT is < or >. We may have a specified chunking size, CHUNKING
7613 (constant 0 for no chunking) and we will have a GWV partitioning
7614 mask, specifying dimensions over which the loop is to be
7615 partitioned (see note below). We generate code that looks like
7616 (this ignores tiling):
7618 <entry_bb> [incoming FALL->body, BRANCH->exit]
7619 typedef signedintify (typeof (V)) T; // underlying signed integral type
7622 T DIR = LTGT == '<' ? +1 : -1;
7623 T chunk_max = GOACC_LOOP_CHUNK (dir, range, S, CHUNK_SIZE, GWV);
7624 T step = GOACC_LOOP_STEP (dir, range, S, CHUNK_SIZE, GWV);
7626 <head_bb> [created by splitting end of entry_bb]
7627 T offset = GOACC_LOOP_OFFSET (dir, range, S, CHUNK_SIZE, GWV, chunk_no);
7628 T bound = GOACC_LOOP_BOUND (dir, range, S, CHUNK_SIZE, GWV, offset);
7629 if (!(offset LTGT bound)) goto bottom_bb;
7631 <body_bb> [incoming]
7635 <cont_bb> [incoming, may == body_bb FALL->exit_bb, BRANCH->body_bb]
7637 if (offset LTGT bound) goto body_bb; [*]
7639 <bottom_bb> [created by splitting start of exit_bb] insert BRANCH->head_bb
7641 if (chunk < chunk_max) goto head_bb;
7643 <exit_bb> [incoming]
7644 V = B + ((range -/+ 1) / S +/- 1) * S [*]
7646 [*] Needed if V live at end of loop. */
7649 expand_oacc_for (struct omp_region
*region
, struct omp_for_data
*fd
)
7651 bool is_oacc_kernels_parallelized
7652 = (lookup_attribute ("oacc kernels parallelized",
7653 DECL_ATTRIBUTES (current_function_decl
)) != NULL
);
7655 bool is_oacc_kernels
7656 = (lookup_attribute ("oacc kernels",
7657 DECL_ATTRIBUTES (current_function_decl
)) != NULL
);
7658 if (is_oacc_kernels_parallelized
)
7659 gcc_checking_assert (is_oacc_kernels
);
7661 gcc_assert (gimple_in_ssa_p (cfun
) == is_oacc_kernels_parallelized
);
7662 /* In the following, some of the 'gimple_in_ssa_p (cfun)' conditionals are
7663 for SSA specifics, and some are for 'parloops' OpenACC
7664 'kernels'-parallelized specifics. */
7666 tree v
= fd
->loop
.v
;
7667 enum tree_code cond_code
= fd
->loop
.cond_code
;
7668 enum tree_code plus_code
= PLUS_EXPR
;
7670 tree chunk_size
= integer_minus_one_node
;
7671 tree gwv
= integer_zero_node
;
7672 tree iter_type
= TREE_TYPE (v
);
7673 tree diff_type
= iter_type
;
7674 tree plus_type
= iter_type
;
7675 struct oacc_collapse
*counts
= NULL
;
7677 gcc_checking_assert (gimple_omp_for_kind (fd
->for_stmt
)
7678 == GF_OMP_FOR_KIND_OACC_LOOP
);
7679 gcc_assert (!gimple_omp_for_combined_into_p (fd
->for_stmt
));
7680 gcc_assert (cond_code
== LT_EXPR
|| cond_code
== GT_EXPR
);
7682 if (POINTER_TYPE_P (iter_type
))
7684 plus_code
= POINTER_PLUS_EXPR
;
7685 plus_type
= sizetype
;
7687 for (int ix
= fd
->collapse
; ix
--;)
7689 tree diff_type2
= TREE_TYPE (fd
->loops
[ix
].step
);
7690 if (TYPE_PRECISION (diff_type
) < TYPE_PRECISION (diff_type2
))
7691 diff_type
= diff_type2
;
7693 if (POINTER_TYPE_P (diff_type
) || TYPE_UNSIGNED (diff_type
))
7694 diff_type
= signed_type_for (diff_type
);
7695 if (TYPE_PRECISION (diff_type
) < TYPE_PRECISION (integer_type_node
))
7696 diff_type
= integer_type_node
;
7698 basic_block entry_bb
= region
->entry
; /* BB ending in OMP_FOR */
7699 basic_block exit_bb
= region
->exit
; /* BB ending in OMP_RETURN */
7700 basic_block cont_bb
= region
->cont
; /* BB ending in OMP_CONTINUE */
7701 basic_block bottom_bb
= NULL
;
7703 /* entry_bb has two successors; the branch edge is to the exit
7704 block, fallthrough edge to body. */
7705 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2
7706 && BRANCH_EDGE (entry_bb
)->dest
== exit_bb
);
7708 /* If cont_bb non-NULL, it has 2 successors. The branch successor is
7709 body_bb, or to a block whose only successor is the body_bb. Its
7710 fallthrough successor is the final block (same as the branch
7711 successor of the entry_bb). */
7714 basic_block body_bb
= FALLTHRU_EDGE (entry_bb
)->dest
;
7715 basic_block bed
= BRANCH_EDGE (cont_bb
)->dest
;
7717 gcc_assert (FALLTHRU_EDGE (cont_bb
)->dest
== exit_bb
);
7718 gcc_assert (bed
== body_bb
|| single_succ_edge (bed
)->dest
== body_bb
);
7721 gcc_assert (!gimple_in_ssa_p (cfun
));
7723 /* The exit block only has entry_bb and cont_bb as predecessors. */
7724 gcc_assert (EDGE_COUNT (exit_bb
->preds
) == 1 + (cont_bb
!= NULL
));
7727 tree chunk_max
= NULL_TREE
;
7729 tree step
= create_tmp_var (diff_type
, ".step");
7730 bool up
= cond_code
== LT_EXPR
;
7731 tree dir
= build_int_cst (diff_type
, up
? +1 : -1);
7732 bool chunking
= !gimple_in_ssa_p (cfun
);
7736 tree tile_size
= NULL_TREE
;
7737 tree element_s
= NULL_TREE
;
7738 tree e_bound
= NULL_TREE
, e_offset
= NULL_TREE
, e_step
= NULL_TREE
;
7739 basic_block elem_body_bb
= NULL
;
7740 basic_block elem_cont_bb
= NULL
;
7742 /* SSA instances. */
7743 tree offset_incr
= NULL_TREE
;
7744 tree offset_init
= NULL_TREE
;
7746 gimple_stmt_iterator gsi
;
7752 edge split
, be
, fte
;
7754 /* Split the end of entry_bb to create head_bb. */
7755 split
= split_block (entry_bb
, last_nondebug_stmt (entry_bb
));
7756 basic_block head_bb
= split
->dest
;
7757 entry_bb
= split
->src
;
7759 /* Chunk setup goes at end of entry_bb, replacing the omp_for. */
7760 gsi
= gsi_last_nondebug_bb (entry_bb
);
7761 gomp_for
*for_stmt
= as_a
<gomp_for
*> (gsi_stmt (gsi
));
7762 loc
= gimple_location (for_stmt
);
7764 if (gimple_in_ssa_p (cfun
))
7766 offset_init
= gimple_omp_for_index (for_stmt
, 0);
7767 gcc_assert (integer_zerop (fd
->loop
.n1
));
7768 /* The SSA parallelizer does gang parallelism. */
7769 gwv
= build_int_cst (integer_type_node
, GOMP_DIM_MASK (GOMP_DIM_GANG
));
7772 if (fd
->collapse
> 1 || fd
->tiling
)
7774 gcc_assert (!gimple_in_ssa_p (cfun
) && up
);
7775 counts
= XALLOCAVEC (struct oacc_collapse
, fd
->collapse
);
7776 tree total
= expand_oacc_collapse_init (fd
, &gsi
, counts
, diff_type
,
7777 TREE_TYPE (fd
->loop
.n2
), loc
);
7779 if (SSA_VAR_P (fd
->loop
.n2
))
7781 total
= force_gimple_operand_gsi (&gsi
, total
, false, NULL_TREE
,
7782 true, GSI_SAME_STMT
);
7783 ass
= gimple_build_assign (fd
->loop
.n2
, total
);
7784 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
7788 tree b
= fd
->loop
.n1
;
7789 tree e
= fd
->loop
.n2
;
7790 tree s
= fd
->loop
.step
;
7792 b
= force_gimple_operand_gsi (&gsi
, b
, true, NULL_TREE
, true, GSI_SAME_STMT
);
7793 e
= force_gimple_operand_gsi (&gsi
, e
, true, NULL_TREE
, true, GSI_SAME_STMT
);
7795 /* Convert the step, avoiding possible unsigned->signed overflow. */
7796 negating
= !up
&& TYPE_UNSIGNED (TREE_TYPE (s
));
7798 s
= fold_build1 (NEGATE_EXPR
, TREE_TYPE (s
), s
);
7799 s
= fold_convert (diff_type
, s
);
7801 s
= fold_build1 (NEGATE_EXPR
, diff_type
, s
);
7802 s
= force_gimple_operand_gsi (&gsi
, s
, true, NULL_TREE
, true, GSI_SAME_STMT
);
7805 chunk_size
= integer_zero_node
;
7806 expr
= fold_convert (diff_type
, chunk_size
);
7807 chunk_size
= force_gimple_operand_gsi (&gsi
, expr
, true,
7808 NULL_TREE
, true, GSI_SAME_STMT
);
7812 /* Determine the tile size and element step,
7813 modify the outer loop step size. */
7814 tile_size
= create_tmp_var (diff_type
, ".tile_size");
7815 expr
= build_int_cst (diff_type
, 1);
7816 for (int ix
= 0; ix
< fd
->collapse
; ix
++)
7817 expr
= fold_build2 (MULT_EXPR
, diff_type
, counts
[ix
].tile
, expr
);
7818 expr
= force_gimple_operand_gsi (&gsi
, expr
, true,
7819 NULL_TREE
, true, GSI_SAME_STMT
);
7820 ass
= gimple_build_assign (tile_size
, expr
);
7821 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
7823 element_s
= create_tmp_var (diff_type
, ".element_s");
7824 ass
= gimple_build_assign (element_s
, s
);
7825 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
7827 expr
= fold_build2 (MULT_EXPR
, diff_type
, s
, tile_size
);
7828 s
= force_gimple_operand_gsi (&gsi
, expr
, true,
7829 NULL_TREE
, true, GSI_SAME_STMT
);
7832 /* Determine the range, avoiding possible unsigned->signed overflow. */
7833 negating
= !up
&& TYPE_UNSIGNED (iter_type
);
7834 expr
= fold_build2 (MINUS_EXPR
, plus_type
,
7835 fold_convert (plus_type
, negating
? b
: e
),
7836 fold_convert (plus_type
, negating
? e
: b
));
7837 expr
= fold_convert (diff_type
, expr
);
7839 expr
= fold_build1 (NEGATE_EXPR
, diff_type
, expr
);
7840 tree range
= force_gimple_operand_gsi (&gsi
, expr
, true,
7841 NULL_TREE
, true, GSI_SAME_STMT
);
7843 chunk_no
= build_int_cst (diff_type
, 0);
7846 gcc_assert (!gimple_in_ssa_p (cfun
));
7849 chunk_max
= create_tmp_var (diff_type
, ".chunk_max");
7850 chunk_no
= create_tmp_var (diff_type
, ".chunk_no");
7852 ass
= gimple_build_assign (chunk_no
, expr
);
7853 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
7855 call
= gimple_build_call_internal (IFN_GOACC_LOOP
, 6,
7856 build_int_cst (integer_type_node
,
7857 IFN_GOACC_LOOP_CHUNKS
),
7858 dir
, range
, s
, chunk_size
, gwv
);
7859 gimple_call_set_lhs (call
, chunk_max
);
7860 gimple_set_location (call
, loc
);
7861 gsi_insert_before (&gsi
, call
, GSI_SAME_STMT
);
7864 chunk_size
= chunk_no
;
7866 call
= gimple_build_call_internal (IFN_GOACC_LOOP
, 6,
7867 build_int_cst (integer_type_node
,
7868 IFN_GOACC_LOOP_STEP
),
7869 dir
, range
, s
, chunk_size
, gwv
);
7870 gimple_call_set_lhs (call
, step
);
7871 gimple_set_location (call
, loc
);
7872 gsi_insert_before (&gsi
, call
, GSI_SAME_STMT
);
7874 /* Remove the GIMPLE_OMP_FOR. */
7875 gsi_remove (&gsi
, true);
7877 /* Fixup edges from head_bb. */
7878 be
= BRANCH_EDGE (head_bb
);
7879 fte
= FALLTHRU_EDGE (head_bb
);
7880 be
->flags
|= EDGE_FALSE_VALUE
;
7881 fte
->flags
^= EDGE_FALLTHRU
| EDGE_TRUE_VALUE
;
7883 basic_block body_bb
= fte
->dest
;
7885 if (gimple_in_ssa_p (cfun
))
7887 gsi
= gsi_last_nondebug_bb (cont_bb
);
7888 gomp_continue
*cont_stmt
= as_a
<gomp_continue
*> (gsi_stmt (gsi
));
7890 offset
= gimple_omp_continue_control_use (cont_stmt
);
7891 offset_incr
= gimple_omp_continue_control_def (cont_stmt
);
7895 offset
= create_tmp_var (diff_type
, ".offset");
7896 offset_init
= offset_incr
= offset
;
7898 bound
= create_tmp_var (TREE_TYPE (offset
), ".bound");
7900 /* Loop offset & bound go into head_bb. */
7901 gsi
= gsi_start_bb (head_bb
);
7903 call
= gimple_build_call_internal (IFN_GOACC_LOOP
, 7,
7904 build_int_cst (integer_type_node
,
7905 IFN_GOACC_LOOP_OFFSET
),
7907 chunk_size
, gwv
, chunk_no
);
7908 gimple_call_set_lhs (call
, offset_init
);
7909 gimple_set_location (call
, loc
);
7910 gsi_insert_after (&gsi
, call
, GSI_CONTINUE_LINKING
);
7912 call
= gimple_build_call_internal (IFN_GOACC_LOOP
, 7,
7913 build_int_cst (integer_type_node
,
7914 IFN_GOACC_LOOP_BOUND
),
7916 chunk_size
, gwv
, offset_init
);
7917 gimple_call_set_lhs (call
, bound
);
7918 gimple_set_location (call
, loc
);
7919 gsi_insert_after (&gsi
, call
, GSI_CONTINUE_LINKING
);
7921 expr
= build2 (cond_code
, boolean_type_node
, offset_init
, bound
);
7922 gsi_insert_after (&gsi
, gimple_build_cond_empty (expr
),
7923 GSI_CONTINUE_LINKING
);
7925 /* V assignment goes into body_bb. */
7926 if (!gimple_in_ssa_p (cfun
))
7928 gsi
= gsi_start_bb (body_bb
);
7930 expr
= build2 (plus_code
, iter_type
, b
,
7931 fold_convert (plus_type
, offset
));
7932 expr
= force_gimple_operand_gsi (&gsi
, expr
, false, NULL_TREE
,
7933 true, GSI_SAME_STMT
);
7934 ass
= gimple_build_assign (v
, expr
);
7935 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
7937 if (fd
->collapse
> 1 || fd
->tiling
)
7938 expand_oacc_collapse_vars (fd
, false, &gsi
, counts
, v
, diff_type
);
7942 /* Determine the range of the element loop -- usually simply
7943 the tile_size, but could be smaller if the final
7944 iteration of the outer loop is a partial tile. */
7945 tree e_range
= create_tmp_var (diff_type
, ".e_range");
7947 expr
= build2 (MIN_EXPR
, diff_type
,
7948 build2 (MINUS_EXPR
, diff_type
, bound
, offset
),
7949 build2 (MULT_EXPR
, diff_type
, tile_size
,
7951 expr
= force_gimple_operand_gsi (&gsi
, expr
, false, NULL_TREE
,
7952 true, GSI_SAME_STMT
);
7953 ass
= gimple_build_assign (e_range
, expr
);
7954 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
7956 /* Determine bound, offset & step of inner loop. */
7957 e_bound
= create_tmp_var (diff_type
, ".e_bound");
7958 e_offset
= create_tmp_var (diff_type
, ".e_offset");
7959 e_step
= create_tmp_var (diff_type
, ".e_step");
7961 /* Mark these as element loops. */
7962 tree t
, e_gwv
= integer_minus_one_node
;
7963 tree chunk
= build_int_cst (diff_type
, 0); /* Never chunked. */
7965 t
= build_int_cst (integer_type_node
, IFN_GOACC_LOOP_OFFSET
);
7966 call
= gimple_build_call_internal (IFN_GOACC_LOOP
, 7, t
, dir
, e_range
,
7967 element_s
, chunk
, e_gwv
, chunk
);
7968 gimple_call_set_lhs (call
, e_offset
);
7969 gimple_set_location (call
, loc
);
7970 gsi_insert_before (&gsi
, call
, GSI_SAME_STMT
);
7972 t
= build_int_cst (integer_type_node
, IFN_GOACC_LOOP_BOUND
);
7973 call
= gimple_build_call_internal (IFN_GOACC_LOOP
, 7, t
, dir
, e_range
,
7974 element_s
, chunk
, e_gwv
, e_offset
);
7975 gimple_call_set_lhs (call
, e_bound
);
7976 gimple_set_location (call
, loc
);
7977 gsi_insert_before (&gsi
, call
, GSI_SAME_STMT
);
7979 t
= build_int_cst (integer_type_node
, IFN_GOACC_LOOP_STEP
);
7980 call
= gimple_build_call_internal (IFN_GOACC_LOOP
, 6, t
, dir
, e_range
,
7981 element_s
, chunk
, e_gwv
);
7982 gimple_call_set_lhs (call
, e_step
);
7983 gimple_set_location (call
, loc
);
7984 gsi_insert_before (&gsi
, call
, GSI_SAME_STMT
);
7986 /* Add test and split block. */
7987 expr
= build2 (cond_code
, boolean_type_node
, e_offset
, e_bound
);
7988 stmt
= gimple_build_cond_empty (expr
);
7989 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
7990 split
= split_block (body_bb
, stmt
);
7991 elem_body_bb
= split
->dest
;
7992 if (cont_bb
== body_bb
)
7993 cont_bb
= elem_body_bb
;
7994 body_bb
= split
->src
;
7996 split
->flags
^= EDGE_FALLTHRU
| EDGE_TRUE_VALUE
;
7998 /* Add a dummy exit for the tiled block when cont_bb is missing. */
7999 if (cont_bb
== NULL
)
8001 edge e
= make_edge (body_bb
, exit_bb
, EDGE_FALSE_VALUE
);
8002 e
->probability
= profile_probability::even ();
8003 split
->probability
= profile_probability::even ();
8006 /* Initialize the user's loop vars. */
8007 gsi
= gsi_start_bb (elem_body_bb
);
8008 expand_oacc_collapse_vars (fd
, true, &gsi
, counts
, e_offset
,
8013 /* Loop increment goes into cont_bb. If this is not a loop, we
8014 will have spawned threads as if it was, and each one will
8015 execute one iteration. The specification is not explicit about
8016 whether such constructs are ill-formed or not, and they can
8017 occur, especially when noreturn routines are involved. */
8020 gsi
= gsi_last_nondebug_bb (cont_bb
);
8021 gomp_continue
*cont_stmt
= as_a
<gomp_continue
*> (gsi_stmt (gsi
));
8022 loc
= gimple_location (cont_stmt
);
8026 /* Insert element loop increment and test. */
8027 expr
= build2 (PLUS_EXPR
, diff_type
, e_offset
, e_step
);
8028 expr
= force_gimple_operand_gsi (&gsi
, expr
, false, NULL_TREE
,
8029 true, GSI_SAME_STMT
);
8030 ass
= gimple_build_assign (e_offset
, expr
);
8031 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
8032 expr
= build2 (cond_code
, boolean_type_node
, e_offset
, e_bound
);
8034 stmt
= gimple_build_cond_empty (expr
);
8035 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
8036 split
= split_block (cont_bb
, stmt
);
8037 elem_cont_bb
= split
->src
;
8038 cont_bb
= split
->dest
;
8040 split
->flags
^= EDGE_FALLTHRU
| EDGE_FALSE_VALUE
;
8041 split
->probability
= profile_probability::unlikely ().guessed ();
8043 = make_edge (elem_cont_bb
, elem_body_bb
, EDGE_TRUE_VALUE
);
8044 latch_edge
->probability
= profile_probability::likely ().guessed ();
8046 edge skip_edge
= make_edge (body_bb
, cont_bb
, EDGE_FALSE_VALUE
);
8047 skip_edge
->probability
= profile_probability::unlikely ().guessed ();
8048 edge loop_entry_edge
= EDGE_SUCC (body_bb
, 1 - skip_edge
->dest_idx
);
8049 loop_entry_edge
->probability
8050 = profile_probability::likely ().guessed ();
8052 gsi
= gsi_for_stmt (cont_stmt
);
8055 /* Increment offset. */
8056 if (gimple_in_ssa_p (cfun
))
8057 expr
= build2 (plus_code
, iter_type
, offset
,
8058 fold_convert (plus_type
, step
));
8060 expr
= build2 (PLUS_EXPR
, diff_type
, offset
, step
);
8061 expr
= force_gimple_operand_gsi (&gsi
, expr
, false, NULL_TREE
,
8062 true, GSI_SAME_STMT
);
8063 ass
= gimple_build_assign (offset_incr
, expr
);
8064 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
8065 expr
= build2 (cond_code
, boolean_type_node
, offset_incr
, bound
);
8066 gsi_insert_before (&gsi
, gimple_build_cond_empty (expr
), GSI_SAME_STMT
);
8068 /* Remove the GIMPLE_OMP_CONTINUE. */
8069 gsi_remove (&gsi
, true);
8071 /* Fixup edges from cont_bb. */
8072 be
= BRANCH_EDGE (cont_bb
);
8073 fte
= FALLTHRU_EDGE (cont_bb
);
8074 be
->flags
|= EDGE_TRUE_VALUE
;
8075 fte
->flags
^= EDGE_FALLTHRU
| EDGE_FALSE_VALUE
;
8079 /* Split the beginning of exit_bb to make bottom_bb. We
8080 need to insert a nop at the start, because splitting is
8081 after a stmt, not before. */
8082 gsi
= gsi_start_bb (exit_bb
);
8083 stmt
= gimple_build_nop ();
8084 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
8085 split
= split_block (exit_bb
, stmt
);
8086 bottom_bb
= split
->src
;
8087 exit_bb
= split
->dest
;
8088 gsi
= gsi_last_bb (bottom_bb
);
8090 /* Chunk increment and test goes into bottom_bb. */
8091 expr
= build2 (PLUS_EXPR
, diff_type
, chunk_no
,
8092 build_int_cst (diff_type
, 1));
8093 ass
= gimple_build_assign (chunk_no
, expr
);
8094 gsi_insert_after (&gsi
, ass
, GSI_CONTINUE_LINKING
);
8096 /* Chunk test at end of bottom_bb. */
8097 expr
= build2 (LT_EXPR
, boolean_type_node
, chunk_no
, chunk_max
);
8098 gsi_insert_after (&gsi
, gimple_build_cond_empty (expr
),
8099 GSI_CONTINUE_LINKING
);
8101 /* Fixup edges from bottom_bb. */
8102 split
->flags
^= EDGE_FALLTHRU
| EDGE_FALSE_VALUE
;
8103 split
->probability
= profile_probability::unlikely ().guessed ();
8104 edge latch_edge
= make_edge (bottom_bb
, head_bb
, EDGE_TRUE_VALUE
);
8105 latch_edge
->probability
= profile_probability::likely ().guessed ();
8109 gsi
= gsi_last_nondebug_bb (exit_bb
);
8110 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
8111 loc
= gimple_location (gsi_stmt (gsi
));
8113 if (!gimple_in_ssa_p (cfun
))
8115 /* Insert the final value of V, in case it is live. This is the
8116 value for the only thread that survives past the join. */
8117 expr
= fold_build2 (MINUS_EXPR
, diff_type
, range
, dir
);
8118 expr
= fold_build2 (PLUS_EXPR
, diff_type
, expr
, s
);
8119 expr
= fold_build2 (TRUNC_DIV_EXPR
, diff_type
, expr
, s
);
8120 expr
= fold_build2 (MULT_EXPR
, diff_type
, expr
, s
);
8121 expr
= build2 (plus_code
, iter_type
, b
, fold_convert (plus_type
, expr
));
8122 expr
= force_gimple_operand_gsi (&gsi
, expr
, false, NULL_TREE
,
8123 true, GSI_SAME_STMT
);
8124 ass
= gimple_build_assign (v
, expr
);
8125 gsi_insert_before (&gsi
, ass
, GSI_SAME_STMT
);
8128 /* Remove the OMP_RETURN. */
8129 gsi_remove (&gsi
, true);
8133 /* We now have one, two or three nested loops. Update the loop
8135 class loop
*parent
= entry_bb
->loop_father
;
8136 class loop
*body
= body_bb
->loop_father
;
8140 class loop
*chunk_loop
= alloc_loop ();
8141 chunk_loop
->header
= head_bb
;
8142 chunk_loop
->latch
= bottom_bb
;
8143 add_loop (chunk_loop
, parent
);
8144 parent
= chunk_loop
;
8146 else if (parent
!= body
)
8148 gcc_assert (body
->header
== body_bb
);
8149 gcc_assert (body
->latch
== cont_bb
8150 || single_pred (body
->latch
) == cont_bb
);
8156 class loop
*body_loop
= alloc_loop ();
8157 body_loop
->header
= body_bb
;
8158 body_loop
->latch
= cont_bb
;
8159 add_loop (body_loop
, parent
);
8163 /* Insert tiling's element loop. */
8164 class loop
*inner_loop
= alloc_loop ();
8165 inner_loop
->header
= elem_body_bb
;
8166 inner_loop
->latch
= elem_cont_bb
;
8167 add_loop (inner_loop
, body_loop
);
8173 /* Expand the OMP loop defined by REGION. */
8176 expand_omp_for (struct omp_region
*region
, gimple
*inner_stmt
)
8178 struct omp_for_data fd
;
8179 struct omp_for_data_loop
*loops
;
8181 loops
= XALLOCAVEC (struct omp_for_data_loop
,
8182 gimple_omp_for_collapse
8183 (last_nondebug_stmt (region
->entry
)));
8184 omp_extract_for_data (as_a
<gomp_for
*> (last_nondebug_stmt (region
->entry
)),
8186 region
->sched_kind
= fd
.sched_kind
;
8187 region
->sched_modifiers
= fd
.sched_modifiers
;
8188 region
->has_lastprivate_conditional
= fd
.lastprivate_conditional
!= 0;
8189 if (fd
.non_rect
&& !gimple_omp_for_combined_into_p (fd
.for_stmt
))
8191 for (int i
= fd
.first_nonrect
; i
<= fd
.last_nonrect
; i
++)
8192 if ((loops
[i
].m1
|| loops
[i
].m2
)
8193 && (loops
[i
].m1
== NULL_TREE
8194 || TREE_CODE (loops
[i
].m1
) == INTEGER_CST
)
8195 && (loops
[i
].m2
== NULL_TREE
8196 || TREE_CODE (loops
[i
].m2
) == INTEGER_CST
)
8197 && TREE_CODE (loops
[i
].step
) == INTEGER_CST
8198 && TREE_CODE (loops
[i
- loops
[i
].outer
].step
) == INTEGER_CST
)
8201 tree itype
= TREE_TYPE (loops
[i
].v
);
8202 if (loops
[i
].m1
&& loops
[i
].m2
)
8203 t
= fold_build2 (MINUS_EXPR
, itype
, loops
[i
].m2
, loops
[i
].m1
);
8204 else if (loops
[i
].m1
)
8205 t
= fold_build1 (NEGATE_EXPR
, itype
, loops
[i
].m1
);
8208 t
= fold_build2 (MULT_EXPR
, itype
, t
,
8209 fold_convert (itype
,
8210 loops
[i
- loops
[i
].outer
].step
));
8211 if (TYPE_UNSIGNED (itype
) && loops
[i
].cond_code
== GT_EXPR
)
8212 t
= fold_build2 (TRUNC_MOD_EXPR
, itype
,
8213 fold_build1 (NEGATE_EXPR
, itype
, t
),
8214 fold_build1 (NEGATE_EXPR
, itype
,
8215 fold_convert (itype
,
8218 t
= fold_build2 (TRUNC_MOD_EXPR
, itype
, t
,
8219 fold_convert (itype
, loops
[i
].step
));
8220 if (integer_nonzerop (t
))
8221 error_at (gimple_location (fd
.for_stmt
),
8222 "invalid OpenMP non-rectangular loop step; "
8223 "%<(%E - %E) * %E%> is not a multiple of loop %d "
8225 loops
[i
].m2
? loops
[i
].m2
: integer_zero_node
,
8226 loops
[i
].m1
? loops
[i
].m1
: integer_zero_node
,
8227 loops
[i
- loops
[i
].outer
].step
, i
+ 1,
8232 gcc_assert (EDGE_COUNT (region
->entry
->succs
) == 2);
8233 BRANCH_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
8234 FALLTHRU_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
8237 gcc_assert (EDGE_COUNT (region
->cont
->succs
) == 2);
8238 BRANCH_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
8239 FALLTHRU_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
8242 /* If there isn't a continue then this is a degerate case where
8243 the introduction of abnormal edges during lowering will prevent
8244 original loops from being detected. Fix that up. */
8245 loops_state_set (LOOPS_NEED_FIXUP
);
8247 if (gimple_omp_for_kind (fd
.for_stmt
) == GF_OMP_FOR_KIND_SIMD
)
8248 expand_omp_simd (region
, &fd
);
8249 else if (gimple_omp_for_kind (fd
.for_stmt
) == GF_OMP_FOR_KIND_OACC_LOOP
)
8251 gcc_assert (!inner_stmt
&& !fd
.non_rect
);
8252 expand_oacc_for (region
, &fd
);
8254 else if (gimple_omp_for_kind (fd
.for_stmt
) == GF_OMP_FOR_KIND_TASKLOOP
)
8256 if (gimple_omp_for_combined_into_p (fd
.for_stmt
))
8257 expand_omp_taskloop_for_inner (region
, &fd
, inner_stmt
);
8259 expand_omp_taskloop_for_outer (region
, &fd
, inner_stmt
);
8261 else if (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
8262 && !fd
.have_ordered
)
8264 if (fd
.chunk_size
== NULL
)
8265 expand_omp_for_static_nochunk (region
, &fd
, inner_stmt
);
8267 expand_omp_for_static_chunk (region
, &fd
, inner_stmt
);
8271 int fn_index
, start_ix
, next_ix
;
8272 unsigned HOST_WIDE_INT sched
= 0;
8273 tree sched_arg
= NULL_TREE
;
8275 gcc_assert (gimple_omp_for_kind (fd
.for_stmt
)
8276 == GF_OMP_FOR_KIND_FOR
&& !fd
.non_rect
);
8277 if (fd
.chunk_size
== NULL
8278 && fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
8279 fd
.chunk_size
= integer_zero_node
;
8280 switch (fd
.sched_kind
)
8282 case OMP_CLAUSE_SCHEDULE_RUNTIME
:
8283 if ((fd
.sched_modifiers
& OMP_CLAUSE_SCHEDULE_NONMONOTONIC
) != 0
8284 && fd
.lastprivate_conditional
== 0)
8286 gcc_assert (!fd
.have_ordered
);
8290 else if ((fd
.sched_modifiers
& OMP_CLAUSE_SCHEDULE_MONOTONIC
) == 0
8292 && fd
.lastprivate_conditional
== 0)
8297 sched
= (HOST_WIDE_INT_1U
<< 31);
8300 case OMP_CLAUSE_SCHEDULE_DYNAMIC
:
8301 case OMP_CLAUSE_SCHEDULE_GUIDED
:
8302 if ((fd
.sched_modifiers
& OMP_CLAUSE_SCHEDULE_MONOTONIC
) == 0
8304 && fd
.lastprivate_conditional
== 0)
8306 fn_index
= 3 + fd
.sched_kind
;
8307 sched
= (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_GUIDED
) + 2;
8310 fn_index
= fd
.sched_kind
;
8311 sched
= (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_GUIDED
) + 2;
8312 sched
+= (HOST_WIDE_INT_1U
<< 31);
8314 case OMP_CLAUSE_SCHEDULE_STATIC
:
8315 gcc_assert (fd
.have_ordered
);
8317 sched
= (HOST_WIDE_INT_1U
<< 31) + 1;
8323 fn_index
+= fd
.have_ordered
* 8;
8325 start_ix
= ((int)BUILT_IN_GOMP_LOOP_DOACROSS_STATIC_START
) + fn_index
;
8327 start_ix
= ((int)BUILT_IN_GOMP_LOOP_STATIC_START
) + fn_index
;
8328 next_ix
= ((int)BUILT_IN_GOMP_LOOP_STATIC_NEXT
) + fn_index
;
8329 if (fd
.have_reductemp
|| fd
.have_pointer_condtemp
)
8332 start_ix
= (int)BUILT_IN_GOMP_LOOP_DOACROSS_START
;
8333 else if (fd
.have_ordered
)
8334 start_ix
= (int)BUILT_IN_GOMP_LOOP_ORDERED_START
;
8336 start_ix
= (int)BUILT_IN_GOMP_LOOP_START
;
8337 sched_arg
= build_int_cstu (long_integer_type_node
, sched
);
8339 fd
.chunk_size
= integer_zero_node
;
8341 if (fd
.iter_type
== long_long_unsigned_type_node
)
8343 start_ix
+= ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_START
8344 - (int)BUILT_IN_GOMP_LOOP_STATIC_START
);
8345 next_ix
+= ((int)BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
8346 - (int)BUILT_IN_GOMP_LOOP_STATIC_NEXT
);
8348 expand_omp_for_generic (region
, &fd
, (enum built_in_function
) start_ix
,
8349 (enum built_in_function
) next_ix
, sched_arg
,
8354 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
8356 v = GOMP_sections_start (n);
8373 v = GOMP_sections_next ();
8378 If this is a combined parallel sections, replace the call to
8379 GOMP_sections_start with call to GOMP_sections_next. */
8382 expand_omp_sections (struct omp_region
*region
)
8384 tree t
, u
, vin
= NULL
, vmain
, vnext
, l2
;
8386 basic_block entry_bb
, l0_bb
, l1_bb
, l2_bb
, default_bb
;
8387 gimple_stmt_iterator si
, switch_si
;
8388 gomp_sections
*sections_stmt
;
8390 gomp_continue
*cont
;
8393 struct omp_region
*inner
;
8395 bool exit_reachable
= region
->cont
!= NULL
;
8397 gcc_assert (region
->exit
!= NULL
);
8398 entry_bb
= region
->entry
;
8399 l0_bb
= single_succ (entry_bb
);
8400 l1_bb
= region
->cont
;
8401 l2_bb
= region
->exit
;
8402 if (single_pred_p (l2_bb
) && single_pred (l2_bb
) == l0_bb
)
8403 l2
= gimple_block_label (l2_bb
);
8406 /* This can happen if there are reductions. */
8407 len
= EDGE_COUNT (l0_bb
->succs
);
8408 gcc_assert (len
> 0);
8409 e
= EDGE_SUCC (l0_bb
, len
- 1);
8410 si
= gsi_last_nondebug_bb (e
->dest
);
8413 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
8414 l2
= gimple_block_label (e
->dest
);
8416 FOR_EACH_EDGE (e
, ei
, l0_bb
->succs
)
8418 si
= gsi_last_nondebug_bb (e
->dest
);
8420 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
8422 l2
= gimple_block_label (e
->dest
);
8428 default_bb
= create_empty_bb (l1_bb
->prev_bb
);
8430 default_bb
= create_empty_bb (l0_bb
);
8432 /* We will build a switch() with enough cases for all the
8433 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
8434 and a default case to abort if something goes wrong. */
8435 len
= EDGE_COUNT (l0_bb
->succs
);
8437 /* Use vec::quick_push on label_vec throughout, since we know the size
8439 auto_vec
<tree
> label_vec (len
);
8441 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
8442 GIMPLE_OMP_SECTIONS statement. */
8443 si
= gsi_last_nondebug_bb (entry_bb
);
8444 sections_stmt
= as_a
<gomp_sections
*> (gsi_stmt (si
));
8445 gcc_assert (gimple_code (sections_stmt
) == GIMPLE_OMP_SECTIONS
);
8446 vin
= gimple_omp_sections_control (sections_stmt
);
8447 tree clauses
= gimple_omp_sections_clauses (sections_stmt
);
8448 tree reductmp
= omp_find_clause (clauses
, OMP_CLAUSE__REDUCTEMP_
);
8449 tree condtmp
= omp_find_clause (clauses
, OMP_CLAUSE__CONDTEMP_
);
8450 tree cond_var
= NULL_TREE
;
8451 if (reductmp
|| condtmp
)
8453 tree reductions
= null_pointer_node
, mem
= null_pointer_node
;
8454 tree memv
= NULL_TREE
, condtemp
= NULL_TREE
;
8455 gimple_stmt_iterator gsi
= gsi_none ();
8459 reductions
= OMP_CLAUSE_DECL (reductmp
);
8460 gcc_assert (TREE_CODE (reductions
) == SSA_NAME
);
8461 g
= SSA_NAME_DEF_STMT (reductions
);
8462 reductions
= gimple_assign_rhs1 (g
);
8463 OMP_CLAUSE_DECL (reductmp
) = reductions
;
8464 gsi
= gsi_for_stmt (g
);
8470 condtemp
= OMP_CLAUSE_DECL (condtmp
);
8471 tree c
= omp_find_clause (OMP_CLAUSE_CHAIN (condtmp
),
8472 OMP_CLAUSE__CONDTEMP_
);
8473 cond_var
= OMP_CLAUSE_DECL (c
);
8474 tree type
= TREE_TYPE (condtemp
);
8475 memv
= create_tmp_var (type
);
8476 TREE_ADDRESSABLE (memv
) = 1;
8478 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
8479 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
8480 && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c
))
8482 unsigned HOST_WIDE_INT sz
8483 = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (type
))) * cnt
;
8484 expand_omp_build_assign (&gsi
, memv
, build_int_cst (type
, sz
),
8486 mem
= build_fold_addr_expr (memv
);
8488 t
= build_int_cst (unsigned_type_node
, len
- 1);
8489 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS2_START
);
8490 stmt
= gimple_build_call (u
, 3, t
, reductions
, mem
);
8491 gimple_call_set_lhs (stmt
, vin
);
8492 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
8495 expand_omp_build_assign (&gsi
, condtemp
, memv
, false);
8496 tree t
= build2 (PLUS_EXPR
, TREE_TYPE (cond_var
),
8497 vin
, build_one_cst (TREE_TYPE (cond_var
)));
8498 expand_omp_build_assign (&gsi
, cond_var
, t
, false);
8502 gsi_remove (&gsi
, true);
8503 release_ssa_name (gimple_assign_lhs (g
));
8506 else if (!is_combined_parallel (region
))
8508 /* If we are not inside a combined parallel+sections region,
8509 call GOMP_sections_start. */
8510 t
= build_int_cst (unsigned_type_node
, len
- 1);
8511 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_START
);
8512 stmt
= gimple_build_call (u
, 1, t
);
8516 /* Otherwise, call GOMP_sections_next. */
8517 u
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT
);
8518 stmt
= gimple_build_call (u
, 0);
8520 if (!reductmp
&& !condtmp
)
8522 gimple_call_set_lhs (stmt
, vin
);
8523 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
8525 gsi_remove (&si
, true);
8527 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
8529 switch_si
= gsi_last_nondebug_bb (l0_bb
);
8530 gcc_assert (gimple_code (gsi_stmt (switch_si
)) == GIMPLE_OMP_SECTIONS_SWITCH
);
8533 cont
= as_a
<gomp_continue
*> (last_nondebug_stmt (l1_bb
));
8534 gcc_assert (gimple_code (cont
) == GIMPLE_OMP_CONTINUE
);
8535 vmain
= gimple_omp_continue_control_use (cont
);
8536 vnext
= gimple_omp_continue_control_def (cont
);
8544 t
= build_case_label (build_int_cst (unsigned_type_node
, 0), NULL
, l2
);
8545 label_vec
.quick_push (t
);
8548 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
8549 for (inner
= region
->inner
, casei
= 1;
8551 inner
= inner
->next
, i
++, casei
++)
8553 basic_block s_entry_bb
, s_exit_bb
;
8555 /* Skip optional reduction region. */
8556 if (inner
->type
== GIMPLE_OMP_ATOMIC_LOAD
)
8563 s_entry_bb
= inner
->entry
;
8564 s_exit_bb
= inner
->exit
;
8566 t
= gimple_block_label (s_entry_bb
);
8567 u
= build_int_cst (unsigned_type_node
, casei
);
8568 u
= build_case_label (u
, NULL
, t
);
8569 label_vec
.quick_push (u
);
8571 si
= gsi_last_nondebug_bb (s_entry_bb
);
8572 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SECTION
);
8573 gcc_assert (i
< len
|| gimple_omp_section_last_p (gsi_stmt (si
)));
8574 gsi_remove (&si
, true);
8575 single_succ_edge (s_entry_bb
)->flags
= EDGE_FALLTHRU
;
8577 if (s_exit_bb
== NULL
)
8580 si
= gsi_last_nondebug_bb (s_exit_bb
);
8581 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
8582 gsi_remove (&si
, true);
8584 single_succ_edge (s_exit_bb
)->flags
= EDGE_FALLTHRU
;
8587 /* Error handling code goes in DEFAULT_BB. */
8588 t
= gimple_block_label (default_bb
);
8589 u
= build_case_label (NULL
, NULL
, t
);
8590 make_edge (l0_bb
, default_bb
, 0);
8591 add_bb_to_loop (default_bb
, current_loops
->tree_root
);
8593 stmt
= gimple_build_switch (vmain
, u
, label_vec
);
8594 gsi_insert_after (&switch_si
, stmt
, GSI_SAME_STMT
);
8595 gsi_remove (&switch_si
, true);
8597 si
= gsi_start_bb (default_bb
);
8598 stmt
= gimple_build_call (builtin_decl_explicit (BUILT_IN_TRAP
), 0);
8599 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
8605 /* Code to get the next section goes in L1_BB. */
8606 si
= gsi_last_nondebug_bb (l1_bb
);
8607 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CONTINUE
);
8609 bfn_decl
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_NEXT
);
8610 stmt
= gimple_build_call (bfn_decl
, 0);
8611 gimple_call_set_lhs (stmt
, vnext
);
8612 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
8615 tree t
= build2 (PLUS_EXPR
, TREE_TYPE (cond_var
),
8616 vnext
, build_one_cst (TREE_TYPE (cond_var
)));
8617 expand_omp_build_assign (&si
, cond_var
, t
, false);
8619 gsi_remove (&si
, true);
8621 single_succ_edge (l1_bb
)->flags
= EDGE_FALLTHRU
;
8624 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
8625 si
= gsi_last_nondebug_bb (l2_bb
);
8626 if (gimple_omp_return_nowait_p (gsi_stmt (si
)))
8627 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_NOWAIT
);
8628 else if (gimple_omp_return_lhs (gsi_stmt (si
)))
8629 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END_CANCEL
);
8631 t
= builtin_decl_explicit (BUILT_IN_GOMP_SECTIONS_END
);
8632 stmt
= gimple_build_call (t
, 0);
8633 if (gimple_omp_return_lhs (gsi_stmt (si
)))
8634 gimple_call_set_lhs (stmt
, gimple_omp_return_lhs (gsi_stmt (si
)));
8635 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
8636 gsi_remove (&si
, true);
8638 set_immediate_dominator (CDI_DOMINATORS
, default_bb
, l0_bb
);
8641 /* Expand code for an OpenMP single or scope directive. We've already expanded
8642 much of the code, here we simply place the GOMP_barrier call. */
8645 expand_omp_single (struct omp_region
*region
)
8647 basic_block entry_bb
, exit_bb
;
8648 gimple_stmt_iterator si
;
8650 entry_bb
= region
->entry
;
8651 exit_bb
= region
->exit
;
8653 si
= gsi_last_nondebug_bb (entry_bb
);
8654 enum gimple_code code
= gimple_code (gsi_stmt (si
));
8655 gcc_assert (code
== GIMPLE_OMP_SINGLE
|| code
== GIMPLE_OMP_SCOPE
);
8656 gsi_remove (&si
, true);
8657 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
8659 if (exit_bb
== NULL
)
8661 gcc_assert (code
== GIMPLE_OMP_SCOPE
);
8665 si
= gsi_last_nondebug_bb (exit_bb
);
8666 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)))
8668 tree t
= gimple_omp_return_lhs (gsi_stmt (si
));
8669 gsi_insert_after (&si
, omp_build_barrier (t
), GSI_SAME_STMT
);
8671 gsi_remove (&si
, true);
8672 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
8675 /* Generic expansion for OpenMP synchronization directives: master,
8676 ordered and critical. All we need to do here is remove the entry
8677 and exit markers for REGION. */
8680 expand_omp_synch (struct omp_region
*region
)
8682 basic_block entry_bb
, exit_bb
;
8683 gimple_stmt_iterator si
;
8685 entry_bb
= region
->entry
;
8686 exit_bb
= region
->exit
;
8688 si
= gsi_last_nondebug_bb (entry_bb
);
8689 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
8690 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_MASTER
8691 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_MASKED
8692 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_TASKGROUP
8693 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ORDERED
8694 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CRITICAL
8695 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_TEAMS
);
8696 if (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_TEAMS
8697 && gimple_omp_teams_host (as_a
<gomp_teams
*> (gsi_stmt (si
))))
8699 expand_omp_taskreg (region
);
8702 gsi_remove (&si
, true);
8703 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
8707 si
= gsi_last_nondebug_bb (exit_bb
);
8708 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
8709 gsi_remove (&si
, true);
8710 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
8714 /* Translate enum omp_memory_order to enum memmodel for the embedded
8715 fail clause in there. */
8717 static enum memmodel
8718 omp_memory_order_to_fail_memmodel (enum omp_memory_order mo
)
8720 switch (mo
& OMP_FAIL_MEMORY_ORDER_MASK
)
8722 case OMP_FAIL_MEMORY_ORDER_UNSPECIFIED
:
8723 switch (mo
& OMP_MEMORY_ORDER_MASK
)
8725 case OMP_MEMORY_ORDER_RELAXED
: return MEMMODEL_RELAXED
;
8726 case OMP_MEMORY_ORDER_ACQUIRE
: return MEMMODEL_ACQUIRE
;
8727 case OMP_MEMORY_ORDER_RELEASE
: return MEMMODEL_RELAXED
;
8728 case OMP_MEMORY_ORDER_ACQ_REL
: return MEMMODEL_ACQUIRE
;
8729 case OMP_MEMORY_ORDER_SEQ_CST
: return MEMMODEL_SEQ_CST
;
8733 case OMP_FAIL_MEMORY_ORDER_RELAXED
: return MEMMODEL_RELAXED
;
8734 case OMP_FAIL_MEMORY_ORDER_ACQUIRE
: return MEMMODEL_ACQUIRE
;
8735 case OMP_FAIL_MEMORY_ORDER_SEQ_CST
: return MEMMODEL_SEQ_CST
;
8736 default: gcc_unreachable ();
8740 /* Translate enum omp_memory_order to enum memmodel. The two enums
8741 are using different numbers so that OMP_MEMORY_ORDER_UNSPECIFIED
8742 is 0 and omp_memory_order has the fail mode encoded in it too. */
8744 static enum memmodel
8745 omp_memory_order_to_memmodel (enum omp_memory_order mo
)
8747 enum memmodel ret
, fail_ret
;
8748 switch (mo
& OMP_MEMORY_ORDER_MASK
)
8750 case OMP_MEMORY_ORDER_RELAXED
: ret
= MEMMODEL_RELAXED
; break;
8751 case OMP_MEMORY_ORDER_ACQUIRE
: ret
= MEMMODEL_ACQUIRE
; break;
8752 case OMP_MEMORY_ORDER_RELEASE
: ret
= MEMMODEL_RELEASE
; break;
8753 case OMP_MEMORY_ORDER_ACQ_REL
: ret
= MEMMODEL_ACQ_REL
; break;
8754 case OMP_MEMORY_ORDER_SEQ_CST
: ret
= MEMMODEL_SEQ_CST
; break;
8755 default: gcc_unreachable ();
8757 /* If we drop the -Winvalid-memory-model warning for C++17 P0418R2,
8758 we can just return ret here unconditionally. Otherwise, work around
8759 it here and make sure fail memmodel is not stronger. */
8760 if ((mo
& OMP_FAIL_MEMORY_ORDER_MASK
) == OMP_FAIL_MEMORY_ORDER_UNSPECIFIED
)
8762 fail_ret
= omp_memory_order_to_fail_memmodel (mo
);
8768 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
8769 operation as a normal volatile load. */
8772 expand_omp_atomic_load (basic_block load_bb
, tree addr
,
8773 tree loaded_val
, int index
)
8775 enum built_in_function tmpbase
;
8776 gimple_stmt_iterator gsi
;
8777 basic_block store_bb
;
8780 tree decl
, type
, itype
;
8782 gsi
= gsi_last_nondebug_bb (load_bb
);
8783 stmt
= gsi_stmt (gsi
);
8784 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_LOAD
);
8785 loc
= gimple_location (stmt
);
8787 /* ??? If the target does not implement atomic_load_optab[mode], and mode
8788 is smaller than word size, then expand_atomic_load assumes that the load
8789 is atomic. We could avoid the builtin entirely in this case. */
8791 tmpbase
= (enum built_in_function
) (BUILT_IN_ATOMIC_LOAD_N
+ index
+ 1);
8792 decl
= builtin_decl_explicit (tmpbase
);
8793 if (decl
== NULL_TREE
)
8796 type
= TREE_TYPE (loaded_val
);
8797 itype
= TREE_TYPE (TREE_TYPE (decl
));
8799 enum omp_memory_order omo
= gimple_omp_atomic_memory_order (stmt
);
8800 tree mo
= build_int_cst (integer_type_node
,
8801 omp_memory_order_to_memmodel (omo
));
8802 gcall
*call
= gimple_build_call (decl
, 2, addr
, mo
);
8803 gimple_set_location (call
, loc
);
8804 gimple_set_vuse (call
, gimple_vuse (stmt
));
8806 if (!useless_type_conversion_p (type
, itype
))
8808 tree lhs
= make_ssa_name (itype
);
8809 gimple_call_set_lhs (call
, lhs
);
8810 gsi_insert_before (&gsi
, call
, GSI_SAME_STMT
);
8811 repl
= gimple_build_assign (loaded_val
,
8812 build1 (VIEW_CONVERT_EXPR
, type
, lhs
));
8813 gimple_set_location (repl
, loc
);
8817 gimple_call_set_lhs (call
, loaded_val
);
8820 gsi_replace (&gsi
, repl
, true);
8822 store_bb
= single_succ (load_bb
);
8823 gsi
= gsi_last_nondebug_bb (store_bb
);
8824 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
8825 gsi_remove (&gsi
, true);
8830 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
8831 operation as a normal volatile store. */
8834 expand_omp_atomic_store (basic_block load_bb
, tree addr
,
8835 tree loaded_val
, tree stored_val
, int index
)
8837 enum built_in_function tmpbase
;
8838 gimple_stmt_iterator gsi
;
8839 basic_block store_bb
= single_succ (load_bb
);
8842 tree decl
, type
, itype
;
8846 gsi
= gsi_last_nondebug_bb (load_bb
);
8847 stmt
= gsi_stmt (gsi
);
8848 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_LOAD
);
8850 /* If the load value is needed, then this isn't a store but an exchange. */
8851 exchange
= gimple_omp_atomic_need_value_p (stmt
);
8853 gsi
= gsi_last_nondebug_bb (store_bb
);
8854 stmt
= gsi_stmt (gsi
);
8855 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_ATOMIC_STORE
);
8856 loc
= gimple_location (stmt
);
8858 /* ??? If the target does not implement atomic_store_optab[mode], and mode
8859 is smaller than word size, then expand_atomic_store assumes that the store
8860 is atomic. We could avoid the builtin entirely in this case. */
8862 tmpbase
= (exchange
? BUILT_IN_ATOMIC_EXCHANGE_N
: BUILT_IN_ATOMIC_STORE_N
);
8863 tmpbase
= (enum built_in_function
) ((int) tmpbase
+ index
+ 1);
8864 decl
= builtin_decl_explicit (tmpbase
);
8865 if (decl
== NULL_TREE
)
8868 type
= TREE_TYPE (stored_val
);
8870 /* Dig out the type of the function's second argument. */
8871 itype
= TREE_TYPE (decl
);
8872 itype
= TYPE_ARG_TYPES (itype
);
8873 itype
= TREE_CHAIN (itype
);
8874 itype
= TREE_VALUE (itype
);
8875 imode
= TYPE_MODE (itype
);
8877 if (exchange
&& !can_atomic_exchange_p (imode
, true))
8880 if (!useless_type_conversion_p (itype
, type
))
8881 stored_val
= fold_build1_loc (loc
, VIEW_CONVERT_EXPR
, itype
, stored_val
);
8882 enum omp_memory_order omo
= gimple_omp_atomic_memory_order (stmt
);
8883 tree mo
= build_int_cst (integer_type_node
,
8884 omp_memory_order_to_memmodel (omo
));
8885 stored_val
= force_gimple_operand_gsi (&gsi
, stored_val
, true, NULL_TREE
,
8886 true, GSI_SAME_STMT
);
8887 gcall
*call
= gimple_build_call (decl
, 3, addr
, stored_val
, mo
);
8888 gimple_set_location (call
, loc
);
8889 gimple_set_vuse (call
, gimple_vuse (stmt
));
8890 gimple_set_vdef (call
, gimple_vdef (stmt
));
8892 gimple
*repl
= call
;
8895 if (!useless_type_conversion_p (type
, itype
))
8897 tree lhs
= make_ssa_name (itype
);
8898 gimple_call_set_lhs (call
, lhs
);
8899 gsi_insert_before (&gsi
, call
, GSI_SAME_STMT
);
8900 repl
= gimple_build_assign (loaded_val
,
8901 build1 (VIEW_CONVERT_EXPR
, type
, lhs
));
8902 gimple_set_location (repl
, loc
);
8905 gimple_call_set_lhs (call
, loaded_val
);
8907 gsi_replace (&gsi
, repl
, true);
8909 /* Remove the GIMPLE_OMP_ATOMIC_LOAD that we verified above. */
8910 gsi
= gsi_last_nondebug_bb (load_bb
);
8911 gsi_remove (&gsi
, true);
8916 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
8917 operation as a __atomic_fetch_op builtin. INDEX is log2 of the
8918 size of the data type, and thus usable to find the index of the builtin
8919 decl. Returns false if the expression is not of the proper form. */
8922 expand_omp_atomic_fetch_op (basic_block load_bb
,
8923 tree addr
, tree loaded_val
,
8924 tree stored_val
, int index
)
8926 enum built_in_function oldbase
, newbase
, tmpbase
;
8927 tree decl
, itype
, call
;
8929 basic_block store_bb
= single_succ (load_bb
);
8930 gimple_stmt_iterator gsi
;
8933 enum tree_code code
;
8934 bool need_old
, need_new
;
8937 /* We expect to find the following sequences:
8940 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
8943 val = tmp OP something; (or: something OP tmp)
8944 GIMPLE_OMP_STORE (val)
8946 ???FIXME: Allow a more flexible sequence.
8947 Perhaps use data flow to pick the statements.
8951 gsi
= gsi_after_labels (store_bb
);
8952 stmt
= gsi_stmt (gsi
);
8953 if (is_gimple_debug (stmt
))
8955 gsi_next_nondebug (&gsi
);
8956 if (gsi_end_p (gsi
))
8958 stmt
= gsi_stmt (gsi
);
8960 loc
= gimple_location (stmt
);
8961 if (!is_gimple_assign (stmt
))
8963 gsi_next_nondebug (&gsi
);
8964 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_OMP_ATOMIC_STORE
)
8966 need_new
= gimple_omp_atomic_need_value_p (gsi_stmt (gsi
));
8967 need_old
= gimple_omp_atomic_need_value_p (last_nondebug_stmt (load_bb
));
8968 enum omp_memory_order omo
8969 = gimple_omp_atomic_memory_order (last_nondebug_stmt (load_bb
));
8970 enum memmodel mo
= omp_memory_order_to_memmodel (omo
);
8971 gcc_checking_assert (!need_old
|| !need_new
);
8973 if (!operand_equal_p (gimple_assign_lhs (stmt
), stored_val
, 0))
8976 /* Check for one of the supported fetch-op operations. */
8977 code
= gimple_assign_rhs_code (stmt
);
8981 case POINTER_PLUS_EXPR
:
8982 oldbase
= BUILT_IN_ATOMIC_FETCH_ADD_N
;
8983 newbase
= BUILT_IN_ATOMIC_ADD_FETCH_N
;
8986 oldbase
= BUILT_IN_ATOMIC_FETCH_SUB_N
;
8987 newbase
= BUILT_IN_ATOMIC_SUB_FETCH_N
;
8990 oldbase
= BUILT_IN_ATOMIC_FETCH_AND_N
;
8991 newbase
= BUILT_IN_ATOMIC_AND_FETCH_N
;
8994 oldbase
= BUILT_IN_ATOMIC_FETCH_OR_N
;
8995 newbase
= BUILT_IN_ATOMIC_OR_FETCH_N
;
8998 oldbase
= BUILT_IN_ATOMIC_FETCH_XOR_N
;
8999 newbase
= BUILT_IN_ATOMIC_XOR_FETCH_N
;
9005 /* Make sure the expression is of the proper form. */
9006 if (operand_equal_p (gimple_assign_rhs1 (stmt
), loaded_val
, 0))
9007 rhs
= gimple_assign_rhs2 (stmt
);
9008 else if (commutative_tree_code (gimple_assign_rhs_code (stmt
))
9009 && operand_equal_p (gimple_assign_rhs2 (stmt
), loaded_val
, 0))
9010 rhs
= gimple_assign_rhs1 (stmt
);
9014 tmpbase
= ((enum built_in_function
)
9015 ((need_new
? newbase
: oldbase
) + index
+ 1));
9016 decl
= builtin_decl_explicit (tmpbase
);
9017 if (decl
== NULL_TREE
)
9019 itype
= TREE_TYPE (TREE_TYPE (decl
));
9020 imode
= TYPE_MODE (itype
);
9022 /* We could test all of the various optabs involved, but the fact of the
9023 matter is that (with the exception of i486 vs i586 and xadd) all targets
9024 that support any atomic operaton optab also implements compare-and-swap.
9025 Let optabs.cc take care of expanding any compare-and-swap loop. */
9026 if (!can_compare_and_swap_p (imode
, true) || !can_atomic_load_p (imode
))
9029 gsi
= gsi_last_nondebug_bb (load_bb
);
9030 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_LOAD
);
9032 /* OpenMP does not imply any barrier-like semantics on its atomic ops.
9033 It only requires that the operation happen atomically. Thus we can
9034 use the RELAXED memory model. */
9035 call
= build_call_expr_loc (loc
, decl
, 3, addr
,
9036 fold_convert_loc (loc
, itype
, rhs
),
9037 build_int_cst (NULL
, mo
));
9039 if (need_old
|| need_new
)
9041 lhs
= need_old
? loaded_val
: stored_val
;
9042 call
= fold_convert_loc (loc
, TREE_TYPE (lhs
), call
);
9043 call
= build2_loc (loc
, MODIFY_EXPR
, void_type_node
, lhs
, call
);
9046 call
= fold_convert_loc (loc
, void_type_node
, call
);
9047 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
9048 gsi_remove (&gsi
, true);
9050 gsi
= gsi_last_nondebug_bb (store_bb
);
9051 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
9052 gsi_remove (&gsi
, true);
9053 gsi
= gsi_last_nondebug_bb (store_bb
);
9054 stmt
= gsi_stmt (gsi
);
9055 gsi_remove (&gsi
, true);
9057 if (gimple_in_ssa_p (cfun
))
9058 release_defs (stmt
);
9063 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
9064 compare and exchange as an ATOMIC_COMPARE_EXCHANGE internal function.
9065 Returns false if the expression is not of the proper form. */
9068 expand_omp_atomic_cas (basic_block load_bb
, tree addr
,
9069 tree loaded_val
, tree stored_val
, int index
)
9071 /* We expect to find the following sequences:
9074 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
9077 val = tmp == e ? d : tmp;
9078 GIMPLE_OMP_ATOMIC_STORE (val)
9080 or in store_bb instead:
9082 val = tmp2 ? d : tmp;
9083 GIMPLE_OMP_ATOMIC_STORE (val)
9086 tmp3 = VIEW_CONVERT_EXPR<integral_type>(tmp);
9087 val = e == tmp3 ? d : tmp;
9088 GIMPLE_OMP_ATOMIC_STORE (val)
9093 basic_block store_bb
= single_succ (load_bb
);
9094 gimple_stmt_iterator gsi
= gsi_last_nondebug_bb (store_bb
);
9095 gimple
*store_stmt
= gsi_stmt (gsi
);
9096 if (!store_stmt
|| gimple_code (store_stmt
) != GIMPLE_OMP_ATOMIC_STORE
)
9098 gsi_prev_nondebug (&gsi
);
9099 if (gsi_end_p (gsi
))
9101 gimple
*condexpr_stmt
= gsi_stmt (gsi
);
9102 if (!is_gimple_assign (condexpr_stmt
)
9103 || gimple_assign_rhs_code (condexpr_stmt
) != COND_EXPR
)
9105 if (!operand_equal_p (gimple_assign_lhs (condexpr_stmt
), stored_val
, 0))
9107 gimple
*cond_stmt
= NULL
;
9108 gimple
*vce_stmt
= NULL
;
9109 gsi_prev_nondebug (&gsi
);
9110 if (!gsi_end_p (gsi
))
9112 cond_stmt
= gsi_stmt (gsi
);
9113 if (!is_gimple_assign (cond_stmt
))
9115 if (gimple_assign_rhs_code (cond_stmt
) == EQ_EXPR
)
9117 gsi_prev_nondebug (&gsi
);
9118 if (!gsi_end_p (gsi
))
9120 vce_stmt
= gsi_stmt (gsi
);
9121 if (!is_gimple_assign (vce_stmt
)
9122 || gimple_assign_rhs_code (vce_stmt
) != VIEW_CONVERT_EXPR
)
9126 else if (gimple_assign_rhs_code (cond_stmt
) == VIEW_CONVERT_EXPR
)
9127 std::swap (vce_stmt
, cond_stmt
);
9132 tree vce_rhs
= gimple_assign_rhs1 (vce_stmt
);
9133 if (TREE_CODE (vce_rhs
) != VIEW_CONVERT_EXPR
9134 || !operand_equal_p (TREE_OPERAND (vce_rhs
, 0), loaded_val
))
9136 if (!INTEGRAL_TYPE_P (TREE_TYPE (vce_rhs
))
9137 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE (loaded_val
))
9138 || !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (vce_rhs
)),
9139 TYPE_SIZE (TREE_TYPE (loaded_val
))))
9141 gsi_prev_nondebug (&gsi
);
9142 if (!gsi_end_p (gsi
))
9146 tree cond
= gimple_assign_rhs1 (condexpr_stmt
);
9147 tree cond_op1
, cond_op2
;
9150 /* We should now always get a separate cond_stmt. */
9151 if (!operand_equal_p (cond
, gimple_assign_lhs (cond_stmt
)))
9153 cond_op1
= gimple_assign_rhs1 (cond_stmt
);
9154 cond_op2
= gimple_assign_rhs2 (cond_stmt
);
9156 else if (TREE_CODE (cond
) != EQ_EXPR
&& TREE_CODE (cond
) != NE_EXPR
)
9160 cond_op1
= TREE_OPERAND (cond
, 0);
9161 cond_op2
= TREE_OPERAND (cond
, 1);
9164 if (TREE_CODE (cond
) == NE_EXPR
)
9166 if (!operand_equal_p (gimple_assign_rhs2 (condexpr_stmt
), loaded_val
))
9168 d
= gimple_assign_rhs3 (condexpr_stmt
);
9170 else if (!operand_equal_p (gimple_assign_rhs3 (condexpr_stmt
), loaded_val
))
9173 d
= gimple_assign_rhs2 (condexpr_stmt
);
9174 tree e
= vce_stmt
? gimple_assign_lhs (vce_stmt
) : loaded_val
;
9175 if (operand_equal_p (e
, cond_op1
))
9177 else if (operand_equal_p (e
, cond_op2
))
9182 location_t loc
= gimple_location (store_stmt
);
9183 gimple
*load_stmt
= last_nondebug_stmt (load_bb
);
9184 bool need_new
= gimple_omp_atomic_need_value_p (store_stmt
);
9185 bool need_old
= gimple_omp_atomic_need_value_p (load_stmt
);
9186 bool weak
= gimple_omp_atomic_weak_p (load_stmt
);
9187 enum omp_memory_order omo
= gimple_omp_atomic_memory_order (load_stmt
);
9188 tree mo
= build_int_cst (NULL
, omp_memory_order_to_memmodel (omo
));
9189 tree fmo
= build_int_cst (NULL
, omp_memory_order_to_fail_memmodel (omo
));
9190 gcc_checking_assert (!need_old
|| !need_new
);
9192 enum built_in_function fncode
9193 = (enum built_in_function
) ((int) BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
9195 tree cmpxchg
= builtin_decl_explicit (fncode
);
9196 if (cmpxchg
== NULL_TREE
)
9198 tree itype
= TREE_TYPE (TREE_TYPE (cmpxchg
));
9200 if (!can_compare_and_swap_p (TYPE_MODE (itype
), true)
9201 || !can_atomic_load_p (TYPE_MODE (itype
)))
9204 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (loaded_val
));
9205 if (SCALAR_FLOAT_TYPE_P (type
) && !vce_stmt
)
9208 gsi
= gsi_for_stmt (store_stmt
);
9209 if (!useless_type_conversion_p (itype
, TREE_TYPE (e
)))
9211 tree ne
= create_tmp_reg (itype
);
9212 gimple
*g
= gimple_build_assign (ne
, NOP_EXPR
, e
);
9213 gimple_set_location (g
, loc
);
9214 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
9217 if (!useless_type_conversion_p (itype
, TREE_TYPE (d
)))
9219 tree nd
= create_tmp_reg (itype
);
9220 enum tree_code code
;
9221 if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (d
)))
9223 code
= VIEW_CONVERT_EXPR
;
9224 d
= build1 (VIEW_CONVERT_EXPR
, itype
, d
);
9228 gimple
*g
= gimple_build_assign (nd
, code
, d
);
9229 gimple_set_location (g
, loc
);
9230 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
9234 tree ctype
= build_complex_type (itype
);
9235 int flag
= int_size_in_bytes (itype
) + (weak
? 256 : 0);
9237 = gimple_build_call_internal (IFN_ATOMIC_COMPARE_EXCHANGE
, 6, addr
, e
, d
,
9238 build_int_cst (integer_type_node
, flag
),
9240 tree cres
= create_tmp_reg (ctype
);
9241 gimple_call_set_lhs (g
, cres
);
9242 gimple_set_location (g
, loc
);
9243 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
9245 if (cond_stmt
|| need_old
|| need_new
)
9247 tree im
= create_tmp_reg (itype
);
9248 g
= gimple_build_assign (im
, IMAGPART_EXPR
,
9249 build1 (IMAGPART_EXPR
, itype
, cres
));
9250 gimple_set_location (g
, loc
);
9251 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
9253 tree re
= NULL_TREE
;
9254 if (need_old
|| need_new
)
9256 re
= create_tmp_reg (itype
);
9257 g
= gimple_build_assign (re
, REALPART_EXPR
,
9258 build1 (REALPART_EXPR
, itype
, cres
));
9259 gimple_set_location (g
, loc
);
9260 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
9265 g
= gimple_build_assign (cond
, NOP_EXPR
, im
);
9266 gimple_set_location (g
, loc
);
9267 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
9272 g
= gimple_build_assign (create_tmp_reg (itype
), COND_EXPR
,
9274 ? cond
: build2 (NE_EXPR
, boolean_type_node
,
9275 im
, build_zero_cst (itype
)),
9277 gimple_set_location (g
, loc
);
9278 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
9279 re
= gimple_assign_lhs (g
);
9282 if (need_old
|| need_new
)
9284 tree v
= need_old
? loaded_val
: stored_val
;
9285 enum tree_code code
;
9286 if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (v
)))
9288 code
= VIEW_CONVERT_EXPR
;
9289 re
= build1 (VIEW_CONVERT_EXPR
, TREE_TYPE (v
), re
);
9291 else if (!useless_type_conversion_p (TREE_TYPE (v
), itype
))
9294 code
= TREE_CODE (re
);
9295 g
= gimple_build_assign (v
, code
, re
);
9296 gimple_set_location (g
, loc
);
9297 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
9301 gsi_remove (&gsi
, true);
9302 gsi
= gsi_for_stmt (load_stmt
);
9303 gsi_remove (&gsi
, true);
9304 gsi
= gsi_for_stmt (condexpr_stmt
);
9305 gsi_remove (&gsi
, true);
9308 gsi
= gsi_for_stmt (cond_stmt
);
9309 gsi_remove (&gsi
, true);
9313 gsi
= gsi_for_stmt (vce_stmt
);
9314 gsi_remove (&gsi
, true);
9320 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
9324 newval = rhs; // with oldval replacing *addr in rhs
9325 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
9326 if (oldval != newval)
9329 INDEX is log2 of the size of the data type, and thus usable to find the
9330 index of the builtin decl. */
9333 expand_omp_atomic_pipeline (basic_block load_bb
, basic_block store_bb
,
9334 tree addr
, tree loaded_val
, tree stored_val
,
9337 tree loadedi
, storedi
, initial
, new_storedi
, old_vali
;
9338 tree type
, itype
, cmpxchg
, iaddr
, atype
;
9339 gimple_stmt_iterator si
;
9340 basic_block loop_header
= single_succ (load_bb
);
9343 enum built_in_function fncode
;
9345 fncode
= (enum built_in_function
)((int)BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_N
9347 cmpxchg
= builtin_decl_explicit (fncode
);
9348 if (cmpxchg
== NULL_TREE
)
9350 type
= TYPE_MAIN_VARIANT (TREE_TYPE (loaded_val
));
9352 itype
= TREE_TYPE (TREE_TYPE (cmpxchg
));
9354 if (!can_compare_and_swap_p (TYPE_MODE (itype
), true)
9355 || !can_atomic_load_p (TYPE_MODE (itype
)))
9358 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
9359 si
= gsi_last_nondebug_bb (load_bb
);
9360 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
9361 location_t loc
= gimple_location (gsi_stmt (si
));
9362 enum omp_memory_order omo
= gimple_omp_atomic_memory_order (gsi_stmt (si
));
9363 tree mo
= build_int_cst (NULL
, omp_memory_order_to_memmodel (omo
));
9364 tree fmo
= build_int_cst (NULL
, omp_memory_order_to_fail_memmodel (omo
));
9366 /* For floating-point values, we'll need to view-convert them to integers
9367 so that we can perform the atomic compare and swap. Simplify the
9368 following code by always setting up the "i"ntegral variables. */
9369 if (!INTEGRAL_TYPE_P (type
) && !POINTER_TYPE_P (type
))
9373 iaddr
= create_tmp_reg (build_pointer_type_for_mode (itype
, ptr_mode
,
9377 = force_gimple_operand_gsi (&si
,
9378 fold_convert (TREE_TYPE (iaddr
), addr
),
9379 false, NULL_TREE
, true, GSI_SAME_STMT
);
9380 stmt
= gimple_build_assign (iaddr
, iaddr_val
);
9381 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
9382 loadedi
= create_tmp_var (itype
);
9383 if (gimple_in_ssa_p (cfun
))
9384 loadedi
= make_ssa_name (loadedi
);
9389 loadedi
= loaded_val
;
9392 fncode
= (enum built_in_function
) (BUILT_IN_ATOMIC_LOAD_N
+ index
+ 1);
9393 tree loaddecl
= builtin_decl_explicit (fncode
);
9396 = fold_convert (atype
,
9397 build_call_expr (loaddecl
, 2, iaddr
,
9398 build_int_cst (NULL_TREE
,
9399 MEMMODEL_RELAXED
)));
9403 = build_int_cst (build_pointer_type_for_mode (atype
, ptr_mode
,
9405 initial
= build2 (MEM_REF
, atype
, iaddr
, off
);
9409 = force_gimple_operand_gsi (&si
, initial
, true, NULL_TREE
, true,
9412 /* Move the value to the LOADEDI temporary. */
9413 if (gimple_in_ssa_p (cfun
))
9415 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header
)));
9416 phi
= create_phi_node (loadedi
, loop_header
);
9417 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, single_succ_edge (load_bb
)),
9421 gsi_insert_before (&si
,
9422 gimple_build_assign (loadedi
, initial
),
9424 if (loadedi
!= loaded_val
)
9426 gimple_stmt_iterator gsi2
;
9429 x
= build1 (VIEW_CONVERT_EXPR
, type
, loadedi
);
9430 gsi2
= gsi_start_bb (loop_header
);
9431 if (gimple_in_ssa_p (cfun
))
9434 x
= force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
9435 true, GSI_SAME_STMT
);
9436 stmt
= gimple_build_assign (loaded_val
, x
);
9437 gsi_insert_before (&gsi2
, stmt
, GSI_SAME_STMT
);
9441 x
= build2 (MODIFY_EXPR
, TREE_TYPE (loaded_val
), loaded_val
, x
);
9442 force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
9443 true, GSI_SAME_STMT
);
9446 gsi_remove (&si
, true);
9448 si
= gsi_last_nondebug_bb (store_bb
);
9449 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
9452 storedi
= stored_val
;
9455 = force_gimple_operand_gsi (&si
,
9456 build1 (VIEW_CONVERT_EXPR
, itype
,
9457 stored_val
), true, NULL_TREE
, true,
9460 /* Build the compare&swap statement. */
9461 tree ctype
= build_complex_type (itype
);
9462 int flag
= int_size_in_bytes (itype
);
9463 new_storedi
= build_call_expr_internal_loc (loc
, IFN_ATOMIC_COMPARE_EXCHANGE
,
9464 ctype
, 6, iaddr
, loadedi
,
9466 build_int_cst (integer_type_node
,
9469 new_storedi
= build1 (REALPART_EXPR
, itype
, new_storedi
);
9470 new_storedi
= force_gimple_operand_gsi (&si
,
9471 fold_convert (TREE_TYPE (loadedi
),
9474 true, GSI_SAME_STMT
);
9476 if (gimple_in_ssa_p (cfun
))
9480 old_vali
= create_tmp_var (TREE_TYPE (loadedi
));
9481 stmt
= gimple_build_assign (old_vali
, loadedi
);
9482 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
9484 stmt
= gimple_build_assign (loadedi
, new_storedi
);
9485 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
9488 /* Note that we always perform the comparison as an integer, even for
9489 floating point. This allows the atomic operation to properly
9490 succeed even with NaNs and -0.0. */
9491 tree ne
= build2 (NE_EXPR
, boolean_type_node
, new_storedi
, old_vali
);
9492 stmt
= gimple_build_cond_empty (ne
);
9493 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
9496 e
= single_succ_edge (store_bb
);
9497 e
->flags
&= ~EDGE_FALLTHRU
;
9498 e
->flags
|= EDGE_FALSE_VALUE
;
9499 /* Expect no looping. */
9500 e
->probability
= profile_probability::guessed_always ();
9502 e
= make_edge (store_bb
, loop_header
, EDGE_TRUE_VALUE
);
9503 e
->probability
= profile_probability::guessed_never ();
9505 /* Copy the new value to loadedi (we already did that before the condition
9506 if we are not in SSA). */
9507 if (gimple_in_ssa_p (cfun
))
9509 phi
= gimple_seq_first_stmt (phi_nodes (loop_header
));
9510 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, e
), new_storedi
);
9513 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
9514 stmt
= gsi_stmt (si
);
9515 gsi_remove (&si
, true);
9516 if (gimple_in_ssa_p (cfun
))
9517 release_defs (stmt
);
9519 class loop
*loop
= alloc_loop ();
9520 loop
->header
= loop_header
;
9521 loop
->latch
= store_bb
;
9522 add_loop (loop
, loop_header
->loop_father
);
9527 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
9529 GOMP_atomic_start ();
9533 The result is not globally atomic, but works so long as all parallel
9534 references are within #pragma omp atomic directives. According to
9535 responses received from omp@openmp.org, appears to be within spec.
9536 Which makes sense, since that's how several other compilers handle
9537 this situation as well.
9538 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
9539 expanding. STORED_VAL is the operand of the matching
9540 GIMPLE_OMP_ATOMIC_STORE.
9543 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
9547 GIMPLE_OMP_ATOMIC_STORE (stored_val) with
9552 expand_omp_atomic_mutex (basic_block load_bb
, basic_block store_bb
,
9553 tree addr
, tree loaded_val
, tree stored_val
)
9555 gimple_stmt_iterator si
;
9559 si
= gsi_last_nondebug_bb (load_bb
);
9560 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
9562 t
= builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_START
);
9563 t
= build_call_expr (t
, 0);
9564 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
9566 tree mem
= build_simple_mem_ref (addr
);
9567 TREE_TYPE (mem
) = TREE_TYPE (loaded_val
);
9568 TREE_OPERAND (mem
, 1)
9569 = fold_convert (build_pointer_type_for_mode (TREE_TYPE (mem
), ptr_mode
,
9571 TREE_OPERAND (mem
, 1));
9572 stmt
= gimple_build_assign (loaded_val
, mem
);
9573 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
9574 gsi_remove (&si
, true);
9576 si
= gsi_last_nondebug_bb (store_bb
);
9577 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
9579 stmt
= gimple_build_assign (unshare_expr (mem
), stored_val
);
9580 gimple_set_vuse (stmt
, gimple_vuse (gsi_stmt (si
)));
9581 gimple_set_vdef (stmt
, gimple_vdef (gsi_stmt (si
)));
9582 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
9584 t
= builtin_decl_explicit (BUILT_IN_GOMP_ATOMIC_END
);
9585 t
= build_call_expr (t
, 0);
9586 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
9587 gsi_remove (&si
, true);
9591 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
9592 using expand_omp_atomic_fetch_op. If it failed, we try to
9593 call expand_omp_atomic_pipeline, and if it fails too, the
9594 ultimate fallback is wrapping the operation in a mutex
9595 (expand_omp_atomic_mutex). REGION is the atomic region built
9596 by build_omp_regions_1(). */
9599 expand_omp_atomic (struct omp_region
*region
)
9601 basic_block load_bb
= region
->entry
, store_bb
= region
->exit
;
9602 gomp_atomic_load
*load
9603 = as_a
<gomp_atomic_load
*> (last_nondebug_stmt (load_bb
));
9604 gomp_atomic_store
*store
9605 = as_a
<gomp_atomic_store
*> (last_nondebug_stmt (store_bb
));
9606 tree loaded_val
= gimple_omp_atomic_load_lhs (load
);
9607 tree addr
= gimple_omp_atomic_load_rhs (load
);
9608 tree stored_val
= gimple_omp_atomic_store_val (store
);
9609 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (loaded_val
));
9610 HOST_WIDE_INT index
;
9612 /* Make sure the type is one of the supported sizes. */
9613 index
= tree_to_uhwi (TYPE_SIZE_UNIT (type
));
9614 index
= exact_log2 (index
);
9615 if (index
>= 0 && index
<= 4)
9617 unsigned int align
= TYPE_ALIGN_UNIT (type
);
9619 /* __sync builtins require strict data alignment. */
9620 if (exact_log2 (align
) >= index
)
9624 if (loaded_val
== stored_val
9625 && (is_int_mode (TYPE_MODE (type
), &smode
)
9626 || is_float_mode (TYPE_MODE (type
), &smode
))
9627 && GET_MODE_BITSIZE (smode
) <= BITS_PER_WORD
9628 && expand_omp_atomic_load (load_bb
, addr
, loaded_val
, index
))
9632 if ((is_int_mode (TYPE_MODE (type
), &smode
)
9633 || is_float_mode (TYPE_MODE (type
), &smode
))
9634 && GET_MODE_BITSIZE (smode
) <= BITS_PER_WORD
9635 && store_bb
== single_succ (load_bb
)
9636 && first_stmt (store_bb
) == store
9637 && expand_omp_atomic_store (load_bb
, addr
, loaded_val
,
9641 /* When possible, use specialized atomic update functions. */
9642 if ((INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
))
9643 && store_bb
== single_succ (load_bb
)
9644 && expand_omp_atomic_fetch_op (load_bb
, addr
,
9645 loaded_val
, stored_val
, index
))
9648 /* When possible, use ATOMIC_COMPARE_EXCHANGE ifn without a loop. */
9649 if (store_bb
== single_succ (load_bb
)
9650 && !gimple_in_ssa_p (cfun
)
9651 && expand_omp_atomic_cas (load_bb
, addr
, loaded_val
, stored_val
,
9655 /* If we don't have specialized __sync builtins, try and implement
9656 as a compare and swap loop. */
9657 if (expand_omp_atomic_pipeline (load_bb
, store_bb
, addr
,
9658 loaded_val
, stored_val
, index
))
9663 /* The ultimate fallback is wrapping the operation in a mutex. */
9664 expand_omp_atomic_mutex (load_bb
, store_bb
, addr
, loaded_val
, stored_val
);
9667 /* Mark the loops inside the kernels region starting at REGION_ENTRY and ending
9671 mark_loops_in_oacc_kernels_region (basic_block region_entry
,
9672 basic_block region_exit
)
9674 class loop
*outer
= region_entry
->loop_father
;
9675 gcc_assert (region_exit
== NULL
|| outer
== region_exit
->loop_father
);
9677 /* Don't parallelize the kernels region if it contains more than one outer
9679 unsigned int nr_outer_loops
= 0;
9680 class loop
*single_outer
= NULL
;
9681 for (class loop
*loop
= outer
->inner
; loop
!= NULL
; loop
= loop
->next
)
9683 gcc_assert (loop_outer (loop
) == outer
);
9685 if (!dominated_by_p (CDI_DOMINATORS
, loop
->header
, region_entry
))
9688 if (region_exit
!= NULL
9689 && dominated_by_p (CDI_DOMINATORS
, loop
->header
, region_exit
))
9693 single_outer
= loop
;
9695 if (nr_outer_loops
!= 1)
9698 for (class loop
*loop
= single_outer
->inner
;
9704 /* Mark the loops in the region. */
9705 for (class loop
*loop
= single_outer
; loop
!= NULL
; loop
= loop
->inner
)
9706 loop
->in_oacc_kernels_region
= true;
9709 /* Build target argument identifier from the DEVICE identifier, value
9710 identifier ID and whether the element also has a SUBSEQUENT_PARAM. */
9713 get_target_argument_identifier_1 (int device
, bool subseqent_param
, int id
)
9715 tree t
= build_int_cst (integer_type_node
, device
);
9716 if (subseqent_param
)
9717 t
= fold_build2 (BIT_IOR_EXPR
, integer_type_node
, t
,
9718 build_int_cst (integer_type_node
,
9719 GOMP_TARGET_ARG_SUBSEQUENT_PARAM
));
9720 t
= fold_build2 (BIT_IOR_EXPR
, integer_type_node
, t
,
9721 build_int_cst (integer_type_node
, id
));
9725 /* Like above but return it in type that can be directly stored as an element
9726 of the argument array. */
9729 get_target_argument_identifier (int device
, bool subseqent_param
, int id
)
9731 tree t
= get_target_argument_identifier_1 (device
, subseqent_param
, id
);
9732 return fold_convert (ptr_type_node
, t
);
9735 /* Return a target argument consisting of DEVICE identifier, value identifier
9736 ID, and the actual VALUE. */
9739 get_target_argument_value (gimple_stmt_iterator
*gsi
, int device
, int id
,
9742 tree t
= fold_build2 (LSHIFT_EXPR
, integer_type_node
,
9743 fold_convert (integer_type_node
, value
),
9744 build_int_cst (unsigned_type_node
,
9745 GOMP_TARGET_ARG_VALUE_SHIFT
));
9746 t
= fold_build2 (BIT_IOR_EXPR
, integer_type_node
, t
,
9747 get_target_argument_identifier_1 (device
, false, id
));
9748 t
= fold_convert (ptr_type_node
, t
);
9749 return force_gimple_operand_gsi (gsi
, t
, true, NULL
, true, GSI_SAME_STMT
);
9752 /* If VALUE is an integer constant greater than -2^15 and smaller than 2^15,
9753 push one argument to ARGS with both the DEVICE, ID and VALUE embedded in it,
9754 otherwise push an identifier (with DEVICE and ID) and the VALUE in two
9758 push_target_argument_according_to_value (gimple_stmt_iterator
*gsi
, int device
,
9759 int id
, tree value
, vec
<tree
> *args
)
9761 if (tree_fits_shwi_p (value
)
9762 && tree_to_shwi (value
) > -(1 << 15)
9763 && tree_to_shwi (value
) < (1 << 15))
9764 args
->quick_push (get_target_argument_value (gsi
, device
, id
, value
));
9767 args
->quick_push (get_target_argument_identifier (device
, true, id
));
9768 value
= fold_convert (ptr_type_node
, value
);
9769 value
= force_gimple_operand_gsi (gsi
, value
, true, NULL
, true,
9771 args
->quick_push (value
);
9775 /* Create an array of arguments that is then passed to GOMP_target. */
9778 get_target_arguments (gimple_stmt_iterator
*gsi
, gomp_target
*tgt_stmt
)
9780 auto_vec
<tree
, 6> args
;
9781 tree clauses
= gimple_omp_target_clauses (tgt_stmt
);
9782 tree t
, c
= omp_find_clause (clauses
, OMP_CLAUSE_NUM_TEAMS
);
9784 t
= OMP_CLAUSE_NUM_TEAMS_UPPER_EXPR (c
);
9786 t
= integer_minus_one_node
;
9787 push_target_argument_according_to_value (gsi
, GOMP_TARGET_ARG_DEVICE_ALL
,
9788 GOMP_TARGET_ARG_NUM_TEAMS
, t
, &args
);
9790 c
= omp_find_clause (clauses
, OMP_CLAUSE_THREAD_LIMIT
);
9792 t
= OMP_CLAUSE_THREAD_LIMIT_EXPR (c
);
9794 t
= integer_minus_one_node
;
9795 push_target_argument_according_to_value (gsi
, GOMP_TARGET_ARG_DEVICE_ALL
,
9796 GOMP_TARGET_ARG_THREAD_LIMIT
, t
,
9799 /* Produce more, perhaps device specific, arguments here. */
9801 tree argarray
= create_tmp_var (build_array_type_nelts (ptr_type_node
,
9802 args
.length () + 1),
9803 ".omp_target_args");
9804 for (unsigned i
= 0; i
< args
.length (); i
++)
9806 tree ref
= build4 (ARRAY_REF
, ptr_type_node
, argarray
,
9807 build_int_cst (integer_type_node
, i
),
9808 NULL_TREE
, NULL_TREE
);
9809 gsi_insert_before (gsi
, gimple_build_assign (ref
, args
[i
]),
9812 tree ref
= build4 (ARRAY_REF
, ptr_type_node
, argarray
,
9813 build_int_cst (integer_type_node
, args
.length ()),
9814 NULL_TREE
, NULL_TREE
);
9815 gsi_insert_before (gsi
, gimple_build_assign (ref
, null_pointer_node
),
9817 TREE_ADDRESSABLE (argarray
) = 1;
9818 return build_fold_addr_expr (argarray
);
9821 /* Expand the GIMPLE_OMP_TARGET starting at REGION. */
9824 expand_omp_target (struct omp_region
*region
)
9826 basic_block entry_bb
, exit_bb
, new_bb
;
9827 struct function
*child_cfun
;
9828 tree child_fn
, child_fn2
, block
, t
, c
;
9829 gimple_stmt_iterator gsi
;
9830 gomp_target
*entry_stmt
;
9836 entry_stmt
= as_a
<gomp_target
*> (last_nondebug_stmt (region
->entry
));
9837 target_kind
= gimple_omp_target_kind (entry_stmt
);
9838 new_bb
= region
->entry
;
9840 offloaded
= is_gimple_omp_offloaded (entry_stmt
);
9841 switch (target_kind
)
9843 case GF_OMP_TARGET_KIND_REGION
:
9844 case GF_OMP_TARGET_KIND_UPDATE
:
9845 case GF_OMP_TARGET_KIND_ENTER_DATA
:
9846 case GF_OMP_TARGET_KIND_EXIT_DATA
:
9847 case GF_OMP_TARGET_KIND_OACC_PARALLEL
:
9848 case GF_OMP_TARGET_KIND_OACC_KERNELS
:
9849 case GF_OMP_TARGET_KIND_OACC_SERIAL
:
9850 case GF_OMP_TARGET_KIND_OACC_UPDATE
:
9851 case GF_OMP_TARGET_KIND_OACC_ENTER_DATA
:
9852 case GF_OMP_TARGET_KIND_OACC_EXIT_DATA
:
9853 case GF_OMP_TARGET_KIND_OACC_DECLARE
:
9854 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED
:
9855 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE
:
9856 case GF_OMP_TARGET_KIND_DATA
:
9857 case GF_OMP_TARGET_KIND_OACC_DATA
:
9858 case GF_OMP_TARGET_KIND_OACC_HOST_DATA
:
9859 case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS
:
9865 tree clauses
= gimple_omp_target_clauses (entry_stmt
);
9867 bool is_ancestor
= false;
9868 child_fn
= child_fn2
= NULL_TREE
;
9872 c
= omp_find_clause (clauses
, OMP_CLAUSE_DEVICE
);
9873 if (ENABLE_OFFLOADING
&& c
)
9874 is_ancestor
= OMP_CLAUSE_DEVICE_ANCESTOR (c
);
9875 child_fn
= gimple_omp_target_child_fn (entry_stmt
);
9876 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
9879 /* Supported by expand_omp_taskreg, but not here. */
9880 if (child_cfun
!= NULL
)
9881 gcc_checking_assert (!child_cfun
->cfg
);
9882 gcc_checking_assert (!gimple_in_ssa_p (cfun
));
9884 entry_bb
= region
->entry
;
9885 exit_bb
= region
->exit
;
9887 if (target_kind
== GF_OMP_TARGET_KIND_OACC_KERNELS
)
9888 mark_loops_in_oacc_kernels_region (region
->entry
, region
->exit
);
9890 /* Going on, all OpenACC compute constructs are mapped to
9891 'BUILT_IN_GOACC_PARALLEL', and get their compute regions outlined.
9892 To distinguish between them, we attach attributes. */
9893 switch (target_kind
)
9895 case GF_OMP_TARGET_KIND_OACC_PARALLEL
:
9896 DECL_ATTRIBUTES (child_fn
)
9897 = tree_cons (get_identifier ("oacc parallel"),
9898 NULL_TREE
, DECL_ATTRIBUTES (child_fn
));
9900 case GF_OMP_TARGET_KIND_OACC_KERNELS
:
9901 DECL_ATTRIBUTES (child_fn
)
9902 = tree_cons (get_identifier ("oacc kernels"),
9903 NULL_TREE
, DECL_ATTRIBUTES (child_fn
));
9905 case GF_OMP_TARGET_KIND_OACC_SERIAL
:
9906 DECL_ATTRIBUTES (child_fn
)
9907 = tree_cons (get_identifier ("oacc serial"),
9908 NULL_TREE
, DECL_ATTRIBUTES (child_fn
));
9910 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED
:
9911 DECL_ATTRIBUTES (child_fn
)
9912 = tree_cons (get_identifier ("oacc parallel_kernels_parallelized"),
9913 NULL_TREE
, DECL_ATTRIBUTES (child_fn
));
9915 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE
:
9916 DECL_ATTRIBUTES (child_fn
)
9917 = tree_cons (get_identifier ("oacc parallel_kernels_gang_single"),
9918 NULL_TREE
, DECL_ATTRIBUTES (child_fn
));
9921 /* Make sure we don't miss any. */
9922 gcc_checking_assert (!(is_gimple_omp_oacc (entry_stmt
)
9923 && is_gimple_omp_offloaded (entry_stmt
)));
9929 unsigned srcidx
, dstidx
, num
;
9931 /* If the offloading region needs data sent from the parent
9932 function, then the very first statement (except possible
9933 tree profile counter updates) of the offloading body
9934 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
9935 &.OMP_DATA_O is passed as an argument to the child function,
9936 we need to replace it with the argument as seen by the child
9939 In most cases, this will end up being the identity assignment
9940 .OMP_DATA_I = .OMP_DATA_I. However, if the offloading body had
9941 a function call that has been inlined, the original PARM_DECL
9942 .OMP_DATA_I may have been converted into a different local
9943 variable. In which case, we need to keep the assignment. */
9944 tree data_arg
= gimple_omp_target_data_arg (entry_stmt
);
9947 basic_block entry_succ_bb
= single_succ (entry_bb
);
9948 gimple_stmt_iterator gsi
;
9950 gimple
*tgtcopy_stmt
= NULL
;
9951 tree sender
= TREE_VEC_ELT (data_arg
, 0);
9953 for (gsi
= gsi_start_bb (entry_succ_bb
); ; gsi_next (&gsi
))
9955 gcc_assert (!gsi_end_p (gsi
));
9956 stmt
= gsi_stmt (gsi
);
9957 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
9960 if (gimple_num_ops (stmt
) == 2)
9962 tree arg
= gimple_assign_rhs1 (stmt
);
9964 /* We're ignoring the subcode because we're
9965 effectively doing a STRIP_NOPS. */
9967 if ((TREE_CODE (arg
) == ADDR_EXPR
9968 && TREE_OPERAND (arg
, 0) == sender
)
9971 tgtcopy_stmt
= stmt
;
9977 gcc_assert (tgtcopy_stmt
!= NULL
);
9978 arg
= DECL_ARGUMENTS (child_fn
);
9980 gcc_assert (gimple_assign_lhs (tgtcopy_stmt
) == arg
);
9981 gsi_remove (&gsi
, true);
9984 /* Declare local variables needed in CHILD_CFUN. */
9985 block
= DECL_INITIAL (child_fn
);
9986 BLOCK_VARS (block
) = vec2chain (child_cfun
->local_decls
);
9987 /* The gimplifier could record temporaries in the offloading block
9988 rather than in containing function's local_decls chain,
9989 which would mean cgraph missed finalizing them. Do it now. */
9990 for (t
= BLOCK_VARS (block
); t
; t
= DECL_CHAIN (t
))
9991 if (VAR_P (t
) && TREE_STATIC (t
) && !DECL_EXTERNAL (t
))
9992 varpool_node::finalize_decl (t
);
9993 DECL_SAVED_TREE (child_fn
) = NULL
;
9994 /* We'll create a CFG for child_fn, so no gimple body is needed. */
9995 gimple_set_body (child_fn
, NULL
);
9996 TREE_USED (block
) = 1;
9998 /* Reset DECL_CONTEXT on function arguments. */
9999 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= DECL_CHAIN (t
))
10000 DECL_CONTEXT (t
) = child_fn
;
10002 /* Split ENTRY_BB at GIMPLE_*,
10003 so that it can be moved to the child function. */
10004 gsi
= gsi_last_nondebug_bb (entry_bb
);
10005 stmt
= gsi_stmt (gsi
);
10007 && gimple_code (stmt
) == gimple_code (entry_stmt
));
10008 e
= split_block (entry_bb
, stmt
);
10009 gsi_remove (&gsi
, true);
10010 entry_bb
= e
->dest
;
10011 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
10013 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
10016 gsi
= gsi_last_nondebug_bb (exit_bb
);
10017 gcc_assert (!gsi_end_p (gsi
)
10018 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
10019 stmt
= gimple_build_return (NULL
);
10020 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
10021 gsi_remove (&gsi
, true);
10024 /* Move the offloading region into CHILD_CFUN. */
10026 block
= gimple_block (entry_stmt
);
10028 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
, block
);
10030 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
10031 /* When the OMP expansion process cannot guarantee an up-to-date
10032 loop tree arrange for the child function to fixup loops. */
10033 if (loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
10034 child_cfun
->x_current_loops
->state
|= LOOPS_NEED_FIXUP
;
10036 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
10037 num
= vec_safe_length (child_cfun
->local_decls
);
10038 for (srcidx
= 0, dstidx
= 0; srcidx
< num
; srcidx
++)
10040 t
= (*child_cfun
->local_decls
)[srcidx
];
10041 if (DECL_CONTEXT (t
) == cfun
->decl
)
10043 if (srcidx
!= dstidx
)
10044 (*child_cfun
->local_decls
)[dstidx
] = t
;
10048 vec_safe_truncate (child_cfun
->local_decls
, dstidx
);
10050 /* Inform the callgraph about the new function. */
10051 child_cfun
->curr_properties
= cfun
->curr_properties
;
10052 child_cfun
->has_simduid_loops
|= cfun
->has_simduid_loops
;
10053 child_cfun
->has_force_vectorize_loops
|= cfun
->has_force_vectorize_loops
;
10054 cgraph_node
*node
= cgraph_node::get_create (child_fn
);
10055 node
->parallelized_function
= 1;
10056 node
->has_omp_variant_constructs
10057 |= cgraph_node::get (cfun
->decl
)->has_omp_variant_constructs
;
10058 cgraph_node::add_new_function (child_fn
, true);
10060 /* Add the new function to the offload table. */
10061 if (ENABLE_OFFLOADING
)
10064 DECL_PRESERVE_P (child_fn
) = 1;
10066 vec_safe_push (offload_funcs
, child_fn
);
10069 bool need_asm
= DECL_ASSEMBLER_NAME_SET_P (current_function_decl
)
10070 && !DECL_ASSEMBLER_NAME_SET_P (child_fn
);
10072 /* Fix the callgraph edges for child_cfun. Those for cfun will be
10073 fixed in a following pass. */
10074 push_cfun (child_cfun
);
10076 assign_assembler_name_if_needed (child_fn
);
10077 cgraph_edge::rebuild_edges ();
10079 /* Some EH regions might become dead, see PR34608. If
10080 pass_cleanup_cfg isn't the first pass to happen with the
10081 new child, these dead EH edges might cause problems.
10082 Clean them up now. */
10083 if (flag_exceptions
)
10086 bool changed
= false;
10088 FOR_EACH_BB_FN (bb
, cfun
)
10089 changed
|= gimple_purge_dead_eh_edges (bb
);
10091 cleanup_tree_cfg ();
10093 if (flag_checking
&& !loops_state_satisfies_p (LOOPS_NEED_FIXUP
))
10094 verify_loop_structure ();
10097 if (dump_file
&& !gimple_in_ssa_p (cfun
))
10099 omp_any_child_fn_dumped
= true;
10100 dump_function_header (dump_file
, child_fn
, dump_flags
);
10101 dump_function_to_file (child_fn
, dump_file
, dump_flags
);
10104 adjust_context_and_scope (region
, gimple_block (entry_stmt
), child_fn
);
10106 /* Handle the case that an inner ancestor:1 target is called by an outer
10110 cgraph_node
*fn2_node
;
10111 child_fn2
= build_decl (DECL_SOURCE_LOCATION (child_fn
),
10113 clone_function_name (child_fn
, "nohost"),
10114 TREE_TYPE (child_fn
));
10116 DECL_PRESERVE_P (child_fn2
) = 1;
10117 TREE_STATIC (child_fn2
) = 1;
10118 DECL_ARTIFICIAL (child_fn2
) = 1;
10119 DECL_IGNORED_P (child_fn2
) = 0;
10120 TREE_PUBLIC (child_fn2
) = 0;
10121 DECL_UNINLINABLE (child_fn2
) = 1;
10122 DECL_EXTERNAL (child_fn2
) = 0;
10123 DECL_CONTEXT (child_fn2
) = DECL_CONTEXT (child_fn
);
10124 DECL_INITIAL (child_fn2
) = make_node (BLOCK
);
10125 BLOCK_SUPERCONTEXT (DECL_INITIAL (child_fn2
)) = child_fn2
;
10126 DECL_ATTRIBUTES (child_fn
)
10127 = remove_attribute ("omp target entrypoint",
10128 DECL_ATTRIBUTES (child_fn
));
10129 DECL_ATTRIBUTES (child_fn2
)
10130 = tree_cons (get_identifier ("omp target device_ancestor_nohost"),
10131 NULL_TREE
, copy_list (DECL_ATTRIBUTES (child_fn
)));
10132 DECL_ATTRIBUTES (child_fn
)
10133 = tree_cons (get_identifier ("omp target device_ancestor_host"),
10134 NULL_TREE
, DECL_ATTRIBUTES (child_fn
));
10135 DECL_FUNCTION_SPECIFIC_OPTIMIZATION (child_fn2
)
10136 = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (current_function_decl
);
10137 DECL_FUNCTION_SPECIFIC_TARGET (child_fn2
)
10138 = DECL_FUNCTION_SPECIFIC_TARGET (current_function_decl
);
10139 DECL_FUNCTION_VERSIONED (child_fn2
)
10140 = DECL_FUNCTION_VERSIONED (current_function_decl
);
10142 fn2_node
= cgraph_node::get_create (child_fn2
);
10143 fn2_node
->offloadable
= 1;
10144 fn2_node
->force_output
= 1;
10145 node
->offloadable
= 0;
10147 /* Enable pass_omp_device_lower pass. */
10148 fn2_node
= cgraph_node::get (DECL_CONTEXT (child_fn
));
10149 fn2_node
->has_omp_variant_constructs
= 1;
10151 t
= build_decl (DECL_SOURCE_LOCATION (child_fn
),
10152 RESULT_DECL
, NULL_TREE
, void_type_node
);
10153 DECL_ARTIFICIAL (t
) = 1;
10154 DECL_IGNORED_P (t
) = 1;
10155 DECL_CONTEXT (t
) = child_fn2
;
10156 DECL_RESULT (child_fn2
) = t
;
10157 DECL_SAVED_TREE (child_fn2
) = build1 (RETURN_EXPR
,
10158 void_type_node
, NULL
);
10159 tree tmp
= DECL_ARGUMENTS (child_fn
);
10160 t
= build_decl (DECL_SOURCE_LOCATION (child_fn
), PARM_DECL
,
10161 DECL_NAME (tmp
), TREE_TYPE (tmp
));
10162 DECL_ARTIFICIAL (t
) = 1;
10163 DECL_NAMELESS (t
) = 1;
10164 DECL_ARG_TYPE (t
) = ptr_type_node
;
10165 DECL_CONTEXT (t
) = current_function_decl
;
10167 TREE_READONLY (t
) = 1;
10168 DECL_ARGUMENTS (child_fn2
) = t
;
10169 gcc_assert (TREE_CHAIN (tmp
) == NULL_TREE
);
10171 gimplify_function_tree (child_fn2
);
10172 cgraph_node::add_new_function (child_fn2
, true);
10174 vec_safe_push (offload_funcs
, child_fn2
);
10175 if (dump_file
&& !gimple_in_ssa_p (cfun
))
10177 dump_function_header (dump_file
, child_fn2
, dump_flags
);
10178 dump_function_to_file (child_fn2
, dump_file
, dump_flags
);
10183 /* Emit a library call to launch the offloading region, or do data
10185 tree t1
, t2
, t3
, t4
, depend
;
10186 enum built_in_function start_ix
;
10187 unsigned int flags_i
= 0;
10189 switch (gimple_omp_target_kind (entry_stmt
))
10191 case GF_OMP_TARGET_KIND_REGION
:
10192 start_ix
= BUILT_IN_GOMP_TARGET
;
10194 case GF_OMP_TARGET_KIND_DATA
:
10195 start_ix
= BUILT_IN_GOMP_TARGET_DATA
;
10197 case GF_OMP_TARGET_KIND_UPDATE
:
10198 start_ix
= BUILT_IN_GOMP_TARGET_UPDATE
;
10200 case GF_OMP_TARGET_KIND_ENTER_DATA
:
10201 start_ix
= BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA
;
10203 case GF_OMP_TARGET_KIND_EXIT_DATA
:
10204 start_ix
= BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA
;
10205 flags_i
|= GOMP_TARGET_FLAG_EXIT_DATA
;
10207 case GF_OMP_TARGET_KIND_OACC_PARALLEL
:
10208 case GF_OMP_TARGET_KIND_OACC_KERNELS
:
10209 case GF_OMP_TARGET_KIND_OACC_SERIAL
:
10210 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED
:
10211 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE
:
10212 start_ix
= BUILT_IN_GOACC_PARALLEL
;
10214 case GF_OMP_TARGET_KIND_OACC_DATA
:
10215 case GF_OMP_TARGET_KIND_OACC_HOST_DATA
:
10216 case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS
:
10217 start_ix
= BUILT_IN_GOACC_DATA_START
;
10219 case GF_OMP_TARGET_KIND_OACC_UPDATE
:
10220 start_ix
= BUILT_IN_GOACC_UPDATE
;
10222 case GF_OMP_TARGET_KIND_OACC_ENTER_DATA
:
10223 start_ix
= BUILT_IN_GOACC_ENTER_DATA
;
10225 case GF_OMP_TARGET_KIND_OACC_EXIT_DATA
:
10226 start_ix
= BUILT_IN_GOACC_EXIT_DATA
;
10228 case GF_OMP_TARGET_KIND_OACC_DECLARE
:
10229 start_ix
= BUILT_IN_GOACC_DECLARE
;
10232 gcc_unreachable ();
10235 tree device
= NULL_TREE
;
10236 location_t device_loc
= UNKNOWN_LOCATION
;
10237 tree goacc_flags
= NULL_TREE
;
10238 bool need_device_adjustment
= false;
10239 gimple_stmt_iterator adj_gsi
;
10240 if (is_gimple_omp_oacc (entry_stmt
))
10242 /* By default, no GOACC_FLAGs are set. */
10243 goacc_flags
= integer_zero_node
;
10247 c
= omp_find_clause (clauses
, OMP_CLAUSE_DEVICE
);
10250 device
= OMP_CLAUSE_DEVICE_ID (c
);
10251 /* Ensure 'device' is of the correct type. */
10252 device
= fold_convert_loc (device_loc
, integer_type_node
, device
);
10253 if (TREE_CODE (device
) == INTEGER_CST
)
10255 if (wi::to_wide (device
) == GOMP_DEVICE_ICV
)
10256 device
= build_int_cst (integer_type_node
,
10257 GOMP_DEVICE_HOST_FALLBACK
);
10258 else if (wi::to_wide (device
) == GOMP_DEVICE_HOST_FALLBACK
)
10259 device
= build_int_cst (integer_type_node
,
10260 GOMP_DEVICE_HOST_FALLBACK
- 1);
10263 need_device_adjustment
= true;
10264 device_loc
= OMP_CLAUSE_LOCATION (c
);
10265 if (OMP_CLAUSE_DEVICE_ANCESTOR (c
))
10266 device
= build_int_cst (integer_type_node
,
10267 GOMP_DEVICE_HOST_FALLBACK
);
10271 /* By default, the value of DEVICE is GOMP_DEVICE_ICV (let runtime
10272 library choose). */
10273 device
= build_int_cst (integer_type_node
, GOMP_DEVICE_ICV
);
10274 device_loc
= gimple_location (entry_stmt
);
10277 c
= omp_find_clause (clauses
, OMP_CLAUSE_NOWAIT
);
10278 /* FIXME: in_reduction(...) nowait is unimplemented yet, pretend
10279 nowait doesn't appear. */
10280 if (c
&& omp_find_clause (clauses
, OMP_CLAUSE_IN_REDUCTION
))
10283 flags_i
|= GOMP_TARGET_FLAG_NOWAIT
;
10286 /* By default, there is no conditional. */
10287 tree cond
= NULL_TREE
;
10288 c
= omp_find_clause (clauses
, OMP_CLAUSE_IF
);
10290 cond
= OMP_CLAUSE_IF_EXPR (c
);
10291 /* If we found the clause 'if (cond)', build:
10292 OpenACC: goacc_flags = (cond ? goacc_flags
10293 : goacc_flags | GOACC_FLAG_HOST_FALLBACK)
10294 OpenMP: device = (cond ? device : GOMP_DEVICE_HOST_FALLBACK) */
10298 if (is_gimple_omp_oacc (entry_stmt
))
10303 cond
= gimple_boolify (cond
);
10305 basic_block cond_bb
, then_bb
, else_bb
;
10307 tree tmp_var
= create_tmp_var (TREE_TYPE (*tp
));
10309 e
= split_block_after_labels (new_bb
);
10312 gsi
= gsi_last_nondebug_bb (new_bb
);
10314 e
= split_block (new_bb
, gsi_stmt (gsi
));
10320 then_bb
= create_empty_bb (cond_bb
);
10321 else_bb
= create_empty_bb (then_bb
);
10322 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
10323 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
10325 stmt
= gimple_build_cond_empty (cond
);
10326 gsi
= gsi_last_bb (cond_bb
);
10327 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
10329 gsi
= gsi_start_bb (then_bb
);
10330 stmt
= gimple_build_assign (tmp_var
, *tp
);
10331 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
10334 gsi
= gsi_start_bb (else_bb
);
10335 if (is_gimple_omp_oacc (entry_stmt
))
10336 stmt
= gimple_build_assign (tmp_var
,
10339 build_int_cst (integer_type_node
,
10340 GOACC_FLAG_HOST_FALLBACK
));
10342 stmt
= gimple_build_assign (tmp_var
,
10343 build_int_cst (integer_type_node
,
10344 GOMP_DEVICE_HOST_FALLBACK
));
10345 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
10347 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
10348 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
10349 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
10350 add_bb_to_loop (else_bb
, cond_bb
->loop_father
);
10351 make_edge (then_bb
, new_bb
, EDGE_FALLTHRU
);
10352 make_edge (else_bb
, new_bb
, EDGE_FALLTHRU
);
10356 gsi
= gsi_last_nondebug_bb (new_bb
);
10360 gsi
= gsi_last_nondebug_bb (new_bb
);
10362 if (device
!= NULL_TREE
)
10363 device
= force_gimple_operand_gsi (&gsi
, device
, true, NULL_TREE
,
10364 true, GSI_SAME_STMT
);
10365 if (need_device_adjustment
)
10367 tree tmp_var
= create_tmp_var (TREE_TYPE (device
));
10368 stmt
= gimple_build_assign (tmp_var
, device
);
10369 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
10370 adj_gsi
= gsi_for_stmt (stmt
);
10375 if ((c
= omp_find_clause (clauses
, OMP_CLAUSE_SELF
)) != NULL_TREE
)
10377 gcc_assert ((is_gimple_omp_oacc (entry_stmt
) && offloaded
)
10378 || (gimple_omp_target_kind (entry_stmt
)
10379 == GF_OMP_TARGET_KIND_OACC_DATA_KERNELS
));
10383 e
= split_block_after_labels (new_bb
);
10386 gsi
= gsi_last_nondebug_bb (new_bb
);
10388 e
= split_block (new_bb
, gsi_stmt (gsi
));
10390 basic_block cond_bb
= e
->src
;
10394 basic_block then_bb
= create_empty_bb (cond_bb
);
10395 basic_block else_bb
= create_empty_bb (then_bb
);
10396 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
10397 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
10399 tree self_cond
= gimple_boolify (OMP_CLAUSE_SELF_EXPR (c
));
10400 stmt
= gimple_build_cond_empty (self_cond
);
10401 gsi
= gsi_last_bb (cond_bb
);
10402 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
10404 tree tmp_var
= create_tmp_var (TREE_TYPE (goacc_flags
));
10405 stmt
= gimple_build_assign (tmp_var
, BIT_IOR_EXPR
, goacc_flags
,
10406 build_int_cst (integer_type_node
,
10407 GOACC_FLAG_LOCAL_DEVICE
));
10408 gsi
= gsi_start_bb (then_bb
);
10409 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
10411 gsi
= gsi_start_bb (else_bb
);
10412 stmt
= gimple_build_assign (tmp_var
, goacc_flags
);
10413 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
10415 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
10416 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
10417 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
10418 add_bb_to_loop (else_bb
, cond_bb
->loop_father
);
10419 make_edge (then_bb
, new_bb
, EDGE_FALLTHRU
);
10420 make_edge (else_bb
, new_bb
, EDGE_FALLTHRU
);
10422 goacc_flags
= tmp_var
;
10423 gsi
= gsi_last_nondebug_bb (new_bb
);
10426 if (need_device_adjustment
)
10428 tree uns
= fold_convert (unsigned_type_node
, device
);
10429 uns
= force_gimple_operand_gsi (&adj_gsi
, uns
, true, NULL_TREE
,
10430 false, GSI_CONTINUE_LINKING
);
10431 edge e
= split_block (gsi_bb (adj_gsi
), gsi_stmt (adj_gsi
));
10432 basic_block cond_bb
= e
->src
;
10433 basic_block else_bb
= e
->dest
;
10434 if (gsi_bb (adj_gsi
) == new_bb
)
10437 gsi
= gsi_last_nondebug_bb (new_bb
);
10440 basic_block then_bb
= create_empty_bb (cond_bb
);
10441 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
10443 cond
= build2 (GT_EXPR
, boolean_type_node
, uns
,
10444 build_int_cst (unsigned_type_node
,
10445 GOMP_DEVICE_HOST_FALLBACK
- 1));
10446 stmt
= gimple_build_cond_empty (cond
);
10447 adj_gsi
= gsi_last_bb (cond_bb
);
10448 gsi_insert_after (&adj_gsi
, stmt
, GSI_CONTINUE_LINKING
);
10450 adj_gsi
= gsi_start_bb (then_bb
);
10451 tree add
= build2 (PLUS_EXPR
, integer_type_node
, device
,
10452 build_int_cst (integer_type_node
, -1));
10453 stmt
= gimple_build_assign (device
, add
);
10454 gsi_insert_after (&adj_gsi
, stmt
, GSI_CONTINUE_LINKING
);
10456 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
10457 e
->flags
= EDGE_FALSE_VALUE
;
10458 add_bb_to_loop (then_bb
, cond_bb
->loop_father
);
10459 make_edge (then_bb
, else_bb
, EDGE_FALLTHRU
);
10462 t
= gimple_omp_target_data_arg (entry_stmt
);
10465 t1
= size_zero_node
;
10466 t2
= build_zero_cst (ptr_type_node
);
10470 else if (TREE_VEC_LENGTH (t
) == 3 || is_gimple_omp_oacc (entry_stmt
))
10472 t1
= TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (TREE_VEC_ELT (t
, 1))));
10473 t1
= size_binop (PLUS_EXPR
, t1
, size_int (1));
10474 t2
= build_fold_addr_expr (TREE_VEC_ELT (t
, 0));
10475 t3
= build_fold_addr_expr (TREE_VEC_ELT (t
, 1));
10476 t4
= build_fold_addr_expr (TREE_VEC_ELT (t
, 2));
10480 t1
= force_gimple_operand_gsi (&gsi
, TREE_VEC_ELT (t
, 3), true, NULL_TREE
,
10481 true, GSI_SAME_STMT
);
10482 t2
= force_gimple_operand_gsi (&gsi
, TREE_VEC_ELT (t
, 0), true, NULL_TREE
,
10483 true, GSI_SAME_STMT
);
10484 t3
= force_gimple_operand_gsi (&gsi
, TREE_VEC_ELT (t
, 1), true, NULL_TREE
,
10485 true, GSI_SAME_STMT
);
10486 t4
= force_gimple_operand_gsi (&gsi
, TREE_VEC_ELT (t
, 2), true, NULL_TREE
,
10487 true, GSI_SAME_STMT
);
10491 bool tagging
= false;
10492 /* The maximum number used by any start_ix, without varargs. */
10493 auto_vec
<tree
, 11> args
;
10494 if (is_gimple_omp_oacc (entry_stmt
))
10496 tree goacc_flags_m
= fold_build1 (GOACC_FLAGS_MARSHAL_OP
,
10497 TREE_TYPE (goacc_flags
), goacc_flags
);
10498 goacc_flags_m
= force_gimple_operand_gsi (&gsi
, goacc_flags_m
, true,
10501 args
.quick_push (goacc_flags_m
);
10504 args
.quick_push (device
);
10506 args
.quick_push (build_fold_addr_expr (child_fn2
? child_fn2
: child_fn
));
10507 args
.quick_push (t1
);
10508 args
.quick_push (t2
);
10509 args
.quick_push (t3
);
10510 args
.quick_push (t4
);
10513 case BUILT_IN_GOACC_DATA_START
:
10514 case BUILT_IN_GOACC_DECLARE
:
10515 case BUILT_IN_GOMP_TARGET_DATA
:
10517 case BUILT_IN_GOMP_TARGET
:
10518 case BUILT_IN_GOMP_TARGET_UPDATE
:
10519 case BUILT_IN_GOMP_TARGET_ENTER_EXIT_DATA
:
10520 args
.quick_push (build_int_cst (unsigned_type_node
, flags_i
));
10521 c
= omp_find_clause (clauses
, OMP_CLAUSE_DEPEND
);
10523 depend
= OMP_CLAUSE_DECL (c
);
10525 depend
= build_int_cst (ptr_type_node
, 0);
10526 args
.quick_push (depend
);
10527 if (start_ix
== BUILT_IN_GOMP_TARGET
)
10528 args
.quick_push (get_target_arguments (&gsi
, entry_stmt
));
10530 case BUILT_IN_GOACC_PARALLEL
:
10531 if (lookup_attribute ("oacc serial", DECL_ATTRIBUTES (child_fn
)) != NULL
)
10533 tree dims
= NULL_TREE
;
10536 /* For serial constructs we set all dimensions to 1. */
10537 for (ix
= GOMP_DIM_MAX
; ix
--;)
10538 dims
= tree_cons (NULL_TREE
, integer_one_node
, dims
);
10539 oacc_replace_fn_attrib (child_fn
, dims
);
10542 oacc_set_fn_attrib (child_fn
, clauses
, &args
);
10545 case BUILT_IN_GOACC_ENTER_DATA
:
10546 case BUILT_IN_GOACC_EXIT_DATA
:
10547 case BUILT_IN_GOACC_UPDATE
:
10549 tree t_async
= NULL_TREE
;
10551 /* If present, use the value specified by the respective
10552 clause, making sure that is of the correct type. */
10553 c
= omp_find_clause (clauses
, OMP_CLAUSE_ASYNC
);
10555 t_async
= fold_convert_loc (OMP_CLAUSE_LOCATION (c
),
10557 OMP_CLAUSE_ASYNC_EXPR (c
));
10559 /* Default values for t_async. */
10560 t_async
= fold_convert_loc (gimple_location (entry_stmt
),
10562 build_int_cst (integer_type_node
,
10564 if (tagging
&& t_async
)
10566 unsigned HOST_WIDE_INT i_async
= GOMP_LAUNCH_OP_MAX
;
10568 if (TREE_CODE (t_async
) == INTEGER_CST
)
10570 /* See if we can pack the async arg in to the tag's
10572 i_async
= TREE_INT_CST_LOW (t_async
);
10573 if (i_async
< GOMP_LAUNCH_OP_MAX
)
10574 t_async
= NULL_TREE
;
10576 i_async
= GOMP_LAUNCH_OP_MAX
;
10578 args
.safe_push (oacc_launch_pack (GOMP_LAUNCH_ASYNC
, NULL_TREE
,
10582 args
.safe_push (force_gimple_operand_gsi (&gsi
, t_async
, true,
10586 /* Save the argument index, and ... */
10587 unsigned t_wait_idx
= args
.length ();
10588 unsigned num_waits
= 0;
10589 c
= omp_find_clause (clauses
, OMP_CLAUSE_WAIT
);
10591 /* ... push a placeholder. */
10592 args
.safe_push (integer_zero_node
);
10594 for (; c
; c
= OMP_CLAUSE_CHAIN (c
))
10595 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_WAIT
)
10597 tree arg
= fold_convert_loc (OMP_CLAUSE_LOCATION (c
),
10599 OMP_CLAUSE_WAIT_EXPR (c
));
10600 arg
= force_gimple_operand_gsi (&gsi
, arg
, true, NULL_TREE
, true,
10602 args
.safe_push (arg
);
10606 if (!tagging
|| num_waits
)
10610 /* Now that we know the number, update the placeholder. */
10612 len
= oacc_launch_pack (GOMP_LAUNCH_WAIT
, NULL_TREE
, num_waits
);
10614 len
= build_int_cst (integer_type_node
, num_waits
);
10615 len
= fold_convert_loc (gimple_location (entry_stmt
),
10616 unsigned_type_node
, len
);
10617 args
[t_wait_idx
] = len
;
10622 gcc_unreachable ();
10625 /* Push terminal marker - zero. */
10626 args
.safe_push (oacc_launch_pack (0, NULL_TREE
, 0));
10630 g
= gimple_build_call_internal (IFN_GOMP_TARGET_REV
, 1,
10631 build_fold_addr_expr (child_fn
));
10632 gimple_set_location (g
, gimple_location (entry_stmt
));
10633 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
10636 g
= gimple_build_call_vec (builtin_decl_explicit (start_ix
), args
);
10637 gimple_set_location (g
, gimple_location (entry_stmt
));
10638 gsi_insert_before (&gsi
, g
, GSI_SAME_STMT
);
10641 g
= gsi_stmt (gsi
);
10642 gcc_assert (g
&& gimple_code (g
) == GIMPLE_OMP_TARGET
);
10643 gsi_remove (&gsi
, true);
10647 /* Expand the parallel region tree rooted at REGION. Expansion
10648 proceeds in depth-first order. Innermost regions are expanded
10649 first. This way, parallel regions that require a new function to
10650 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
10651 internal dependencies in their body. */
10654 expand_omp (struct omp_region
*region
)
10656 omp_any_child_fn_dumped
= false;
10659 location_t saved_location
;
10660 gimple
*inner_stmt
= NULL
;
10662 /* First, determine whether this is a combined parallel+workshare
10664 if (region
->type
== GIMPLE_OMP_PARALLEL
)
10665 determine_parallel_type (region
);
10667 if (region
->type
== GIMPLE_OMP_FOR
10668 && gimple_omp_for_combined_p (last_nondebug_stmt (region
->entry
)))
10669 inner_stmt
= last_nondebug_stmt (region
->inner
->entry
);
10672 expand_omp (region
->inner
);
10674 saved_location
= input_location
;
10675 if (gimple_has_location (last_nondebug_stmt (region
->entry
)))
10676 input_location
= gimple_location (last_nondebug_stmt (region
->entry
));
10678 switch (region
->type
)
10680 case GIMPLE_OMP_PARALLEL
:
10681 case GIMPLE_OMP_TASK
:
10682 expand_omp_taskreg (region
);
10685 case GIMPLE_OMP_FOR
:
10686 expand_omp_for (region
, inner_stmt
);
10689 case GIMPLE_OMP_SECTIONS
:
10690 expand_omp_sections (region
);
10693 case GIMPLE_OMP_SECTION
:
10694 /* Individual omp sections are handled together with their
10695 parent GIMPLE_OMP_SECTIONS region. */
10698 case GIMPLE_OMP_STRUCTURED_BLOCK
:
10699 /* We should have gotten rid of these in gimple lowering. */
10700 gcc_unreachable ();
10702 case GIMPLE_OMP_SINGLE
:
10703 case GIMPLE_OMP_SCOPE
:
10704 expand_omp_single (region
);
10707 case GIMPLE_OMP_ORDERED
:
10709 gomp_ordered
*ord_stmt
10710 = as_a
<gomp_ordered
*> (last_nondebug_stmt (region
->entry
));
10711 if (gimple_omp_ordered_standalone_p (ord_stmt
))
10713 /* We'll expand these when expanding corresponding
10714 worksharing region with ordered(n) clause. */
10715 gcc_assert (region
->outer
10716 && region
->outer
->type
== GIMPLE_OMP_FOR
);
10717 region
->ord_stmt
= ord_stmt
;
10722 case GIMPLE_OMP_MASTER
:
10723 case GIMPLE_OMP_MASKED
:
10724 case GIMPLE_OMP_TASKGROUP
:
10725 case GIMPLE_OMP_CRITICAL
:
10726 case GIMPLE_OMP_TEAMS
:
10727 expand_omp_synch (region
);
10730 case GIMPLE_OMP_ATOMIC_LOAD
:
10731 expand_omp_atomic (region
);
10734 case GIMPLE_OMP_TARGET
:
10735 expand_omp_target (region
);
10739 gcc_unreachable ();
10742 input_location
= saved_location
;
10743 region
= region
->next
;
10745 if (omp_any_child_fn_dumped
)
10748 dump_function_header (dump_file
, current_function_decl
, dump_flags
);
10749 omp_any_child_fn_dumped
= false;
10753 /* Helper for build_omp_regions. Scan the dominator tree starting at
10754 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
10755 true, the function ends once a single tree is built (otherwise, whole
10756 forest of OMP constructs may be built). */
10759 build_omp_regions_1 (basic_block bb
, struct omp_region
*parent
,
10762 gimple_stmt_iterator gsi
;
10766 gsi
= gsi_last_nondebug_bb (bb
);
10767 if (!gsi_end_p (gsi
) && is_gimple_omp (gsi_stmt (gsi
)))
10769 struct omp_region
*region
;
10770 enum gimple_code code
;
10772 stmt
= gsi_stmt (gsi
);
10773 code
= gimple_code (stmt
);
10774 if (code
== GIMPLE_OMP_RETURN
)
10776 /* STMT is the return point out of region PARENT. Mark it
10777 as the exit point and make PARENT the immediately
10778 enclosing region. */
10779 gcc_assert (parent
);
10782 parent
= parent
->outer
;
10784 else if (code
== GIMPLE_OMP_ATOMIC_STORE
)
10786 /* GIMPLE_OMP_ATOMIC_STORE is analogous to
10787 GIMPLE_OMP_RETURN, but matches with
10788 GIMPLE_OMP_ATOMIC_LOAD. */
10789 gcc_assert (parent
);
10790 gcc_assert (parent
->type
== GIMPLE_OMP_ATOMIC_LOAD
);
10793 parent
= parent
->outer
;
10795 else if (code
== GIMPLE_OMP_CONTINUE
)
10797 gcc_assert (parent
);
10800 else if (code
== GIMPLE_OMP_SECTIONS_SWITCH
)
10802 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
10803 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
10807 region
= new_omp_region (bb
, code
, parent
);
10809 if (code
== GIMPLE_OMP_TARGET
)
10811 switch (gimple_omp_target_kind (stmt
))
10813 case GF_OMP_TARGET_KIND_REGION
:
10814 case GF_OMP_TARGET_KIND_OACC_PARALLEL
:
10815 case GF_OMP_TARGET_KIND_OACC_KERNELS
:
10816 case GF_OMP_TARGET_KIND_OACC_SERIAL
:
10817 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED
:
10818 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE
:
10820 case GF_OMP_TARGET_KIND_UPDATE
:
10821 case GF_OMP_TARGET_KIND_ENTER_DATA
:
10822 case GF_OMP_TARGET_KIND_EXIT_DATA
:
10823 case GF_OMP_TARGET_KIND_DATA
:
10824 case GF_OMP_TARGET_KIND_OACC_DATA
:
10825 case GF_OMP_TARGET_KIND_OACC_HOST_DATA
:
10826 case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS
:
10827 case GF_OMP_TARGET_KIND_OACC_UPDATE
:
10828 case GF_OMP_TARGET_KIND_OACC_ENTER_DATA
:
10829 case GF_OMP_TARGET_KIND_OACC_EXIT_DATA
:
10830 case GF_OMP_TARGET_KIND_OACC_DECLARE
:
10831 /* ..., other than for those stand-alone directives...
10832 To be precise, target data isn't stand-alone, but
10833 gimplifier put the end API call into try finally block
10834 for it, so omp expansion can treat it as such. */
10838 gcc_unreachable ();
10841 else if (code
== GIMPLE_OMP_ORDERED
10842 && gimple_omp_ordered_standalone_p (stmt
))
10843 /* #pragma omp ordered depend is also just a stand-alone
10846 else if (code
== GIMPLE_OMP_TASK
10847 && gimple_omp_task_taskwait_p (stmt
))
10848 /* #pragma omp taskwait depend(...) is a stand-alone directive. */
10850 else if (code
== GIMPLE_OMP_TASKGROUP
)
10851 /* #pragma omp taskgroup isn't a stand-alone directive, but
10852 gimplifier put the end API call into try finall block
10853 for it, so omp expansion can treat it as such. */
10855 /* ..., this directive becomes the parent for a new region. */
10861 if (single_tree
&& !parent
)
10864 for (son
= first_dom_son (CDI_DOMINATORS
, bb
);
10866 son
= next_dom_son (CDI_DOMINATORS
, son
))
10867 build_omp_regions_1 (son
, parent
, single_tree
);
10870 /* Builds the tree of OMP regions rooted at ROOT, storing it to
10871 root_omp_region. */
10874 build_omp_regions_root (basic_block root
)
10876 gcc_assert (root_omp_region
== NULL
);
10877 build_omp_regions_1 (root
, NULL
, true);
10878 gcc_assert (root_omp_region
!= NULL
);
10881 /* Expands omp construct (and its subconstructs) starting in HEAD. */
10884 omp_expand_local (basic_block head
)
10886 build_omp_regions_root (head
);
10887 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
10889 fprintf (dump_file
, "\nOMP region tree\n\n");
10890 dump_omp_region (dump_file
, root_omp_region
, 0);
10891 fprintf (dump_file
, "\n");
10894 remove_exit_barriers (root_omp_region
);
10895 expand_omp (root_omp_region
);
10897 omp_free_regions ();
10900 /* Scan the CFG and build a tree of OMP regions. Return the root of
10901 the OMP region tree. */
10904 build_omp_regions (void)
10906 gcc_assert (root_omp_region
== NULL
);
10907 calculate_dominance_info (CDI_DOMINATORS
);
10908 build_omp_regions_1 (ENTRY_BLOCK_PTR_FOR_FN (cfun
), NULL
, false);
10911 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
10913 static unsigned int
10914 execute_expand_omp (void)
10916 build_omp_regions ();
10918 if (!root_omp_region
)
10923 fprintf (dump_file
, "\nOMP region tree\n\n");
10924 dump_omp_region (dump_file
, root_omp_region
, 0);
10925 fprintf (dump_file
, "\n");
10928 remove_exit_barriers (root_omp_region
);
10930 expand_omp (root_omp_region
);
10932 omp_free_regions ();
10934 return (TODO_cleanup_cfg
10935 | (gimple_in_ssa_p (cfun
) ? TODO_update_ssa_only_virtuals
: 0));
10938 /* OMP expansion -- the default pass, run before creation of SSA form. */
10942 const pass_data pass_data_expand_omp
=
10944 GIMPLE_PASS
, /* type */
10945 "ompexp", /* name */
10946 OPTGROUP_OMP
, /* optinfo_flags */
10947 TV_NONE
, /* tv_id */
10948 PROP_gimple_any
, /* properties_required */
10949 PROP_gimple_eomp
, /* properties_provided */
10950 0, /* properties_destroyed */
10951 0, /* todo_flags_start */
10952 0, /* todo_flags_finish */
10955 class pass_expand_omp
: public gimple_opt_pass
10958 pass_expand_omp (gcc::context
*ctxt
)
10959 : gimple_opt_pass (pass_data_expand_omp
, ctxt
)
10962 /* opt_pass methods: */
10963 unsigned int execute (function
*) final override
10965 bool gate
= ((flag_openacc
!= 0 || flag_openmp
!= 0
10966 || flag_openmp_simd
!= 0)
10967 && !seen_error ());
10969 /* This pass always runs, to provide PROP_gimple_eomp.
10970 But often, there is nothing to do. */
10974 return execute_expand_omp ();
10977 }; // class pass_expand_omp
10979 } // anon namespace
10982 make_pass_expand_omp (gcc::context
*ctxt
)
10984 return new pass_expand_omp (ctxt
);
10989 const pass_data pass_data_expand_omp_ssa
=
10991 GIMPLE_PASS
, /* type */
10992 "ompexpssa", /* name */
10993 OPTGROUP_OMP
, /* optinfo_flags */
10994 TV_NONE
, /* tv_id */
10995 PROP_cfg
| PROP_ssa
, /* properties_required */
10996 PROP_gimple_eomp
, /* properties_provided */
10997 0, /* properties_destroyed */
10998 0, /* todo_flags_start */
10999 TODO_cleanup_cfg
| TODO_rebuild_alias
, /* todo_flags_finish */
11002 class pass_expand_omp_ssa
: public gimple_opt_pass
11005 pass_expand_omp_ssa (gcc::context
*ctxt
)
11006 : gimple_opt_pass (pass_data_expand_omp_ssa
, ctxt
)
11009 /* opt_pass methods: */
11010 bool gate (function
*fun
) final override
11012 return !(fun
->curr_properties
& PROP_gimple_eomp
);
11014 unsigned int execute (function
*) final override
11016 return execute_expand_omp ();
11018 opt_pass
* clone () final override
11020 return new pass_expand_omp_ssa (m_ctxt
);
11023 }; // class pass_expand_omp_ssa
11025 } // anon namespace
11028 make_pass_expand_omp_ssa (gcc::context
*ctxt
)
11030 return new pass_expand_omp_ssa (ctxt
);
11033 /* Called from tree-cfg.cc::make_edges to create cfg edges for all relevant
11037 omp_make_gimple_edges (basic_block bb
, struct omp_region
**region
,
11040 gimple
*last
= last_nondebug_stmt (bb
);
11041 enum gimple_code code
= gimple_code (last
);
11042 struct omp_region
*cur_region
= *region
;
11043 bool fallthru
= false;
11047 case GIMPLE_OMP_PARALLEL
:
11048 case GIMPLE_OMP_FOR
:
11049 case GIMPLE_OMP_SINGLE
:
11050 case GIMPLE_OMP_TEAMS
:
11051 case GIMPLE_OMP_MASTER
:
11052 case GIMPLE_OMP_MASKED
:
11053 case GIMPLE_OMP_SCOPE
:
11054 case GIMPLE_OMP_CRITICAL
:
11055 case GIMPLE_OMP_SECTION
:
11056 cur_region
= new_omp_region (bb
, code
, cur_region
);
11060 case GIMPLE_OMP_TASKGROUP
:
11061 cur_region
= new_omp_region (bb
, code
, cur_region
);
11063 cur_region
= cur_region
->outer
;
11066 case GIMPLE_OMP_TASK
:
11067 cur_region
= new_omp_region (bb
, code
, cur_region
);
11069 if (gimple_omp_task_taskwait_p (last
))
11070 cur_region
= cur_region
->outer
;
11073 case GIMPLE_OMP_ORDERED
:
11074 cur_region
= new_omp_region (bb
, code
, cur_region
);
11076 if (gimple_omp_ordered_standalone_p (last
))
11077 cur_region
= cur_region
->outer
;
11080 case GIMPLE_OMP_TARGET
:
11081 cur_region
= new_omp_region (bb
, code
, cur_region
);
11083 switch (gimple_omp_target_kind (last
))
11085 case GF_OMP_TARGET_KIND_REGION
:
11086 case GF_OMP_TARGET_KIND_OACC_PARALLEL
:
11087 case GF_OMP_TARGET_KIND_OACC_KERNELS
:
11088 case GF_OMP_TARGET_KIND_OACC_SERIAL
:
11089 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_PARALLELIZED
:
11090 case GF_OMP_TARGET_KIND_OACC_PARALLEL_KERNELS_GANG_SINGLE
:
11092 case GF_OMP_TARGET_KIND_UPDATE
:
11093 case GF_OMP_TARGET_KIND_ENTER_DATA
:
11094 case GF_OMP_TARGET_KIND_EXIT_DATA
:
11095 case GF_OMP_TARGET_KIND_DATA
:
11096 case GF_OMP_TARGET_KIND_OACC_DATA
:
11097 case GF_OMP_TARGET_KIND_OACC_HOST_DATA
:
11098 case GF_OMP_TARGET_KIND_OACC_DATA_KERNELS
:
11099 case GF_OMP_TARGET_KIND_OACC_UPDATE
:
11100 case GF_OMP_TARGET_KIND_OACC_ENTER_DATA
:
11101 case GF_OMP_TARGET_KIND_OACC_EXIT_DATA
:
11102 case GF_OMP_TARGET_KIND_OACC_DECLARE
:
11103 cur_region
= cur_region
->outer
;
11106 gcc_unreachable ();
11110 case GIMPLE_OMP_SECTIONS
:
11111 cur_region
= new_omp_region (bb
, code
, cur_region
);
11115 case GIMPLE_OMP_SECTIONS_SWITCH
:
11119 case GIMPLE_OMP_ATOMIC_LOAD
:
11120 case GIMPLE_OMP_ATOMIC_STORE
:
11124 case GIMPLE_OMP_RETURN
:
11125 /* In the case of a GIMPLE_OMP_SECTION, the edge will go
11126 somewhere other than the next block. This will be
11128 cur_region
->exit
= bb
;
11129 if (cur_region
->type
== GIMPLE_OMP_TASK
)
11130 /* Add an edge corresponding to not scheduling the task
11132 make_edge (cur_region
->entry
, bb
, EDGE_ABNORMAL
);
11133 fallthru
= cur_region
->type
!= GIMPLE_OMP_SECTION
;
11134 cur_region
= cur_region
->outer
;
11137 case GIMPLE_OMP_CONTINUE
:
11138 cur_region
->cont
= bb
;
11139 switch (cur_region
->type
)
11141 case GIMPLE_OMP_FOR
:
11142 /* Mark all GIMPLE_OMP_FOR and GIMPLE_OMP_CONTINUE
11143 succs edges as abnormal to prevent splitting
11145 single_succ_edge (cur_region
->entry
)->flags
|= EDGE_ABNORMAL
;
11146 /* Make the loopback edge. */
11147 make_edge (bb
, single_succ (cur_region
->entry
),
11150 /* Create an edge from GIMPLE_OMP_FOR to exit, which
11151 corresponds to the case that the body of the loop
11152 is not executed at all. */
11153 make_edge (cur_region
->entry
, bb
->next_bb
, EDGE_ABNORMAL
);
11154 make_edge (bb
, bb
->next_bb
, EDGE_FALLTHRU
| EDGE_ABNORMAL
);
11158 case GIMPLE_OMP_SECTIONS
:
11159 /* Wire up the edges into and out of the nested sections. */
11161 basic_block switch_bb
= single_succ (cur_region
->entry
);
11163 struct omp_region
*i
;
11164 for (i
= cur_region
->inner
; i
; i
= i
->next
)
11166 gcc_assert (i
->type
== GIMPLE_OMP_SECTION
);
11167 make_edge (switch_bb
, i
->entry
, 0);
11168 make_edge (i
->exit
, bb
, EDGE_FALLTHRU
);
11171 /* Make the loopback edge to the block with
11172 GIMPLE_OMP_SECTIONS_SWITCH. */
11173 make_edge (bb
, switch_bb
, 0);
11175 /* Make the edge from the switch to exit. */
11176 make_edge (switch_bb
, bb
->next_bb
, 0);
11181 case GIMPLE_OMP_TASK
:
11186 gcc_unreachable ();
11191 gcc_unreachable ();
11194 if (*region
!= cur_region
)
11196 *region
= cur_region
;
11198 *region_idx
= cur_region
->entry
->index
;