1 /* Lowering pass for OpenMP directives. Converts OpenMP directives
2 into explicit calls to the runtime library (libgomp) and data
3 marshalling to implement data sharing and copying clauses.
4 Contributed by Diego Novillo <dnovillo@redhat.com>
6 Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
31 #include "tree-iterator.h"
32 #include "tree-inline.h"
33 #include "langhooks.h"
34 #include "diagnostic.h"
35 #include "tree-flow.h"
41 #include "tree-pass.h"
44 #include "splay-tree.h"
49 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
50 phases. The first phase scans the function looking for OMP statements
51 and then for variables that must be replaced to satisfy data sharing
52 clauses. The second phase expands code for the constructs, as well as
53 re-gimplifying things when variables have been replaced with complex
56 Final code generation is done by pass_expand_omp. The flowgraph is
57 scanned for parallel regions which are then moved to a new
58 function, to be invoked by the thread library. */
60 /* Context structure. Used to store information about each parallel
61 directive in the code. */
63 typedef struct omp_context
65 /* This field must be at the beginning, as we do "inheritance": Some
66 callback functions for tree-inline.c (e.g., omp_copy_decl)
67 receive a copy_body_data pointer that is up-casted to an
68 omp_context pointer. */
71 /* The tree of contexts corresponding to the encountered constructs. */
72 struct omp_context
*outer
;
75 /* Map variables to fields in a structure that allows communication
76 between sending and receiving threads. */
82 /* These are used just by task contexts, if task firstprivate fn is
83 needed. srecord_type is used to communicate from the thread
84 that encountered the task construct to task firstprivate fn,
85 record_type is allocated by GOMP_task, initialized by task firstprivate
86 fn and passed to the task body fn. */
87 splay_tree sfield_map
;
90 /* A chain of variables to add to the top-level block surrounding the
91 construct. In the case of a parallel, this is in the child function. */
94 /* What to do with variables with implicitly determined sharing
96 enum omp_clause_default_kind default_kind
;
98 /* Nesting depth of this context. Used to beautify error messages re
99 invalid gotos. The outermost ctx is depth 1, with depth 0 being
100 reserved for the main body of the function. */
103 /* True if this parallel directive is nested within another. */
108 struct omp_for_data_loop
110 tree v
, n1
, n2
, step
;
111 enum tree_code cond_code
;
114 /* A structure describing the main elements of a parallel loop. */
118 struct omp_for_data_loop loop
;
123 bool have_nowait
, have_ordered
;
124 enum omp_clause_schedule_kind sched_kind
;
125 struct omp_for_data_loop
*loops
;
129 static splay_tree all_contexts
;
130 static int taskreg_nesting_level
;
131 struct omp_region
*root_omp_region
;
132 static bitmap task_shared_vars
;
134 static void scan_omp (gimple_seq
, omp_context
*);
135 static tree
scan_omp_1_op (tree
*, int *, void *);
137 #define WALK_SUBSTMTS \
141 case GIMPLE_EH_FILTER: \
142 /* The sub-statements for these should be walked. */ \
143 *handled_ops_p = false; \
146 /* Convenience function for calling scan_omp_1_op on tree operands. */
149 scan_omp_op (tree
*tp
, omp_context
*ctx
)
151 struct walk_stmt_info wi
;
153 memset (&wi
, 0, sizeof (wi
));
155 wi
.want_locations
= true;
157 return walk_tree (tp
, scan_omp_1_op
, &wi
, NULL
);
160 static void lower_omp (gimple_seq
, omp_context
*);
161 static tree
lookup_decl_in_outer_ctx (tree
, omp_context
*);
162 static tree
maybe_lookup_decl_in_outer_ctx (tree
, omp_context
*);
164 /* Find an OpenMP clause of type KIND within CLAUSES. */
167 find_omp_clause (tree clauses
, enum omp_clause_code kind
)
169 for (; clauses
; clauses
= OMP_CLAUSE_CHAIN (clauses
))
170 if (OMP_CLAUSE_CODE (clauses
) == kind
)
176 /* Return true if CTX is for an omp parallel. */
179 is_parallel_ctx (omp_context
*ctx
)
181 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
;
185 /* Return true if CTX is for an omp task. */
188 is_task_ctx (omp_context
*ctx
)
190 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_TASK
;
194 /* Return true if CTX is for an omp parallel or omp task. */
197 is_taskreg_ctx (omp_context
*ctx
)
199 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
200 || gimple_code (ctx
->stmt
) == GIMPLE_OMP_TASK
;
204 /* Return true if REGION is a combined parallel+workshare region. */
207 is_combined_parallel (struct omp_region
*region
)
209 return region
->is_combined_parallel
;
213 /* Extract the header elements of parallel loop FOR_STMT and store
217 extract_omp_for_data (gimple for_stmt
, struct omp_for_data
*fd
,
218 struct omp_for_data_loop
*loops
)
220 tree t
, var
, *collapse_iter
, *collapse_count
;
221 tree count
= NULL_TREE
, iter_type
= long_integer_type_node
;
222 struct omp_for_data_loop
*loop
;
224 struct omp_for_data_loop dummy_loop
;
225 location_t loc
= gimple_location (for_stmt
);
227 fd
->for_stmt
= for_stmt
;
229 fd
->collapse
= gimple_omp_for_collapse (for_stmt
);
230 if (fd
->collapse
> 1)
233 fd
->loops
= &fd
->loop
;
235 fd
->have_nowait
= fd
->have_ordered
= false;
236 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
237 fd
->chunk_size
= NULL_TREE
;
238 collapse_iter
= NULL
;
239 collapse_count
= NULL
;
241 for (t
= gimple_omp_for_clauses (for_stmt
); t
; t
= OMP_CLAUSE_CHAIN (t
))
242 switch (OMP_CLAUSE_CODE (t
))
244 case OMP_CLAUSE_NOWAIT
:
245 fd
->have_nowait
= true;
247 case OMP_CLAUSE_ORDERED
:
248 fd
->have_ordered
= true;
250 case OMP_CLAUSE_SCHEDULE
:
251 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_KIND (t
);
252 fd
->chunk_size
= OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t
);
254 case OMP_CLAUSE_COLLAPSE
:
255 if (fd
->collapse
> 1)
257 collapse_iter
= &OMP_CLAUSE_COLLAPSE_ITERVAR (t
);
258 collapse_count
= &OMP_CLAUSE_COLLAPSE_COUNT (t
);
264 /* FIXME: for now map schedule(auto) to schedule(static).
265 There should be analysis to determine whether all iterations
266 are approximately the same amount of work (then schedule(static)
267 is best) or if it varies (then schedule(dynamic,N) is better). */
268 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_AUTO
)
270 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
271 gcc_assert (fd
->chunk_size
== NULL
);
273 gcc_assert (fd
->collapse
== 1 || collapse_iter
!= NULL
);
274 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
275 gcc_assert (fd
->chunk_size
== NULL
);
276 else if (fd
->chunk_size
== NULL
)
278 /* We only need to compute a default chunk size for ordered
279 static loops and dynamic loops. */
280 if (fd
->sched_kind
!= OMP_CLAUSE_SCHEDULE_STATIC
283 fd
->chunk_size
= (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
284 ? integer_zero_node
: integer_one_node
;
287 for (i
= 0; i
< fd
->collapse
; i
++)
289 if (fd
->collapse
== 1)
291 else if (loops
!= NULL
)
297 loop
->v
= gimple_omp_for_index (for_stmt
, i
);
298 gcc_assert (SSA_VAR_P (loop
->v
));
299 gcc_assert (TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
300 || TREE_CODE (TREE_TYPE (loop
->v
)) == POINTER_TYPE
);
301 var
= TREE_CODE (loop
->v
) == SSA_NAME
? SSA_NAME_VAR (loop
->v
) : loop
->v
;
302 loop
->n1
= gimple_omp_for_initial (for_stmt
, i
);
304 loop
->cond_code
= gimple_omp_for_cond (for_stmt
, i
);
305 loop
->n2
= gimple_omp_for_final (for_stmt
, i
);
306 switch (loop
->cond_code
)
312 if (POINTER_TYPE_P (TREE_TYPE (loop
->n2
)))
313 loop
->n2
= fold_build2_loc (loc
,
314 POINTER_PLUS_EXPR
, TREE_TYPE (loop
->n2
),
315 loop
->n2
, size_one_node
);
317 loop
->n2
= fold_build2_loc (loc
,
318 PLUS_EXPR
, TREE_TYPE (loop
->n2
), loop
->n2
,
319 build_int_cst (TREE_TYPE (loop
->n2
), 1));
320 loop
->cond_code
= LT_EXPR
;
323 if (POINTER_TYPE_P (TREE_TYPE (loop
->n2
)))
324 loop
->n2
= fold_build2_loc (loc
,
325 POINTER_PLUS_EXPR
, TREE_TYPE (loop
->n2
),
326 loop
->n2
, size_int (-1));
328 loop
->n2
= fold_build2_loc (loc
,
329 MINUS_EXPR
, TREE_TYPE (loop
->n2
), loop
->n2
,
330 build_int_cst (TREE_TYPE (loop
->n2
), 1));
331 loop
->cond_code
= GT_EXPR
;
337 t
= gimple_omp_for_incr (for_stmt
, i
);
338 gcc_assert (TREE_OPERAND (t
, 0) == var
);
339 switch (TREE_CODE (t
))
342 case POINTER_PLUS_EXPR
:
343 loop
->step
= TREE_OPERAND (t
, 1);
346 loop
->step
= TREE_OPERAND (t
, 1);
347 loop
->step
= fold_build1_loc (loc
,
348 NEGATE_EXPR
, TREE_TYPE (loop
->step
),
355 if (iter_type
!= long_long_unsigned_type_node
)
357 if (POINTER_TYPE_P (TREE_TYPE (loop
->v
)))
358 iter_type
= long_long_unsigned_type_node
;
359 else if (TYPE_UNSIGNED (TREE_TYPE (loop
->v
))
360 && TYPE_PRECISION (TREE_TYPE (loop
->v
))
361 >= TYPE_PRECISION (iter_type
))
365 if (loop
->cond_code
== LT_EXPR
)
366 n
= fold_build2_loc (loc
,
367 PLUS_EXPR
, TREE_TYPE (loop
->v
),
368 loop
->n2
, loop
->step
);
371 if (TREE_CODE (n
) != INTEGER_CST
372 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type
), n
))
373 iter_type
= long_long_unsigned_type_node
;
375 else if (TYPE_PRECISION (TREE_TYPE (loop
->v
))
376 > TYPE_PRECISION (iter_type
))
380 if (loop
->cond_code
== LT_EXPR
)
383 n2
= fold_build2_loc (loc
,
384 PLUS_EXPR
, TREE_TYPE (loop
->v
),
385 loop
->n2
, loop
->step
);
389 n1
= fold_build2_loc (loc
,
390 MINUS_EXPR
, TREE_TYPE (loop
->v
),
391 loop
->n2
, loop
->step
);
394 if (TREE_CODE (n1
) != INTEGER_CST
395 || TREE_CODE (n2
) != INTEGER_CST
396 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type
), n1
)
397 || !tree_int_cst_lt (n2
, TYPE_MAX_VALUE (iter_type
)))
398 iter_type
= long_long_unsigned_type_node
;
402 if (collapse_count
&& *collapse_count
== NULL
)
404 if ((i
== 0 || count
!= NULL_TREE
)
405 && TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
406 && TREE_CONSTANT (loop
->n1
)
407 && TREE_CONSTANT (loop
->n2
)
408 && TREE_CODE (loop
->step
) == INTEGER_CST
)
410 tree itype
= TREE_TYPE (loop
->v
);
412 if (POINTER_TYPE_P (itype
))
414 = lang_hooks
.types
.type_for_size (TYPE_PRECISION (itype
), 0);
415 t
= build_int_cst (itype
, (loop
->cond_code
== LT_EXPR
? -1 : 1));
416 t
= fold_build2_loc (loc
,
418 fold_convert_loc (loc
, itype
, loop
->step
), t
);
419 t
= fold_build2_loc (loc
, PLUS_EXPR
, itype
, t
,
420 fold_convert_loc (loc
, itype
, loop
->n2
));
421 t
= fold_build2_loc (loc
, MINUS_EXPR
, itype
, t
,
422 fold_convert_loc (loc
, itype
, loop
->n1
));
423 if (TYPE_UNSIGNED (itype
) && loop
->cond_code
== GT_EXPR
)
424 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
,
425 fold_build1_loc (loc
, NEGATE_EXPR
, itype
, t
),
426 fold_build1_loc (loc
, NEGATE_EXPR
, itype
,
427 fold_convert_loc (loc
, itype
,
430 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
, t
,
431 fold_convert_loc (loc
, itype
, loop
->step
));
432 t
= fold_convert_loc (loc
, long_long_unsigned_type_node
, t
);
433 if (count
!= NULL_TREE
)
434 count
= fold_build2_loc (loc
,
435 MULT_EXPR
, long_long_unsigned_type_node
,
439 if (TREE_CODE (count
) != INTEGER_CST
)
449 if (!tree_int_cst_lt (count
, TYPE_MAX_VALUE (long_integer_type_node
)))
450 iter_type
= long_long_unsigned_type_node
;
452 iter_type
= long_integer_type_node
;
454 else if (collapse_iter
&& *collapse_iter
!= NULL
)
455 iter_type
= TREE_TYPE (*collapse_iter
);
456 fd
->iter_type
= iter_type
;
457 if (collapse_iter
&& *collapse_iter
== NULL
)
458 *collapse_iter
= create_tmp_var (iter_type
, ".iter");
459 if (collapse_count
&& *collapse_count
== NULL
)
462 *collapse_count
= fold_convert_loc (loc
, iter_type
, count
);
464 *collapse_count
= create_tmp_var (iter_type
, ".count");
467 if (fd
->collapse
> 1)
469 fd
->loop
.v
= *collapse_iter
;
470 fd
->loop
.n1
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
471 fd
->loop
.n2
= *collapse_count
;
472 fd
->loop
.step
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 1);
473 fd
->loop
.cond_code
= LT_EXPR
;
478 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
479 is the immediate dominator of PAR_ENTRY_BB, return true if there
480 are no data dependencies that would prevent expanding the parallel
481 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
483 When expanding a combined parallel+workshare region, the call to
484 the child function may need additional arguments in the case of
485 GIMPLE_OMP_FOR regions. In some cases, these arguments are
486 computed out of variables passed in from the parent to the child
487 via 'struct .omp_data_s'. For instance:
489 #pragma omp parallel for schedule (guided, i * 4)
494 # BLOCK 2 (PAR_ENTRY_BB)
496 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
498 # BLOCK 3 (WS_ENTRY_BB)
499 .omp_data_i = &.omp_data_o;
500 D.1667 = .omp_data_i->i;
502 #pragma omp for schedule (guided, D.1598)
504 When we outline the parallel region, the call to the child function
505 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
506 that value is computed *after* the call site. So, in principle we
507 cannot do the transformation.
509 To see whether the code in WS_ENTRY_BB blocks the combined
510 parallel+workshare call, we collect all the variables used in the
511 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
512 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
515 FIXME. If we had the SSA form built at this point, we could merely
516 hoist the code in block 3 into block 2 and be done with it. But at
517 this point we don't have dataflow information and though we could
518 hack something up here, it is really not worth the aggravation. */
521 workshare_safe_to_combine_p (basic_block ws_entry_bb
)
523 struct omp_for_data fd
;
524 gimple ws_stmt
= last_stmt (ws_entry_bb
);
526 if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
529 gcc_assert (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
);
531 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
533 if (fd
.collapse
> 1 && TREE_CODE (fd
.loop
.n2
) != INTEGER_CST
)
535 if (fd
.iter_type
!= long_integer_type_node
)
538 /* FIXME. We give up too easily here. If any of these arguments
539 are not constants, they will likely involve variables that have
540 been mapped into fields of .omp_data_s for sharing with the child
541 function. With appropriate data flow, it would be possible to
543 if (!is_gimple_min_invariant (fd
.loop
.n1
)
544 || !is_gimple_min_invariant (fd
.loop
.n2
)
545 || !is_gimple_min_invariant (fd
.loop
.step
)
546 || (fd
.chunk_size
&& !is_gimple_min_invariant (fd
.chunk_size
)))
553 /* Collect additional arguments needed to emit a combined
554 parallel+workshare call. WS_STMT is the workshare directive being
558 get_ws_args_for (gimple ws_stmt
)
561 location_t loc
= gimple_location (ws_stmt
);
563 if (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
)
565 struct omp_for_data fd
;
568 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
573 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.chunk_size
);
574 ws_args
= tree_cons (NULL
, t
, ws_args
);
577 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.step
);
578 ws_args
= tree_cons (NULL
, t
, ws_args
);
580 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.n2
);
581 ws_args
= tree_cons (NULL
, t
, ws_args
);
583 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.n1
);
584 ws_args
= tree_cons (NULL
, t
, ws_args
);
588 else if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
590 /* Number of sections is equal to the number of edges from the
591 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
592 the exit of the sections region. */
593 basic_block bb
= single_succ (gimple_bb (ws_stmt
));
594 t
= build_int_cst (unsigned_type_node
, EDGE_COUNT (bb
->succs
) - 1);
595 t
= tree_cons (NULL
, t
, NULL
);
603 /* Discover whether REGION is a combined parallel+workshare region. */
606 determine_parallel_type (struct omp_region
*region
)
608 basic_block par_entry_bb
, par_exit_bb
;
609 basic_block ws_entry_bb
, ws_exit_bb
;
611 if (region
== NULL
|| region
->inner
== NULL
612 || region
->exit
== NULL
|| region
->inner
->exit
== NULL
613 || region
->inner
->cont
== NULL
)
616 /* We only support parallel+for and parallel+sections. */
617 if (region
->type
!= GIMPLE_OMP_PARALLEL
618 || (region
->inner
->type
!= GIMPLE_OMP_FOR
619 && region
->inner
->type
!= GIMPLE_OMP_SECTIONS
))
622 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
623 WS_EXIT_BB -> PAR_EXIT_BB. */
624 par_entry_bb
= region
->entry
;
625 par_exit_bb
= region
->exit
;
626 ws_entry_bb
= region
->inner
->entry
;
627 ws_exit_bb
= region
->inner
->exit
;
629 if (single_succ (par_entry_bb
) == ws_entry_bb
630 && single_succ (ws_exit_bb
) == par_exit_bb
631 && workshare_safe_to_combine_p (ws_entry_bb
)
632 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb
))
633 || (last_and_only_stmt (ws_entry_bb
)
634 && last_and_only_stmt (par_exit_bb
))))
636 gimple ws_stmt
= last_stmt (ws_entry_bb
);
638 if (region
->inner
->type
== GIMPLE_OMP_FOR
)
640 /* If this is a combined parallel loop, we need to determine
641 whether or not to use the combined library calls. There
642 are two cases where we do not apply the transformation:
643 static loops and any kind of ordered loop. In the first
644 case, we already open code the loop so there is no need
645 to do anything else. In the latter case, the combined
646 parallel loop call would still need extra synchronization
647 to implement ordered semantics, so there would not be any
648 gain in using the combined call. */
649 tree clauses
= gimple_omp_for_clauses (ws_stmt
);
650 tree c
= find_omp_clause (clauses
, OMP_CLAUSE_SCHEDULE
);
652 || OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_STATIC
653 || find_omp_clause (clauses
, OMP_CLAUSE_ORDERED
))
655 region
->is_combined_parallel
= false;
656 region
->inner
->is_combined_parallel
= false;
661 region
->is_combined_parallel
= true;
662 region
->inner
->is_combined_parallel
= true;
663 region
->ws_args
= get_ws_args_for (ws_stmt
);
668 /* Return true if EXPR is variable sized. */
671 is_variable_sized (const_tree expr
)
673 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr
)));
676 /* Return true if DECL is a reference type. */
679 is_reference (tree decl
)
681 return lang_hooks
.decls
.omp_privatize_by_reference (decl
);
684 /* Lookup variables in the decl or field splay trees. The "maybe" form
685 allows for the variable form to not have been entered, otherwise we
686 assert that the variable must have been entered. */
689 lookup_decl (tree var
, omp_context
*ctx
)
692 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
697 maybe_lookup_decl (const_tree var
, omp_context
*ctx
)
700 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
701 return n
? *n
: NULL_TREE
;
705 lookup_field (tree var
, omp_context
*ctx
)
708 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
709 return (tree
) n
->value
;
713 lookup_sfield (tree var
, omp_context
*ctx
)
716 n
= splay_tree_lookup (ctx
->sfield_map
717 ? ctx
->sfield_map
: ctx
->field_map
,
718 (splay_tree_key
) var
);
719 return (tree
) n
->value
;
723 maybe_lookup_field (tree var
, omp_context
*ctx
)
726 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
727 return n
? (tree
) n
->value
: NULL_TREE
;
730 /* Return true if DECL should be copied by pointer. SHARED_CTX is
731 the parallel context if DECL is to be shared. */
734 use_pointer_for_field (tree decl
, omp_context
*shared_ctx
)
736 if (AGGREGATE_TYPE_P (TREE_TYPE (decl
)))
739 /* We can only use copy-in/copy-out semantics for shared variables
740 when we know the value is not accessible from an outer scope. */
743 /* ??? Trivially accessible from anywhere. But why would we even
744 be passing an address in this case? Should we simply assert
745 this to be false, or should we have a cleanup pass that removes
746 these from the list of mappings? */
747 if (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
750 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
751 without analyzing the expression whether or not its location
752 is accessible to anyone else. In the case of nested parallel
753 regions it certainly may be. */
754 if (TREE_CODE (decl
) != RESULT_DECL
&& DECL_HAS_VALUE_EXPR_P (decl
))
757 /* Do not use copy-in/copy-out for variables that have their
759 if (TREE_ADDRESSABLE (decl
))
762 /* Disallow copy-in/out in nested parallel if
763 decl is shared in outer parallel, otherwise
764 each thread could store the shared variable
765 in its own copy-in location, making the
766 variable no longer really shared. */
767 if (!TREE_READONLY (decl
) && shared_ctx
->is_nested
)
771 for (up
= shared_ctx
->outer
; up
; up
= up
->outer
)
772 if (is_taskreg_ctx (up
) && maybe_lookup_decl (decl
, up
))
779 for (c
= gimple_omp_taskreg_clauses (up
->stmt
);
780 c
; c
= OMP_CLAUSE_CHAIN (c
))
781 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
782 && OMP_CLAUSE_DECL (c
) == decl
)
790 /* For tasks avoid using copy-in/out, unless they are readonly
791 (in which case just copy-in is used). As tasks can be
792 deferred or executed in different thread, when GOMP_task
793 returns, the task hasn't necessarily terminated. */
794 if (!TREE_READONLY (decl
) && is_task_ctx (shared_ctx
))
796 tree outer
= maybe_lookup_decl_in_outer_ctx (decl
, shared_ctx
);
797 if (is_gimple_reg (outer
))
799 /* Taking address of OUTER in lower_send_shared_vars
800 might need regimplification of everything that uses the
802 if (!task_shared_vars
)
803 task_shared_vars
= BITMAP_ALLOC (NULL
);
804 bitmap_set_bit (task_shared_vars
, DECL_UID (outer
));
805 TREE_ADDRESSABLE (outer
) = 1;
814 /* Create a new VAR_DECL and copy information from VAR to it. */
817 copy_var_decl (tree var
, tree name
, tree type
)
819 tree copy
= build_decl (DECL_SOURCE_LOCATION (var
), VAR_DECL
, name
, type
);
821 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (var
);
822 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (var
);
823 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (var
);
824 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (var
);
825 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (var
);
826 DECL_CONTEXT (copy
) = DECL_CONTEXT (var
);
827 TREE_USED (copy
) = 1;
828 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
833 /* Construct a new automatic decl similar to VAR. */
836 omp_copy_decl_2 (tree var
, tree name
, tree type
, omp_context
*ctx
)
838 tree copy
= copy_var_decl (var
, name
, type
);
840 DECL_CONTEXT (copy
) = current_function_decl
;
841 TREE_CHAIN (copy
) = ctx
->block_vars
;
842 ctx
->block_vars
= copy
;
848 omp_copy_decl_1 (tree var
, omp_context
*ctx
)
850 return omp_copy_decl_2 (var
, DECL_NAME (var
), TREE_TYPE (var
), ctx
);
853 /* Build tree nodes to access the field for VAR on the receiver side. */
856 build_receiver_ref (tree var
, bool by_ref
, omp_context
*ctx
)
858 tree x
, field
= lookup_field (var
, ctx
);
860 /* If the receiver record type was remapped in the child function,
861 remap the field into the new record type. */
862 x
= maybe_lookup_field (field
, ctx
);
866 x
= build_fold_indirect_ref (ctx
->receiver_decl
);
867 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL
);
869 x
= build_fold_indirect_ref (x
);
874 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
875 of a parallel, this is a component reference; for workshare constructs
876 this is some variable. */
879 build_outer_var_ref (tree var
, omp_context
*ctx
)
883 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
, ctx
)))
885 else if (is_variable_sized (var
))
887 x
= TREE_OPERAND (DECL_VALUE_EXPR (var
), 0);
888 x
= build_outer_var_ref (x
, ctx
);
889 x
= build_fold_indirect_ref (x
);
891 else if (is_taskreg_ctx (ctx
))
893 bool by_ref
= use_pointer_for_field (var
, NULL
);
894 x
= build_receiver_ref (var
, by_ref
, ctx
);
897 x
= lookup_decl (var
, ctx
->outer
);
898 else if (is_reference (var
))
899 /* This can happen with orphaned constructs. If var is reference, it is
900 possible it is shared and as such valid. */
905 if (is_reference (var
))
906 x
= build_fold_indirect_ref (x
);
911 /* Build tree nodes to access the field for VAR on the sender side. */
914 build_sender_ref (tree var
, omp_context
*ctx
)
916 tree field
= lookup_sfield (var
, ctx
);
917 return build3 (COMPONENT_REF
, TREE_TYPE (field
),
918 ctx
->sender_decl
, field
, NULL
);
921 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
924 install_var_field (tree var
, bool by_ref
, int mask
, omp_context
*ctx
)
926 tree field
, type
, sfield
= NULL_TREE
;
928 gcc_assert ((mask
& 1) == 0
929 || !splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
));
930 gcc_assert ((mask
& 2) == 0 || !ctx
->sfield_map
931 || !splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) var
));
933 type
= TREE_TYPE (var
);
935 type
= build_pointer_type (type
);
936 else if ((mask
& 3) == 1 && is_reference (var
))
937 type
= TREE_TYPE (type
);
939 field
= build_decl (DECL_SOURCE_LOCATION (var
),
940 FIELD_DECL
, DECL_NAME (var
), type
);
942 /* Remember what variable this field was created for. This does have a
943 side effect of making dwarf2out ignore this member, so for helpful
944 debugging we clear it later in delete_omp_context. */
945 DECL_ABSTRACT_ORIGIN (field
) = var
;
946 if (type
== TREE_TYPE (var
))
948 DECL_ALIGN (field
) = DECL_ALIGN (var
);
949 DECL_USER_ALIGN (field
) = DECL_USER_ALIGN (var
);
950 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (var
);
953 DECL_ALIGN (field
) = TYPE_ALIGN (type
);
957 insert_field_into_struct (ctx
->record_type
, field
);
958 if (ctx
->srecord_type
)
960 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
961 FIELD_DECL
, DECL_NAME (var
), type
);
962 DECL_ABSTRACT_ORIGIN (sfield
) = var
;
963 DECL_ALIGN (sfield
) = DECL_ALIGN (field
);
964 DECL_USER_ALIGN (sfield
) = DECL_USER_ALIGN (field
);
965 TREE_THIS_VOLATILE (sfield
) = TREE_THIS_VOLATILE (field
);
966 insert_field_into_struct (ctx
->srecord_type
, sfield
);
971 if (ctx
->srecord_type
== NULL_TREE
)
975 ctx
->srecord_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
976 ctx
->sfield_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
977 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= TREE_CHAIN (t
))
979 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
980 FIELD_DECL
, DECL_NAME (t
), TREE_TYPE (t
));
981 DECL_ABSTRACT_ORIGIN (sfield
) = DECL_ABSTRACT_ORIGIN (t
);
982 insert_field_into_struct (ctx
->srecord_type
, sfield
);
983 splay_tree_insert (ctx
->sfield_map
,
984 (splay_tree_key
) DECL_ABSTRACT_ORIGIN (t
),
985 (splay_tree_value
) sfield
);
989 insert_field_into_struct ((mask
& 1) ? ctx
->record_type
990 : ctx
->srecord_type
, field
);
994 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) var
,
995 (splay_tree_value
) field
);
996 if ((mask
& 2) && ctx
->sfield_map
)
997 splay_tree_insert (ctx
->sfield_map
, (splay_tree_key
) var
,
998 (splay_tree_value
) sfield
);
1002 install_var_local (tree var
, omp_context
*ctx
)
1004 tree new_var
= omp_copy_decl_1 (var
, ctx
);
1005 insert_decl_map (&ctx
->cb
, var
, new_var
);
1009 /* Adjust the replacement for DECL in CTX for the new context. This means
1010 copying the DECL_VALUE_EXPR, and fixing up the type. */
1013 fixup_remapped_decl (tree decl
, omp_context
*ctx
, bool private_debug
)
1015 tree new_decl
, size
;
1017 new_decl
= lookup_decl (decl
, ctx
);
1019 TREE_TYPE (new_decl
) = remap_type (TREE_TYPE (decl
), &ctx
->cb
);
1021 if ((!TREE_CONSTANT (DECL_SIZE (new_decl
)) || private_debug
)
1022 && DECL_HAS_VALUE_EXPR_P (decl
))
1024 tree ve
= DECL_VALUE_EXPR (decl
);
1025 walk_tree (&ve
, copy_tree_body_r
, &ctx
->cb
, NULL
);
1026 SET_DECL_VALUE_EXPR (new_decl
, ve
);
1027 DECL_HAS_VALUE_EXPR_P (new_decl
) = 1;
1030 if (!TREE_CONSTANT (DECL_SIZE (new_decl
)))
1032 size
= remap_decl (DECL_SIZE (decl
), &ctx
->cb
);
1033 if (size
== error_mark_node
)
1034 size
= TYPE_SIZE (TREE_TYPE (new_decl
));
1035 DECL_SIZE (new_decl
) = size
;
1037 size
= remap_decl (DECL_SIZE_UNIT (decl
), &ctx
->cb
);
1038 if (size
== error_mark_node
)
1039 size
= TYPE_SIZE_UNIT (TREE_TYPE (new_decl
));
1040 DECL_SIZE_UNIT (new_decl
) = size
;
1044 /* The callback for remap_decl. Search all containing contexts for a
1045 mapping of the variable; this avoids having to duplicate the splay
1046 tree ahead of time. We know a mapping doesn't already exist in the
1047 given context. Create new mappings to implement default semantics. */
1050 omp_copy_decl (tree var
, copy_body_data
*cb
)
1052 omp_context
*ctx
= (omp_context
*) cb
;
1055 if (TREE_CODE (var
) == LABEL_DECL
)
1057 new_var
= create_artificial_label (DECL_SOURCE_LOCATION (var
));
1058 DECL_CONTEXT (new_var
) = current_function_decl
;
1059 insert_decl_map (&ctx
->cb
, var
, new_var
);
1063 while (!is_taskreg_ctx (ctx
))
1068 new_var
= maybe_lookup_decl (var
, ctx
);
1073 if (is_global_var (var
) || decl_function_context (var
) != ctx
->cb
.src_fn
)
1076 return error_mark_node
;
1080 /* Return the parallel region associated with STMT. */
1082 /* Debugging dumps for parallel regions. */
1083 void dump_omp_region (FILE *, struct omp_region
*, int);
1084 void debug_omp_region (struct omp_region
*);
1085 void debug_all_omp_regions (void);
1087 /* Dump the parallel region tree rooted at REGION. */
1090 dump_omp_region (FILE *file
, struct omp_region
*region
, int indent
)
1092 fprintf (file
, "%*sbb %d: %s\n", indent
, "", region
->entry
->index
,
1093 gimple_code_name
[region
->type
]);
1096 dump_omp_region (file
, region
->inner
, indent
+ 4);
1100 fprintf (file
, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent
, "",
1101 region
->cont
->index
);
1105 fprintf (file
, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent
, "",
1106 region
->exit
->index
);
1108 fprintf (file
, "%*s[no exit marker]\n", indent
, "");
1111 dump_omp_region (file
, region
->next
, indent
);
1115 debug_omp_region (struct omp_region
*region
)
1117 dump_omp_region (stderr
, region
, 0);
1121 debug_all_omp_regions (void)
1123 dump_omp_region (stderr
, root_omp_region
, 0);
1127 /* Create a new parallel region starting at STMT inside region PARENT. */
1130 new_omp_region (basic_block bb
, enum gimple_code type
,
1131 struct omp_region
*parent
)
1133 struct omp_region
*region
= XCNEW (struct omp_region
);
1135 region
->outer
= parent
;
1137 region
->type
= type
;
1141 /* This is a nested region. Add it to the list of inner
1142 regions in PARENT. */
1143 region
->next
= parent
->inner
;
1144 parent
->inner
= region
;
1148 /* This is a toplevel region. Add it to the list of toplevel
1149 regions in ROOT_OMP_REGION. */
1150 region
->next
= root_omp_region
;
1151 root_omp_region
= region
;
1157 /* Release the memory associated with the region tree rooted at REGION. */
1160 free_omp_region_1 (struct omp_region
*region
)
1162 struct omp_region
*i
, *n
;
1164 for (i
= region
->inner
; i
; i
= n
)
1167 free_omp_region_1 (i
);
1173 /* Release the memory for the entire omp region tree. */
1176 free_omp_regions (void)
1178 struct omp_region
*r
, *n
;
1179 for (r
= root_omp_region
; r
; r
= n
)
1182 free_omp_region_1 (r
);
1184 root_omp_region
= NULL
;
1188 /* Create a new context, with OUTER_CTX being the surrounding context. */
1190 static omp_context
*
1191 new_omp_context (gimple stmt
, omp_context
*outer_ctx
)
1193 omp_context
*ctx
= XCNEW (omp_context
);
1195 splay_tree_insert (all_contexts
, (splay_tree_key
) stmt
,
1196 (splay_tree_value
) ctx
);
1201 ctx
->outer
= outer_ctx
;
1202 ctx
->cb
= outer_ctx
->cb
;
1203 ctx
->cb
.block
= NULL
;
1204 ctx
->depth
= outer_ctx
->depth
+ 1;
1208 ctx
->cb
.src_fn
= current_function_decl
;
1209 ctx
->cb
.dst_fn
= current_function_decl
;
1210 ctx
->cb
.src_node
= cgraph_node (current_function_decl
);
1211 ctx
->cb
.dst_node
= ctx
->cb
.src_node
;
1212 ctx
->cb
.src_cfun
= cfun
;
1213 ctx
->cb
.copy_decl
= omp_copy_decl
;
1214 ctx
->cb
.eh_lp_nr
= 0;
1215 ctx
->cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
1219 ctx
->cb
.decl_map
= pointer_map_create ();
1224 static gimple_seq
maybe_catch_exception (gimple_seq
);
1226 /* Finalize task copyfn. */
1229 finalize_task_copyfn (gimple task_stmt
)
1231 struct function
*child_cfun
;
1232 tree child_fn
, old_fn
;
1233 gimple_seq seq
, new_seq
;
1236 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
1237 if (child_fn
== NULL_TREE
)
1240 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
1242 /* Inform the callgraph about the new function. */
1243 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
1244 = cfun
->curr_properties
;
1246 old_fn
= current_function_decl
;
1247 push_cfun (child_cfun
);
1248 current_function_decl
= child_fn
;
1249 bind
= gimplify_body (&DECL_SAVED_TREE (child_fn
), child_fn
, false);
1250 seq
= gimple_seq_alloc ();
1251 gimple_seq_add_stmt (&seq
, bind
);
1252 new_seq
= maybe_catch_exception (seq
);
1255 bind
= gimple_build_bind (NULL
, new_seq
, NULL
);
1256 seq
= gimple_seq_alloc ();
1257 gimple_seq_add_stmt (&seq
, bind
);
1259 gimple_set_body (child_fn
, seq
);
1261 current_function_decl
= old_fn
;
1263 cgraph_add_new_function (child_fn
, false);
1266 /* Destroy a omp_context data structures. Called through the splay tree
1267 value delete callback. */
1270 delete_omp_context (splay_tree_value value
)
1272 omp_context
*ctx
= (omp_context
*) value
;
1274 pointer_map_destroy (ctx
->cb
.decl_map
);
1277 splay_tree_delete (ctx
->field_map
);
1278 if (ctx
->sfield_map
)
1279 splay_tree_delete (ctx
->sfield_map
);
1281 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1282 it produces corrupt debug information. */
1283 if (ctx
->record_type
)
1286 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= TREE_CHAIN (t
))
1287 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1289 if (ctx
->srecord_type
)
1292 for (t
= TYPE_FIELDS (ctx
->srecord_type
); t
; t
= TREE_CHAIN (t
))
1293 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1296 if (is_task_ctx (ctx
))
1297 finalize_task_copyfn (ctx
->stmt
);
1302 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1306 fixup_child_record_type (omp_context
*ctx
)
1308 tree f
, type
= ctx
->record_type
;
1310 /* ??? It isn't sufficient to just call remap_type here, because
1311 variably_modified_type_p doesn't work the way we expect for
1312 record types. Testing each field for whether it needs remapping
1313 and creating a new record by hand works, however. */
1314 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
1315 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
1319 tree name
, new_fields
= NULL
;
1321 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1322 name
= DECL_NAME (TYPE_NAME (ctx
->record_type
));
1323 name
= build_decl (DECL_SOURCE_LOCATION (ctx
->receiver_decl
),
1324 TYPE_DECL
, name
, type
);
1325 TYPE_NAME (type
) = name
;
1327 for (f
= TYPE_FIELDS (ctx
->record_type
); f
; f
= TREE_CHAIN (f
))
1329 tree new_f
= copy_node (f
);
1330 DECL_CONTEXT (new_f
) = type
;
1331 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &ctx
->cb
);
1332 TREE_CHAIN (new_f
) = new_fields
;
1333 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &ctx
->cb
, NULL
);
1334 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
,
1336 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
1340 /* Arrange to be able to look up the receiver field
1341 given the sender field. */
1342 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) f
,
1343 (splay_tree_value
) new_f
);
1345 TYPE_FIELDS (type
) = nreverse (new_fields
);
1349 TREE_TYPE (ctx
->receiver_decl
) = build_pointer_type (type
);
1352 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1353 specified by CLAUSES. */
1356 scan_sharing_clauses (tree clauses
, omp_context
*ctx
)
1359 bool scan_array_reductions
= false;
1361 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1365 switch (OMP_CLAUSE_CODE (c
))
1367 case OMP_CLAUSE_PRIVATE
:
1368 decl
= OMP_CLAUSE_DECL (c
);
1369 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
1371 else if (!is_variable_sized (decl
))
1372 install_var_local (decl
, ctx
);
1375 case OMP_CLAUSE_SHARED
:
1376 gcc_assert (is_taskreg_ctx (ctx
));
1377 decl
= OMP_CLAUSE_DECL (c
);
1378 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl
))
1379 || !is_variable_sized (decl
));
1380 /* Global variables don't need to be copied,
1381 the receiver side will use them directly. */
1382 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1384 by_ref
= use_pointer_for_field (decl
, ctx
);
1385 if (! TREE_READONLY (decl
)
1386 || TREE_ADDRESSABLE (decl
)
1388 || is_reference (decl
))
1390 install_var_field (decl
, by_ref
, 3, ctx
);
1391 install_var_local (decl
, ctx
);
1394 /* We don't need to copy const scalar vars back. */
1395 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_FIRSTPRIVATE
);
1398 case OMP_CLAUSE_LASTPRIVATE
:
1399 /* Let the corresponding firstprivate clause create
1401 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1405 case OMP_CLAUSE_FIRSTPRIVATE
:
1406 case OMP_CLAUSE_REDUCTION
:
1407 decl
= OMP_CLAUSE_DECL (c
);
1409 if (is_variable_sized (decl
))
1411 if (is_task_ctx (ctx
))
1412 install_var_field (decl
, false, 1, ctx
);
1415 else if (is_taskreg_ctx (ctx
))
1418 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
));
1419 by_ref
= use_pointer_for_field (decl
, NULL
);
1421 if (is_task_ctx (ctx
)
1422 && (global
|| by_ref
|| is_reference (decl
)))
1424 install_var_field (decl
, false, 1, ctx
);
1426 install_var_field (decl
, by_ref
, 2, ctx
);
1429 install_var_field (decl
, by_ref
, 3, ctx
);
1431 install_var_local (decl
, ctx
);
1434 case OMP_CLAUSE_COPYPRIVATE
:
1436 scan_omp_op (&OMP_CLAUSE_DECL (c
), ctx
->outer
);
1439 case OMP_CLAUSE_COPYIN
:
1440 decl
= OMP_CLAUSE_DECL (c
);
1441 by_ref
= use_pointer_for_field (decl
, NULL
);
1442 install_var_field (decl
, by_ref
, 3, ctx
);
1445 case OMP_CLAUSE_DEFAULT
:
1446 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
1450 case OMP_CLAUSE_NUM_THREADS
:
1451 case OMP_CLAUSE_SCHEDULE
:
1453 scan_omp_op (&OMP_CLAUSE_OPERAND (c
, 0), ctx
->outer
);
1456 case OMP_CLAUSE_NOWAIT
:
1457 case OMP_CLAUSE_ORDERED
:
1458 case OMP_CLAUSE_COLLAPSE
:
1459 case OMP_CLAUSE_UNTIED
:
1467 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1469 switch (OMP_CLAUSE_CODE (c
))
1471 case OMP_CLAUSE_LASTPRIVATE
:
1472 /* Let the corresponding firstprivate clause create
1474 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1475 scan_array_reductions
= true;
1476 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1480 case OMP_CLAUSE_PRIVATE
:
1481 case OMP_CLAUSE_FIRSTPRIVATE
:
1482 case OMP_CLAUSE_REDUCTION
:
1483 decl
= OMP_CLAUSE_DECL (c
);
1484 if (is_variable_sized (decl
))
1485 install_var_local (decl
, ctx
);
1486 fixup_remapped_decl (decl
, ctx
,
1487 OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_PRIVATE
1488 && OMP_CLAUSE_PRIVATE_DEBUG (c
));
1489 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1490 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1491 scan_array_reductions
= true;
1494 case OMP_CLAUSE_SHARED
:
1495 decl
= OMP_CLAUSE_DECL (c
);
1496 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1497 fixup_remapped_decl (decl
, ctx
, false);
1500 case OMP_CLAUSE_COPYPRIVATE
:
1501 case OMP_CLAUSE_COPYIN
:
1502 case OMP_CLAUSE_DEFAULT
:
1504 case OMP_CLAUSE_NUM_THREADS
:
1505 case OMP_CLAUSE_SCHEDULE
:
1506 case OMP_CLAUSE_NOWAIT
:
1507 case OMP_CLAUSE_ORDERED
:
1508 case OMP_CLAUSE_COLLAPSE
:
1509 case OMP_CLAUSE_UNTIED
:
1517 if (scan_array_reductions
)
1518 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1519 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1520 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1522 scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
1523 scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
1525 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
1526 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1527 scan_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
1530 /* Create a new name for omp child function. Returns an identifier. */
1532 static GTY(()) unsigned int tmp_ompfn_id_num
;
1535 create_omp_child_function_name (bool task_copy
)
1537 tree name
= DECL_ASSEMBLER_NAME (current_function_decl
);
1538 size_t len
= IDENTIFIER_LENGTH (name
);
1539 char *tmp_name
, *prefix
;
1542 suffix
= task_copy
? "_omp_cpyfn" : "_omp_fn";
1543 prefix
= XALLOCAVEC (char, len
+ strlen (suffix
) + 1);
1544 memcpy (prefix
, IDENTIFIER_POINTER (name
), len
);
1545 strcpy (prefix
+ len
, suffix
);
1546 #ifndef NO_DOT_IN_LABEL
1548 #elif !defined NO_DOLLAR_IN_LABEL
1551 ASM_FORMAT_PRIVATE_NAME (tmp_name
, prefix
, tmp_ompfn_id_num
++);
1552 return get_identifier (tmp_name
);
1555 /* Build a decl for the omp child function. It'll not contain a body
1556 yet, just the bare decl. */
1559 create_omp_child_function (omp_context
*ctx
, bool task_copy
)
1561 tree decl
, type
, name
, t
;
1563 name
= create_omp_child_function_name (task_copy
);
1565 type
= build_function_type_list (void_type_node
, ptr_type_node
,
1566 ptr_type_node
, NULL_TREE
);
1568 type
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
1570 decl
= build_decl (gimple_location (ctx
->stmt
),
1571 FUNCTION_DECL
, name
, type
);
1574 ctx
->cb
.dst_fn
= decl
;
1576 gimple_omp_task_set_copy_fn (ctx
->stmt
, decl
);
1578 TREE_STATIC (decl
) = 1;
1579 TREE_USED (decl
) = 1;
1580 DECL_ARTIFICIAL (decl
) = 1;
1581 DECL_IGNORED_P (decl
) = 0;
1582 TREE_PUBLIC (decl
) = 0;
1583 DECL_UNINLINABLE (decl
) = 1;
1584 DECL_EXTERNAL (decl
) = 0;
1585 DECL_CONTEXT (decl
) = NULL_TREE
;
1586 DECL_INITIAL (decl
) = make_node (BLOCK
);
1588 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1589 RESULT_DECL
, NULL_TREE
, void_type_node
);
1590 DECL_ARTIFICIAL (t
) = 1;
1591 DECL_IGNORED_P (t
) = 1;
1592 DECL_CONTEXT (t
) = decl
;
1593 DECL_RESULT (decl
) = t
;
1595 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1596 PARM_DECL
, get_identifier (".omp_data_i"), ptr_type_node
);
1597 DECL_ARTIFICIAL (t
) = 1;
1598 DECL_ARG_TYPE (t
) = ptr_type_node
;
1599 DECL_CONTEXT (t
) = current_function_decl
;
1601 DECL_ARGUMENTS (decl
) = t
;
1603 ctx
->receiver_decl
= t
;
1606 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1607 PARM_DECL
, get_identifier (".omp_data_o"),
1609 DECL_ARTIFICIAL (t
) = 1;
1610 DECL_ARG_TYPE (t
) = ptr_type_node
;
1611 DECL_CONTEXT (t
) = current_function_decl
;
1613 TREE_ADDRESSABLE (t
) = 1;
1614 TREE_CHAIN (t
) = DECL_ARGUMENTS (decl
);
1615 DECL_ARGUMENTS (decl
) = t
;
1618 /* Allocate memory for the function structure. The call to
1619 allocate_struct_function clobbers CFUN, so we need to restore
1621 push_struct_function (decl
);
1622 cfun
->function_end_locus
= gimple_location (ctx
->stmt
);
1627 /* Scan an OpenMP parallel directive. */
1630 scan_omp_parallel (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1634 gimple stmt
= gsi_stmt (*gsi
);
1636 /* Ignore parallel directives with empty bodies, unless there
1637 are copyin clauses. */
1639 && empty_body_p (gimple_omp_body (stmt
))
1640 && find_omp_clause (gimple_omp_parallel_clauses (stmt
),
1641 OMP_CLAUSE_COPYIN
) == NULL
)
1643 gsi_replace (gsi
, gimple_build_nop (), false);
1647 ctx
= new_omp_context (stmt
, outer_ctx
);
1648 if (taskreg_nesting_level
> 1)
1649 ctx
->is_nested
= true;
1650 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1651 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1652 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1653 name
= create_tmp_var_name (".omp_data_s");
1654 name
= build_decl (gimple_location (stmt
),
1655 TYPE_DECL
, name
, ctx
->record_type
);
1656 TYPE_NAME (ctx
->record_type
) = name
;
1657 create_omp_child_function (ctx
, false);
1658 gimple_omp_parallel_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
1660 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt
), ctx
);
1661 scan_omp (gimple_omp_body (stmt
), ctx
);
1663 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1664 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1667 layout_type (ctx
->record_type
);
1668 fixup_child_record_type (ctx
);
1672 /* Scan an OpenMP task directive. */
1675 scan_omp_task (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1679 gimple stmt
= gsi_stmt (*gsi
);
1680 location_t loc
= gimple_location (stmt
);
1682 /* Ignore task directives with empty bodies. */
1684 && empty_body_p (gimple_omp_body (stmt
)))
1686 gsi_replace (gsi
, gimple_build_nop (), false);
1690 ctx
= new_omp_context (stmt
, outer_ctx
);
1691 if (taskreg_nesting_level
> 1)
1692 ctx
->is_nested
= true;
1693 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1694 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1695 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1696 name
= create_tmp_var_name (".omp_data_s");
1697 name
= build_decl (gimple_location (stmt
),
1698 TYPE_DECL
, name
, ctx
->record_type
);
1699 TYPE_NAME (ctx
->record_type
) = name
;
1700 create_omp_child_function (ctx
, false);
1701 gimple_omp_task_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
1703 scan_sharing_clauses (gimple_omp_task_clauses (stmt
), ctx
);
1705 if (ctx
->srecord_type
)
1707 name
= create_tmp_var_name (".omp_data_a");
1708 name
= build_decl (gimple_location (stmt
),
1709 TYPE_DECL
, name
, ctx
->srecord_type
);
1710 TYPE_NAME (ctx
->srecord_type
) = name
;
1711 create_omp_child_function (ctx
, true);
1714 scan_omp (gimple_omp_body (stmt
), ctx
);
1716 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1718 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1719 t
= build_int_cst (long_integer_type_node
, 0);
1720 gimple_omp_task_set_arg_size (stmt
, t
);
1721 t
= build_int_cst (long_integer_type_node
, 1);
1722 gimple_omp_task_set_arg_align (stmt
, t
);
1726 tree
*p
, vla_fields
= NULL_TREE
, *q
= &vla_fields
;
1727 /* Move VLA fields to the end. */
1728 p
= &TYPE_FIELDS (ctx
->record_type
);
1730 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p
))
1731 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p
))))
1734 *p
= TREE_CHAIN (*p
);
1735 TREE_CHAIN (*q
) = NULL_TREE
;
1736 q
= &TREE_CHAIN (*q
);
1739 p
= &TREE_CHAIN (*p
);
1741 layout_type (ctx
->record_type
);
1742 fixup_child_record_type (ctx
);
1743 if (ctx
->srecord_type
)
1744 layout_type (ctx
->srecord_type
);
1745 t
= fold_convert_loc (loc
, long_integer_type_node
,
1746 TYPE_SIZE_UNIT (ctx
->record_type
));
1747 gimple_omp_task_set_arg_size (stmt
, t
);
1748 t
= build_int_cst (long_integer_type_node
,
1749 TYPE_ALIGN_UNIT (ctx
->record_type
));
1750 gimple_omp_task_set_arg_align (stmt
, t
);
1755 /* Scan an OpenMP loop directive. */
1758 scan_omp_for (gimple stmt
, omp_context
*outer_ctx
)
1763 ctx
= new_omp_context (stmt
, outer_ctx
);
1765 scan_sharing_clauses (gimple_omp_for_clauses (stmt
), ctx
);
1767 scan_omp (gimple_omp_for_pre_body (stmt
), ctx
);
1768 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
1770 scan_omp_op (gimple_omp_for_index_ptr (stmt
, i
), ctx
);
1771 scan_omp_op (gimple_omp_for_initial_ptr (stmt
, i
), ctx
);
1772 scan_omp_op (gimple_omp_for_final_ptr (stmt
, i
), ctx
);
1773 scan_omp_op (gimple_omp_for_incr_ptr (stmt
, i
), ctx
);
1775 scan_omp (gimple_omp_body (stmt
), ctx
);
1778 /* Scan an OpenMP sections directive. */
1781 scan_omp_sections (gimple stmt
, omp_context
*outer_ctx
)
1785 ctx
= new_omp_context (stmt
, outer_ctx
);
1786 scan_sharing_clauses (gimple_omp_sections_clauses (stmt
), ctx
);
1787 scan_omp (gimple_omp_body (stmt
), ctx
);
1790 /* Scan an OpenMP single directive. */
1793 scan_omp_single (gimple stmt
, omp_context
*outer_ctx
)
1798 ctx
= new_omp_context (stmt
, outer_ctx
);
1799 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1800 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1801 name
= create_tmp_var_name (".omp_copy_s");
1802 name
= build_decl (gimple_location (stmt
),
1803 TYPE_DECL
, name
, ctx
->record_type
);
1804 TYPE_NAME (ctx
->record_type
) = name
;
1806 scan_sharing_clauses (gimple_omp_single_clauses (stmt
), ctx
);
1807 scan_omp (gimple_omp_body (stmt
), ctx
);
1809 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1810 ctx
->record_type
= NULL
;
1812 layout_type (ctx
->record_type
);
1816 /* Check OpenMP nesting restrictions. */
1818 check_omp_nesting_restrictions (gimple stmt
, omp_context
*ctx
)
1820 switch (gimple_code (stmt
))
1822 case GIMPLE_OMP_FOR
:
1823 case GIMPLE_OMP_SECTIONS
:
1824 case GIMPLE_OMP_SINGLE
:
1826 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1827 switch (gimple_code (ctx
->stmt
))
1829 case GIMPLE_OMP_FOR
:
1830 case GIMPLE_OMP_SECTIONS
:
1831 case GIMPLE_OMP_SINGLE
:
1832 case GIMPLE_OMP_ORDERED
:
1833 case GIMPLE_OMP_MASTER
:
1834 case GIMPLE_OMP_TASK
:
1835 if (is_gimple_call (stmt
))
1837 warning (0, "barrier region may not be closely nested inside "
1838 "of work-sharing, critical, ordered, master or "
1839 "explicit task region");
1842 warning (0, "work-sharing region may not be closely nested inside "
1843 "of work-sharing, critical, ordered, master or explicit "
1846 case GIMPLE_OMP_PARALLEL
:
1852 case GIMPLE_OMP_MASTER
:
1853 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1854 switch (gimple_code (ctx
->stmt
))
1856 case GIMPLE_OMP_FOR
:
1857 case GIMPLE_OMP_SECTIONS
:
1858 case GIMPLE_OMP_SINGLE
:
1859 case GIMPLE_OMP_TASK
:
1860 warning (0, "master region may not be closely nested inside "
1861 "of work-sharing or explicit task region");
1863 case GIMPLE_OMP_PARALLEL
:
1869 case GIMPLE_OMP_ORDERED
:
1870 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1871 switch (gimple_code (ctx
->stmt
))
1873 case GIMPLE_OMP_CRITICAL
:
1874 case GIMPLE_OMP_TASK
:
1875 warning (0, "ordered region may not be closely nested inside "
1876 "of critical or explicit task region");
1878 case GIMPLE_OMP_FOR
:
1879 if (find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
1880 OMP_CLAUSE_ORDERED
) == NULL
)
1881 warning (0, "ordered region must be closely nested inside "
1882 "a loop region with an ordered clause");
1884 case GIMPLE_OMP_PARALLEL
:
1890 case GIMPLE_OMP_CRITICAL
:
1891 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1892 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_CRITICAL
1893 && (gimple_omp_critical_name (stmt
)
1894 == gimple_omp_critical_name (ctx
->stmt
)))
1896 warning (0, "critical region may not be nested inside a critical "
1897 "region with the same name");
1907 /* Helper function scan_omp.
1909 Callback for walk_tree or operators in walk_gimple_stmt used to
1910 scan for OpenMP directives in TP. */
1913 scan_omp_1_op (tree
*tp
, int *walk_subtrees
, void *data
)
1915 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
1916 omp_context
*ctx
= (omp_context
*) wi
->info
;
1919 switch (TREE_CODE (t
))
1926 *tp
= remap_decl (t
, &ctx
->cb
);
1930 if (ctx
&& TYPE_P (t
))
1931 *tp
= remap_type (t
, &ctx
->cb
);
1932 else if (!DECL_P (t
))
1936 TREE_TYPE (t
) = remap_type (TREE_TYPE (t
), &ctx
->cb
);
1945 /* Helper function for scan_omp.
1947 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1948 the current statement in GSI. */
1951 scan_omp_1_stmt (gimple_stmt_iterator
*gsi
, bool *handled_ops_p
,
1952 struct walk_stmt_info
*wi
)
1954 gimple stmt
= gsi_stmt (*gsi
);
1955 omp_context
*ctx
= (omp_context
*) wi
->info
;
1957 if (gimple_has_location (stmt
))
1958 input_location
= gimple_location (stmt
);
1960 /* Check the OpenMP nesting restrictions. */
1963 if (is_gimple_omp (stmt
))
1964 check_omp_nesting_restrictions (stmt
, ctx
);
1965 else if (is_gimple_call (stmt
))
1967 tree fndecl
= gimple_call_fndecl (stmt
);
1968 if (fndecl
&& DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
1969 && DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_GOMP_BARRIER
)
1970 check_omp_nesting_restrictions (stmt
, ctx
);
1974 *handled_ops_p
= true;
1976 switch (gimple_code (stmt
))
1978 case GIMPLE_OMP_PARALLEL
:
1979 taskreg_nesting_level
++;
1980 scan_omp_parallel (gsi
, ctx
);
1981 taskreg_nesting_level
--;
1984 case GIMPLE_OMP_TASK
:
1985 taskreg_nesting_level
++;
1986 scan_omp_task (gsi
, ctx
);
1987 taskreg_nesting_level
--;
1990 case GIMPLE_OMP_FOR
:
1991 scan_omp_for (stmt
, ctx
);
1994 case GIMPLE_OMP_SECTIONS
:
1995 scan_omp_sections (stmt
, ctx
);
1998 case GIMPLE_OMP_SINGLE
:
1999 scan_omp_single (stmt
, ctx
);
2002 case GIMPLE_OMP_SECTION
:
2003 case GIMPLE_OMP_MASTER
:
2004 case GIMPLE_OMP_ORDERED
:
2005 case GIMPLE_OMP_CRITICAL
:
2006 ctx
= new_omp_context (stmt
, ctx
);
2007 scan_omp (gimple_omp_body (stmt
), ctx
);
2014 *handled_ops_p
= false;
2016 for (var
= gimple_bind_vars (stmt
); var
; var
= TREE_CHAIN (var
))
2017 insert_decl_map (&ctx
->cb
, var
, var
);
2021 *handled_ops_p
= false;
2029 /* Scan all the statements starting at the current statement. CTX
2030 contains context information about the OpenMP directives and
2031 clauses found during the scan. */
2034 scan_omp (gimple_seq body
, omp_context
*ctx
)
2036 location_t saved_location
;
2037 struct walk_stmt_info wi
;
2039 memset (&wi
, 0, sizeof (wi
));
2041 wi
.want_locations
= true;
2043 saved_location
= input_location
;
2044 walk_gimple_seq (body
, scan_omp_1_stmt
, scan_omp_1_op
, &wi
);
2045 input_location
= saved_location
;
2048 /* Re-gimplification and code generation routines. */
2050 /* Build a call to GOMP_barrier. */
2053 build_omp_barrier (void)
2055 return build_call_expr (built_in_decls
[BUILT_IN_GOMP_BARRIER
], 0);
2058 /* If a context was created for STMT when it was scanned, return it. */
2060 static omp_context
*
2061 maybe_lookup_ctx (gimple stmt
)
2064 n
= splay_tree_lookup (all_contexts
, (splay_tree_key
) stmt
);
2065 return n
? (omp_context
*) n
->value
: NULL
;
2069 /* Find the mapping for DECL in CTX or the immediately enclosing
2070 context that has a mapping for DECL.
2072 If CTX is a nested parallel directive, we may have to use the decl
2073 mappings created in CTX's parent context. Suppose that we have the
2074 following parallel nesting (variable UIDs showed for clarity):
2077 #omp parallel shared(iD.1562) -> outer parallel
2078 iD.1562 = iD.1562 + 1;
2080 #omp parallel shared (iD.1562) -> inner parallel
2081 iD.1562 = iD.1562 - 1;
2083 Each parallel structure will create a distinct .omp_data_s structure
2084 for copying iD.1562 in/out of the directive:
2086 outer parallel .omp_data_s.1.i -> iD.1562
2087 inner parallel .omp_data_s.2.i -> iD.1562
2089 A shared variable mapping will produce a copy-out operation before
2090 the parallel directive and a copy-in operation after it. So, in
2091 this case we would have:
2094 .omp_data_o.1.i = iD.1562;
2095 #omp parallel shared(iD.1562) -> outer parallel
2096 .omp_data_i.1 = &.omp_data_o.1
2097 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2099 .omp_data_o.2.i = iD.1562; -> **
2100 #omp parallel shared(iD.1562) -> inner parallel
2101 .omp_data_i.2 = &.omp_data_o.2
2102 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2105 ** This is a problem. The symbol iD.1562 cannot be referenced
2106 inside the body of the outer parallel region. But since we are
2107 emitting this copy operation while expanding the inner parallel
2108 directive, we need to access the CTX structure of the outer
2109 parallel directive to get the correct mapping:
2111 .omp_data_o.2.i = .omp_data_i.1->i
2113 Since there may be other workshare or parallel directives enclosing
2114 the parallel directive, it may be necessary to walk up the context
2115 parent chain. This is not a problem in general because nested
2116 parallelism happens only rarely. */
2119 lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2124 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2125 t
= maybe_lookup_decl (decl
, up
);
2127 gcc_assert (!ctx
->is_nested
|| t
|| is_global_var (decl
));
2129 return t
? t
: decl
;
2133 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2134 in outer contexts. */
2137 maybe_lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2142 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2143 t
= maybe_lookup_decl (decl
, up
);
2145 return t
? t
: decl
;
2149 /* Construct the initialization value for reduction CLAUSE. */
2152 omp_reduction_init (tree clause
, tree type
)
2154 location_t loc
= OMP_CLAUSE_LOCATION (clause
);
2155 switch (OMP_CLAUSE_REDUCTION_CODE (clause
))
2162 case TRUTH_ORIF_EXPR
:
2163 case TRUTH_XOR_EXPR
:
2165 return fold_convert_loc (loc
, type
, integer_zero_node
);
2168 case TRUTH_AND_EXPR
:
2169 case TRUTH_ANDIF_EXPR
:
2171 return fold_convert_loc (loc
, type
, integer_one_node
);
2174 return fold_convert_loc (loc
, type
, integer_minus_one_node
);
2177 if (SCALAR_FLOAT_TYPE_P (type
))
2179 REAL_VALUE_TYPE max
, min
;
2180 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2183 real_arithmetic (&min
, NEGATE_EXPR
, &max
, NULL
);
2186 real_maxval (&min
, 1, TYPE_MODE (type
));
2187 return build_real (type
, min
);
2191 gcc_assert (INTEGRAL_TYPE_P (type
));
2192 return TYPE_MIN_VALUE (type
);
2196 if (SCALAR_FLOAT_TYPE_P (type
))
2198 REAL_VALUE_TYPE max
;
2199 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2202 real_maxval (&max
, 0, TYPE_MODE (type
));
2203 return build_real (type
, max
);
2207 gcc_assert (INTEGRAL_TYPE_P (type
));
2208 return TYPE_MAX_VALUE (type
);
2216 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2217 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2218 private variables. Initialization statements go in ILIST, while calls
2219 to destructors go in DLIST. */
2222 lower_rec_input_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*dlist
,
2225 gimple_stmt_iterator diter
;
2226 tree c
, dtor
, copyin_seq
, x
, ptr
;
2227 bool copyin_by_ref
= false;
2228 bool lastprivate_firstprivate
= false;
2231 *dlist
= gimple_seq_alloc ();
2232 diter
= gsi_start (*dlist
);
2235 /* Do all the fixed sized types in the first pass, and the variable sized
2236 types in the second pass. This makes sure that the scalar arguments to
2237 the variable sized types are processed before we use them in the
2238 variable sized operations. */
2239 for (pass
= 0; pass
< 2; ++pass
)
2241 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2243 enum omp_clause_code c_kind
= OMP_CLAUSE_CODE (c
);
2246 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2250 case OMP_CLAUSE_PRIVATE
:
2251 if (OMP_CLAUSE_PRIVATE_DEBUG (c
))
2254 case OMP_CLAUSE_SHARED
:
2255 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c
), ctx
) == NULL
)
2257 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c
)));
2260 case OMP_CLAUSE_FIRSTPRIVATE
:
2261 case OMP_CLAUSE_COPYIN
:
2262 case OMP_CLAUSE_REDUCTION
:
2264 case OMP_CLAUSE_LASTPRIVATE
:
2265 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2267 lastprivate_firstprivate
= true;
2276 new_var
= var
= OMP_CLAUSE_DECL (c
);
2277 if (c_kind
!= OMP_CLAUSE_COPYIN
)
2278 new_var
= lookup_decl (var
, ctx
);
2280 if (c_kind
== OMP_CLAUSE_SHARED
|| c_kind
== OMP_CLAUSE_COPYIN
)
2285 else if (is_variable_sized (var
))
2287 /* For variable sized types, we need to allocate the
2288 actual storage here. Call alloca and store the
2289 result in the pointer decl that we created elsewhere. */
2293 if (c_kind
!= OMP_CLAUSE_FIRSTPRIVATE
|| !is_task_ctx (ctx
))
2298 ptr
= DECL_VALUE_EXPR (new_var
);
2299 gcc_assert (TREE_CODE (ptr
) == INDIRECT_REF
);
2300 ptr
= TREE_OPERAND (ptr
, 0);
2301 gcc_assert (DECL_P (ptr
));
2302 x
= TYPE_SIZE_UNIT (TREE_TYPE (new_var
));
2304 /* void *tmp = __builtin_alloca */
2306 = gimple_build_call (built_in_decls
[BUILT_IN_ALLOCA
], 1, x
);
2307 tmp
= create_tmp_var_raw (ptr_type_node
, NULL
);
2308 gimple_add_tmp_var (tmp
);
2309 gimple_call_set_lhs (stmt
, tmp
);
2311 gimple_seq_add_stmt (ilist
, stmt
);
2313 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ptr
), tmp
);
2314 gimplify_assign (ptr
, x
, ilist
);
2317 else if (is_reference (var
))
2319 /* For references that are being privatized for Fortran,
2320 allocate new backing storage for the new pointer
2321 variable. This allows us to avoid changing all the
2322 code that expects a pointer to something that expects
2323 a direct variable. Note that this doesn't apply to
2324 C++, since reference types are disallowed in data
2325 sharing clauses there, except for NRV optimized
2330 x
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var
)));
2331 if (c_kind
== OMP_CLAUSE_FIRSTPRIVATE
&& is_task_ctx (ctx
))
2333 x
= build_receiver_ref (var
, false, ctx
);
2334 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2336 else if (TREE_CONSTANT (x
))
2338 const char *name
= NULL
;
2339 if (DECL_NAME (var
))
2340 name
= IDENTIFIER_POINTER (DECL_NAME (new_var
));
2342 x
= create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var
)),
2344 gimple_add_tmp_var (x
);
2345 TREE_ADDRESSABLE (x
) = 1;
2346 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2350 x
= build_call_expr_loc (clause_loc
,
2351 built_in_decls
[BUILT_IN_ALLOCA
], 1, x
);
2354 x
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), x
);
2355 gimplify_assign (new_var
, x
, ilist
);
2357 new_var
= build_fold_indirect_ref_loc (clause_loc
, new_var
);
2359 else if (c_kind
== OMP_CLAUSE_REDUCTION
2360 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2368 switch (OMP_CLAUSE_CODE (c
))
2370 case OMP_CLAUSE_SHARED
:
2371 /* Shared global vars are just accessed directly. */
2372 if (is_global_var (new_var
))
2374 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2375 needs to be delayed until after fixup_child_record_type so
2376 that we get the correct type during the dereference. */
2377 by_ref
= use_pointer_for_field (var
, ctx
);
2378 x
= build_receiver_ref (var
, by_ref
, ctx
);
2379 SET_DECL_VALUE_EXPR (new_var
, x
);
2380 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2382 /* ??? If VAR is not passed by reference, and the variable
2383 hasn't been initialized yet, then we'll get a warning for
2384 the store into the omp_data_s structure. Ideally, we'd be
2385 able to notice this and not store anything at all, but
2386 we're generating code too early. Suppress the warning. */
2388 TREE_NO_WARNING (var
) = 1;
2391 case OMP_CLAUSE_LASTPRIVATE
:
2392 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2396 case OMP_CLAUSE_PRIVATE
:
2397 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_PRIVATE
)
2398 x
= build_outer_var_ref (var
, ctx
);
2399 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
2401 if (is_task_ctx (ctx
))
2402 x
= build_receiver_ref (var
, false, ctx
);
2404 x
= build_outer_var_ref (var
, ctx
);
2408 x
= lang_hooks
.decls
.omp_clause_default_ctor (c
, new_var
, x
);
2410 gimplify_and_add (x
, ilist
);
2414 x
= lang_hooks
.decls
.omp_clause_dtor (c
, new_var
);
2417 gimple_seq tseq
= NULL
;
2420 gimplify_stmt (&dtor
, &tseq
);
2421 gsi_insert_seq_before (&diter
, tseq
, GSI_SAME_STMT
);
2425 case OMP_CLAUSE_FIRSTPRIVATE
:
2426 if (is_task_ctx (ctx
))
2428 if (is_reference (var
) || is_variable_sized (var
))
2430 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
,
2432 || use_pointer_for_field (var
, NULL
))
2434 x
= build_receiver_ref (var
, false, ctx
);
2435 SET_DECL_VALUE_EXPR (new_var
, x
);
2436 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2440 x
= build_outer_var_ref (var
, ctx
);
2441 x
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, new_var
, x
);
2442 gimplify_and_add (x
, ilist
);
2446 case OMP_CLAUSE_COPYIN
:
2447 by_ref
= use_pointer_for_field (var
, NULL
);
2448 x
= build_receiver_ref (var
, by_ref
, ctx
);
2449 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, x
);
2450 append_to_statement_list (x
, ©in_seq
);
2451 copyin_by_ref
|= by_ref
;
2454 case OMP_CLAUSE_REDUCTION
:
2455 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2457 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
2458 x
= build_outer_var_ref (var
, ctx
);
2460 if (is_reference (var
))
2461 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2462 SET_DECL_VALUE_EXPR (placeholder
, x
);
2463 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
2464 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
2465 gimple_seq_add_seq (ilist
,
2466 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
2467 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
2468 DECL_HAS_VALUE_EXPR_P (placeholder
) = 0;
2472 x
= omp_reduction_init (c
, TREE_TYPE (new_var
));
2473 gcc_assert (TREE_CODE (TREE_TYPE (new_var
)) != ARRAY_TYPE
);
2474 gimplify_assign (new_var
, x
, ilist
);
2484 /* The copyin sequence is not to be executed by the main thread, since
2485 that would result in self-copies. Perhaps not visible to scalars,
2486 but it certainly is to C++ operator=. */
2489 x
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
2490 x
= build2 (NE_EXPR
, boolean_type_node
, x
,
2491 build_int_cst (TREE_TYPE (x
), 0));
2492 x
= build3 (COND_EXPR
, void_type_node
, x
, copyin_seq
, NULL
);
2493 gimplify_and_add (x
, ilist
);
2496 /* If any copyin variable is passed by reference, we must ensure the
2497 master thread doesn't modify it before it is copied over in all
2498 threads. Similarly for variables in both firstprivate and
2499 lastprivate clauses we need to ensure the lastprivate copying
2500 happens after firstprivate copying in all threads. */
2501 if (copyin_by_ref
|| lastprivate_firstprivate
)
2502 gimplify_and_add (build_omp_barrier (), ilist
);
2506 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2507 both parallel and workshare constructs. PREDICATE may be NULL if it's
2511 lower_lastprivate_clauses (tree clauses
, tree predicate
, gimple_seq
*stmt_list
,
2514 tree x
, c
, label
= NULL
;
2515 bool par_clauses
= false;
2517 /* Early exit if there are no lastprivate clauses. */
2518 clauses
= find_omp_clause (clauses
, OMP_CLAUSE_LASTPRIVATE
);
2519 if (clauses
== NULL
)
2521 /* If this was a workshare clause, see if it had been combined
2522 with its parallel. In that case, look for the clauses on the
2523 parallel statement itself. */
2524 if (is_parallel_ctx (ctx
))
2528 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
2531 clauses
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
2532 OMP_CLAUSE_LASTPRIVATE
);
2533 if (clauses
== NULL
)
2541 tree label_true
, arm1
, arm2
;
2543 label
= create_artificial_label (UNKNOWN_LOCATION
);
2544 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
2545 arm1
= TREE_OPERAND (predicate
, 0);
2546 arm2
= TREE_OPERAND (predicate
, 1);
2547 gimplify_expr (&arm1
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
2548 gimplify_expr (&arm2
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
2549 stmt
= gimple_build_cond (TREE_CODE (predicate
), arm1
, arm2
,
2551 gimple_seq_add_stmt (stmt_list
, stmt
);
2552 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label_true
));
2555 for (c
= clauses
; c
;)
2558 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2560 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
2562 var
= OMP_CLAUSE_DECL (c
);
2563 new_var
= lookup_decl (var
, ctx
);
2565 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
2567 lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
2568 gimple_seq_add_seq (stmt_list
,
2569 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
2571 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) = NULL
;
2573 x
= build_outer_var_ref (var
, ctx
);
2574 if (is_reference (var
))
2575 new_var
= build_fold_indirect_ref_loc (clause_loc
, new_var
);
2576 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, x
, new_var
);
2577 gimplify_and_add (x
, stmt_list
);
2579 c
= OMP_CLAUSE_CHAIN (c
);
2580 if (c
== NULL
&& !par_clauses
)
2582 /* If this was a workshare clause, see if it had been combined
2583 with its parallel. In that case, continue looking for the
2584 clauses also on the parallel statement itself. */
2585 if (is_parallel_ctx (ctx
))
2589 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
2592 c
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
2593 OMP_CLAUSE_LASTPRIVATE
);
2599 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label
));
2603 /* Generate code to implement the REDUCTION clauses. */
2606 lower_reduction_clauses (tree clauses
, gimple_seq
*stmt_seqp
, omp_context
*ctx
)
2608 gimple_seq sub_seq
= NULL
;
2613 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2614 update in that case, otherwise use a lock. */
2615 for (c
= clauses
; c
&& count
< 2; c
= OMP_CLAUSE_CHAIN (c
))
2616 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
2618 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2620 /* Never use OMP_ATOMIC for array reductions. */
2630 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2632 tree var
, ref
, new_var
;
2633 enum tree_code code
;
2634 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2636 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
)
2639 var
= OMP_CLAUSE_DECL (c
);
2640 new_var
= lookup_decl (var
, ctx
);
2641 if (is_reference (var
))
2642 new_var
= build_fold_indirect_ref_loc (clause_loc
, new_var
);
2643 ref
= build_outer_var_ref (var
, ctx
);
2644 code
= OMP_CLAUSE_REDUCTION_CODE (c
);
2646 /* reduction(-:var) sums up the partial results, so it acts
2647 identically to reduction(+:var). */
2648 if (code
== MINUS_EXPR
)
2653 tree addr
= build_fold_addr_expr_loc (clause_loc
, ref
);
2655 addr
= save_expr (addr
);
2656 ref
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (addr
)), addr
);
2657 x
= fold_build2_loc (clause_loc
, code
, TREE_TYPE (ref
), ref
, new_var
);
2658 x
= build2 (OMP_ATOMIC
, void_type_node
, addr
, x
);
2659 gimplify_and_add (x
, stmt_seqp
);
2663 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2665 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
2667 if (is_reference (var
))
2668 ref
= build_fold_addr_expr_loc (clause_loc
, ref
);
2669 SET_DECL_VALUE_EXPR (placeholder
, ref
);
2670 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
2671 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
2672 gimple_seq_add_seq (&sub_seq
, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
2673 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
2674 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
) = NULL
;
2678 x
= build2 (code
, TREE_TYPE (ref
), ref
, new_var
);
2679 ref
= build_outer_var_ref (var
, ctx
);
2680 gimplify_assign (ref
, x
, &sub_seq
);
2684 stmt
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_ATOMIC_START
], 0);
2685 gimple_seq_add_stmt (stmt_seqp
, stmt
);
2687 gimple_seq_add_seq (stmt_seqp
, sub_seq
);
2689 stmt
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_ATOMIC_END
], 0);
2690 gimple_seq_add_stmt (stmt_seqp
, stmt
);
2694 /* Generate code to implement the COPYPRIVATE clauses. */
2697 lower_copyprivate_clauses (tree clauses
, gimple_seq
*slist
, gimple_seq
*rlist
,
2702 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2706 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2708 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYPRIVATE
)
2711 var
= OMP_CLAUSE_DECL (c
);
2712 by_ref
= use_pointer_for_field (var
, NULL
);
2714 ref
= build_sender_ref (var
, ctx
);
2715 x
= lookup_decl_in_outer_ctx (var
, ctx
);
2716 x
= by_ref
? build_fold_addr_expr_loc (clause_loc
, x
) : x
;
2717 gimplify_assign (ref
, x
, slist
);
2719 ref
= build_receiver_ref (var
, by_ref
, ctx
);
2720 if (is_reference (var
))
2722 ref
= build_fold_indirect_ref_loc (clause_loc
, ref
);
2723 var
= build_fold_indirect_ref_loc (clause_loc
, var
);
2725 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, var
, ref
);
2726 gimplify_and_add (x
, rlist
);
2731 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2732 and REDUCTION from the sender (aka parent) side. */
2735 lower_send_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*olist
,
2740 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2742 tree val
, ref
, x
, var
;
2743 bool by_ref
, do_in
= false, do_out
= false;
2744 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2746 switch (OMP_CLAUSE_CODE (c
))
2748 case OMP_CLAUSE_PRIVATE
:
2749 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
2752 case OMP_CLAUSE_FIRSTPRIVATE
:
2753 case OMP_CLAUSE_COPYIN
:
2754 case OMP_CLAUSE_LASTPRIVATE
:
2755 case OMP_CLAUSE_REDUCTION
:
2761 val
= OMP_CLAUSE_DECL (c
);
2762 var
= lookup_decl_in_outer_ctx (val
, ctx
);
2764 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYIN
2765 && is_global_var (var
))
2767 if (is_variable_sized (val
))
2769 by_ref
= use_pointer_for_field (val
, NULL
);
2771 switch (OMP_CLAUSE_CODE (c
))
2773 case OMP_CLAUSE_PRIVATE
:
2774 case OMP_CLAUSE_FIRSTPRIVATE
:
2775 case OMP_CLAUSE_COPYIN
:
2779 case OMP_CLAUSE_LASTPRIVATE
:
2780 if (by_ref
|| is_reference (val
))
2782 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2789 if (lang_hooks
.decls
.omp_private_outer_ref (val
))
2794 case OMP_CLAUSE_REDUCTION
:
2796 do_out
= !(by_ref
|| is_reference (val
));
2805 ref
= build_sender_ref (val
, ctx
);
2806 x
= by_ref
? build_fold_addr_expr_loc (clause_loc
, var
) : var
;
2807 gimplify_assign (ref
, x
, ilist
);
2808 if (is_task_ctx (ctx
))
2809 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref
, 1)) = NULL
;
2814 ref
= build_sender_ref (val
, ctx
);
2815 gimplify_assign (var
, ref
, olist
);
2820 /* Generate code to implement SHARED from the sender (aka parent)
2821 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2822 list things that got automatically shared. */
2825 lower_send_shared_vars (gimple_seq
*ilist
, gimple_seq
*olist
, omp_context
*ctx
)
2827 tree var
, ovar
, nvar
, f
, x
, record_type
;
2829 if (ctx
->record_type
== NULL
)
2832 record_type
= ctx
->srecord_type
? ctx
->srecord_type
: ctx
->record_type
;
2833 for (f
= TYPE_FIELDS (record_type
); f
; f
= TREE_CHAIN (f
))
2835 ovar
= DECL_ABSTRACT_ORIGIN (f
);
2836 nvar
= maybe_lookup_decl (ovar
, ctx
);
2837 if (!nvar
|| !DECL_HAS_VALUE_EXPR_P (nvar
))
2840 /* If CTX is a nested parallel directive. Find the immediately
2841 enclosing parallel or workshare construct that contains a
2842 mapping for OVAR. */
2843 var
= lookup_decl_in_outer_ctx (ovar
, ctx
);
2845 if (use_pointer_for_field (ovar
, ctx
))
2847 x
= build_sender_ref (ovar
, ctx
);
2848 var
= build_fold_addr_expr (var
);
2849 gimplify_assign (x
, var
, ilist
);
2853 x
= build_sender_ref (ovar
, ctx
);
2854 gimplify_assign (x
, var
, ilist
);
2856 if (!TREE_READONLY (var
)
2857 /* We don't need to receive a new reference to a result
2858 or parm decl. In fact we may not store to it as we will
2859 invalidate any pending RSO and generate wrong gimple
2861 && !((TREE_CODE (var
) == RESULT_DECL
2862 || TREE_CODE (var
) == PARM_DECL
)
2863 && DECL_BY_REFERENCE (var
)))
2865 x
= build_sender_ref (ovar
, ctx
);
2866 gimplify_assign (var
, x
, olist
);
2873 /* A convenience function to build an empty GIMPLE_COND with just the
2877 gimple_build_cond_empty (tree cond
)
2879 enum tree_code pred_code
;
2882 gimple_cond_get_ops_from_tree (cond
, &pred_code
, &lhs
, &rhs
);
2883 return gimple_build_cond (pred_code
, lhs
, rhs
, NULL_TREE
, NULL_TREE
);
2887 /* Build the function calls to GOMP_parallel_start etc to actually
2888 generate the parallel operation. REGION is the parallel region
2889 being expanded. BB is the block where to insert the code. WS_ARGS
2890 will be set if this is a call to a combined parallel+workshare
2891 construct, it contains the list of additional arguments needed by
2892 the workshare construct. */
2895 expand_parallel_call (struct omp_region
*region
, basic_block bb
,
2896 gimple entry_stmt
, tree ws_args
)
2898 tree t
, t1
, t2
, val
, cond
, c
, clauses
;
2899 gimple_stmt_iterator gsi
;
2902 location_t clause_loc
;
2904 clauses
= gimple_omp_parallel_clauses (entry_stmt
);
2906 /* Determine what flavor of GOMP_parallel_start we will be
2908 start_ix
= BUILT_IN_GOMP_PARALLEL_START
;
2909 if (is_combined_parallel (region
))
2911 switch (region
->inner
->type
)
2913 case GIMPLE_OMP_FOR
:
2914 gcc_assert (region
->inner
->sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
2915 start_ix
= BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2916 + (region
->inner
->sched_kind
2917 == OMP_CLAUSE_SCHEDULE_RUNTIME
2918 ? 3 : region
->inner
->sched_kind
);
2920 case GIMPLE_OMP_SECTIONS
:
2921 start_ix
= BUILT_IN_GOMP_PARALLEL_SECTIONS_START
;
2928 /* By default, the value of NUM_THREADS is zero (selected at run time)
2929 and there is no conditional. */
2931 val
= build_int_cst (unsigned_type_node
, 0);
2933 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
2935 cond
= OMP_CLAUSE_IF_EXPR (c
);
2937 c
= find_omp_clause (clauses
, OMP_CLAUSE_NUM_THREADS
);
2940 val
= OMP_CLAUSE_NUM_THREADS_EXPR (c
);
2941 clause_loc
= OMP_CLAUSE_LOCATION (c
);
2944 clause_loc
= gimple_location (entry_stmt
);
2946 /* Ensure 'val' is of the correct type. */
2947 val
= fold_convert_loc (clause_loc
, unsigned_type_node
, val
);
2949 /* If we found the clause 'if (cond)', build either
2950 (cond != 0) or (cond ? val : 1u). */
2953 gimple_stmt_iterator gsi
;
2955 cond
= gimple_boolify (cond
);
2957 if (integer_zerop (val
))
2958 val
= fold_build2_loc (clause_loc
,
2959 EQ_EXPR
, unsigned_type_node
, cond
,
2960 build_int_cst (TREE_TYPE (cond
), 0));
2963 basic_block cond_bb
, then_bb
, else_bb
;
2964 edge e
, e_then
, e_else
;
2965 tree tmp_then
, tmp_else
, tmp_join
, tmp_var
;
2967 tmp_var
= create_tmp_var (TREE_TYPE (val
), NULL
);
2968 if (gimple_in_ssa_p (cfun
))
2970 tmp_then
= make_ssa_name (tmp_var
, NULL
);
2971 tmp_else
= make_ssa_name (tmp_var
, NULL
);
2972 tmp_join
= make_ssa_name (tmp_var
, NULL
);
2981 e
= split_block (bb
, NULL
);
2986 then_bb
= create_empty_bb (cond_bb
);
2987 else_bb
= create_empty_bb (then_bb
);
2988 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
2989 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
2991 stmt
= gimple_build_cond_empty (cond
);
2992 gsi
= gsi_start_bb (cond_bb
);
2993 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
2995 gsi
= gsi_start_bb (then_bb
);
2996 stmt
= gimple_build_assign (tmp_then
, val
);
2997 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
2999 gsi
= gsi_start_bb (else_bb
);
3000 stmt
= gimple_build_assign
3001 (tmp_else
, build_int_cst (unsigned_type_node
, 1));
3002 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3004 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
3005 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
3006 e_then
= make_edge (then_bb
, bb
, EDGE_FALLTHRU
);
3007 e_else
= make_edge (else_bb
, bb
, EDGE_FALLTHRU
);
3009 if (gimple_in_ssa_p (cfun
))
3011 gimple phi
= create_phi_node (tmp_join
, bb
);
3012 SSA_NAME_DEF_STMT (tmp_join
) = phi
;
3013 add_phi_arg (phi
, tmp_then
, e_then
, UNKNOWN_LOCATION
);
3014 add_phi_arg (phi
, tmp_else
, e_else
, UNKNOWN_LOCATION
);
3020 gsi
= gsi_start_bb (bb
);
3021 val
= force_gimple_operand_gsi (&gsi
, val
, true, NULL_TREE
,
3022 false, GSI_CONTINUE_LINKING
);
3025 gsi
= gsi_last_bb (bb
);
3026 t
= gimple_omp_parallel_data_arg (entry_stmt
);
3028 t1
= null_pointer_node
;
3030 t1
= build_fold_addr_expr (t
);
3031 t2
= build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt
));
3035 tree args
= tree_cons (NULL
, t2
,
3036 tree_cons (NULL
, t1
,
3037 tree_cons (NULL
, val
, ws_args
)));
3038 t
= build_function_call_expr (UNKNOWN_LOCATION
,
3039 built_in_decls
[start_ix
], args
);
3042 t
= build_call_expr (built_in_decls
[start_ix
], 3, t2
, t1
, val
);
3044 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3045 false, GSI_CONTINUE_LINKING
);
3047 t
= gimple_omp_parallel_data_arg (entry_stmt
);
3049 t
= null_pointer_node
;
3051 t
= build_fold_addr_expr (t
);
3052 t
= build_call_expr_loc (gimple_location (entry_stmt
),
3053 gimple_omp_parallel_child_fn (entry_stmt
), 1, t
);
3054 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3055 false, GSI_CONTINUE_LINKING
);
3057 t
= build_call_expr_loc (gimple_location (entry_stmt
),
3058 built_in_decls
[BUILT_IN_GOMP_PARALLEL_END
], 0);
3059 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3060 false, GSI_CONTINUE_LINKING
);
3064 /* Build the function call to GOMP_task to actually
3065 generate the task operation. BB is the block where to insert the code. */
3068 expand_task_call (basic_block bb
, gimple entry_stmt
)
3070 tree t
, t1
, t2
, t3
, flags
, cond
, c
, clauses
;
3071 gimple_stmt_iterator gsi
;
3072 location_t loc
= gimple_location (entry_stmt
);
3074 clauses
= gimple_omp_task_clauses (entry_stmt
);
3076 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
3078 cond
= gimple_boolify (OMP_CLAUSE_IF_EXPR (c
));
3080 cond
= boolean_true_node
;
3082 c
= find_omp_clause (clauses
, OMP_CLAUSE_UNTIED
);
3083 flags
= build_int_cst (unsigned_type_node
, (c
? 1 : 0));
3085 gsi
= gsi_last_bb (bb
);
3086 t
= gimple_omp_task_data_arg (entry_stmt
);
3088 t2
= null_pointer_node
;
3090 t2
= build_fold_addr_expr_loc (loc
, t
);
3091 t1
= build_fold_addr_expr_loc (loc
, gimple_omp_task_child_fn (entry_stmt
));
3092 t
= gimple_omp_task_copy_fn (entry_stmt
);
3094 t3
= null_pointer_node
;
3096 t3
= build_fold_addr_expr_loc (loc
, t
);
3098 t
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_TASK
], 7, t1
, t2
, t3
,
3099 gimple_omp_task_arg_size (entry_stmt
),
3100 gimple_omp_task_arg_align (entry_stmt
), cond
, flags
);
3102 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3103 false, GSI_CONTINUE_LINKING
);
3107 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3108 catch handler and return it. This prevents programs from violating the
3109 structured block semantics with throws. */
3112 maybe_catch_exception (gimple_seq body
)
3117 if (!flag_exceptions
)
3120 if (lang_protect_cleanup_actions
)
3121 decl
= lang_protect_cleanup_actions ();
3123 decl
= built_in_decls
[BUILT_IN_TRAP
];
3125 g
= gimple_build_eh_must_not_throw (decl
);
3126 g
= gimple_build_try (body
, gimple_seq_alloc_with_stmt (g
),
3129 return gimple_seq_alloc_with_stmt (g
);
3132 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3135 list2chain (tree list
)
3139 for (t
= list
; t
; t
= TREE_CHAIN (t
))
3141 tree var
= TREE_VALUE (t
);
3143 TREE_CHAIN (var
) = TREE_VALUE (TREE_CHAIN (t
));
3145 TREE_CHAIN (var
) = NULL_TREE
;
3148 return list
? TREE_VALUE (list
) : NULL_TREE
;
3152 /* Remove barriers in REGION->EXIT's block. Note that this is only
3153 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3154 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3155 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3159 remove_exit_barrier (struct omp_region
*region
)
3161 gimple_stmt_iterator gsi
;
3162 basic_block exit_bb
;
3166 int any_addressable_vars
= -1;
3168 exit_bb
= region
->exit
;
3170 /* If the parallel region doesn't return, we don't have REGION->EXIT
3175 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3176 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3177 statements that can appear in between are extremely limited -- no
3178 memory operations at all. Here, we allow nothing at all, so the
3179 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3180 gsi
= gsi_last_bb (exit_bb
);
3181 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
3183 if (!gsi_end_p (gsi
) && gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
3186 FOR_EACH_EDGE (e
, ei
, exit_bb
->preds
)
3188 gsi
= gsi_last_bb (e
->src
);
3189 if (gsi_end_p (gsi
))
3191 stmt
= gsi_stmt (gsi
);
3192 if (gimple_code (stmt
) == GIMPLE_OMP_RETURN
3193 && !gimple_omp_return_nowait_p (stmt
))
3195 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3196 in many cases. If there could be tasks queued, the barrier
3197 might be needed to let the tasks run before some local
3198 variable of the parallel that the task uses as shared
3199 runs out of scope. The task can be spawned either
3200 from within current function (this would be easy to check)
3201 or from some function it calls and gets passed an address
3202 of such a variable. */
3203 if (any_addressable_vars
< 0)
3205 gimple parallel_stmt
= last_stmt (region
->entry
);
3206 tree child_fun
= gimple_omp_parallel_child_fn (parallel_stmt
);
3207 tree local_decls
= DECL_STRUCT_FUNCTION (child_fun
)->local_decls
;
3210 any_addressable_vars
= 0;
3211 for (; local_decls
; local_decls
= TREE_CHAIN (local_decls
))
3212 if (TREE_ADDRESSABLE (TREE_VALUE (local_decls
)))
3214 any_addressable_vars
= 1;
3217 for (block
= gimple_block (stmt
);
3218 !any_addressable_vars
3220 && TREE_CODE (block
) == BLOCK
;
3221 block
= BLOCK_SUPERCONTEXT (block
))
3223 for (local_decls
= BLOCK_VARS (block
);
3225 local_decls
= TREE_CHAIN (local_decls
))
3226 if (TREE_ADDRESSABLE (local_decls
))
3228 any_addressable_vars
= 1;
3231 if (block
== gimple_block (parallel_stmt
))
3235 if (!any_addressable_vars
)
3236 gimple_omp_return_set_nowait (stmt
);
3242 remove_exit_barriers (struct omp_region
*region
)
3244 if (region
->type
== GIMPLE_OMP_PARALLEL
)
3245 remove_exit_barrier (region
);
3249 region
= region
->inner
;
3250 remove_exit_barriers (region
);
3251 while (region
->next
)
3253 region
= region
->next
;
3254 remove_exit_barriers (region
);
3259 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3260 calls. These can't be declared as const functions, but
3261 within one parallel body they are constant, so they can be
3262 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3263 which are declared const. Similarly for task body, except
3264 that in untied task omp_get_thread_num () can change at any task
3265 scheduling point. */
3268 optimize_omp_library_calls (gimple entry_stmt
)
3271 gimple_stmt_iterator gsi
;
3273 = DECL_ASSEMBLER_NAME (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
]);
3275 = DECL_ASSEMBLER_NAME (built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
]);
3276 bool untied_task
= (gimple_code (entry_stmt
) == GIMPLE_OMP_TASK
3277 && find_omp_clause (gimple_omp_task_clauses (entry_stmt
),
3278 OMP_CLAUSE_UNTIED
) != NULL
);
3281 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3283 gimple call
= gsi_stmt (gsi
);
3286 if (is_gimple_call (call
)
3287 && (decl
= gimple_call_fndecl (call
))
3288 && DECL_EXTERNAL (decl
)
3289 && TREE_PUBLIC (decl
)
3290 && DECL_INITIAL (decl
) == NULL
)
3294 if (DECL_NAME (decl
) == thr_num_id
)
3296 /* In #pragma omp task untied omp_get_thread_num () can change
3297 during the execution of the task region. */
3300 built_in
= built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
];
3302 else if (DECL_NAME (decl
) == num_thr_id
)
3303 built_in
= built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
];
3307 if (DECL_ASSEMBLER_NAME (decl
) != DECL_ASSEMBLER_NAME (built_in
)
3308 || gimple_call_num_args (call
) != 0)
3311 if (flag_exceptions
&& !TREE_NOTHROW (decl
))
3314 if (TREE_CODE (TREE_TYPE (decl
)) != FUNCTION_TYPE
3315 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl
)),
3316 TREE_TYPE (TREE_TYPE (built_in
))))
3319 gimple_call_set_fndecl (call
, built_in
);
3324 /* Expand the OpenMP parallel or task directive starting at REGION. */
3327 expand_omp_taskreg (struct omp_region
*region
)
3329 basic_block entry_bb
, exit_bb
, new_bb
;
3330 struct function
*child_cfun
;
3331 tree child_fn
, block
, t
, ws_args
, *tp
;
3333 gimple_stmt_iterator gsi
;
3334 gimple entry_stmt
, stmt
;
3337 entry_stmt
= last_stmt (region
->entry
);
3338 child_fn
= gimple_omp_taskreg_child_fn (entry_stmt
);
3339 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
3340 /* If this function has been already instrumented, make sure
3341 the child function isn't instrumented again. */
3342 child_cfun
->after_tree_profile
= cfun
->after_tree_profile
;
3344 entry_bb
= region
->entry
;
3345 exit_bb
= region
->exit
;
3347 if (is_combined_parallel (region
))
3348 ws_args
= region
->ws_args
;
3350 ws_args
= NULL_TREE
;
3352 if (child_cfun
->cfg
)
3354 /* Due to inlining, it may happen that we have already outlined
3355 the region, in which case all we need to do is make the
3356 sub-graph unreachable and emit the parallel call. */
3357 edge entry_succ_e
, exit_succ_e
;
3358 gimple_stmt_iterator gsi
;
3360 entry_succ_e
= single_succ_edge (entry_bb
);
3362 gsi
= gsi_last_bb (entry_bb
);
3363 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_PARALLEL
3364 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_TASK
);
3365 gsi_remove (&gsi
, true);
3370 exit_succ_e
= single_succ_edge (exit_bb
);
3371 make_edge (new_bb
, exit_succ_e
->dest
, EDGE_FALLTHRU
);
3373 remove_edge_and_dominated_blocks (entry_succ_e
);
3377 /* If the parallel region needs data sent from the parent
3378 function, then the very first statement (except possible
3379 tree profile counter updates) of the parallel body
3380 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3381 &.OMP_DATA_O is passed as an argument to the child function,
3382 we need to replace it with the argument as seen by the child
3385 In most cases, this will end up being the identity assignment
3386 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3387 a function call that has been inlined, the original PARM_DECL
3388 .OMP_DATA_I may have been converted into a different local
3389 variable. In which case, we need to keep the assignment. */
3390 if (gimple_omp_taskreg_data_arg (entry_stmt
))
3392 basic_block entry_succ_bb
= single_succ (entry_bb
);
3393 gimple_stmt_iterator gsi
;
3395 gimple parcopy_stmt
= NULL
;
3397 for (gsi
= gsi_start_bb (entry_succ_bb
); ; gsi_next (&gsi
))
3401 gcc_assert (!gsi_end_p (gsi
));
3402 stmt
= gsi_stmt (gsi
);
3403 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
3406 if (gimple_num_ops (stmt
) == 2)
3408 tree arg
= gimple_assign_rhs1 (stmt
);
3410 /* We're ignore the subcode because we're
3411 effectively doing a STRIP_NOPS. */
3413 if (TREE_CODE (arg
) == ADDR_EXPR
3414 && TREE_OPERAND (arg
, 0)
3415 == gimple_omp_taskreg_data_arg (entry_stmt
))
3417 parcopy_stmt
= stmt
;
3423 gcc_assert (parcopy_stmt
!= NULL
);
3424 arg
= DECL_ARGUMENTS (child_fn
);
3426 if (!gimple_in_ssa_p (cfun
))
3428 if (gimple_assign_lhs (parcopy_stmt
) == arg
)
3429 gsi_remove (&gsi
, true);
3432 /* ?? Is setting the subcode really necessary ?? */
3433 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (arg
));
3434 gimple_assign_set_rhs1 (parcopy_stmt
, arg
);
3439 /* If we are in ssa form, we must load the value from the default
3440 definition of the argument. That should not be defined now,
3441 since the argument is not used uninitialized. */
3442 gcc_assert (gimple_default_def (cfun
, arg
) == NULL
);
3443 narg
= make_ssa_name (arg
, gimple_build_nop ());
3444 set_default_def (arg
, narg
);
3445 /* ?? Is setting the subcode really necessary ?? */
3446 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (narg
));
3447 gimple_assign_set_rhs1 (parcopy_stmt
, narg
);
3448 update_stmt (parcopy_stmt
);
3452 /* Declare local variables needed in CHILD_CFUN. */
3453 block
= DECL_INITIAL (child_fn
);
3454 BLOCK_VARS (block
) = list2chain (child_cfun
->local_decls
);
3455 /* The gimplifier could record temporaries in parallel/task block
3456 rather than in containing function's local_decls chain,
3457 which would mean cgraph missed finalizing them. Do it now. */
3458 for (t
= BLOCK_VARS (block
); t
; t
= TREE_CHAIN (t
))
3459 if (TREE_CODE (t
) == VAR_DECL
3461 && !DECL_EXTERNAL (t
))
3462 varpool_finalize_decl (t
);
3463 DECL_SAVED_TREE (child_fn
) = NULL
;
3464 gimple_set_body (child_fn
, bb_seq (single_succ (entry_bb
)));
3465 TREE_USED (block
) = 1;
3467 /* Reset DECL_CONTEXT on function arguments. */
3468 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= TREE_CHAIN (t
))
3469 DECL_CONTEXT (t
) = child_fn
;
3471 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3472 so that it can be moved to the child function. */
3473 gsi
= gsi_last_bb (entry_bb
);
3474 stmt
= gsi_stmt (gsi
);
3475 gcc_assert (stmt
&& (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
3476 || gimple_code (stmt
) == GIMPLE_OMP_TASK
));
3477 gsi_remove (&gsi
, true);
3478 e
= split_block (entry_bb
, stmt
);
3480 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
3482 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3485 gsi
= gsi_last_bb (exit_bb
);
3486 gcc_assert (!gsi_end_p (gsi
)
3487 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
3488 stmt
= gimple_build_return (NULL
);
3489 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
3490 gsi_remove (&gsi
, true);
3493 /* Move the parallel region into CHILD_CFUN. */
3495 if (gimple_in_ssa_p (cfun
))
3497 push_cfun (child_cfun
);
3498 init_tree_ssa (child_cfun
);
3499 init_ssa_operands ();
3500 cfun
->gimple_df
->in_ssa_p
= true;
3505 block
= gimple_block (entry_stmt
);
3507 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
, block
);
3509 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
3511 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3512 for (tp
= &child_cfun
->local_decls
; *tp
; )
3513 if (DECL_CONTEXT (TREE_VALUE (*tp
)) != cfun
->decl
)
3514 tp
= &TREE_CHAIN (*tp
);
3516 *tp
= TREE_CHAIN (*tp
);
3518 /* Inform the callgraph about the new function. */
3519 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
3520 = cfun
->curr_properties
;
3521 cgraph_add_new_function (child_fn
, true);
3523 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3524 fixed in a following pass. */
3525 push_cfun (child_cfun
);
3526 save_current
= current_function_decl
;
3527 current_function_decl
= child_fn
;
3529 optimize_omp_library_calls (entry_stmt
);
3530 rebuild_cgraph_edges ();
3532 /* Some EH regions might become dead, see PR34608. If
3533 pass_cleanup_cfg isn't the first pass to happen with the
3534 new child, these dead EH edges might cause problems.
3535 Clean them up now. */
3536 if (flag_exceptions
)
3539 bool changed
= false;
3542 changed
|= gimple_purge_dead_eh_edges (bb
);
3544 cleanup_tree_cfg ();
3546 if (gimple_in_ssa_p (cfun
))
3547 update_ssa (TODO_update_ssa
);
3548 current_function_decl
= save_current
;
3552 /* Emit a library call to launch the children threads. */
3553 if (gimple_code (entry_stmt
) == GIMPLE_OMP_PARALLEL
)
3554 expand_parallel_call (region
, new_bb
, entry_stmt
, ws_args
);
3556 expand_task_call (new_bb
, entry_stmt
);
3557 update_ssa (TODO_update_ssa_only_virtuals
);
3561 /* A subroutine of expand_omp_for. Generate code for a parallel
3562 loop with any schedule. Given parameters:
3564 for (V = N1; V cond N2; V += STEP) BODY;
3566 where COND is "<" or ">", we generate pseudocode
3568 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3569 if (more) goto L0; else goto L3;
3576 if (V cond iend) goto L1; else goto L2;
3578 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3581 If this is a combined omp parallel loop, instead of the call to
3582 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3584 For collapsed loops, given parameters:
3586 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3587 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3588 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3591 we generate pseudocode
3597 count3 = (adj + N32 - N31) / STEP3;
3602 count2 = (adj + N22 - N21) / STEP2;
3607 count1 = (adj + N12 - N11) / STEP1;
3608 count = count1 * count2 * count3;
3609 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3610 if (more) goto L0; else goto L3;
3614 V3 = N31 + (T % count3) * STEP3;
3616 V2 = N21 + (T % count2) * STEP2;
3618 V1 = N11 + T * STEP1;
3623 if (V < iend) goto L10; else goto L2;
3626 if (V3 cond3 N32) goto L1; else goto L11;
3630 if (V2 cond2 N22) goto L1; else goto L12;
3636 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3642 expand_omp_for_generic (struct omp_region
*region
,
3643 struct omp_for_data
*fd
,
3644 enum built_in_function start_fn
,
3645 enum built_in_function next_fn
)
3647 tree type
, istart0
, iend0
, iend
;
3648 tree t
, vmain
, vback
, bias
= NULL_TREE
;
3649 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
, collapse_bb
;
3650 basic_block l2_bb
= NULL
, l3_bb
= NULL
;
3651 gimple_stmt_iterator gsi
;
3653 bool in_combined_parallel
= is_combined_parallel (region
);
3654 bool broken_loop
= region
->cont
== NULL
;
3656 tree
*counts
= NULL
;
3659 gcc_assert (!broken_loop
|| !in_combined_parallel
);
3660 gcc_assert (fd
->iter_type
== long_integer_type_node
3661 || !in_combined_parallel
);
3663 type
= TREE_TYPE (fd
->loop
.v
);
3664 istart0
= create_tmp_var (fd
->iter_type
, ".istart0");
3665 iend0
= create_tmp_var (fd
->iter_type
, ".iend0");
3666 TREE_ADDRESSABLE (istart0
) = 1;
3667 TREE_ADDRESSABLE (iend0
) = 1;
3668 if (gimple_in_ssa_p (cfun
))
3670 add_referenced_var (istart0
);
3671 add_referenced_var (iend0
);
3674 /* See if we need to bias by LLONG_MIN. */
3675 if (fd
->iter_type
== long_long_unsigned_type_node
3676 && TREE_CODE (type
) == INTEGER_TYPE
3677 && !TYPE_UNSIGNED (type
))
3681 if (fd
->loop
.cond_code
== LT_EXPR
)
3684 n2
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
3688 n1
= fold_build2 (MINUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
3691 if (TREE_CODE (n1
) != INTEGER_CST
3692 || TREE_CODE (n2
) != INTEGER_CST
3693 || ((tree_int_cst_sgn (n1
) < 0) ^ (tree_int_cst_sgn (n2
) < 0)))
3694 bias
= fold_convert (fd
->iter_type
, TYPE_MIN_VALUE (type
));
3697 entry_bb
= region
->entry
;
3698 cont_bb
= region
->cont
;
3700 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
3701 gcc_assert (broken_loop
3702 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
3703 l0_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
3704 l1_bb
= single_succ (l0_bb
);
3707 l2_bb
= create_empty_bb (cont_bb
);
3708 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l1_bb
);
3709 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
3713 l3_bb
= BRANCH_EDGE (entry_bb
)->dest
;
3714 exit_bb
= region
->exit
;
3716 gsi
= gsi_last_bb (entry_bb
);
3718 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
3719 if (fd
->collapse
> 1)
3721 /* collapsed loops need work for expansion in SSA form. */
3722 gcc_assert (!gimple_in_ssa_p (cfun
));
3723 counts
= (tree
*) alloca (fd
->collapse
* sizeof (tree
));
3724 for (i
= 0; i
< fd
->collapse
; i
++)
3726 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
3728 if (POINTER_TYPE_P (itype
))
3729 itype
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (itype
), 0);
3730 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
== LT_EXPR
3732 t
= fold_build2 (PLUS_EXPR
, itype
,
3733 fold_convert (itype
, fd
->loops
[i
].step
), t
);
3734 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
3735 fold_convert (itype
, fd
->loops
[i
].n2
));
3736 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
3737 fold_convert (itype
, fd
->loops
[i
].n1
));
3738 if (TYPE_UNSIGNED (itype
) && fd
->loops
[i
].cond_code
== GT_EXPR
)
3739 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
3740 fold_build1 (NEGATE_EXPR
, itype
, t
),
3741 fold_build1 (NEGATE_EXPR
, itype
,
3742 fold_convert (itype
,
3743 fd
->loops
[i
].step
)));
3745 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
,
3746 fold_convert (itype
, fd
->loops
[i
].step
));
3747 t
= fold_convert (type
, t
);
3748 if (TREE_CODE (t
) == INTEGER_CST
)
3752 counts
[i
] = create_tmp_var (type
, ".count");
3753 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3754 true, GSI_SAME_STMT
);
3755 stmt
= gimple_build_assign (counts
[i
], t
);
3756 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3758 if (SSA_VAR_P (fd
->loop
.n2
))
3764 t
= fold_build2 (MULT_EXPR
, type
, fd
->loop
.n2
, counts
[i
]);
3765 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3766 true, GSI_SAME_STMT
);
3768 stmt
= gimple_build_assign (fd
->loop
.n2
, t
);
3769 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3773 if (in_combined_parallel
)
3775 /* In a combined parallel loop, emit a call to
3776 GOMP_loop_foo_next. */
3777 t
= build_call_expr (built_in_decls
[next_fn
], 2,
3778 build_fold_addr_expr (istart0
),
3779 build_fold_addr_expr (iend0
));
3783 tree t0
, t1
, t2
, t3
, t4
;
3784 /* If this is not a combined parallel loop, emit a call to
3785 GOMP_loop_foo_start in ENTRY_BB. */
3786 t4
= build_fold_addr_expr (iend0
);
3787 t3
= build_fold_addr_expr (istart0
);
3788 t2
= fold_convert (fd
->iter_type
, fd
->loop
.step
);
3789 if (POINTER_TYPE_P (type
)
3790 && TYPE_PRECISION (type
) != TYPE_PRECISION (fd
->iter_type
))
3792 /* Avoid casting pointers to integer of a different size. */
3794 = lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
), 0);
3795 t1
= fold_convert (fd
->iter_type
, fold_convert (itype
, fd
->loop
.n2
));
3796 t0
= fold_convert (fd
->iter_type
, fold_convert (itype
, fd
->loop
.n1
));
3800 t1
= fold_convert (fd
->iter_type
, fd
->loop
.n2
);
3801 t0
= fold_convert (fd
->iter_type
, fd
->loop
.n1
);
3805 t1
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t1
, bias
);
3806 t0
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t0
, bias
);
3808 if (fd
->iter_type
== long_integer_type_node
)
3812 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
3813 t
= build_call_expr (built_in_decls
[start_fn
], 6,
3814 t0
, t1
, t2
, t
, t3
, t4
);
3817 t
= build_call_expr (built_in_decls
[start_fn
], 5,
3818 t0
, t1
, t2
, t3
, t4
);
3825 /* The GOMP_loop_ull_*start functions have additional boolean
3826 argument, true for < loops and false for > loops.
3827 In Fortran, the C bool type can be different from
3828 boolean_type_node. */
3829 c_bool_type
= TREE_TYPE (TREE_TYPE (built_in_decls
[start_fn
]));
3830 t5
= build_int_cst (c_bool_type
,
3831 fd
->loop
.cond_code
== LT_EXPR
? 1 : 0);
3834 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
3835 t
= build_call_expr (built_in_decls
[start_fn
], 7,
3836 t5
, t0
, t1
, t2
, t
, t3
, t4
);
3839 t
= build_call_expr (built_in_decls
[start_fn
], 6,
3840 t5
, t0
, t1
, t2
, t3
, t4
);
3843 if (TREE_TYPE (t
) != boolean_type_node
)
3844 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
3845 t
, build_int_cst (TREE_TYPE (t
), 0));
3846 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3847 true, GSI_SAME_STMT
);
3848 gsi_insert_after (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
3850 /* Remove the GIMPLE_OMP_FOR statement. */
3851 gsi_remove (&gsi
, true);
3853 /* Iteration setup for sequential loop goes in L0_BB. */
3854 gsi
= gsi_start_bb (l0_bb
);
3857 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
3858 if (POINTER_TYPE_P (type
))
3859 t
= fold_convert (lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
),
3861 t
= fold_convert (type
, t
);
3862 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3863 false, GSI_CONTINUE_LINKING
);
3864 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
3865 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3869 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
3870 if (POINTER_TYPE_P (type
))
3871 t
= fold_convert (lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
),
3873 t
= fold_convert (type
, t
);
3874 iend
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3875 false, GSI_CONTINUE_LINKING
);
3876 if (fd
->collapse
> 1)
3878 tree tem
= create_tmp_var (type
, ".tem");
3880 stmt
= gimple_build_assign (tem
, fd
->loop
.v
);
3881 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3882 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
3884 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
), itype
;
3886 if (POINTER_TYPE_P (vtype
))
3887 itype
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (vtype
), 0);
3888 t
= fold_build2 (TRUNC_MOD_EXPR
, type
, tem
, counts
[i
]);
3889 t
= fold_convert (itype
, t
);
3890 t
= fold_build2 (MULT_EXPR
, itype
, t
,
3891 fold_convert (itype
, fd
->loops
[i
].step
));
3892 if (POINTER_TYPE_P (vtype
))
3893 t
= fold_build2 (POINTER_PLUS_EXPR
, vtype
,
3894 fd
->loops
[i
].n1
, fold_convert (sizetype
, t
));
3896 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[i
].n1
, t
);
3897 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3898 false, GSI_CONTINUE_LINKING
);
3899 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
3900 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3903 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, tem
, counts
[i
]);
3904 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3905 false, GSI_CONTINUE_LINKING
);
3906 stmt
= gimple_build_assign (tem
, t
);
3907 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3914 /* Code to control the increment and predicate for the sequential
3915 loop goes in the CONT_BB. */
3916 gsi
= gsi_last_bb (cont_bb
);
3917 stmt
= gsi_stmt (gsi
);
3918 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
3919 vmain
= gimple_omp_continue_control_use (stmt
);
3920 vback
= gimple_omp_continue_control_def (stmt
);
3922 if (POINTER_TYPE_P (type
))
3923 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, vmain
,
3924 fold_convert (sizetype
, fd
->loop
.step
));
3926 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
3927 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3928 true, GSI_SAME_STMT
);
3929 stmt
= gimple_build_assign (vback
, t
);
3930 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3932 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, vback
, iend
);
3933 stmt
= gimple_build_cond_empty (t
);
3934 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3936 /* Remove GIMPLE_OMP_CONTINUE. */
3937 gsi_remove (&gsi
, true);
3939 if (fd
->collapse
> 1)
3941 basic_block last_bb
, bb
;
3944 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
3946 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
);
3948 bb
= create_empty_bb (last_bb
);
3949 gsi
= gsi_start_bb (bb
);
3951 if (i
< fd
->collapse
- 1)
3953 e
= make_edge (last_bb
, bb
, EDGE_FALSE_VALUE
);
3954 e
->probability
= REG_BR_PROB_BASE
/ 8;
3956 t
= fd
->loops
[i
+ 1].n1
;
3957 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3958 false, GSI_CONTINUE_LINKING
);
3959 stmt
= gimple_build_assign (fd
->loops
[i
+ 1].v
, t
);
3960 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3965 set_immediate_dominator (CDI_DOMINATORS
, bb
, last_bb
);
3967 if (POINTER_TYPE_P (vtype
))
3968 t
= fold_build2 (POINTER_PLUS_EXPR
, vtype
,
3970 fold_convert (sizetype
, fd
->loops
[i
].step
));
3972 t
= fold_build2 (PLUS_EXPR
, vtype
, fd
->loops
[i
].v
,
3974 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3975 false, GSI_CONTINUE_LINKING
);
3976 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
3977 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3981 t
= fd
->loops
[i
].n2
;
3982 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3983 false, GSI_CONTINUE_LINKING
);
3984 t
= fold_build2 (fd
->loops
[i
].cond_code
, boolean_type_node
,
3986 stmt
= gimple_build_cond_empty (t
);
3987 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3988 e
= make_edge (bb
, l1_bb
, EDGE_TRUE_VALUE
);
3989 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
3992 make_edge (bb
, l1_bb
, EDGE_FALLTHRU
);
3997 /* Emit code to get the next parallel iteration in L2_BB. */
3998 gsi
= gsi_start_bb (l2_bb
);
4000 t
= build_call_expr (built_in_decls
[next_fn
], 2,
4001 build_fold_addr_expr (istart0
),
4002 build_fold_addr_expr (iend0
));
4003 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4004 false, GSI_CONTINUE_LINKING
);
4005 if (TREE_TYPE (t
) != boolean_type_node
)
4006 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
4007 t
, build_int_cst (TREE_TYPE (t
), 0));
4008 stmt
= gimple_build_cond_empty (t
);
4009 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4012 /* Add the loop cleanup function. */
4013 gsi
= gsi_last_bb (exit_bb
);
4014 if (gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4015 t
= built_in_decls
[BUILT_IN_GOMP_LOOP_END_NOWAIT
];
4017 t
= built_in_decls
[BUILT_IN_GOMP_LOOP_END
];
4018 stmt
= gimple_build_call (t
, 0);
4019 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
4020 gsi_remove (&gsi
, true);
4022 /* Connect the new blocks. */
4023 find_edge (entry_bb
, l0_bb
)->flags
= EDGE_TRUE_VALUE
;
4024 find_edge (entry_bb
, l3_bb
)->flags
= EDGE_FALSE_VALUE
;
4030 e
= find_edge (cont_bb
, l3_bb
);
4031 ne
= make_edge (l2_bb
, l3_bb
, EDGE_FALSE_VALUE
);
4033 phis
= phi_nodes (l3_bb
);
4034 for (gsi
= gsi_start (phis
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4036 gimple phi
= gsi_stmt (gsi
);
4037 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, ne
),
4038 PHI_ARG_DEF_FROM_EDGE (phi
, e
));
4042 make_edge (cont_bb
, l2_bb
, EDGE_FALSE_VALUE
);
4043 if (fd
->collapse
> 1)
4045 e
= find_edge (cont_bb
, l1_bb
);
4047 e
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
4051 e
= find_edge (cont_bb
, l1_bb
);
4052 e
->flags
= EDGE_TRUE_VALUE
;
4054 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
4055 find_edge (cont_bb
, l2_bb
)->probability
= REG_BR_PROB_BASE
/ 8;
4056 make_edge (l2_bb
, l0_bb
, EDGE_TRUE_VALUE
);
4058 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
,
4059 recompute_dominator (CDI_DOMINATORS
, l2_bb
));
4060 set_immediate_dominator (CDI_DOMINATORS
, l3_bb
,
4061 recompute_dominator (CDI_DOMINATORS
, l3_bb
));
4062 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
,
4063 recompute_dominator (CDI_DOMINATORS
, l0_bb
));
4064 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
,
4065 recompute_dominator (CDI_DOMINATORS
, l1_bb
));
4070 /* A subroutine of expand_omp_for. Generate code for a parallel
4071 loop with static schedule and no specified chunk size. Given
4074 for (V = N1; V cond N2; V += STEP) BODY;
4076 where COND is "<" or ">", we generate pseudocode
4082 if ((__typeof (V)) -1 > 0 && cond is >)
4083 n = -(adj + N2 - N1) / -STEP;
4085 n = (adj + N2 - N1) / STEP;
4087 q += (q * nthreads != n);
4089 e0 = min(s0 + q, n);
4091 if (s0 >= e0) goto L2; else goto L0;
4097 if (V cond e) goto L1;
4102 expand_omp_for_static_nochunk (struct omp_region
*region
,
4103 struct omp_for_data
*fd
)
4105 tree n
, q
, s0
, e0
, e
, t
, nthreads
, threadid
;
4106 tree type
, itype
, vmain
, vback
;
4107 basic_block entry_bb
, exit_bb
, seq_start_bb
, body_bb
, cont_bb
;
4109 gimple_stmt_iterator gsi
;
4112 itype
= type
= TREE_TYPE (fd
->loop
.v
);
4113 if (POINTER_TYPE_P (type
))
4114 itype
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
), 0);
4116 entry_bb
= region
->entry
;
4117 cont_bb
= region
->cont
;
4118 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
4119 gcc_assert (BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
4120 seq_start_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
4121 body_bb
= single_succ (seq_start_bb
);
4122 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
4123 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
4124 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
4125 exit_bb
= region
->exit
;
4127 /* Iteration space partitioning goes in ENTRY_BB. */
4128 gsi
= gsi_last_bb (entry_bb
);
4129 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4131 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
], 0);
4132 t
= fold_convert (itype
, t
);
4133 nthreads
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4134 true, GSI_SAME_STMT
);
4136 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
4137 t
= fold_convert (itype
, t
);
4138 threadid
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4139 true, GSI_SAME_STMT
);
4142 = force_gimple_operand_gsi (&gsi
, fold_convert (type
, fd
->loop
.n1
),
4143 true, NULL_TREE
, true, GSI_SAME_STMT
);
4145 = force_gimple_operand_gsi (&gsi
, fold_convert (itype
, fd
->loop
.n2
),
4146 true, NULL_TREE
, true, GSI_SAME_STMT
);
4148 = force_gimple_operand_gsi (&gsi
, fold_convert (itype
, fd
->loop
.step
),
4149 true, NULL_TREE
, true, GSI_SAME_STMT
);
4151 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
4152 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loop
.step
, t
);
4153 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fd
->loop
.n2
);
4154 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, fd
->loop
.n1
));
4155 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
4156 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4157 fold_build1 (NEGATE_EXPR
, itype
, t
),
4158 fold_build1 (NEGATE_EXPR
, itype
, fd
->loop
.step
));
4160 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, fd
->loop
.step
);
4161 t
= fold_convert (itype
, t
);
4162 n
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4164 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, n
, nthreads
);
4165 q
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4167 t
= fold_build2 (MULT_EXPR
, itype
, q
, nthreads
);
4168 t
= fold_build2 (NE_EXPR
, itype
, t
, n
);
4169 t
= fold_build2 (PLUS_EXPR
, itype
, q
, t
);
4170 q
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4172 t
= build2 (MULT_EXPR
, itype
, q
, threadid
);
4173 s0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4175 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, q
);
4176 t
= fold_build2 (MIN_EXPR
, itype
, t
, n
);
4177 e0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4179 t
= build2 (GE_EXPR
, boolean_type_node
, s0
, e0
);
4180 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4182 /* Remove the GIMPLE_OMP_FOR statement. */
4183 gsi_remove (&gsi
, true);
4185 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4186 gsi
= gsi_start_bb (seq_start_bb
);
4188 t
= fold_convert (itype
, s0
);
4189 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4190 if (POINTER_TYPE_P (type
))
4191 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4192 fold_convert (sizetype
, t
));
4194 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4195 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4196 false, GSI_CONTINUE_LINKING
);
4197 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4198 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4200 t
= fold_convert (itype
, e0
);
4201 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4202 if (POINTER_TYPE_P (type
))
4203 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4204 fold_convert (sizetype
, t
));
4206 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4207 e
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4208 false, GSI_CONTINUE_LINKING
);
4210 /* The code controlling the sequential loop replaces the
4211 GIMPLE_OMP_CONTINUE. */
4212 gsi
= gsi_last_bb (cont_bb
);
4213 stmt
= gsi_stmt (gsi
);
4214 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4215 vmain
= gimple_omp_continue_control_use (stmt
);
4216 vback
= gimple_omp_continue_control_def (stmt
);
4218 if (POINTER_TYPE_P (type
))
4219 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, vmain
,
4220 fold_convert (sizetype
, fd
->loop
.step
));
4222 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
4223 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4224 true, GSI_SAME_STMT
);
4225 stmt
= gimple_build_assign (vback
, t
);
4226 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4228 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, vback
, e
);
4229 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4231 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4232 gsi_remove (&gsi
, true);
4234 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4235 gsi
= gsi_last_bb (exit_bb
);
4236 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4237 force_gimple_operand_gsi (&gsi
, build_omp_barrier (), false, NULL_TREE
,
4238 false, GSI_SAME_STMT
);
4239 gsi_remove (&gsi
, true);
4241 /* Connect all the blocks. */
4242 find_edge (entry_bb
, seq_start_bb
)->flags
= EDGE_FALSE_VALUE
;
4243 find_edge (entry_bb
, fin_bb
)->flags
= EDGE_TRUE_VALUE
;
4245 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
4246 find_edge (cont_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
4248 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
, entry_bb
);
4249 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
4250 recompute_dominator (CDI_DOMINATORS
, body_bb
));
4251 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
4252 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
4256 /* A subroutine of expand_omp_for. Generate code for a parallel
4257 loop with static schedule and a specified chunk size. Given
4260 for (V = N1; V cond N2; V += STEP) BODY;
4262 where COND is "<" or ">", we generate pseudocode
4268 if ((__typeof (V)) -1 > 0 && cond is >)
4269 n = -(adj + N2 - N1) / -STEP;
4271 n = (adj + N2 - N1) / STEP;
4273 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4274 here so that V is defined
4275 if the loop is not entered
4277 s0 = (trip * nthreads + threadid) * CHUNK;
4278 e0 = min(s0 + CHUNK, n);
4279 if (s0 < n) goto L1; else goto L4;
4286 if (V cond e) goto L2; else goto L3;
4294 expand_omp_for_static_chunk (struct omp_region
*region
, struct omp_for_data
*fd
)
4296 tree n
, s0
, e0
, e
, t
;
4297 tree trip_var
, trip_init
, trip_main
, trip_back
, nthreads
, threadid
;
4298 tree type
, itype
, v_main
, v_back
, v_extra
;
4299 basic_block entry_bb
, exit_bb
, body_bb
, seq_start_bb
, iter_part_bb
;
4300 basic_block trip_update_bb
, cont_bb
, fin_bb
;
4301 gimple_stmt_iterator si
;
4305 itype
= type
= TREE_TYPE (fd
->loop
.v
);
4306 if (POINTER_TYPE_P (type
))
4307 itype
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
), 0);
4309 entry_bb
= region
->entry
;
4310 se
= split_block (entry_bb
, last_stmt (entry_bb
));
4312 iter_part_bb
= se
->dest
;
4313 cont_bb
= region
->cont
;
4314 gcc_assert (EDGE_COUNT (iter_part_bb
->succs
) == 2);
4315 gcc_assert (BRANCH_EDGE (iter_part_bb
)->dest
4316 == FALLTHRU_EDGE (cont_bb
)->dest
);
4317 seq_start_bb
= split_edge (FALLTHRU_EDGE (iter_part_bb
));
4318 body_bb
= single_succ (seq_start_bb
);
4319 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
4320 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
4321 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
4322 trip_update_bb
= split_edge (FALLTHRU_EDGE (cont_bb
));
4323 exit_bb
= region
->exit
;
4325 /* Trip and adjustment setup goes in ENTRY_BB. */
4326 si
= gsi_last_bb (entry_bb
);
4327 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_FOR
);
4329 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
], 0);
4330 t
= fold_convert (itype
, t
);
4331 nthreads
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4332 true, GSI_SAME_STMT
);
4334 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
4335 t
= fold_convert (itype
, t
);
4336 threadid
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4337 true, GSI_SAME_STMT
);
4340 = force_gimple_operand_gsi (&si
, fold_convert (type
, fd
->loop
.n1
),
4341 true, NULL_TREE
, true, GSI_SAME_STMT
);
4343 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->loop
.n2
),
4344 true, NULL_TREE
, true, GSI_SAME_STMT
);
4346 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->loop
.step
),
4347 true, NULL_TREE
, true, GSI_SAME_STMT
);
4349 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->chunk_size
),
4350 true, NULL_TREE
, true, GSI_SAME_STMT
);
4352 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
4353 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loop
.step
, t
);
4354 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fd
->loop
.n2
);
4355 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, fd
->loop
.n1
));
4356 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
4357 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4358 fold_build1 (NEGATE_EXPR
, itype
, t
),
4359 fold_build1 (NEGATE_EXPR
, itype
, fd
->loop
.step
));
4361 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, fd
->loop
.step
);
4362 t
= fold_convert (itype
, t
);
4363 n
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4364 true, GSI_SAME_STMT
);
4366 trip_var
= create_tmp_var (itype
, ".trip");
4367 if (gimple_in_ssa_p (cfun
))
4369 add_referenced_var (trip_var
);
4370 trip_init
= make_ssa_name (trip_var
, NULL
);
4371 trip_main
= make_ssa_name (trip_var
, NULL
);
4372 trip_back
= make_ssa_name (trip_var
, NULL
);
4376 trip_init
= trip_var
;
4377 trip_main
= trip_var
;
4378 trip_back
= trip_var
;
4381 stmt
= gimple_build_assign (trip_init
, build_int_cst (itype
, 0));
4382 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4384 t
= fold_build2 (MULT_EXPR
, itype
, threadid
, fd
->chunk_size
);
4385 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4386 if (POINTER_TYPE_P (type
))
4387 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4388 fold_convert (sizetype
, t
));
4390 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4391 v_extra
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4392 true, GSI_SAME_STMT
);
4394 /* Remove the GIMPLE_OMP_FOR. */
4395 gsi_remove (&si
, true);
4397 /* Iteration space partitioning goes in ITER_PART_BB. */
4398 si
= gsi_last_bb (iter_part_bb
);
4400 t
= fold_build2 (MULT_EXPR
, itype
, trip_main
, nthreads
);
4401 t
= fold_build2 (PLUS_EXPR
, itype
, t
, threadid
);
4402 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->chunk_size
);
4403 s0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4404 false, GSI_CONTINUE_LINKING
);
4406 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, fd
->chunk_size
);
4407 t
= fold_build2 (MIN_EXPR
, itype
, t
, n
);
4408 e0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4409 false, GSI_CONTINUE_LINKING
);
4411 t
= build2 (LT_EXPR
, boolean_type_node
, s0
, n
);
4412 gsi_insert_after (&si
, gimple_build_cond_empty (t
), GSI_CONTINUE_LINKING
);
4414 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4415 si
= gsi_start_bb (seq_start_bb
);
4417 t
= fold_convert (itype
, s0
);
4418 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4419 if (POINTER_TYPE_P (type
))
4420 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4421 fold_convert (sizetype
, t
));
4423 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4424 t
= force_gimple_operand_gsi (&si
, t
, false, NULL_TREE
,
4425 false, GSI_CONTINUE_LINKING
);
4426 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4427 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4429 t
= fold_convert (itype
, e0
);
4430 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4431 if (POINTER_TYPE_P (type
))
4432 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4433 fold_convert (sizetype
, t
));
4435 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4436 e
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4437 false, GSI_CONTINUE_LINKING
);
4439 /* The code controlling the sequential loop goes in CONT_BB,
4440 replacing the GIMPLE_OMP_CONTINUE. */
4441 si
= gsi_last_bb (cont_bb
);
4442 stmt
= gsi_stmt (si
);
4443 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4444 v_main
= gimple_omp_continue_control_use (stmt
);
4445 v_back
= gimple_omp_continue_control_def (stmt
);
4447 if (POINTER_TYPE_P (type
))
4448 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, v_main
,
4449 fold_convert (sizetype
, fd
->loop
.step
));
4451 t
= fold_build2 (PLUS_EXPR
, type
, v_main
, fd
->loop
.step
);
4452 stmt
= gimple_build_assign (v_back
, t
);
4453 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4455 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, v_back
, e
);
4456 gsi_insert_before (&si
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4458 /* Remove GIMPLE_OMP_CONTINUE. */
4459 gsi_remove (&si
, true);
4461 /* Trip update code goes into TRIP_UPDATE_BB. */
4462 si
= gsi_start_bb (trip_update_bb
);
4464 t
= build_int_cst (itype
, 1);
4465 t
= build2 (PLUS_EXPR
, itype
, trip_main
, t
);
4466 stmt
= gimple_build_assign (trip_back
, t
);
4467 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4469 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4470 si
= gsi_last_bb (exit_bb
);
4471 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)))
4472 force_gimple_operand_gsi (&si
, build_omp_barrier (), false, NULL_TREE
,
4473 false, GSI_SAME_STMT
);
4474 gsi_remove (&si
, true);
4476 /* Connect the new blocks. */
4477 find_edge (iter_part_bb
, seq_start_bb
)->flags
= EDGE_TRUE_VALUE
;
4478 find_edge (iter_part_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
4480 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
4481 find_edge (cont_bb
, trip_update_bb
)->flags
= EDGE_FALSE_VALUE
;
4483 redirect_edge_and_branch (single_succ_edge (trip_update_bb
), iter_part_bb
);
4485 if (gimple_in_ssa_p (cfun
))
4487 gimple_stmt_iterator psi
;
4490 edge_var_map_vector head
;
4494 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4495 remove arguments of the phi nodes in fin_bb. We need to create
4496 appropriate phi nodes in iter_part_bb instead. */
4497 se
= single_pred_edge (fin_bb
);
4498 re
= single_succ_edge (trip_update_bb
);
4499 head
= redirect_edge_var_map_vector (re
);
4500 ene
= single_succ_edge (entry_bb
);
4502 psi
= gsi_start_phis (fin_bb
);
4503 for (i
= 0; !gsi_end_p (psi
) && VEC_iterate (edge_var_map
, head
, i
, vm
);
4504 gsi_next (&psi
), ++i
)
4507 source_location locus
;
4509 phi
= gsi_stmt (psi
);
4510 t
= gimple_phi_result (phi
);
4511 gcc_assert (t
== redirect_edge_var_map_result (vm
));
4512 nphi
= create_phi_node (t
, iter_part_bb
);
4513 SSA_NAME_DEF_STMT (t
) = nphi
;
4515 t
= PHI_ARG_DEF_FROM_EDGE (phi
, se
);
4516 locus
= gimple_phi_arg_location_from_edge (phi
, se
);
4518 /* A special case -- fd->loop.v is not yet computed in
4519 iter_part_bb, we need to use v_extra instead. */
4520 if (t
== fd
->loop
.v
)
4522 add_phi_arg (nphi
, t
, ene
, locus
);
4523 locus
= redirect_edge_var_map_location (vm
);
4524 add_phi_arg (nphi
, redirect_edge_var_map_def (vm
), re
, locus
);
4526 gcc_assert (!gsi_end_p (psi
) && i
== VEC_length (edge_var_map
, head
));
4527 redirect_edge_var_map_clear (re
);
4530 psi
= gsi_start_phis (fin_bb
);
4531 if (gsi_end_p (psi
))
4533 remove_phi_node (&psi
, false);
4536 /* Make phi node for trip. */
4537 phi
= create_phi_node (trip_main
, iter_part_bb
);
4538 SSA_NAME_DEF_STMT (trip_main
) = phi
;
4539 add_phi_arg (phi
, trip_back
, single_succ_edge (trip_update_bb
),
4541 add_phi_arg (phi
, trip_init
, single_succ_edge (entry_bb
),
4545 set_immediate_dominator (CDI_DOMINATORS
, trip_update_bb
, cont_bb
);
4546 set_immediate_dominator (CDI_DOMINATORS
, iter_part_bb
,
4547 recompute_dominator (CDI_DOMINATORS
, iter_part_bb
));
4548 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
4549 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
4550 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
,
4551 recompute_dominator (CDI_DOMINATORS
, seq_start_bb
));
4552 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
4553 recompute_dominator (CDI_DOMINATORS
, body_bb
));
4557 /* Expand the OpenMP loop defined by REGION. */
4560 expand_omp_for (struct omp_region
*region
)
4562 struct omp_for_data fd
;
4563 struct omp_for_data_loop
*loops
;
4566 = (struct omp_for_data_loop
*)
4567 alloca (gimple_omp_for_collapse (last_stmt (region
->entry
))
4568 * sizeof (struct omp_for_data_loop
));
4569 extract_omp_for_data (last_stmt (region
->entry
), &fd
, loops
);
4570 region
->sched_kind
= fd
.sched_kind
;
4572 gcc_assert (EDGE_COUNT (region
->entry
->succs
) == 2);
4573 BRANCH_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
4574 FALLTHRU_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
4577 gcc_assert (EDGE_COUNT (region
->cont
->succs
) == 2);
4578 BRANCH_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
4579 FALLTHRU_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
4582 if (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
4585 && region
->cont
!= NULL
)
4587 if (fd
.chunk_size
== NULL
)
4588 expand_omp_for_static_nochunk (region
, &fd
);
4590 expand_omp_for_static_chunk (region
, &fd
);
4594 int fn_index
, start_ix
, next_ix
;
4596 gcc_assert (fd
.sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
4597 fn_index
= (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
4598 ? 3 : fd
.sched_kind
;
4599 fn_index
+= fd
.have_ordered
* 4;
4600 start_ix
= BUILT_IN_GOMP_LOOP_STATIC_START
+ fn_index
;
4601 next_ix
= BUILT_IN_GOMP_LOOP_STATIC_NEXT
+ fn_index
;
4602 if (fd
.iter_type
== long_long_unsigned_type_node
)
4604 start_ix
+= BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4605 - BUILT_IN_GOMP_LOOP_STATIC_START
;
4606 next_ix
+= BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4607 - BUILT_IN_GOMP_LOOP_STATIC_NEXT
;
4609 expand_omp_for_generic (region
, &fd
, (enum built_in_function
) start_ix
,
4610 (enum built_in_function
) next_ix
);
4613 update_ssa (TODO_update_ssa_only_virtuals
);
4617 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4619 v = GOMP_sections_start (n);
4636 v = GOMP_sections_next ();
4641 If this is a combined parallel sections, replace the call to
4642 GOMP_sections_start with call to GOMP_sections_next. */
4645 expand_omp_sections (struct omp_region
*region
)
4647 tree t
, u
, vin
= NULL
, vmain
, vnext
, l2
;
4648 VEC (tree
,heap
) *label_vec
;
4650 basic_block entry_bb
, l0_bb
, l1_bb
, l2_bb
, default_bb
;
4651 gimple_stmt_iterator si
, switch_si
;
4652 gimple sections_stmt
, stmt
, cont
;
4655 struct omp_region
*inner
;
4657 bool exit_reachable
= region
->cont
!= NULL
;
4659 gcc_assert (exit_reachable
== (region
->exit
!= NULL
));
4660 entry_bb
= region
->entry
;
4661 l0_bb
= single_succ (entry_bb
);
4662 l1_bb
= region
->cont
;
4663 l2_bb
= region
->exit
;
4666 if (single_pred_p (l2_bb
) && single_pred (l2_bb
) == l0_bb
)
4667 l2
= gimple_block_label (l2_bb
);
4670 /* This can happen if there are reductions. */
4671 len
= EDGE_COUNT (l0_bb
->succs
);
4672 gcc_assert (len
> 0);
4673 e
= EDGE_SUCC (l0_bb
, len
- 1);
4674 si
= gsi_last_bb (e
->dest
);
4677 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
4678 l2
= gimple_block_label (e
->dest
);
4680 FOR_EACH_EDGE (e
, ei
, l0_bb
->succs
)
4682 si
= gsi_last_bb (e
->dest
);
4684 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
4686 l2
= gimple_block_label (e
->dest
);
4691 default_bb
= create_empty_bb (l1_bb
->prev_bb
);
4695 default_bb
= create_empty_bb (l0_bb
);
4696 l2
= gimple_block_label (default_bb
);
4699 /* We will build a switch() with enough cases for all the
4700 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4701 and a default case to abort if something goes wrong. */
4702 len
= EDGE_COUNT (l0_bb
->succs
);
4704 /* Use VEC_quick_push on label_vec throughout, since we know the size
4706 label_vec
= VEC_alloc (tree
, heap
, len
);
4708 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4709 GIMPLE_OMP_SECTIONS statement. */
4710 si
= gsi_last_bb (entry_bb
);
4711 sections_stmt
= gsi_stmt (si
);
4712 gcc_assert (gimple_code (sections_stmt
) == GIMPLE_OMP_SECTIONS
);
4713 vin
= gimple_omp_sections_control (sections_stmt
);
4714 if (!is_combined_parallel (region
))
4716 /* If we are not inside a combined parallel+sections region,
4717 call GOMP_sections_start. */
4718 t
= build_int_cst (unsigned_type_node
,
4719 exit_reachable
? len
- 1 : len
);
4720 u
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_START
];
4721 stmt
= gimple_build_call (u
, 1, t
);
4725 /* Otherwise, call GOMP_sections_next. */
4726 u
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_NEXT
];
4727 stmt
= gimple_build_call (u
, 0);
4729 gimple_call_set_lhs (stmt
, vin
);
4730 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4731 gsi_remove (&si
, true);
4733 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4735 switch_si
= gsi_last_bb (l0_bb
);
4736 gcc_assert (gimple_code (gsi_stmt (switch_si
)) == GIMPLE_OMP_SECTIONS_SWITCH
);
4739 cont
= last_stmt (l1_bb
);
4740 gcc_assert (gimple_code (cont
) == GIMPLE_OMP_CONTINUE
);
4741 vmain
= gimple_omp_continue_control_use (cont
);
4742 vnext
= gimple_omp_continue_control_def (cont
);
4753 t
= build3 (CASE_LABEL_EXPR
, void_type_node
,
4754 build_int_cst (unsigned_type_node
, 0), NULL
, l2
);
4755 VEC_quick_push (tree
, label_vec
, t
);
4759 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4760 for (inner
= region
->inner
, casei
= 1;
4762 inner
= inner
->next
, i
++, casei
++)
4764 basic_block s_entry_bb
, s_exit_bb
;
4766 /* Skip optional reduction region. */
4767 if (inner
->type
== GIMPLE_OMP_ATOMIC_LOAD
)
4774 s_entry_bb
= inner
->entry
;
4775 s_exit_bb
= inner
->exit
;
4777 t
= gimple_block_label (s_entry_bb
);
4778 u
= build_int_cst (unsigned_type_node
, casei
);
4779 u
= build3 (CASE_LABEL_EXPR
, void_type_node
, u
, NULL
, t
);
4780 VEC_quick_push (tree
, label_vec
, u
);
4782 si
= gsi_last_bb (s_entry_bb
);
4783 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SECTION
);
4784 gcc_assert (i
< len
|| gimple_omp_section_last_p (gsi_stmt (si
)));
4785 gsi_remove (&si
, true);
4786 single_succ_edge (s_entry_bb
)->flags
= EDGE_FALLTHRU
;
4788 if (s_exit_bb
== NULL
)
4791 si
= gsi_last_bb (s_exit_bb
);
4792 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
4793 gsi_remove (&si
, true);
4795 single_succ_edge (s_exit_bb
)->flags
= EDGE_FALLTHRU
;
4798 /* Error handling code goes in DEFAULT_BB. */
4799 t
= gimple_block_label (default_bb
);
4800 u
= build3 (CASE_LABEL_EXPR
, void_type_node
, NULL
, NULL
, t
);
4801 make_edge (l0_bb
, default_bb
, 0);
4803 stmt
= gimple_build_switch_vec (vmain
, u
, label_vec
);
4804 gsi_insert_after (&switch_si
, stmt
, GSI_SAME_STMT
);
4805 gsi_remove (&switch_si
, true);
4806 VEC_free (tree
, heap
, label_vec
);
4808 si
= gsi_start_bb (default_bb
);
4809 stmt
= gimple_build_call (built_in_decls
[BUILT_IN_TRAP
], 0);
4810 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4814 /* Code to get the next section goes in L1_BB. */
4815 si
= gsi_last_bb (l1_bb
);
4816 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CONTINUE
);
4818 stmt
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_SECTIONS_NEXT
], 0);
4819 gimple_call_set_lhs (stmt
, vnext
);
4820 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4821 gsi_remove (&si
, true);
4823 single_succ_edge (l1_bb
)->flags
= EDGE_FALLTHRU
;
4825 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4826 si
= gsi_last_bb (l2_bb
);
4827 if (gimple_omp_return_nowait_p (gsi_stmt (si
)))
4828 t
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_END_NOWAIT
];
4830 t
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_END
];
4831 stmt
= gimple_build_call (t
, 0);
4832 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4833 gsi_remove (&si
, true);
4836 set_immediate_dominator (CDI_DOMINATORS
, default_bb
, l0_bb
);
4840 /* Expand code for an OpenMP single directive. We've already expanded
4841 much of the code, here we simply place the GOMP_barrier call. */
4844 expand_omp_single (struct omp_region
*region
)
4846 basic_block entry_bb
, exit_bb
;
4847 gimple_stmt_iterator si
;
4848 bool need_barrier
= false;
4850 entry_bb
= region
->entry
;
4851 exit_bb
= region
->exit
;
4853 si
= gsi_last_bb (entry_bb
);
4854 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4855 be removed. We need to ensure that the thread that entered the single
4856 does not exit before the data is copied out by the other threads. */
4857 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si
)),
4858 OMP_CLAUSE_COPYPRIVATE
))
4859 need_barrier
= true;
4860 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
);
4861 gsi_remove (&si
, true);
4862 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
4864 si
= gsi_last_bb (exit_bb
);
4865 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)) || need_barrier
)
4866 force_gimple_operand_gsi (&si
, build_omp_barrier (), false, NULL_TREE
,
4867 false, GSI_SAME_STMT
);
4868 gsi_remove (&si
, true);
4869 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
4873 /* Generic expansion for OpenMP synchronization directives: master,
4874 ordered and critical. All we need to do here is remove the entry
4875 and exit markers for REGION. */
4878 expand_omp_synch (struct omp_region
*region
)
4880 basic_block entry_bb
, exit_bb
;
4881 gimple_stmt_iterator si
;
4883 entry_bb
= region
->entry
;
4884 exit_bb
= region
->exit
;
4886 si
= gsi_last_bb (entry_bb
);
4887 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
4888 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_MASTER
4889 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ORDERED
4890 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CRITICAL
);
4891 gsi_remove (&si
, true);
4892 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
4896 si
= gsi_last_bb (exit_bb
);
4897 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
4898 gsi_remove (&si
, true);
4899 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
4903 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
4904 operation as a __sync_fetch_and_op builtin. INDEX is log2 of the
4905 size of the data type, and thus usable to find the index of the builtin
4906 decl. Returns false if the expression is not of the proper form. */
4909 expand_omp_atomic_fetch_op (basic_block load_bb
,
4910 tree addr
, tree loaded_val
,
4911 tree stored_val
, int index
)
4913 enum built_in_function base
;
4914 tree decl
, itype
, call
;
4915 enum insn_code
*optab
;
4917 basic_block store_bb
= single_succ (load_bb
);
4918 gimple_stmt_iterator gsi
;
4922 /* We expect to find the following sequences:
4925 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
4928 val = tmp OP something; (or: something OP tmp)
4929 GIMPLE_OMP_STORE (val)
4931 ???FIXME: Allow a more flexible sequence.
4932 Perhaps use data flow to pick the statements.
4936 gsi
= gsi_after_labels (store_bb
);
4937 stmt
= gsi_stmt (gsi
);
4938 loc
= gimple_location (stmt
);
4939 if (!is_gimple_assign (stmt
))
4942 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_OMP_ATOMIC_STORE
)
4945 if (!operand_equal_p (gimple_assign_lhs (stmt
), stored_val
, 0))
4948 /* Check for one of the supported fetch-op operations. */
4949 switch (gimple_assign_rhs_code (stmt
))
4952 case POINTER_PLUS_EXPR
:
4953 base
= BUILT_IN_FETCH_AND_ADD_N
;
4954 optab
= sync_add_optab
;
4957 base
= BUILT_IN_FETCH_AND_SUB_N
;
4958 optab
= sync_add_optab
;
4961 base
= BUILT_IN_FETCH_AND_AND_N
;
4962 optab
= sync_and_optab
;
4965 base
= BUILT_IN_FETCH_AND_OR_N
;
4966 optab
= sync_ior_optab
;
4969 base
= BUILT_IN_FETCH_AND_XOR_N
;
4970 optab
= sync_xor_optab
;
4975 /* Make sure the expression is of the proper form. */
4976 if (operand_equal_p (gimple_assign_rhs1 (stmt
), loaded_val
, 0))
4977 rhs
= gimple_assign_rhs2 (stmt
);
4978 else if (commutative_tree_code (gimple_assign_rhs_code (stmt
))
4979 && operand_equal_p (gimple_assign_rhs2 (stmt
), loaded_val
, 0))
4980 rhs
= gimple_assign_rhs1 (stmt
);
4984 decl
= built_in_decls
[base
+ index
+ 1];
4985 itype
= TREE_TYPE (TREE_TYPE (decl
));
4987 if (optab
[TYPE_MODE (itype
)] == CODE_FOR_nothing
)
4990 gsi
= gsi_last_bb (load_bb
);
4991 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_LOAD
);
4992 call
= build_call_expr_loc (loc
,
4994 fold_convert_loc (loc
, itype
, rhs
));
4995 call
= fold_convert_loc (loc
, void_type_node
, call
);
4996 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4997 gsi_remove (&gsi
, true);
4999 gsi
= gsi_last_bb (store_bb
);
5000 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
5001 gsi_remove (&gsi
, true);
5002 gsi
= gsi_last_bb (store_bb
);
5003 gsi_remove (&gsi
, true);
5005 if (gimple_in_ssa_p (cfun
))
5006 update_ssa (TODO_update_ssa_no_phi
);
5011 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5015 newval = rhs; // with oldval replacing *addr in rhs
5016 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5017 if (oldval != newval)
5020 INDEX is log2 of the size of the data type, and thus usable to find the
5021 index of the builtin decl. */
5024 expand_omp_atomic_pipeline (basic_block load_bb
, basic_block store_bb
,
5025 tree addr
, tree loaded_val
, tree stored_val
,
5028 tree loadedi
, storedi
, initial
, new_storedi
, old_vali
;
5029 tree type
, itype
, cmpxchg
, iaddr
;
5030 gimple_stmt_iterator si
;
5031 basic_block loop_header
= single_succ (load_bb
);
5035 cmpxchg
= built_in_decls
[BUILT_IN_VAL_COMPARE_AND_SWAP_N
+ index
+ 1];
5036 type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
5037 itype
= TREE_TYPE (TREE_TYPE (cmpxchg
));
5039 if (sync_compare_and_swap
[TYPE_MODE (itype
)] == CODE_FOR_nothing
)
5042 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5043 si
= gsi_last_bb (load_bb
);
5044 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5046 /* For floating-point values, we'll need to view-convert them to integers
5047 so that we can perform the atomic compare and swap. Simplify the
5048 following code by always setting up the "i"ntegral variables. */
5049 if (!INTEGRAL_TYPE_P (type
) && !POINTER_TYPE_P (type
))
5053 iaddr
= create_tmp_var (build_pointer_type_for_mode (itype
, ptr_mode
,
5056 = force_gimple_operand_gsi (&si
,
5057 fold_convert (TREE_TYPE (iaddr
), addr
),
5058 false, NULL_TREE
, true, GSI_SAME_STMT
);
5059 stmt
= gimple_build_assign (iaddr
, iaddr_val
);
5060 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5061 loadedi
= create_tmp_var (itype
, NULL
);
5062 if (gimple_in_ssa_p (cfun
))
5064 add_referenced_var (iaddr
);
5065 add_referenced_var (loadedi
);
5066 loadedi
= make_ssa_name (loadedi
, NULL
);
5072 loadedi
= loaded_val
;
5075 initial
= force_gimple_operand_gsi (&si
, build_fold_indirect_ref (iaddr
),
5076 true, NULL_TREE
, true, GSI_SAME_STMT
);
5078 /* Move the value to the LOADEDI temporary. */
5079 if (gimple_in_ssa_p (cfun
))
5081 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header
)));
5082 phi
= create_phi_node (loadedi
, loop_header
);
5083 SSA_NAME_DEF_STMT (loadedi
) = phi
;
5084 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, single_succ_edge (load_bb
)),
5088 gsi_insert_before (&si
,
5089 gimple_build_assign (loadedi
, initial
),
5091 if (loadedi
!= loaded_val
)
5093 gimple_stmt_iterator gsi2
;
5096 x
= build1 (VIEW_CONVERT_EXPR
, type
, loadedi
);
5097 gsi2
= gsi_start_bb (loop_header
);
5098 if (gimple_in_ssa_p (cfun
))
5101 x
= force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
5102 true, GSI_SAME_STMT
);
5103 stmt
= gimple_build_assign (loaded_val
, x
);
5104 gsi_insert_before (&gsi2
, stmt
, GSI_SAME_STMT
);
5108 x
= build2 (MODIFY_EXPR
, TREE_TYPE (loaded_val
), loaded_val
, x
);
5109 force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
5110 true, GSI_SAME_STMT
);
5113 gsi_remove (&si
, true);
5115 si
= gsi_last_bb (store_bb
);
5116 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
5119 storedi
= stored_val
;
5122 force_gimple_operand_gsi (&si
,
5123 build1 (VIEW_CONVERT_EXPR
, itype
,
5124 stored_val
), true, NULL_TREE
, true,
5127 /* Build the compare&swap statement. */
5128 new_storedi
= build_call_expr (cmpxchg
, 3, iaddr
, loadedi
, storedi
);
5129 new_storedi
= force_gimple_operand_gsi (&si
,
5130 fold_convert (TREE_TYPE (loadedi
),
5133 true, GSI_SAME_STMT
);
5135 if (gimple_in_ssa_p (cfun
))
5139 old_vali
= create_tmp_var (TREE_TYPE (loadedi
), NULL
);
5140 if (gimple_in_ssa_p (cfun
))
5141 add_referenced_var (old_vali
);
5142 stmt
= gimple_build_assign (old_vali
, loadedi
);
5143 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5145 stmt
= gimple_build_assign (loadedi
, new_storedi
);
5146 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5149 /* Note that we always perform the comparison as an integer, even for
5150 floating point. This allows the atomic operation to properly
5151 succeed even with NaNs and -0.0. */
5152 stmt
= gimple_build_cond_empty
5153 (build2 (NE_EXPR
, boolean_type_node
,
5154 new_storedi
, old_vali
));
5155 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5158 e
= single_succ_edge (store_bb
);
5159 e
->flags
&= ~EDGE_FALLTHRU
;
5160 e
->flags
|= EDGE_FALSE_VALUE
;
5162 e
= make_edge (store_bb
, loop_header
, EDGE_TRUE_VALUE
);
5164 /* Copy the new value to loadedi (we already did that before the condition
5165 if we are not in SSA). */
5166 if (gimple_in_ssa_p (cfun
))
5168 phi
= gimple_seq_first_stmt (phi_nodes (loop_header
));
5169 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, e
), new_storedi
);
5172 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5173 gsi_remove (&si
, true);
5175 if (gimple_in_ssa_p (cfun
))
5176 update_ssa (TODO_update_ssa_no_phi
);
5181 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5183 GOMP_atomic_start ();
5187 The result is not globally atomic, but works so long as all parallel
5188 references are within #pragma omp atomic directives. According to
5189 responses received from omp@openmp.org, appears to be within spec.
5190 Which makes sense, since that's how several other compilers handle
5191 this situation as well.
5192 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5193 expanding. STORED_VAL is the operand of the matching
5194 GIMPLE_OMP_ATOMIC_STORE.
5197 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5201 GIMPLE_OMP_ATOMIC_ATORE (stored_val) with
5206 expand_omp_atomic_mutex (basic_block load_bb
, basic_block store_bb
,
5207 tree addr
, tree loaded_val
, tree stored_val
)
5209 gimple_stmt_iterator si
;
5213 si
= gsi_last_bb (load_bb
);
5214 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5216 t
= built_in_decls
[BUILT_IN_GOMP_ATOMIC_START
];
5217 t
= build_function_call_expr (UNKNOWN_LOCATION
, t
, 0);
5218 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5220 stmt
= gimple_build_assign (loaded_val
, build_fold_indirect_ref (addr
));
5221 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5222 gsi_remove (&si
, true);
5224 si
= gsi_last_bb (store_bb
);
5225 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
5227 stmt
= gimple_build_assign (build_fold_indirect_ref (unshare_expr (addr
)),
5229 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5231 t
= built_in_decls
[BUILT_IN_GOMP_ATOMIC_END
];
5232 t
= build_function_call_expr (UNKNOWN_LOCATION
, t
, 0);
5233 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5234 gsi_remove (&si
, true);
5236 if (gimple_in_ssa_p (cfun
))
5237 update_ssa (TODO_update_ssa_no_phi
);
5241 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5242 using expand_omp_atomic_fetch_op. If it failed, we try to
5243 call expand_omp_atomic_pipeline, and if it fails too, the
5244 ultimate fallback is wrapping the operation in a mutex
5245 (expand_omp_atomic_mutex). REGION is the atomic region built
5246 by build_omp_regions_1(). */
5249 expand_omp_atomic (struct omp_region
*region
)
5251 basic_block load_bb
= region
->entry
, store_bb
= region
->exit
;
5252 gimple load
= last_stmt (load_bb
), store
= last_stmt (store_bb
);
5253 tree loaded_val
= gimple_omp_atomic_load_lhs (load
);
5254 tree addr
= gimple_omp_atomic_load_rhs (load
);
5255 tree stored_val
= gimple_omp_atomic_store_val (store
);
5256 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
5257 HOST_WIDE_INT index
;
5259 /* Make sure the type is one of the supported sizes. */
5260 index
= tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
5261 index
= exact_log2 (index
);
5262 if (index
>= 0 && index
<= 4)
5264 unsigned int align
= TYPE_ALIGN_UNIT (type
);
5266 /* __sync builtins require strict data alignment. */
5267 if (exact_log2 (align
) >= index
)
5269 /* When possible, use specialized atomic update functions. */
5270 if ((INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
))
5271 && store_bb
== single_succ (load_bb
))
5273 if (expand_omp_atomic_fetch_op (load_bb
, addr
,
5274 loaded_val
, stored_val
, index
))
5278 /* If we don't have specialized __sync builtins, try and implement
5279 as a compare and swap loop. */
5280 if (expand_omp_atomic_pipeline (load_bb
, store_bb
, addr
,
5281 loaded_val
, stored_val
, index
))
5286 /* The ultimate fallback is wrapping the operation in a mutex. */
5287 expand_omp_atomic_mutex (load_bb
, store_bb
, addr
, loaded_val
, stored_val
);
5291 /* Expand the parallel region tree rooted at REGION. Expansion
5292 proceeds in depth-first order. Innermost regions are expanded
5293 first. This way, parallel regions that require a new function to
5294 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5295 internal dependencies in their body. */
5298 expand_omp (struct omp_region
*region
)
5302 location_t saved_location
;
5304 /* First, determine whether this is a combined parallel+workshare
5306 if (region
->type
== GIMPLE_OMP_PARALLEL
)
5307 determine_parallel_type (region
);
5310 expand_omp (region
->inner
);
5312 saved_location
= input_location
;
5313 if (gimple_has_location (last_stmt (region
->entry
)))
5314 input_location
= gimple_location (last_stmt (region
->entry
));
5316 switch (region
->type
)
5318 case GIMPLE_OMP_PARALLEL
:
5319 case GIMPLE_OMP_TASK
:
5320 expand_omp_taskreg (region
);
5323 case GIMPLE_OMP_FOR
:
5324 expand_omp_for (region
);
5327 case GIMPLE_OMP_SECTIONS
:
5328 expand_omp_sections (region
);
5331 case GIMPLE_OMP_SECTION
:
5332 /* Individual omp sections are handled together with their
5333 parent GIMPLE_OMP_SECTIONS region. */
5336 case GIMPLE_OMP_SINGLE
:
5337 expand_omp_single (region
);
5340 case GIMPLE_OMP_MASTER
:
5341 case GIMPLE_OMP_ORDERED
:
5342 case GIMPLE_OMP_CRITICAL
:
5343 expand_omp_synch (region
);
5346 case GIMPLE_OMP_ATOMIC_LOAD
:
5347 expand_omp_atomic (region
);
5354 input_location
= saved_location
;
5355 region
= region
->next
;
5360 /* Helper for build_omp_regions. Scan the dominator tree starting at
5361 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5362 true, the function ends once a single tree is built (otherwise, whole
5363 forest of OMP constructs may be built). */
5366 build_omp_regions_1 (basic_block bb
, struct omp_region
*parent
,
5369 gimple_stmt_iterator gsi
;
5373 gsi
= gsi_last_bb (bb
);
5374 if (!gsi_end_p (gsi
) && is_gimple_omp (gsi_stmt (gsi
)))
5376 struct omp_region
*region
;
5377 enum gimple_code code
;
5379 stmt
= gsi_stmt (gsi
);
5380 code
= gimple_code (stmt
);
5381 if (code
== GIMPLE_OMP_RETURN
)
5383 /* STMT is the return point out of region PARENT. Mark it
5384 as the exit point and make PARENT the immediately
5385 enclosing region. */
5386 gcc_assert (parent
);
5389 parent
= parent
->outer
;
5391 else if (code
== GIMPLE_OMP_ATOMIC_STORE
)
5393 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5394 GIMPLE_OMP_RETURN, but matches with
5395 GIMPLE_OMP_ATOMIC_LOAD. */
5396 gcc_assert (parent
);
5397 gcc_assert (parent
->type
== GIMPLE_OMP_ATOMIC_LOAD
);
5400 parent
= parent
->outer
;
5403 else if (code
== GIMPLE_OMP_CONTINUE
)
5405 gcc_assert (parent
);
5408 else if (code
== GIMPLE_OMP_SECTIONS_SWITCH
)
5410 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5411 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5416 /* Otherwise, this directive becomes the parent for a new
5418 region
= new_omp_region (bb
, code
, parent
);
5423 if (single_tree
&& !parent
)
5426 for (son
= first_dom_son (CDI_DOMINATORS
, bb
);
5428 son
= next_dom_son (CDI_DOMINATORS
, son
))
5429 build_omp_regions_1 (son
, parent
, single_tree
);
5432 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5436 build_omp_regions_root (basic_block root
)
5438 gcc_assert (root_omp_region
== NULL
);
5439 build_omp_regions_1 (root
, NULL
, true);
5440 gcc_assert (root_omp_region
!= NULL
);
5443 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5446 omp_expand_local (basic_block head
)
5448 build_omp_regions_root (head
);
5449 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5451 fprintf (dump_file
, "\nOMP region tree\n\n");
5452 dump_omp_region (dump_file
, root_omp_region
, 0);
5453 fprintf (dump_file
, "\n");
5456 remove_exit_barriers (root_omp_region
);
5457 expand_omp (root_omp_region
);
5459 free_omp_regions ();
5462 /* Scan the CFG and build a tree of OMP regions. Return the root of
5463 the OMP region tree. */
5466 build_omp_regions (void)
5468 gcc_assert (root_omp_region
== NULL
);
5469 calculate_dominance_info (CDI_DOMINATORS
);
5470 build_omp_regions_1 (ENTRY_BLOCK_PTR
, NULL
, false);
5473 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5476 execute_expand_omp (void)
5478 build_omp_regions ();
5480 if (!root_omp_region
)
5485 fprintf (dump_file
, "\nOMP region tree\n\n");
5486 dump_omp_region (dump_file
, root_omp_region
, 0);
5487 fprintf (dump_file
, "\n");
5490 remove_exit_barriers (root_omp_region
);
5492 expand_omp (root_omp_region
);
5494 cleanup_tree_cfg ();
5496 free_omp_regions ();
5501 /* OMP expansion -- the default pass, run before creation of SSA form. */
5504 gate_expand_omp (void)
5506 return (flag_openmp
!= 0 && errorcount
== 0);
5509 struct gimple_opt_pass pass_expand_omp
=
5513 "ompexp", /* name */
5514 gate_expand_omp
, /* gate */
5515 execute_expand_omp
, /* execute */
5518 0, /* static_pass_number */
5519 TV_NONE
, /* tv_id */
5520 PROP_gimple_any
, /* properties_required */
5521 0, /* properties_provided */
5522 0, /* properties_destroyed */
5523 0, /* todo_flags_start */
5524 TODO_dump_func
/* todo_flags_finish */
5528 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5530 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5531 CTX is the enclosing OMP context for the current statement. */
5534 lower_omp_sections (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5536 tree block
, control
;
5537 gimple_stmt_iterator tgsi
;
5539 gimple stmt
, new_stmt
, bind
, t
;
5540 gimple_seq ilist
, dlist
, olist
, new_body
, body
;
5541 struct gimplify_ctx gctx
;
5543 stmt
= gsi_stmt (*gsi_p
);
5545 push_gimplify_context (&gctx
);
5549 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt
),
5550 &ilist
, &dlist
, ctx
);
5552 tgsi
= gsi_start (gimple_omp_body (stmt
));
5553 for (len
= 0; !gsi_end_p (tgsi
); len
++, gsi_next (&tgsi
))
5556 tgsi
= gsi_start (gimple_omp_body (stmt
));
5558 for (i
= 0; i
< len
; i
++, gsi_next (&tgsi
))
5563 sec_start
= gsi_stmt (tgsi
);
5564 sctx
= maybe_lookup_ctx (sec_start
);
5567 gimple_seq_add_stmt (&body
, sec_start
);
5569 lower_omp (gimple_omp_body (sec_start
), sctx
);
5570 gimple_seq_add_seq (&body
, gimple_omp_body (sec_start
));
5571 gimple_omp_set_body (sec_start
, NULL
);
5575 gimple_seq l
= NULL
;
5576 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt
), NULL
,
5578 gimple_seq_add_seq (&body
, l
);
5579 gimple_omp_section_set_last (sec_start
);
5582 gimple_seq_add_stmt (&body
, gimple_build_omp_return (false));
5585 block
= make_node (BLOCK
);
5586 bind
= gimple_build_bind (NULL
, body
, block
);
5589 lower_reduction_clauses (gimple_omp_sections_clauses (stmt
), &olist
, ctx
);
5591 block
= make_node (BLOCK
);
5592 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
5594 pop_gimplify_context (new_stmt
);
5595 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
5596 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
5597 if (BLOCK_VARS (block
))
5598 TREE_USED (block
) = 1;
5601 gimple_seq_add_seq (&new_body
, ilist
);
5602 gimple_seq_add_stmt (&new_body
, stmt
);
5603 gimple_seq_add_stmt (&new_body
, gimple_build_omp_sections_switch ());
5604 gimple_seq_add_stmt (&new_body
, bind
);
5606 control
= create_tmp_var (unsigned_type_node
, ".section");
5607 t
= gimple_build_omp_continue (control
, control
);
5608 gimple_omp_sections_set_control (stmt
, control
);
5609 gimple_seq_add_stmt (&new_body
, t
);
5611 gimple_seq_add_seq (&new_body
, olist
);
5612 gimple_seq_add_seq (&new_body
, dlist
);
5614 new_body
= maybe_catch_exception (new_body
);
5616 t
= gimple_build_omp_return
5617 (!!find_omp_clause (gimple_omp_sections_clauses (stmt
),
5618 OMP_CLAUSE_NOWAIT
));
5619 gimple_seq_add_stmt (&new_body
, t
);
5621 gimple_bind_set_body (new_stmt
, new_body
);
5622 gimple_omp_set_body (stmt
, NULL
);
5624 gsi_replace (gsi_p
, new_stmt
, true);
5628 /* A subroutine of lower_omp_single. Expand the simple form of
5629 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5631 if (GOMP_single_start ())
5633 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5635 FIXME. It may be better to delay expanding the logic of this until
5636 pass_expand_omp. The expanded logic may make the job more difficult
5637 to a synchronization analysis pass. */
5640 lower_omp_single_simple (gimple single_stmt
, gimple_seq
*pre_p
)
5642 location_t loc
= gimple_location (single_stmt
);
5643 tree tlabel
= create_artificial_label (loc
);
5644 tree flabel
= create_artificial_label (loc
);
5648 decl
= built_in_decls
[BUILT_IN_GOMP_SINGLE_START
];
5649 lhs
= create_tmp_var (TREE_TYPE (TREE_TYPE (decl
)), NULL
);
5650 call
= gimple_build_call (decl
, 0);
5651 gimple_call_set_lhs (call
, lhs
);
5652 gimple_seq_add_stmt (pre_p
, call
);
5654 cond
= gimple_build_cond (EQ_EXPR
, lhs
,
5655 fold_convert_loc (loc
, TREE_TYPE (lhs
),
5658 gimple_seq_add_stmt (pre_p
, cond
);
5659 gimple_seq_add_stmt (pre_p
, gimple_build_label (tlabel
));
5660 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
5661 gimple_seq_add_stmt (pre_p
, gimple_build_label (flabel
));
5665 /* A subroutine of lower_omp_single. Expand the simple form of
5666 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5668 #pragma omp single copyprivate (a, b, c)
5670 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5673 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5679 GOMP_single_copy_end (©out);
5690 FIXME. It may be better to delay expanding the logic of this until
5691 pass_expand_omp. The expanded logic may make the job more difficult
5692 to a synchronization analysis pass. */
5695 lower_omp_single_copy (gimple single_stmt
, gimple_seq
*pre_p
, omp_context
*ctx
)
5697 tree ptr_type
, t
, l0
, l1
, l2
;
5698 gimple_seq copyin_seq
;
5699 location_t loc
= gimple_location (single_stmt
);
5701 ctx
->sender_decl
= create_tmp_var (ctx
->record_type
, ".omp_copy_o");
5703 ptr_type
= build_pointer_type (ctx
->record_type
);
5704 ctx
->receiver_decl
= create_tmp_var (ptr_type
, ".omp_copy_i");
5706 l0
= create_artificial_label (loc
);
5707 l1
= create_artificial_label (loc
);
5708 l2
= create_artificial_label (loc
);
5710 t
= build_call_expr_loc (loc
, built_in_decls
[BUILT_IN_GOMP_SINGLE_COPY_START
], 0);
5711 t
= fold_convert_loc (loc
, ptr_type
, t
);
5712 gimplify_assign (ctx
->receiver_decl
, t
, pre_p
);
5714 t
= build2 (EQ_EXPR
, boolean_type_node
, ctx
->receiver_decl
,
5715 build_int_cst (ptr_type
, 0));
5716 t
= build3 (COND_EXPR
, void_type_node
, t
,
5717 build_and_jump (&l0
), build_and_jump (&l1
));
5718 gimplify_and_add (t
, pre_p
);
5720 gimple_seq_add_stmt (pre_p
, gimple_build_label (l0
));
5722 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
5725 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt
), pre_p
,
5728 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
5729 t
= build_call_expr_loc (loc
, built_in_decls
[BUILT_IN_GOMP_SINGLE_COPY_END
],
5731 gimplify_and_add (t
, pre_p
);
5733 t
= build_and_jump (&l2
);
5734 gimplify_and_add (t
, pre_p
);
5736 gimple_seq_add_stmt (pre_p
, gimple_build_label (l1
));
5738 gimple_seq_add_seq (pre_p
, copyin_seq
);
5740 gimple_seq_add_stmt (pre_p
, gimple_build_label (l2
));
5744 /* Expand code for an OpenMP single directive. */
5747 lower_omp_single (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5750 gimple t
, bind
, single_stmt
= gsi_stmt (*gsi_p
);
5751 gimple_seq bind_body
, dlist
;
5752 struct gimplify_ctx gctx
;
5754 push_gimplify_context (&gctx
);
5757 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt
),
5758 &bind_body
, &dlist
, ctx
);
5759 lower_omp (gimple_omp_body (single_stmt
), ctx
);
5761 gimple_seq_add_stmt (&bind_body
, single_stmt
);
5763 if (ctx
->record_type
)
5764 lower_omp_single_copy (single_stmt
, &bind_body
, ctx
);
5766 lower_omp_single_simple (single_stmt
, &bind_body
);
5768 gimple_omp_set_body (single_stmt
, NULL
);
5770 gimple_seq_add_seq (&bind_body
, dlist
);
5772 bind_body
= maybe_catch_exception (bind_body
);
5774 t
= gimple_build_omp_return
5775 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt
),
5776 OMP_CLAUSE_NOWAIT
));
5777 gimple_seq_add_stmt (&bind_body
, t
);
5779 block
= make_node (BLOCK
);
5780 bind
= gimple_build_bind (NULL
, bind_body
, block
);
5782 pop_gimplify_context (bind
);
5784 gimple_bind_append_vars (bind
, ctx
->block_vars
);
5785 BLOCK_VARS (block
) = ctx
->block_vars
;
5786 gsi_replace (gsi_p
, bind
, true);
5787 if (BLOCK_VARS (block
))
5788 TREE_USED (block
) = 1;
5792 /* Expand code for an OpenMP master directive. */
5795 lower_omp_master (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5797 tree block
, lab
= NULL
, x
;
5798 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
5799 location_t loc
= gimple_location (stmt
);
5801 struct gimplify_ctx gctx
;
5803 push_gimplify_context (&gctx
);
5805 block
= make_node (BLOCK
);
5806 bind
= gimple_build_bind (NULL
, gimple_seq_alloc_with_stmt (stmt
),
5809 x
= build_call_expr_loc (loc
, built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
5810 x
= build2 (EQ_EXPR
, boolean_type_node
, x
, integer_zero_node
);
5811 x
= build3 (COND_EXPR
, void_type_node
, x
, NULL
, build_and_jump (&lab
));
5813 gimplify_and_add (x
, &tseq
);
5814 gimple_bind_add_seq (bind
, tseq
);
5816 lower_omp (gimple_omp_body (stmt
), ctx
);
5817 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
5818 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
5819 gimple_omp_set_body (stmt
, NULL
);
5821 gimple_bind_add_stmt (bind
, gimple_build_label (lab
));
5823 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
5825 pop_gimplify_context (bind
);
5827 gimple_bind_append_vars (bind
, ctx
->block_vars
);
5828 BLOCK_VARS (block
) = ctx
->block_vars
;
5829 gsi_replace (gsi_p
, bind
, true);
5833 /* Expand code for an OpenMP ordered directive. */
5836 lower_omp_ordered (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5839 gimple stmt
= gsi_stmt (*gsi_p
), bind
, x
;
5840 struct gimplify_ctx gctx
;
5842 push_gimplify_context (&gctx
);
5844 block
= make_node (BLOCK
);
5845 bind
= gimple_build_bind (NULL
, gimple_seq_alloc_with_stmt (stmt
),
5848 x
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_ORDERED_START
], 0);
5849 gimple_bind_add_stmt (bind
, x
);
5851 lower_omp (gimple_omp_body (stmt
), ctx
);
5852 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
5853 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
5854 gimple_omp_set_body (stmt
, NULL
);
5856 x
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_ORDERED_END
], 0);
5857 gimple_bind_add_stmt (bind
, x
);
5859 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
5861 pop_gimplify_context (bind
);
5863 gimple_bind_append_vars (bind
, ctx
->block_vars
);
5864 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
5865 gsi_replace (gsi_p
, bind
, true);
5869 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
5870 substitution of a couple of function calls. But in the NAMED case,
5871 requires that languages coordinate a symbol name. It is therefore
5872 best put here in common code. */
5874 static GTY((param1_is (tree
), param2_is (tree
)))
5875 splay_tree critical_name_mutexes
;
5878 lower_omp_critical (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5881 tree name
, lock
, unlock
;
5882 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
5883 location_t loc
= gimple_location (stmt
);
5885 struct gimplify_ctx gctx
;
5887 name
= gimple_omp_critical_name (stmt
);
5893 if (!critical_name_mutexes
)
5894 critical_name_mutexes
5895 = splay_tree_new_ggc (splay_tree_compare_pointers
);
5897 n
= splay_tree_lookup (critical_name_mutexes
, (splay_tree_key
) name
);
5902 decl
= create_tmp_var_raw (ptr_type_node
, NULL
);
5904 new_str
= ACONCAT ((".gomp_critical_user_",
5905 IDENTIFIER_POINTER (name
), NULL
));
5906 DECL_NAME (decl
) = get_identifier (new_str
);
5907 TREE_PUBLIC (decl
) = 1;
5908 TREE_STATIC (decl
) = 1;
5909 DECL_COMMON (decl
) = 1;
5910 DECL_ARTIFICIAL (decl
) = 1;
5911 DECL_IGNORED_P (decl
) = 1;
5912 varpool_finalize_decl (decl
);
5914 splay_tree_insert (critical_name_mutexes
, (splay_tree_key
) name
,
5915 (splay_tree_value
) decl
);
5918 decl
= (tree
) n
->value
;
5920 lock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_NAME_START
];
5921 lock
= build_call_expr_loc (loc
, lock
, 1, build_fold_addr_expr_loc (loc
, decl
));
5923 unlock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_NAME_END
];
5924 unlock
= build_call_expr_loc (loc
, unlock
, 1,
5925 build_fold_addr_expr_loc (loc
, decl
));
5929 lock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_START
];
5930 lock
= build_call_expr_loc (loc
, lock
, 0);
5932 unlock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_END
];
5933 unlock
= build_call_expr_loc (loc
, unlock
, 0);
5936 push_gimplify_context (&gctx
);
5938 block
= make_node (BLOCK
);
5939 bind
= gimple_build_bind (NULL
, gimple_seq_alloc_with_stmt (stmt
), block
);
5941 tbody
= gimple_bind_body (bind
);
5942 gimplify_and_add (lock
, &tbody
);
5943 gimple_bind_set_body (bind
, tbody
);
5945 lower_omp (gimple_omp_body (stmt
), ctx
);
5946 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
5947 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
5948 gimple_omp_set_body (stmt
, NULL
);
5950 tbody
= gimple_bind_body (bind
);
5951 gimplify_and_add (unlock
, &tbody
);
5952 gimple_bind_set_body (bind
, tbody
);
5954 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
5956 pop_gimplify_context (bind
);
5957 gimple_bind_append_vars (bind
, ctx
->block_vars
);
5958 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
5959 gsi_replace (gsi_p
, bind
, true);
5963 /* A subroutine of lower_omp_for. Generate code to emit the predicate
5964 for a lastprivate clause. Given a loop control predicate of (V
5965 cond N2), we gate the clause on (!(V cond N2)). The lowered form
5966 is appended to *DLIST, iterator initialization is appended to
5970 lower_omp_for_lastprivate (struct omp_for_data
*fd
, gimple_seq
*body_p
,
5971 gimple_seq
*dlist
, struct omp_context
*ctx
)
5973 tree clauses
, cond
, vinit
;
5974 enum tree_code cond_code
;
5977 cond_code
= fd
->loop
.cond_code
;
5978 cond_code
= cond_code
== LT_EXPR
? GE_EXPR
: LE_EXPR
;
5980 /* When possible, use a strict equality expression. This can let VRP
5981 type optimizations deduce the value and remove a copy. */
5982 if (host_integerp (fd
->loop
.step
, 0))
5984 HOST_WIDE_INT step
= TREE_INT_CST_LOW (fd
->loop
.step
);
5985 if (step
== 1 || step
== -1)
5986 cond_code
= EQ_EXPR
;
5989 cond
= build2 (cond_code
, boolean_type_node
, fd
->loop
.v
, fd
->loop
.n2
);
5991 clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
5993 lower_lastprivate_clauses (clauses
, cond
, &stmts
, ctx
);
5994 if (!gimple_seq_empty_p (stmts
))
5996 gimple_seq_add_seq (&stmts
, *dlist
);
5999 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6000 vinit
= fd
->loop
.n1
;
6001 if (cond_code
== EQ_EXPR
6002 && host_integerp (fd
->loop
.n2
, 0)
6003 && ! integer_zerop (fd
->loop
.n2
))
6004 vinit
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
6006 /* Initialize the iterator variable, so that threads that don't execute
6007 any iterations don't execute the lastprivate clauses by accident. */
6008 gimplify_assign (fd
->loop
.v
, vinit
, body_p
);
6013 /* Lower code for an OpenMP loop directive. */
6016 lower_omp_for (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6019 struct omp_for_data fd
;
6020 gimple stmt
= gsi_stmt (*gsi_p
), new_stmt
;
6021 gimple_seq omp_for_body
, body
, dlist
;
6023 struct gimplify_ctx gctx
;
6025 push_gimplify_context (&gctx
);
6027 lower_omp (gimple_omp_for_pre_body (stmt
), ctx
);
6028 lower_omp (gimple_omp_body (stmt
), ctx
);
6030 block
= make_node (BLOCK
);
6031 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
6033 /* Move declaration of temporaries in the loop body before we make
6035 omp_for_body
= gimple_omp_body (stmt
);
6036 if (!gimple_seq_empty_p (omp_for_body
)
6037 && gimple_code (gimple_seq_first_stmt (omp_for_body
)) == GIMPLE_BIND
)
6039 tree vars
= gimple_bind_vars (gimple_seq_first_stmt (omp_for_body
));
6040 gimple_bind_append_vars (new_stmt
, vars
);
6043 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6046 lower_rec_input_clauses (gimple_omp_for_clauses (stmt
), &body
, &dlist
, ctx
);
6047 gimple_seq_add_seq (&body
, gimple_omp_for_pre_body (stmt
));
6049 /* Lower the header expressions. At this point, we can assume that
6050 the header is of the form:
6052 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6054 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6055 using the .omp_data_s mapping, if needed. */
6056 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
6058 rhs_p
= gimple_omp_for_initial_ptr (stmt
, i
);
6059 if (!is_gimple_min_invariant (*rhs_p
))
6060 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6062 rhs_p
= gimple_omp_for_final_ptr (stmt
, i
);
6063 if (!is_gimple_min_invariant (*rhs_p
))
6064 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6066 rhs_p
= &TREE_OPERAND (gimple_omp_for_incr (stmt
, i
), 1);
6067 if (!is_gimple_min_invariant (*rhs_p
))
6068 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6071 /* Once lowered, extract the bounds and clauses. */
6072 extract_omp_for_data (stmt
, &fd
, NULL
);
6074 lower_omp_for_lastprivate (&fd
, &body
, &dlist
, ctx
);
6076 gimple_seq_add_stmt (&body
, stmt
);
6077 gimple_seq_add_seq (&body
, gimple_omp_body (stmt
));
6079 gimple_seq_add_stmt (&body
, gimple_build_omp_continue (fd
.loop
.v
,
6082 /* After the loop, add exit clauses. */
6083 lower_reduction_clauses (gimple_omp_for_clauses (stmt
), &body
, ctx
);
6084 gimple_seq_add_seq (&body
, dlist
);
6086 body
= maybe_catch_exception (body
);
6088 /* Region exit marker goes at the end of the loop body. */
6089 gimple_seq_add_stmt (&body
, gimple_build_omp_return (fd
.have_nowait
));
6091 pop_gimplify_context (new_stmt
);
6093 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
6094 BLOCK_VARS (block
) = gimple_bind_vars (new_stmt
);
6095 if (BLOCK_VARS (block
))
6096 TREE_USED (block
) = 1;
6098 gimple_bind_set_body (new_stmt
, body
);
6099 gimple_omp_set_body (stmt
, NULL
);
6100 gimple_omp_for_set_pre_body (stmt
, NULL
);
6101 gsi_replace (gsi_p
, new_stmt
, true);
6104 /* Callback for walk_stmts. Check if the current statement only contains
6105 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6108 check_combined_parallel (gimple_stmt_iterator
*gsi_p
,
6109 bool *handled_ops_p
,
6110 struct walk_stmt_info
*wi
)
6112 int *info
= (int *) wi
->info
;
6113 gimple stmt
= gsi_stmt (*gsi_p
);
6115 *handled_ops_p
= true;
6116 switch (gimple_code (stmt
))
6120 case GIMPLE_OMP_FOR
:
6121 case GIMPLE_OMP_SECTIONS
:
6122 *info
= *info
== 0 ? 1 : -1;
6131 struct omp_taskcopy_context
6133 /* This field must be at the beginning, as we do "inheritance": Some
6134 callback functions for tree-inline.c (e.g., omp_copy_decl)
6135 receive a copy_body_data pointer that is up-casted to an
6136 omp_context pointer. */
6142 task_copyfn_copy_decl (tree var
, copy_body_data
*cb
)
6144 struct omp_taskcopy_context
*tcctx
= (struct omp_taskcopy_context
*) cb
;
6146 if (splay_tree_lookup (tcctx
->ctx
->sfield_map
, (splay_tree_key
) var
))
6147 return create_tmp_var (TREE_TYPE (var
), NULL
);
6153 task_copyfn_remap_type (struct omp_taskcopy_context
*tcctx
, tree orig_type
)
6155 tree name
, new_fields
= NULL
, type
, f
;
6157 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6158 name
= DECL_NAME (TYPE_NAME (orig_type
));
6159 name
= build_decl (gimple_location (tcctx
->ctx
->stmt
),
6160 TYPE_DECL
, name
, type
);
6161 TYPE_NAME (type
) = name
;
6163 for (f
= TYPE_FIELDS (orig_type
); f
; f
= TREE_CHAIN (f
))
6165 tree new_f
= copy_node (f
);
6166 DECL_CONTEXT (new_f
) = type
;
6167 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &tcctx
->cb
);
6168 TREE_CHAIN (new_f
) = new_fields
;
6169 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
6170 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
6171 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
6174 *pointer_map_insert (tcctx
->cb
.decl_map
, f
) = new_f
;
6176 TYPE_FIELDS (type
) = nreverse (new_fields
);
6181 /* Create task copyfn. */
6184 create_task_copyfn (gimple task_stmt
, omp_context
*ctx
)
6186 struct function
*child_cfun
;
6187 tree child_fn
, t
, c
, src
, dst
, f
, sf
, arg
, sarg
, decl
;
6188 tree record_type
, srecord_type
, bind
, list
;
6189 bool record_needs_remap
= false, srecord_needs_remap
= false;
6191 struct omp_taskcopy_context tcctx
;
6192 struct gimplify_ctx gctx
;
6193 location_t loc
= gimple_location (task_stmt
);
6195 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
6196 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
6197 gcc_assert (child_cfun
->cfg
== NULL
);
6198 child_cfun
->dont_save_pending_sizes_p
= 1;
6199 DECL_SAVED_TREE (child_fn
) = alloc_stmt_list ();
6201 /* Reset DECL_CONTEXT on function arguments. */
6202 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= TREE_CHAIN (t
))
6203 DECL_CONTEXT (t
) = child_fn
;
6205 /* Populate the function. */
6206 push_gimplify_context (&gctx
);
6207 current_function_decl
= child_fn
;
6209 bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
6210 TREE_SIDE_EFFECTS (bind
) = 1;
6212 DECL_SAVED_TREE (child_fn
) = bind
;
6213 DECL_SOURCE_LOCATION (child_fn
) = gimple_location (task_stmt
);
6215 /* Remap src and dst argument types if needed. */
6216 record_type
= ctx
->record_type
;
6217 srecord_type
= ctx
->srecord_type
;
6218 for (f
= TYPE_FIELDS (record_type
); f
; f
= TREE_CHAIN (f
))
6219 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
6221 record_needs_remap
= true;
6224 for (f
= TYPE_FIELDS (srecord_type
); f
; f
= TREE_CHAIN (f
))
6225 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
6227 srecord_needs_remap
= true;
6231 if (record_needs_remap
|| srecord_needs_remap
)
6233 memset (&tcctx
, '\0', sizeof (tcctx
));
6234 tcctx
.cb
.src_fn
= ctx
->cb
.src_fn
;
6235 tcctx
.cb
.dst_fn
= child_fn
;
6236 tcctx
.cb
.src_node
= cgraph_node (tcctx
.cb
.src_fn
);
6237 tcctx
.cb
.dst_node
= tcctx
.cb
.src_node
;
6238 tcctx
.cb
.src_cfun
= ctx
->cb
.src_cfun
;
6239 tcctx
.cb
.copy_decl
= task_copyfn_copy_decl
;
6240 tcctx
.cb
.eh_lp_nr
= 0;
6241 tcctx
.cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
6242 tcctx
.cb
.decl_map
= pointer_map_create ();
6245 if (record_needs_remap
)
6246 record_type
= task_copyfn_remap_type (&tcctx
, record_type
);
6247 if (srecord_needs_remap
)
6248 srecord_type
= task_copyfn_remap_type (&tcctx
, srecord_type
);
6251 tcctx
.cb
.decl_map
= NULL
;
6253 push_cfun (child_cfun
);
6255 arg
= DECL_ARGUMENTS (child_fn
);
6256 TREE_TYPE (arg
) = build_pointer_type (record_type
);
6257 sarg
= TREE_CHAIN (arg
);
6258 TREE_TYPE (sarg
) = build_pointer_type (srecord_type
);
6260 /* First pass: initialize temporaries used in record_type and srecord_type
6261 sizes and field offsets. */
6262 if (tcctx
.cb
.decl_map
)
6263 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6264 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
6268 decl
= OMP_CLAUSE_DECL (c
);
6269 p
= (tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, decl
);
6272 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6273 sf
= (tree
) n
->value
;
6274 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6275 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6276 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6277 t
= build2 (MODIFY_EXPR
, TREE_TYPE (*p
), *p
, src
);
6278 append_to_statement_list (t
, &list
);
6281 /* Second pass: copy shared var pointers and copy construct non-VLA
6282 firstprivate vars. */
6283 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6284 switch (OMP_CLAUSE_CODE (c
))
6286 case OMP_CLAUSE_SHARED
:
6287 decl
= OMP_CLAUSE_DECL (c
);
6288 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6291 f
= (tree
) n
->value
;
6292 if (tcctx
.cb
.decl_map
)
6293 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6294 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6295 sf
= (tree
) n
->value
;
6296 if (tcctx
.cb
.decl_map
)
6297 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6298 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6299 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6300 dst
= build_fold_indirect_ref_loc (loc
, arg
);
6301 dst
= build3 (COMPONENT_REF
, TREE_TYPE (f
), dst
, f
, NULL
);
6302 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
6303 append_to_statement_list (t
, &list
);
6305 case OMP_CLAUSE_FIRSTPRIVATE
:
6306 decl
= OMP_CLAUSE_DECL (c
);
6307 if (is_variable_sized (decl
))
6309 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6312 f
= (tree
) n
->value
;
6313 if (tcctx
.cb
.decl_map
)
6314 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6315 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6318 sf
= (tree
) n
->value
;
6319 if (tcctx
.cb
.decl_map
)
6320 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6321 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6322 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6323 if (use_pointer_for_field (decl
, NULL
) || is_reference (decl
))
6324 src
= build_fold_indirect_ref_loc (loc
, src
);
6328 dst
= build_fold_indirect_ref_loc (loc
, arg
);
6329 dst
= build3 (COMPONENT_REF
, TREE_TYPE (f
), dst
, f
, NULL
);
6330 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
6331 append_to_statement_list (t
, &list
);
6333 case OMP_CLAUSE_PRIVATE
:
6334 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
6336 decl
= OMP_CLAUSE_DECL (c
);
6337 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6338 f
= (tree
) n
->value
;
6339 if (tcctx
.cb
.decl_map
)
6340 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6341 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6344 sf
= (tree
) n
->value
;
6345 if (tcctx
.cb
.decl_map
)
6346 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6347 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6348 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6349 if (use_pointer_for_field (decl
, NULL
))
6350 src
= build_fold_indirect_ref_loc (loc
, src
);
6354 dst
= build_fold_indirect_ref_loc (loc
, arg
);
6355 dst
= build3 (COMPONENT_REF
, TREE_TYPE (f
), dst
, f
, NULL
);
6356 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
6357 append_to_statement_list (t
, &list
);
6363 /* Last pass: handle VLA firstprivates. */
6364 if (tcctx
.cb
.decl_map
)
6365 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6366 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
6370 decl
= OMP_CLAUSE_DECL (c
);
6371 if (!is_variable_sized (decl
))
6373 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6376 f
= (tree
) n
->value
;
6377 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6378 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl
));
6379 ind
= DECL_VALUE_EXPR (decl
);
6380 gcc_assert (TREE_CODE (ind
) == INDIRECT_REF
);
6381 gcc_assert (DECL_P (TREE_OPERAND (ind
, 0)));
6382 n
= splay_tree_lookup (ctx
->sfield_map
,
6383 (splay_tree_key
) TREE_OPERAND (ind
, 0));
6384 sf
= (tree
) n
->value
;
6385 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6386 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6387 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6388 src
= build_fold_indirect_ref_loc (loc
, src
);
6389 dst
= build_fold_indirect_ref_loc (loc
, arg
);
6390 dst
= build3 (COMPONENT_REF
, TREE_TYPE (f
), dst
, f
, NULL
);
6391 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
6392 append_to_statement_list (t
, &list
);
6393 n
= splay_tree_lookup (ctx
->field_map
,
6394 (splay_tree_key
) TREE_OPERAND (ind
, 0));
6395 df
= (tree
) n
->value
;
6396 df
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, df
);
6397 ptr
= build_fold_indirect_ref_loc (loc
, arg
);
6398 ptr
= build3 (COMPONENT_REF
, TREE_TYPE (df
), ptr
, df
, NULL
);
6399 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ptr
), ptr
,
6400 build_fold_addr_expr_loc (loc
, dst
));
6401 append_to_statement_list (t
, &list
);
6404 t
= build1 (RETURN_EXPR
, void_type_node
, NULL
);
6405 append_to_statement_list (t
, &list
);
6407 if (tcctx
.cb
.decl_map
)
6408 pointer_map_destroy (tcctx
.cb
.decl_map
);
6409 pop_gimplify_context (NULL
);
6410 BIND_EXPR_BODY (bind
) = list
;
6412 current_function_decl
= ctx
->cb
.src_fn
;
6415 /* Lower the OpenMP parallel or task directive in the current statement
6416 in GSI_P. CTX holds context information for the directive. */
6419 lower_omp_taskreg (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6423 gimple stmt
= gsi_stmt (*gsi_p
);
6424 gimple par_bind
, bind
;
6425 gimple_seq par_body
, olist
, ilist
, par_olist
, par_ilist
, new_body
;
6426 struct gimplify_ctx gctx
;
6427 location_t loc
= gimple_location (stmt
);
6429 clauses
= gimple_omp_taskreg_clauses (stmt
);
6430 par_bind
= gimple_seq_first_stmt (gimple_omp_body (stmt
));
6431 par_body
= gimple_bind_body (par_bind
);
6432 child_fn
= ctx
->cb
.dst_fn
;
6433 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
6434 && !gimple_omp_parallel_combined_p (stmt
))
6436 struct walk_stmt_info wi
;
6439 memset (&wi
, 0, sizeof (wi
));
6442 walk_gimple_seq (par_body
, check_combined_parallel
, NULL
, &wi
);
6444 gimple_omp_parallel_set_combined_p (stmt
, true);
6446 if (ctx
->srecord_type
)
6447 create_task_copyfn (stmt
, ctx
);
6449 push_gimplify_context (&gctx
);
6453 lower_rec_input_clauses (clauses
, &par_ilist
, &par_olist
, ctx
);
6454 lower_omp (par_body
, ctx
);
6455 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
)
6456 lower_reduction_clauses (clauses
, &par_olist
, ctx
);
6458 /* Declare all the variables created by mapping and the variables
6459 declared in the scope of the parallel body. */
6460 record_vars_into (ctx
->block_vars
, child_fn
);
6461 record_vars_into (gimple_bind_vars (par_bind
), child_fn
);
6463 if (ctx
->record_type
)
6466 = create_tmp_var (ctx
->srecord_type
? ctx
->srecord_type
6467 : ctx
->record_type
, ".omp_data_o");
6468 TREE_ADDRESSABLE (ctx
->sender_decl
) = 1;
6469 gimple_omp_taskreg_set_data_arg (stmt
, ctx
->sender_decl
);
6474 lower_send_clauses (clauses
, &ilist
, &olist
, ctx
);
6475 lower_send_shared_vars (&ilist
, &olist
, ctx
);
6477 /* Once all the expansions are done, sequence all the different
6478 fragments inside gimple_omp_body. */
6482 if (ctx
->record_type
)
6484 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
6485 /* fixup_child_record_type might have changed receiver_decl's type. */
6486 t
= fold_convert_loc (loc
, TREE_TYPE (ctx
->receiver_decl
), t
);
6487 gimple_seq_add_stmt (&new_body
,
6488 gimple_build_assign (ctx
->receiver_decl
, t
));
6491 gimple_seq_add_seq (&new_body
, par_ilist
);
6492 gimple_seq_add_seq (&new_body
, par_body
);
6493 gimple_seq_add_seq (&new_body
, par_olist
);
6494 new_body
= maybe_catch_exception (new_body
);
6495 gimple_seq_add_stmt (&new_body
, gimple_build_omp_return (false));
6496 gimple_omp_set_body (stmt
, new_body
);
6498 bind
= gimple_build_bind (NULL
, NULL
, gimple_bind_block (par_bind
));
6499 gimple_bind_add_stmt (bind
, stmt
);
6502 gimple_seq_add_stmt (&ilist
, bind
);
6503 gimple_seq_add_seq (&ilist
, olist
);
6504 bind
= gimple_build_bind (NULL
, ilist
, NULL
);
6507 gsi_replace (gsi_p
, bind
, true);
6509 pop_gimplify_context (NULL
);
6512 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6513 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6514 of OpenMP context, but with task_shared_vars set. */
6517 lower_omp_regimplify_p (tree
*tp
, int *walk_subtrees
,
6522 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6523 if (TREE_CODE (t
) == VAR_DECL
&& data
== NULL
&& DECL_HAS_VALUE_EXPR_P (t
))
6526 if (task_shared_vars
6528 && bitmap_bit_p (task_shared_vars
, DECL_UID (t
)))
6531 /* If a global variable has been privatized, TREE_CONSTANT on
6532 ADDR_EXPR might be wrong. */
6533 if (data
== NULL
&& TREE_CODE (t
) == ADDR_EXPR
)
6534 recompute_tree_invariant_for_addr_expr (t
);
6536 *walk_subtrees
= !TYPE_P (t
) && !DECL_P (t
);
6541 lower_omp_1 (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6543 gimple stmt
= gsi_stmt (*gsi_p
);
6544 struct walk_stmt_info wi
;
6546 if (gimple_has_location (stmt
))
6547 input_location
= gimple_location (stmt
);
6549 if (task_shared_vars
)
6550 memset (&wi
, '\0', sizeof (wi
));
6552 /* If we have issued syntax errors, avoid doing any heavy lifting.
6553 Just replace the OpenMP directives with a NOP to avoid
6554 confusing RTL expansion. */
6555 if (errorcount
&& is_gimple_omp (stmt
))
6557 gsi_replace (gsi_p
, gimple_build_nop (), true);
6561 switch (gimple_code (stmt
))
6564 if ((ctx
|| task_shared_vars
)
6565 && (walk_tree (gimple_cond_lhs_ptr (stmt
), lower_omp_regimplify_p
,
6566 ctx
? NULL
: &wi
, NULL
)
6567 || walk_tree (gimple_cond_rhs_ptr (stmt
), lower_omp_regimplify_p
,
6568 ctx
? NULL
: &wi
, NULL
)))
6569 gimple_regimplify_operands (stmt
, gsi_p
);
6572 lower_omp (gimple_catch_handler (stmt
), ctx
);
6574 case GIMPLE_EH_FILTER
:
6575 lower_omp (gimple_eh_filter_failure (stmt
), ctx
);
6578 lower_omp (gimple_try_eval (stmt
), ctx
);
6579 lower_omp (gimple_try_cleanup (stmt
), ctx
);
6582 lower_omp (gimple_bind_body (stmt
), ctx
);
6584 case GIMPLE_OMP_PARALLEL
:
6585 case GIMPLE_OMP_TASK
:
6586 ctx
= maybe_lookup_ctx (stmt
);
6587 lower_omp_taskreg (gsi_p
, ctx
);
6589 case GIMPLE_OMP_FOR
:
6590 ctx
= maybe_lookup_ctx (stmt
);
6592 lower_omp_for (gsi_p
, ctx
);
6594 case GIMPLE_OMP_SECTIONS
:
6595 ctx
= maybe_lookup_ctx (stmt
);
6597 lower_omp_sections (gsi_p
, ctx
);
6599 case GIMPLE_OMP_SINGLE
:
6600 ctx
= maybe_lookup_ctx (stmt
);
6602 lower_omp_single (gsi_p
, ctx
);
6604 case GIMPLE_OMP_MASTER
:
6605 ctx
= maybe_lookup_ctx (stmt
);
6607 lower_omp_master (gsi_p
, ctx
);
6609 case GIMPLE_OMP_ORDERED
:
6610 ctx
= maybe_lookup_ctx (stmt
);
6612 lower_omp_ordered (gsi_p
, ctx
);
6614 case GIMPLE_OMP_CRITICAL
:
6615 ctx
= maybe_lookup_ctx (stmt
);
6617 lower_omp_critical (gsi_p
, ctx
);
6619 case GIMPLE_OMP_ATOMIC_LOAD
:
6620 if ((ctx
|| task_shared_vars
)
6621 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt
),
6622 lower_omp_regimplify_p
, ctx
? NULL
: &wi
, NULL
))
6623 gimple_regimplify_operands (stmt
, gsi_p
);
6626 if ((ctx
|| task_shared_vars
)
6627 && walk_gimple_op (stmt
, lower_omp_regimplify_p
,
6629 gimple_regimplify_operands (stmt
, gsi_p
);
6635 lower_omp (gimple_seq body
, omp_context
*ctx
)
6637 location_t saved_location
= input_location
;
6638 gimple_stmt_iterator gsi
= gsi_start (body
);
6639 for (gsi
= gsi_start (body
); !gsi_end_p (gsi
); gsi_next (&gsi
))
6640 lower_omp_1 (&gsi
, ctx
);
6641 input_location
= saved_location
;
6644 /* Main entry point. */
6647 execute_lower_omp (void)
6651 /* This pass always runs, to provide PROP_gimple_lomp.
6652 But there is nothing to do unless -fopenmp is given. */
6653 if (flag_openmp
== 0)
6656 all_contexts
= splay_tree_new (splay_tree_compare_pointers
, 0,
6657 delete_omp_context
);
6659 body
= gimple_body (current_function_decl
);
6660 scan_omp (body
, NULL
);
6661 gcc_assert (taskreg_nesting_level
== 0);
6663 if (all_contexts
->root
)
6665 struct gimplify_ctx gctx
;
6667 if (task_shared_vars
)
6668 push_gimplify_context (&gctx
);
6669 lower_omp (body
, NULL
);
6670 if (task_shared_vars
)
6671 pop_gimplify_context (NULL
);
6676 splay_tree_delete (all_contexts
);
6677 all_contexts
= NULL
;
6679 BITMAP_FREE (task_shared_vars
);
6683 struct gimple_opt_pass pass_lower_omp
=
6687 "omplower", /* name */
6689 execute_lower_omp
, /* execute */
6692 0, /* static_pass_number */
6693 TV_NONE
, /* tv_id */
6694 PROP_gimple_any
, /* properties_required */
6695 PROP_gimple_lomp
, /* properties_provided */
6696 0, /* properties_destroyed */
6697 0, /* todo_flags_start */
6698 TODO_dump_func
/* todo_flags_finish */
6702 /* The following is a utility to diagnose OpenMP structured block violations.
6703 It is not part of the "omplower" pass, as that's invoked too late. It
6704 should be invoked by the respective front ends after gimplification. */
6706 static splay_tree all_labels
;
6708 /* Check for mismatched contexts and generate an error if needed. Return
6709 true if an error is detected. */
6712 diagnose_sb_0 (gimple_stmt_iterator
*gsi_p
,
6713 gimple branch_ctx
, gimple label_ctx
)
6715 if (label_ctx
== branch_ctx
)
6720 Previously we kept track of the label's entire context in diagnose_sb_[12]
6721 so we could traverse it and issue a correct "exit" or "enter" error
6722 message upon a structured block violation.
6724 We built the context by building a list with tree_cons'ing, but there is
6725 no easy counterpart in gimple tuples. It seems like far too much work
6726 for issuing exit/enter error messages. If someone really misses the
6727 distinct error message... patches welcome.
6731 /* Try to avoid confusing the user by producing and error message
6732 with correct "exit" or "enter" verbiage. We prefer "exit"
6733 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
6734 if (branch_ctx
== NULL
)
6740 if (TREE_VALUE (label_ctx
) == branch_ctx
)
6745 label_ctx
= TREE_CHAIN (label_ctx
);
6750 error ("invalid exit from OpenMP structured block");
6752 error ("invalid entry to OpenMP structured block");
6755 /* If it's obvious we have an invalid entry, be specific about the error. */
6756 if (branch_ctx
== NULL
)
6757 error ("invalid entry to OpenMP structured block");
6759 /* Otherwise, be vague and lazy, but efficient. */
6760 error ("invalid branch to/from an OpenMP structured block");
6762 gsi_replace (gsi_p
, gimple_build_nop (), false);
6766 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
6767 where each label is found. */
6770 diagnose_sb_1 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
6771 struct walk_stmt_info
*wi
)
6773 gimple context
= (gimple
) wi
->info
;
6774 gimple inner_context
;
6775 gimple stmt
= gsi_stmt (*gsi_p
);
6777 *handled_ops_p
= true;
6779 switch (gimple_code (stmt
))
6783 case GIMPLE_OMP_PARALLEL
:
6784 case GIMPLE_OMP_TASK
:
6785 case GIMPLE_OMP_SECTIONS
:
6786 case GIMPLE_OMP_SINGLE
:
6787 case GIMPLE_OMP_SECTION
:
6788 case GIMPLE_OMP_MASTER
:
6789 case GIMPLE_OMP_ORDERED
:
6790 case GIMPLE_OMP_CRITICAL
:
6791 /* The minimal context here is just the current OMP construct. */
6792 inner_context
= stmt
;
6793 wi
->info
= inner_context
;
6794 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
6798 case GIMPLE_OMP_FOR
:
6799 inner_context
= stmt
;
6800 wi
->info
= inner_context
;
6801 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
6803 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
6804 diagnose_sb_1
, NULL
, wi
);
6805 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
6810 splay_tree_insert (all_labels
, (splay_tree_key
) gimple_label_label (stmt
),
6811 (splay_tree_value
) context
);
6821 /* Pass 2: Check each branch and see if its context differs from that of
6822 the destination label's context. */
6825 diagnose_sb_2 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
6826 struct walk_stmt_info
*wi
)
6828 gimple context
= (gimple
) wi
->info
;
6830 gimple stmt
= gsi_stmt (*gsi_p
);
6832 *handled_ops_p
= true;
6834 switch (gimple_code (stmt
))
6838 case GIMPLE_OMP_PARALLEL
:
6839 case GIMPLE_OMP_TASK
:
6840 case GIMPLE_OMP_SECTIONS
:
6841 case GIMPLE_OMP_SINGLE
:
6842 case GIMPLE_OMP_SECTION
:
6843 case GIMPLE_OMP_MASTER
:
6844 case GIMPLE_OMP_ORDERED
:
6845 case GIMPLE_OMP_CRITICAL
:
6847 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_2
, NULL
, wi
);
6851 case GIMPLE_OMP_FOR
:
6853 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
6855 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
6856 diagnose_sb_2
, NULL
, wi
);
6857 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_2
, NULL
, wi
);
6863 tree lab
= gimple_cond_true_label (stmt
);
6866 n
= splay_tree_lookup (all_labels
,
6867 (splay_tree_key
) lab
);
6868 diagnose_sb_0 (gsi_p
, context
,
6869 n
? (gimple
) n
->value
: NULL
);
6871 lab
= gimple_cond_false_label (stmt
);
6874 n
= splay_tree_lookup (all_labels
,
6875 (splay_tree_key
) lab
);
6876 diagnose_sb_0 (gsi_p
, context
,
6877 n
? (gimple
) n
->value
: NULL
);
6884 tree lab
= gimple_goto_dest (stmt
);
6885 if (TREE_CODE (lab
) != LABEL_DECL
)
6888 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
6889 diagnose_sb_0 (gsi_p
, context
, n
? (gimple
) n
->value
: NULL
);
6896 for (i
= 0; i
< gimple_switch_num_labels (stmt
); ++i
)
6898 tree lab
= CASE_LABEL (gimple_switch_label (stmt
, i
));
6899 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
6900 if (n
&& diagnose_sb_0 (gsi_p
, context
, (gimple
) n
->value
))
6907 diagnose_sb_0 (gsi_p
, context
, NULL
);
6918 diagnose_omp_structured_block_errors (void)
6920 struct walk_stmt_info wi
;
6921 gimple_seq body
= gimple_body (current_function_decl
);
6923 all_labels
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
6925 memset (&wi
, 0, sizeof (wi
));
6926 walk_gimple_seq (body
, diagnose_sb_1
, NULL
, &wi
);
6928 memset (&wi
, 0, sizeof (wi
));
6929 wi
.want_locations
= true;
6930 walk_gimple_seq (body
, diagnose_sb_2
, NULL
, &wi
);
6932 splay_tree_delete (all_labels
);
6939 gate_diagnose_omp_blocks (void)
6941 return flag_openmp
!= 0;
6944 struct gimple_opt_pass pass_diagnose_omp_blocks
=
6948 "*diagnose_omp_blocks", /* name */
6949 gate_diagnose_omp_blocks
, /* gate */
6950 diagnose_omp_structured_block_errors
, /* execute */
6953 0, /* static_pass_number */
6954 TV_NONE
, /* tv_id */
6955 PROP_gimple_any
, /* properties_required */
6956 0, /* properties_provided */
6957 0, /* properties_destroyed */
6958 0, /* todo_flags_start */
6959 0, /* todo_flags_finish */
6963 #include "gt-omp-low.h"