1 /* Lowering pass for OpenMP directives. Converts OpenMP directives
2 into explicit calls to the runtime library (libgomp) and data
3 marshalling to implement data sharing and copying clauses.
4 Contributed by Diego Novillo <dnovillo@redhat.com>
6 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010
7 Free Software Foundation, Inc.
9 This file is part of GCC.
11 GCC is free software; you can redistribute it and/or modify it under
12 the terms of the GNU General Public License as published by the Free
13 Software Foundation; either version 3, or (at your option) any later
16 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17 WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with GCC; see the file COPYING3. If not see
23 <http://www.gnu.org/licenses/>. */
27 #include "coretypes.h"
32 #include "tree-iterator.h"
33 #include "tree-inline.h"
34 #include "langhooks.h"
35 #include "diagnostic.h"
36 #include "tree-flow.h"
42 #include "tree-pass.h"
45 #include "splay-tree.h"
50 /* Lowering of OpenMP parallel and workshare constructs proceeds in two
51 phases. The first phase scans the function looking for OMP statements
52 and then for variables that must be replaced to satisfy data sharing
53 clauses. The second phase expands code for the constructs, as well as
54 re-gimplifying things when variables have been replaced with complex
57 Final code generation is done by pass_expand_omp. The flowgraph is
58 scanned for parallel regions which are then moved to a new
59 function, to be invoked by the thread library. */
61 /* Context structure. Used to store information about each parallel
62 directive in the code. */
64 typedef struct omp_context
66 /* This field must be at the beginning, as we do "inheritance": Some
67 callback functions for tree-inline.c (e.g., omp_copy_decl)
68 receive a copy_body_data pointer that is up-casted to an
69 omp_context pointer. */
72 /* The tree of contexts corresponding to the encountered constructs. */
73 struct omp_context
*outer
;
76 /* Map variables to fields in a structure that allows communication
77 between sending and receiving threads. */
83 /* These are used just by task contexts, if task firstprivate fn is
84 needed. srecord_type is used to communicate from the thread
85 that encountered the task construct to task firstprivate fn,
86 record_type is allocated by GOMP_task, initialized by task firstprivate
87 fn and passed to the task body fn. */
88 splay_tree sfield_map
;
91 /* A chain of variables to add to the top-level block surrounding the
92 construct. In the case of a parallel, this is in the child function. */
95 /* What to do with variables with implicitly determined sharing
97 enum omp_clause_default_kind default_kind
;
99 /* Nesting depth of this context. Used to beautify error messages re
100 invalid gotos. The outermost ctx is depth 1, with depth 0 being
101 reserved for the main body of the function. */
104 /* True if this parallel directive is nested within another. */
109 struct omp_for_data_loop
111 tree v
, n1
, n2
, step
;
112 enum tree_code cond_code
;
115 /* A structure describing the main elements of a parallel loop. */
119 struct omp_for_data_loop loop
;
124 bool have_nowait
, have_ordered
;
125 enum omp_clause_schedule_kind sched_kind
;
126 struct omp_for_data_loop
*loops
;
130 static splay_tree all_contexts
;
131 static int taskreg_nesting_level
;
132 struct omp_region
*root_omp_region
;
133 static bitmap task_shared_vars
;
135 static void scan_omp (gimple_seq
, omp_context
*);
136 static tree
scan_omp_1_op (tree
*, int *, void *);
138 #define WALK_SUBSTMTS \
142 case GIMPLE_EH_FILTER: \
143 /* The sub-statements for these should be walked. */ \
144 *handled_ops_p = false; \
147 /* Convenience function for calling scan_omp_1_op on tree operands. */
150 scan_omp_op (tree
*tp
, omp_context
*ctx
)
152 struct walk_stmt_info wi
;
154 memset (&wi
, 0, sizeof (wi
));
156 wi
.want_locations
= true;
158 return walk_tree (tp
, scan_omp_1_op
, &wi
, NULL
);
161 static void lower_omp (gimple_seq
, omp_context
*);
162 static tree
lookup_decl_in_outer_ctx (tree
, omp_context
*);
163 static tree
maybe_lookup_decl_in_outer_ctx (tree
, omp_context
*);
165 /* Find an OpenMP clause of type KIND within CLAUSES. */
168 find_omp_clause (tree clauses
, enum omp_clause_code kind
)
170 for (; clauses
; clauses
= OMP_CLAUSE_CHAIN (clauses
))
171 if (OMP_CLAUSE_CODE (clauses
) == kind
)
177 /* Return true if CTX is for an omp parallel. */
180 is_parallel_ctx (omp_context
*ctx
)
182 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
;
186 /* Return true if CTX is for an omp task. */
189 is_task_ctx (omp_context
*ctx
)
191 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_TASK
;
195 /* Return true if CTX is for an omp parallel or omp task. */
198 is_taskreg_ctx (omp_context
*ctx
)
200 return gimple_code (ctx
->stmt
) == GIMPLE_OMP_PARALLEL
201 || gimple_code (ctx
->stmt
) == GIMPLE_OMP_TASK
;
205 /* Return true if REGION is a combined parallel+workshare region. */
208 is_combined_parallel (struct omp_region
*region
)
210 return region
->is_combined_parallel
;
214 /* Extract the header elements of parallel loop FOR_STMT and store
218 extract_omp_for_data (gimple for_stmt
, struct omp_for_data
*fd
,
219 struct omp_for_data_loop
*loops
)
221 tree t
, var
, *collapse_iter
, *collapse_count
;
222 tree count
= NULL_TREE
, iter_type
= long_integer_type_node
;
223 struct omp_for_data_loop
*loop
;
225 struct omp_for_data_loop dummy_loop
;
226 location_t loc
= gimple_location (for_stmt
);
228 fd
->for_stmt
= for_stmt
;
230 fd
->collapse
= gimple_omp_for_collapse (for_stmt
);
231 if (fd
->collapse
> 1)
234 fd
->loops
= &fd
->loop
;
236 fd
->have_nowait
= fd
->have_ordered
= false;
237 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
238 fd
->chunk_size
= NULL_TREE
;
239 collapse_iter
= NULL
;
240 collapse_count
= NULL
;
242 for (t
= gimple_omp_for_clauses (for_stmt
); t
; t
= OMP_CLAUSE_CHAIN (t
))
243 switch (OMP_CLAUSE_CODE (t
))
245 case OMP_CLAUSE_NOWAIT
:
246 fd
->have_nowait
= true;
248 case OMP_CLAUSE_ORDERED
:
249 fd
->have_ordered
= true;
251 case OMP_CLAUSE_SCHEDULE
:
252 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_KIND (t
);
253 fd
->chunk_size
= OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t
);
255 case OMP_CLAUSE_COLLAPSE
:
256 if (fd
->collapse
> 1)
258 collapse_iter
= &OMP_CLAUSE_COLLAPSE_ITERVAR (t
);
259 collapse_count
= &OMP_CLAUSE_COLLAPSE_COUNT (t
);
265 /* FIXME: for now map schedule(auto) to schedule(static).
266 There should be analysis to determine whether all iterations
267 are approximately the same amount of work (then schedule(static)
268 is best) or if it varies (then schedule(dynamic,N) is better). */
269 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_AUTO
)
271 fd
->sched_kind
= OMP_CLAUSE_SCHEDULE_STATIC
;
272 gcc_assert (fd
->chunk_size
== NULL
);
274 gcc_assert (fd
->collapse
== 1 || collapse_iter
!= NULL
);
275 if (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
276 gcc_assert (fd
->chunk_size
== NULL
);
277 else if (fd
->chunk_size
== NULL
)
279 /* We only need to compute a default chunk size for ordered
280 static loops and dynamic loops. */
281 if (fd
->sched_kind
!= OMP_CLAUSE_SCHEDULE_STATIC
284 fd
->chunk_size
= (fd
->sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
)
285 ? integer_zero_node
: integer_one_node
;
288 for (i
= 0; i
< fd
->collapse
; i
++)
290 if (fd
->collapse
== 1)
292 else if (loops
!= NULL
)
298 loop
->v
= gimple_omp_for_index (for_stmt
, i
);
299 gcc_assert (SSA_VAR_P (loop
->v
));
300 gcc_assert (TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
301 || TREE_CODE (TREE_TYPE (loop
->v
)) == POINTER_TYPE
);
302 var
= TREE_CODE (loop
->v
) == SSA_NAME
? SSA_NAME_VAR (loop
->v
) : loop
->v
;
303 loop
->n1
= gimple_omp_for_initial (for_stmt
, i
);
305 loop
->cond_code
= gimple_omp_for_cond (for_stmt
, i
);
306 loop
->n2
= gimple_omp_for_final (for_stmt
, i
);
307 switch (loop
->cond_code
)
313 if (POINTER_TYPE_P (TREE_TYPE (loop
->n2
)))
314 loop
->n2
= fold_build2_loc (loc
,
315 POINTER_PLUS_EXPR
, TREE_TYPE (loop
->n2
),
316 loop
->n2
, size_one_node
);
318 loop
->n2
= fold_build2_loc (loc
,
319 PLUS_EXPR
, TREE_TYPE (loop
->n2
), loop
->n2
,
320 build_int_cst (TREE_TYPE (loop
->n2
), 1));
321 loop
->cond_code
= LT_EXPR
;
324 if (POINTER_TYPE_P (TREE_TYPE (loop
->n2
)))
325 loop
->n2
= fold_build2_loc (loc
,
326 POINTER_PLUS_EXPR
, TREE_TYPE (loop
->n2
),
327 loop
->n2
, size_int (-1));
329 loop
->n2
= fold_build2_loc (loc
,
330 MINUS_EXPR
, TREE_TYPE (loop
->n2
), loop
->n2
,
331 build_int_cst (TREE_TYPE (loop
->n2
), 1));
332 loop
->cond_code
= GT_EXPR
;
338 t
= gimple_omp_for_incr (for_stmt
, i
);
339 gcc_assert (TREE_OPERAND (t
, 0) == var
);
340 switch (TREE_CODE (t
))
343 case POINTER_PLUS_EXPR
:
344 loop
->step
= TREE_OPERAND (t
, 1);
347 loop
->step
= TREE_OPERAND (t
, 1);
348 loop
->step
= fold_build1_loc (loc
,
349 NEGATE_EXPR
, TREE_TYPE (loop
->step
),
356 if (iter_type
!= long_long_unsigned_type_node
)
358 if (POINTER_TYPE_P (TREE_TYPE (loop
->v
)))
359 iter_type
= long_long_unsigned_type_node
;
360 else if (TYPE_UNSIGNED (TREE_TYPE (loop
->v
))
361 && TYPE_PRECISION (TREE_TYPE (loop
->v
))
362 >= TYPE_PRECISION (iter_type
))
366 if (loop
->cond_code
== LT_EXPR
)
367 n
= fold_build2_loc (loc
,
368 PLUS_EXPR
, TREE_TYPE (loop
->v
),
369 loop
->n2
, loop
->step
);
372 if (TREE_CODE (n
) != INTEGER_CST
373 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type
), n
))
374 iter_type
= long_long_unsigned_type_node
;
376 else if (TYPE_PRECISION (TREE_TYPE (loop
->v
))
377 > TYPE_PRECISION (iter_type
))
381 if (loop
->cond_code
== LT_EXPR
)
384 n2
= fold_build2_loc (loc
,
385 PLUS_EXPR
, TREE_TYPE (loop
->v
),
386 loop
->n2
, loop
->step
);
390 n1
= fold_build2_loc (loc
,
391 MINUS_EXPR
, TREE_TYPE (loop
->v
),
392 loop
->n2
, loop
->step
);
395 if (TREE_CODE (n1
) != INTEGER_CST
396 || TREE_CODE (n2
) != INTEGER_CST
397 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type
), n1
)
398 || !tree_int_cst_lt (n2
, TYPE_MAX_VALUE (iter_type
)))
399 iter_type
= long_long_unsigned_type_node
;
403 if (collapse_count
&& *collapse_count
== NULL
)
405 if ((i
== 0 || count
!= NULL_TREE
)
406 && TREE_CODE (TREE_TYPE (loop
->v
)) == INTEGER_TYPE
407 && TREE_CONSTANT (loop
->n1
)
408 && TREE_CONSTANT (loop
->n2
)
409 && TREE_CODE (loop
->step
) == INTEGER_CST
)
411 tree itype
= TREE_TYPE (loop
->v
);
413 if (POINTER_TYPE_P (itype
))
415 = lang_hooks
.types
.type_for_size (TYPE_PRECISION (itype
), 0);
416 t
= build_int_cst (itype
, (loop
->cond_code
== LT_EXPR
? -1 : 1));
417 t
= fold_build2_loc (loc
,
419 fold_convert_loc (loc
, itype
, loop
->step
), t
);
420 t
= fold_build2_loc (loc
, PLUS_EXPR
, itype
, t
,
421 fold_convert_loc (loc
, itype
, loop
->n2
));
422 t
= fold_build2_loc (loc
, MINUS_EXPR
, itype
, t
,
423 fold_convert_loc (loc
, itype
, loop
->n1
));
424 if (TYPE_UNSIGNED (itype
) && loop
->cond_code
== GT_EXPR
)
425 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
,
426 fold_build1_loc (loc
, NEGATE_EXPR
, itype
, t
),
427 fold_build1_loc (loc
, NEGATE_EXPR
, itype
,
428 fold_convert_loc (loc
, itype
,
431 t
= fold_build2_loc (loc
, TRUNC_DIV_EXPR
, itype
, t
,
432 fold_convert_loc (loc
, itype
, loop
->step
));
433 t
= fold_convert_loc (loc
, long_long_unsigned_type_node
, t
);
434 if (count
!= NULL_TREE
)
435 count
= fold_build2_loc (loc
,
436 MULT_EXPR
, long_long_unsigned_type_node
,
440 if (TREE_CODE (count
) != INTEGER_CST
)
450 if (!tree_int_cst_lt (count
, TYPE_MAX_VALUE (long_integer_type_node
)))
451 iter_type
= long_long_unsigned_type_node
;
453 iter_type
= long_integer_type_node
;
455 else if (collapse_iter
&& *collapse_iter
!= NULL
)
456 iter_type
= TREE_TYPE (*collapse_iter
);
457 fd
->iter_type
= iter_type
;
458 if (collapse_iter
&& *collapse_iter
== NULL
)
459 *collapse_iter
= create_tmp_var (iter_type
, ".iter");
460 if (collapse_count
&& *collapse_count
== NULL
)
463 *collapse_count
= fold_convert_loc (loc
, iter_type
, count
);
465 *collapse_count
= create_tmp_var (iter_type
, ".count");
468 if (fd
->collapse
> 1)
470 fd
->loop
.v
= *collapse_iter
;
471 fd
->loop
.n1
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
472 fd
->loop
.n2
= *collapse_count
;
473 fd
->loop
.step
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 1);
474 fd
->loop
.cond_code
= LT_EXPR
;
479 /* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
480 is the immediate dominator of PAR_ENTRY_BB, return true if there
481 are no data dependencies that would prevent expanding the parallel
482 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
484 When expanding a combined parallel+workshare region, the call to
485 the child function may need additional arguments in the case of
486 GIMPLE_OMP_FOR regions. In some cases, these arguments are
487 computed out of variables passed in from the parent to the child
488 via 'struct .omp_data_s'. For instance:
490 #pragma omp parallel for schedule (guided, i * 4)
495 # BLOCK 2 (PAR_ENTRY_BB)
497 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
499 # BLOCK 3 (WS_ENTRY_BB)
500 .omp_data_i = &.omp_data_o;
501 D.1667 = .omp_data_i->i;
503 #pragma omp for schedule (guided, D.1598)
505 When we outline the parallel region, the call to the child function
506 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
507 that value is computed *after* the call site. So, in principle we
508 cannot do the transformation.
510 To see whether the code in WS_ENTRY_BB blocks the combined
511 parallel+workshare call, we collect all the variables used in the
512 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
513 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
516 FIXME. If we had the SSA form built at this point, we could merely
517 hoist the code in block 3 into block 2 and be done with it. But at
518 this point we don't have dataflow information and though we could
519 hack something up here, it is really not worth the aggravation. */
522 workshare_safe_to_combine_p (basic_block ws_entry_bb
)
524 struct omp_for_data fd
;
525 gimple ws_stmt
= last_stmt (ws_entry_bb
);
527 if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
530 gcc_assert (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
);
532 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
534 if (fd
.collapse
> 1 && TREE_CODE (fd
.loop
.n2
) != INTEGER_CST
)
536 if (fd
.iter_type
!= long_integer_type_node
)
539 /* FIXME. We give up too easily here. If any of these arguments
540 are not constants, they will likely involve variables that have
541 been mapped into fields of .omp_data_s for sharing with the child
542 function. With appropriate data flow, it would be possible to
544 if (!is_gimple_min_invariant (fd
.loop
.n1
)
545 || !is_gimple_min_invariant (fd
.loop
.n2
)
546 || !is_gimple_min_invariant (fd
.loop
.step
)
547 || (fd
.chunk_size
&& !is_gimple_min_invariant (fd
.chunk_size
)))
554 /* Collect additional arguments needed to emit a combined
555 parallel+workshare call. WS_STMT is the workshare directive being
559 get_ws_args_for (gimple ws_stmt
)
562 location_t loc
= gimple_location (ws_stmt
);
564 if (gimple_code (ws_stmt
) == GIMPLE_OMP_FOR
)
566 struct omp_for_data fd
;
569 extract_omp_for_data (ws_stmt
, &fd
, NULL
);
574 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.chunk_size
);
575 ws_args
= tree_cons (NULL
, t
, ws_args
);
578 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.step
);
579 ws_args
= tree_cons (NULL
, t
, ws_args
);
581 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.n2
);
582 ws_args
= tree_cons (NULL
, t
, ws_args
);
584 t
= fold_convert_loc (loc
, long_integer_type_node
, fd
.loop
.n1
);
585 ws_args
= tree_cons (NULL
, t
, ws_args
);
589 else if (gimple_code (ws_stmt
) == GIMPLE_OMP_SECTIONS
)
591 /* Number of sections is equal to the number of edges from the
592 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
593 the exit of the sections region. */
594 basic_block bb
= single_succ (gimple_bb (ws_stmt
));
595 t
= build_int_cst (unsigned_type_node
, EDGE_COUNT (bb
->succs
) - 1);
596 t
= tree_cons (NULL
, t
, NULL
);
604 /* Discover whether REGION is a combined parallel+workshare region. */
607 determine_parallel_type (struct omp_region
*region
)
609 basic_block par_entry_bb
, par_exit_bb
;
610 basic_block ws_entry_bb
, ws_exit_bb
;
612 if (region
== NULL
|| region
->inner
== NULL
613 || region
->exit
== NULL
|| region
->inner
->exit
== NULL
614 || region
->inner
->cont
== NULL
)
617 /* We only support parallel+for and parallel+sections. */
618 if (region
->type
!= GIMPLE_OMP_PARALLEL
619 || (region
->inner
->type
!= GIMPLE_OMP_FOR
620 && region
->inner
->type
!= GIMPLE_OMP_SECTIONS
))
623 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
624 WS_EXIT_BB -> PAR_EXIT_BB. */
625 par_entry_bb
= region
->entry
;
626 par_exit_bb
= region
->exit
;
627 ws_entry_bb
= region
->inner
->entry
;
628 ws_exit_bb
= region
->inner
->exit
;
630 if (single_succ (par_entry_bb
) == ws_entry_bb
631 && single_succ (ws_exit_bb
) == par_exit_bb
632 && workshare_safe_to_combine_p (ws_entry_bb
)
633 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb
))
634 || (last_and_only_stmt (ws_entry_bb
)
635 && last_and_only_stmt (par_exit_bb
))))
637 gimple ws_stmt
= last_stmt (ws_entry_bb
);
639 if (region
->inner
->type
== GIMPLE_OMP_FOR
)
641 /* If this is a combined parallel loop, we need to determine
642 whether or not to use the combined library calls. There
643 are two cases where we do not apply the transformation:
644 static loops and any kind of ordered loop. In the first
645 case, we already open code the loop so there is no need
646 to do anything else. In the latter case, the combined
647 parallel loop call would still need extra synchronization
648 to implement ordered semantics, so there would not be any
649 gain in using the combined call. */
650 tree clauses
= gimple_omp_for_clauses (ws_stmt
);
651 tree c
= find_omp_clause (clauses
, OMP_CLAUSE_SCHEDULE
);
653 || OMP_CLAUSE_SCHEDULE_KIND (c
) == OMP_CLAUSE_SCHEDULE_STATIC
654 || find_omp_clause (clauses
, OMP_CLAUSE_ORDERED
))
656 region
->is_combined_parallel
= false;
657 region
->inner
->is_combined_parallel
= false;
662 region
->is_combined_parallel
= true;
663 region
->inner
->is_combined_parallel
= true;
664 region
->ws_args
= get_ws_args_for (ws_stmt
);
669 /* Return true if EXPR is variable sized. */
672 is_variable_sized (const_tree expr
)
674 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr
)));
677 /* Return true if DECL is a reference type. */
680 is_reference (tree decl
)
682 return lang_hooks
.decls
.omp_privatize_by_reference (decl
);
685 /* Lookup variables in the decl or field splay trees. The "maybe" form
686 allows for the variable form to not have been entered, otherwise we
687 assert that the variable must have been entered. */
690 lookup_decl (tree var
, omp_context
*ctx
)
693 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
698 maybe_lookup_decl (const_tree var
, omp_context
*ctx
)
701 n
= (tree
*) pointer_map_contains (ctx
->cb
.decl_map
, var
);
702 return n
? *n
: NULL_TREE
;
706 lookup_field (tree var
, omp_context
*ctx
)
709 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
710 return (tree
) n
->value
;
714 lookup_sfield (tree var
, omp_context
*ctx
)
717 n
= splay_tree_lookup (ctx
->sfield_map
718 ? ctx
->sfield_map
: ctx
->field_map
,
719 (splay_tree_key
) var
);
720 return (tree
) n
->value
;
724 maybe_lookup_field (tree var
, omp_context
*ctx
)
727 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
);
728 return n
? (tree
) n
->value
: NULL_TREE
;
731 /* Return true if DECL should be copied by pointer. SHARED_CTX is
732 the parallel context if DECL is to be shared. */
735 use_pointer_for_field (tree decl
, omp_context
*shared_ctx
)
737 if (AGGREGATE_TYPE_P (TREE_TYPE (decl
)))
740 /* We can only use copy-in/copy-out semantics for shared variables
741 when we know the value is not accessible from an outer scope. */
744 /* ??? Trivially accessible from anywhere. But why would we even
745 be passing an address in this case? Should we simply assert
746 this to be false, or should we have a cleanup pass that removes
747 these from the list of mappings? */
748 if (TREE_STATIC (decl
) || DECL_EXTERNAL (decl
))
751 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
752 without analyzing the expression whether or not its location
753 is accessible to anyone else. In the case of nested parallel
754 regions it certainly may be. */
755 if (TREE_CODE (decl
) != RESULT_DECL
&& DECL_HAS_VALUE_EXPR_P (decl
))
758 /* Do not use copy-in/copy-out for variables that have their
760 if (TREE_ADDRESSABLE (decl
))
763 /* Disallow copy-in/out in nested parallel if
764 decl is shared in outer parallel, otherwise
765 each thread could store the shared variable
766 in its own copy-in location, making the
767 variable no longer really shared. */
768 if (!TREE_READONLY (decl
) && shared_ctx
->is_nested
)
772 for (up
= shared_ctx
->outer
; up
; up
= up
->outer
)
773 if (is_taskreg_ctx (up
) && maybe_lookup_decl (decl
, up
))
780 for (c
= gimple_omp_taskreg_clauses (up
->stmt
);
781 c
; c
= OMP_CLAUSE_CHAIN (c
))
782 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_SHARED
783 && OMP_CLAUSE_DECL (c
) == decl
)
791 /* For tasks avoid using copy-in/out, unless they are readonly
792 (in which case just copy-in is used). As tasks can be
793 deferred or executed in different thread, when GOMP_task
794 returns, the task hasn't necessarily terminated. */
795 if (!TREE_READONLY (decl
) && is_task_ctx (shared_ctx
))
797 tree outer
= maybe_lookup_decl_in_outer_ctx (decl
, shared_ctx
);
798 if (is_gimple_reg (outer
))
800 /* Taking address of OUTER in lower_send_shared_vars
801 might need regimplification of everything that uses the
803 if (!task_shared_vars
)
804 task_shared_vars
= BITMAP_ALLOC (NULL
);
805 bitmap_set_bit (task_shared_vars
, DECL_UID (outer
));
806 TREE_ADDRESSABLE (outer
) = 1;
815 /* Create a new VAR_DECL and copy information from VAR to it. */
818 copy_var_decl (tree var
, tree name
, tree type
)
820 tree copy
= build_decl (DECL_SOURCE_LOCATION (var
), VAR_DECL
, name
, type
);
822 TREE_ADDRESSABLE (copy
) = TREE_ADDRESSABLE (var
);
823 TREE_THIS_VOLATILE (copy
) = TREE_THIS_VOLATILE (var
);
824 DECL_GIMPLE_REG_P (copy
) = DECL_GIMPLE_REG_P (var
);
825 DECL_ARTIFICIAL (copy
) = DECL_ARTIFICIAL (var
);
826 DECL_IGNORED_P (copy
) = DECL_IGNORED_P (var
);
827 DECL_CONTEXT (copy
) = DECL_CONTEXT (var
);
828 TREE_USED (copy
) = 1;
829 DECL_SEEN_IN_BIND_EXPR_P (copy
) = 1;
834 /* Construct a new automatic decl similar to VAR. */
837 omp_copy_decl_2 (tree var
, tree name
, tree type
, omp_context
*ctx
)
839 tree copy
= copy_var_decl (var
, name
, type
);
841 DECL_CONTEXT (copy
) = current_function_decl
;
842 TREE_CHAIN (copy
) = ctx
->block_vars
;
843 ctx
->block_vars
= copy
;
849 omp_copy_decl_1 (tree var
, omp_context
*ctx
)
851 return omp_copy_decl_2 (var
, DECL_NAME (var
), TREE_TYPE (var
), ctx
);
854 /* Build tree nodes to access the field for VAR on the receiver side. */
857 build_receiver_ref (tree var
, bool by_ref
, omp_context
*ctx
)
859 tree x
, field
= lookup_field (var
, ctx
);
861 /* If the receiver record type was remapped in the child function,
862 remap the field into the new record type. */
863 x
= maybe_lookup_field (field
, ctx
);
867 x
= build_fold_indirect_ref (ctx
->receiver_decl
);
868 x
= build3 (COMPONENT_REF
, TREE_TYPE (field
), x
, field
, NULL
);
870 x
= build_fold_indirect_ref (x
);
875 /* Build tree nodes to access VAR in the scope outer to CTX. In the case
876 of a parallel, this is a component reference; for workshare constructs
877 this is some variable. */
880 build_outer_var_ref (tree var
, omp_context
*ctx
)
884 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
, ctx
)))
886 else if (is_variable_sized (var
))
888 x
= TREE_OPERAND (DECL_VALUE_EXPR (var
), 0);
889 x
= build_outer_var_ref (x
, ctx
);
890 x
= build_fold_indirect_ref (x
);
892 else if (is_taskreg_ctx (ctx
))
894 bool by_ref
= use_pointer_for_field (var
, NULL
);
895 x
= build_receiver_ref (var
, by_ref
, ctx
);
898 x
= lookup_decl (var
, ctx
->outer
);
899 else if (is_reference (var
))
900 /* This can happen with orphaned constructs. If var is reference, it is
901 possible it is shared and as such valid. */
906 if (is_reference (var
))
907 x
= build_fold_indirect_ref (x
);
912 /* Build tree nodes to access the field for VAR on the sender side. */
915 build_sender_ref (tree var
, omp_context
*ctx
)
917 tree field
= lookup_sfield (var
, ctx
);
918 return build3 (COMPONENT_REF
, TREE_TYPE (field
),
919 ctx
->sender_decl
, field
, NULL
);
922 /* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
925 install_var_field (tree var
, bool by_ref
, int mask
, omp_context
*ctx
)
927 tree field
, type
, sfield
= NULL_TREE
;
929 gcc_assert ((mask
& 1) == 0
930 || !splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) var
));
931 gcc_assert ((mask
& 2) == 0 || !ctx
->sfield_map
932 || !splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) var
));
934 type
= TREE_TYPE (var
);
936 type
= build_pointer_type (type
);
937 else if ((mask
& 3) == 1 && is_reference (var
))
938 type
= TREE_TYPE (type
);
940 field
= build_decl (DECL_SOURCE_LOCATION (var
),
941 FIELD_DECL
, DECL_NAME (var
), type
);
943 /* Remember what variable this field was created for. This does have a
944 side effect of making dwarf2out ignore this member, so for helpful
945 debugging we clear it later in delete_omp_context. */
946 DECL_ABSTRACT_ORIGIN (field
) = var
;
947 if (type
== TREE_TYPE (var
))
949 DECL_ALIGN (field
) = DECL_ALIGN (var
);
950 DECL_USER_ALIGN (field
) = DECL_USER_ALIGN (var
);
951 TREE_THIS_VOLATILE (field
) = TREE_THIS_VOLATILE (var
);
954 DECL_ALIGN (field
) = TYPE_ALIGN (type
);
958 insert_field_into_struct (ctx
->record_type
, field
);
959 if (ctx
->srecord_type
)
961 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
962 FIELD_DECL
, DECL_NAME (var
), type
);
963 DECL_ABSTRACT_ORIGIN (sfield
) = var
;
964 DECL_ALIGN (sfield
) = DECL_ALIGN (field
);
965 DECL_USER_ALIGN (sfield
) = DECL_USER_ALIGN (field
);
966 TREE_THIS_VOLATILE (sfield
) = TREE_THIS_VOLATILE (field
);
967 insert_field_into_struct (ctx
->srecord_type
, sfield
);
972 if (ctx
->srecord_type
== NULL_TREE
)
976 ctx
->srecord_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
977 ctx
->sfield_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
978 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= TREE_CHAIN (t
))
980 sfield
= build_decl (DECL_SOURCE_LOCATION (var
),
981 FIELD_DECL
, DECL_NAME (t
), TREE_TYPE (t
));
982 DECL_ABSTRACT_ORIGIN (sfield
) = DECL_ABSTRACT_ORIGIN (t
);
983 insert_field_into_struct (ctx
->srecord_type
, sfield
);
984 splay_tree_insert (ctx
->sfield_map
,
985 (splay_tree_key
) DECL_ABSTRACT_ORIGIN (t
),
986 (splay_tree_value
) sfield
);
990 insert_field_into_struct ((mask
& 1) ? ctx
->record_type
991 : ctx
->srecord_type
, field
);
995 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) var
,
996 (splay_tree_value
) field
);
997 if ((mask
& 2) && ctx
->sfield_map
)
998 splay_tree_insert (ctx
->sfield_map
, (splay_tree_key
) var
,
999 (splay_tree_value
) sfield
);
1003 install_var_local (tree var
, omp_context
*ctx
)
1005 tree new_var
= omp_copy_decl_1 (var
, ctx
);
1006 insert_decl_map (&ctx
->cb
, var
, new_var
);
1010 /* Adjust the replacement for DECL in CTX for the new context. This means
1011 copying the DECL_VALUE_EXPR, and fixing up the type. */
1014 fixup_remapped_decl (tree decl
, omp_context
*ctx
, bool private_debug
)
1016 tree new_decl
, size
;
1018 new_decl
= lookup_decl (decl
, ctx
);
1020 TREE_TYPE (new_decl
) = remap_type (TREE_TYPE (decl
), &ctx
->cb
);
1022 if ((!TREE_CONSTANT (DECL_SIZE (new_decl
)) || private_debug
)
1023 && DECL_HAS_VALUE_EXPR_P (decl
))
1025 tree ve
= DECL_VALUE_EXPR (decl
);
1026 walk_tree (&ve
, copy_tree_body_r
, &ctx
->cb
, NULL
);
1027 SET_DECL_VALUE_EXPR (new_decl
, ve
);
1028 DECL_HAS_VALUE_EXPR_P (new_decl
) = 1;
1031 if (!TREE_CONSTANT (DECL_SIZE (new_decl
)))
1033 size
= remap_decl (DECL_SIZE (decl
), &ctx
->cb
);
1034 if (size
== error_mark_node
)
1035 size
= TYPE_SIZE (TREE_TYPE (new_decl
));
1036 DECL_SIZE (new_decl
) = size
;
1038 size
= remap_decl (DECL_SIZE_UNIT (decl
), &ctx
->cb
);
1039 if (size
== error_mark_node
)
1040 size
= TYPE_SIZE_UNIT (TREE_TYPE (new_decl
));
1041 DECL_SIZE_UNIT (new_decl
) = size
;
1045 /* The callback for remap_decl. Search all containing contexts for a
1046 mapping of the variable; this avoids having to duplicate the splay
1047 tree ahead of time. We know a mapping doesn't already exist in the
1048 given context. Create new mappings to implement default semantics. */
1051 omp_copy_decl (tree var
, copy_body_data
*cb
)
1053 omp_context
*ctx
= (omp_context
*) cb
;
1056 if (TREE_CODE (var
) == LABEL_DECL
)
1058 new_var
= create_artificial_label (DECL_SOURCE_LOCATION (var
));
1059 DECL_CONTEXT (new_var
) = current_function_decl
;
1060 insert_decl_map (&ctx
->cb
, var
, new_var
);
1064 while (!is_taskreg_ctx (ctx
))
1069 new_var
= maybe_lookup_decl (var
, ctx
);
1074 if (is_global_var (var
) || decl_function_context (var
) != ctx
->cb
.src_fn
)
1077 return error_mark_node
;
1081 /* Return the parallel region associated with STMT. */
1083 /* Debugging dumps for parallel regions. */
1084 void dump_omp_region (FILE *, struct omp_region
*, int);
1085 void debug_omp_region (struct omp_region
*);
1086 void debug_all_omp_regions (void);
1088 /* Dump the parallel region tree rooted at REGION. */
1091 dump_omp_region (FILE *file
, struct omp_region
*region
, int indent
)
1093 fprintf (file
, "%*sbb %d: %s\n", indent
, "", region
->entry
->index
,
1094 gimple_code_name
[region
->type
]);
1097 dump_omp_region (file
, region
->inner
, indent
+ 4);
1101 fprintf (file
, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent
, "",
1102 region
->cont
->index
);
1106 fprintf (file
, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent
, "",
1107 region
->exit
->index
);
1109 fprintf (file
, "%*s[no exit marker]\n", indent
, "");
1112 dump_omp_region (file
, region
->next
, indent
);
1116 debug_omp_region (struct omp_region
*region
)
1118 dump_omp_region (stderr
, region
, 0);
1122 debug_all_omp_regions (void)
1124 dump_omp_region (stderr
, root_omp_region
, 0);
1128 /* Create a new parallel region starting at STMT inside region PARENT. */
1131 new_omp_region (basic_block bb
, enum gimple_code type
,
1132 struct omp_region
*parent
)
1134 struct omp_region
*region
= XCNEW (struct omp_region
);
1136 region
->outer
= parent
;
1138 region
->type
= type
;
1142 /* This is a nested region. Add it to the list of inner
1143 regions in PARENT. */
1144 region
->next
= parent
->inner
;
1145 parent
->inner
= region
;
1149 /* This is a toplevel region. Add it to the list of toplevel
1150 regions in ROOT_OMP_REGION. */
1151 region
->next
= root_omp_region
;
1152 root_omp_region
= region
;
1158 /* Release the memory associated with the region tree rooted at REGION. */
1161 free_omp_region_1 (struct omp_region
*region
)
1163 struct omp_region
*i
, *n
;
1165 for (i
= region
->inner
; i
; i
= n
)
1168 free_omp_region_1 (i
);
1174 /* Release the memory for the entire omp region tree. */
1177 free_omp_regions (void)
1179 struct omp_region
*r
, *n
;
1180 for (r
= root_omp_region
; r
; r
= n
)
1183 free_omp_region_1 (r
);
1185 root_omp_region
= NULL
;
1189 /* Create a new context, with OUTER_CTX being the surrounding context. */
1191 static omp_context
*
1192 new_omp_context (gimple stmt
, omp_context
*outer_ctx
)
1194 omp_context
*ctx
= XCNEW (omp_context
);
1196 splay_tree_insert (all_contexts
, (splay_tree_key
) stmt
,
1197 (splay_tree_value
) ctx
);
1202 ctx
->outer
= outer_ctx
;
1203 ctx
->cb
= outer_ctx
->cb
;
1204 ctx
->cb
.block
= NULL
;
1205 ctx
->depth
= outer_ctx
->depth
+ 1;
1209 ctx
->cb
.src_fn
= current_function_decl
;
1210 ctx
->cb
.dst_fn
= current_function_decl
;
1211 ctx
->cb
.src_node
= cgraph_node (current_function_decl
);
1212 ctx
->cb
.dst_node
= ctx
->cb
.src_node
;
1213 ctx
->cb
.src_cfun
= cfun
;
1214 ctx
->cb
.copy_decl
= omp_copy_decl
;
1215 ctx
->cb
.eh_lp_nr
= 0;
1216 ctx
->cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
1220 ctx
->cb
.decl_map
= pointer_map_create ();
1225 static gimple_seq
maybe_catch_exception (gimple_seq
);
1227 /* Finalize task copyfn. */
1230 finalize_task_copyfn (gimple task_stmt
)
1232 struct function
*child_cfun
;
1233 tree child_fn
, old_fn
;
1234 gimple_seq seq
, new_seq
;
1237 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
1238 if (child_fn
== NULL_TREE
)
1241 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
1243 /* Inform the callgraph about the new function. */
1244 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
1245 = cfun
->curr_properties
;
1247 old_fn
= current_function_decl
;
1248 push_cfun (child_cfun
);
1249 current_function_decl
= child_fn
;
1250 bind
= gimplify_body (&DECL_SAVED_TREE (child_fn
), child_fn
, false);
1251 seq
= gimple_seq_alloc ();
1252 gimple_seq_add_stmt (&seq
, bind
);
1253 new_seq
= maybe_catch_exception (seq
);
1256 bind
= gimple_build_bind (NULL
, new_seq
, NULL
);
1257 seq
= gimple_seq_alloc ();
1258 gimple_seq_add_stmt (&seq
, bind
);
1260 gimple_set_body (child_fn
, seq
);
1262 current_function_decl
= old_fn
;
1264 cgraph_add_new_function (child_fn
, false);
1267 /* Destroy a omp_context data structures. Called through the splay tree
1268 value delete callback. */
1271 delete_omp_context (splay_tree_value value
)
1273 omp_context
*ctx
= (omp_context
*) value
;
1275 pointer_map_destroy (ctx
->cb
.decl_map
);
1278 splay_tree_delete (ctx
->field_map
);
1279 if (ctx
->sfield_map
)
1280 splay_tree_delete (ctx
->sfield_map
);
1282 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1283 it produces corrupt debug information. */
1284 if (ctx
->record_type
)
1287 for (t
= TYPE_FIELDS (ctx
->record_type
); t
; t
= TREE_CHAIN (t
))
1288 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1290 if (ctx
->srecord_type
)
1293 for (t
= TYPE_FIELDS (ctx
->srecord_type
); t
; t
= TREE_CHAIN (t
))
1294 DECL_ABSTRACT_ORIGIN (t
) = NULL
;
1297 if (is_task_ctx (ctx
))
1298 finalize_task_copyfn (ctx
->stmt
);
1303 /* Fix up RECEIVER_DECL with a type that has been remapped to the child
1307 fixup_child_record_type (omp_context
*ctx
)
1309 tree f
, type
= ctx
->record_type
;
1311 /* ??? It isn't sufficient to just call remap_type here, because
1312 variably_modified_type_p doesn't work the way we expect for
1313 record types. Testing each field for whether it needs remapping
1314 and creating a new record by hand works, however. */
1315 for (f
= TYPE_FIELDS (type
); f
; f
= TREE_CHAIN (f
))
1316 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
1320 tree name
, new_fields
= NULL
;
1322 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1323 name
= DECL_NAME (TYPE_NAME (ctx
->record_type
));
1324 name
= build_decl (DECL_SOURCE_LOCATION (ctx
->receiver_decl
),
1325 TYPE_DECL
, name
, type
);
1326 TYPE_NAME (type
) = name
;
1328 for (f
= TYPE_FIELDS (ctx
->record_type
); f
; f
= TREE_CHAIN (f
))
1330 tree new_f
= copy_node (f
);
1331 DECL_CONTEXT (new_f
) = type
;
1332 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &ctx
->cb
);
1333 TREE_CHAIN (new_f
) = new_fields
;
1334 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &ctx
->cb
, NULL
);
1335 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
,
1337 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
1341 /* Arrange to be able to look up the receiver field
1342 given the sender field. */
1343 splay_tree_insert (ctx
->field_map
, (splay_tree_key
) f
,
1344 (splay_tree_value
) new_f
);
1346 TYPE_FIELDS (type
) = nreverse (new_fields
);
1350 TREE_TYPE (ctx
->receiver_decl
) = build_pointer_type (type
);
1353 /* Instantiate decls as necessary in CTX to satisfy the data sharing
1354 specified by CLAUSES. */
1357 scan_sharing_clauses (tree clauses
, omp_context
*ctx
)
1360 bool scan_array_reductions
= false;
1362 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1366 switch (OMP_CLAUSE_CODE (c
))
1368 case OMP_CLAUSE_PRIVATE
:
1369 decl
= OMP_CLAUSE_DECL (c
);
1370 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
1372 else if (!is_variable_sized (decl
))
1373 install_var_local (decl
, ctx
);
1376 case OMP_CLAUSE_SHARED
:
1377 gcc_assert (is_taskreg_ctx (ctx
));
1378 decl
= OMP_CLAUSE_DECL (c
);
1379 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl
))
1380 || !is_variable_sized (decl
));
1381 /* Global variables don't need to be copied,
1382 the receiver side will use them directly. */
1383 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1385 by_ref
= use_pointer_for_field (decl
, ctx
);
1386 if (! TREE_READONLY (decl
)
1387 || TREE_ADDRESSABLE (decl
)
1389 || is_reference (decl
))
1391 install_var_field (decl
, by_ref
, 3, ctx
);
1392 install_var_local (decl
, ctx
);
1395 /* We don't need to copy const scalar vars back. */
1396 OMP_CLAUSE_SET_CODE (c
, OMP_CLAUSE_FIRSTPRIVATE
);
1399 case OMP_CLAUSE_LASTPRIVATE
:
1400 /* Let the corresponding firstprivate clause create
1402 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1406 case OMP_CLAUSE_FIRSTPRIVATE
:
1407 case OMP_CLAUSE_REDUCTION
:
1408 decl
= OMP_CLAUSE_DECL (c
);
1410 if (is_variable_sized (decl
))
1412 if (is_task_ctx (ctx
))
1413 install_var_field (decl
, false, 1, ctx
);
1416 else if (is_taskreg_ctx (ctx
))
1419 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
));
1420 by_ref
= use_pointer_for_field (decl
, NULL
);
1422 if (is_task_ctx (ctx
)
1423 && (global
|| by_ref
|| is_reference (decl
)))
1425 install_var_field (decl
, false, 1, ctx
);
1427 install_var_field (decl
, by_ref
, 2, ctx
);
1430 install_var_field (decl
, by_ref
, 3, ctx
);
1432 install_var_local (decl
, ctx
);
1435 case OMP_CLAUSE_COPYPRIVATE
:
1436 case OMP_CLAUSE_COPYIN
:
1437 decl
= OMP_CLAUSE_DECL (c
);
1438 by_ref
= use_pointer_for_field (decl
, NULL
);
1439 install_var_field (decl
, by_ref
, 3, ctx
);
1442 case OMP_CLAUSE_DEFAULT
:
1443 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_KIND (c
);
1447 case OMP_CLAUSE_NUM_THREADS
:
1448 case OMP_CLAUSE_SCHEDULE
:
1450 scan_omp_op (&OMP_CLAUSE_OPERAND (c
, 0), ctx
->outer
);
1453 case OMP_CLAUSE_NOWAIT
:
1454 case OMP_CLAUSE_ORDERED
:
1455 case OMP_CLAUSE_COLLAPSE
:
1456 case OMP_CLAUSE_UNTIED
:
1464 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1466 switch (OMP_CLAUSE_CODE (c
))
1468 case OMP_CLAUSE_LASTPRIVATE
:
1469 /* Let the corresponding firstprivate clause create
1471 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1472 scan_array_reductions
= true;
1473 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
1477 case OMP_CLAUSE_PRIVATE
:
1478 case OMP_CLAUSE_FIRSTPRIVATE
:
1479 case OMP_CLAUSE_REDUCTION
:
1480 decl
= OMP_CLAUSE_DECL (c
);
1481 if (is_variable_sized (decl
))
1482 install_var_local (decl
, ctx
);
1483 fixup_remapped_decl (decl
, ctx
,
1484 OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_PRIVATE
1485 && OMP_CLAUSE_PRIVATE_DEBUG (c
));
1486 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1487 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1488 scan_array_reductions
= true;
1491 case OMP_CLAUSE_SHARED
:
1492 decl
= OMP_CLAUSE_DECL (c
);
1493 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl
, ctx
)))
1494 fixup_remapped_decl (decl
, ctx
, false);
1497 case OMP_CLAUSE_COPYPRIVATE
:
1498 case OMP_CLAUSE_COPYIN
:
1499 case OMP_CLAUSE_DEFAULT
:
1501 case OMP_CLAUSE_NUM_THREADS
:
1502 case OMP_CLAUSE_SCHEDULE
:
1503 case OMP_CLAUSE_NOWAIT
:
1504 case OMP_CLAUSE_ORDERED
:
1505 case OMP_CLAUSE_COLLAPSE
:
1506 case OMP_CLAUSE_UNTIED
:
1514 if (scan_array_reductions
)
1515 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
1516 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
1517 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
1519 scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
1520 scan_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
1522 else if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
1523 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
1524 scan_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
1527 /* Create a new name for omp child function. Returns an identifier. */
1529 static GTY(()) unsigned int tmp_ompfn_id_num
;
1532 create_omp_child_function_name (bool task_copy
)
1534 tree name
= DECL_ASSEMBLER_NAME (current_function_decl
);
1535 size_t len
= IDENTIFIER_LENGTH (name
);
1536 char *tmp_name
, *prefix
;
1539 suffix
= task_copy
? "_omp_cpyfn" : "_omp_fn";
1540 prefix
= XALLOCAVEC (char, len
+ strlen (suffix
) + 1);
1541 memcpy (prefix
, IDENTIFIER_POINTER (name
), len
);
1542 strcpy (prefix
+ len
, suffix
);
1543 #ifndef NO_DOT_IN_LABEL
1545 #elif !defined NO_DOLLAR_IN_LABEL
1548 ASM_FORMAT_PRIVATE_NAME (tmp_name
, prefix
, tmp_ompfn_id_num
++);
1549 return get_identifier (tmp_name
);
1552 /* Build a decl for the omp child function. It'll not contain a body
1553 yet, just the bare decl. */
1556 create_omp_child_function (omp_context
*ctx
, bool task_copy
)
1558 tree decl
, type
, name
, t
;
1560 name
= create_omp_child_function_name (task_copy
);
1562 type
= build_function_type_list (void_type_node
, ptr_type_node
,
1563 ptr_type_node
, NULL_TREE
);
1565 type
= build_function_type_list (void_type_node
, ptr_type_node
, NULL_TREE
);
1567 decl
= build_decl (gimple_location (ctx
->stmt
),
1568 FUNCTION_DECL
, name
, type
);
1571 ctx
->cb
.dst_fn
= decl
;
1573 gimple_omp_task_set_copy_fn (ctx
->stmt
, decl
);
1575 TREE_STATIC (decl
) = 1;
1576 TREE_USED (decl
) = 1;
1577 DECL_ARTIFICIAL (decl
) = 1;
1578 DECL_IGNORED_P (decl
) = 0;
1579 TREE_PUBLIC (decl
) = 0;
1580 DECL_UNINLINABLE (decl
) = 1;
1581 DECL_EXTERNAL (decl
) = 0;
1582 DECL_CONTEXT (decl
) = NULL_TREE
;
1583 DECL_INITIAL (decl
) = make_node (BLOCK
);
1585 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1586 RESULT_DECL
, NULL_TREE
, void_type_node
);
1587 DECL_ARTIFICIAL (t
) = 1;
1588 DECL_IGNORED_P (t
) = 1;
1589 DECL_CONTEXT (t
) = decl
;
1590 DECL_RESULT (decl
) = t
;
1592 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1593 PARM_DECL
, get_identifier (".omp_data_i"), ptr_type_node
);
1594 DECL_ARTIFICIAL (t
) = 1;
1595 DECL_ARG_TYPE (t
) = ptr_type_node
;
1596 DECL_CONTEXT (t
) = current_function_decl
;
1598 DECL_ARGUMENTS (decl
) = t
;
1600 ctx
->receiver_decl
= t
;
1603 t
= build_decl (DECL_SOURCE_LOCATION (decl
),
1604 PARM_DECL
, get_identifier (".omp_data_o"),
1606 DECL_ARTIFICIAL (t
) = 1;
1607 DECL_ARG_TYPE (t
) = ptr_type_node
;
1608 DECL_CONTEXT (t
) = current_function_decl
;
1610 TREE_ADDRESSABLE (t
) = 1;
1611 TREE_CHAIN (t
) = DECL_ARGUMENTS (decl
);
1612 DECL_ARGUMENTS (decl
) = t
;
1615 /* Allocate memory for the function structure. The call to
1616 allocate_struct_function clobbers CFUN, so we need to restore
1618 push_struct_function (decl
);
1619 cfun
->function_end_locus
= gimple_location (ctx
->stmt
);
1624 /* Scan an OpenMP parallel directive. */
1627 scan_omp_parallel (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1631 gimple stmt
= gsi_stmt (*gsi
);
1633 /* Ignore parallel directives with empty bodies, unless there
1634 are copyin clauses. */
1636 && empty_body_p (gimple_omp_body (stmt
))
1637 && find_omp_clause (gimple_omp_parallel_clauses (stmt
),
1638 OMP_CLAUSE_COPYIN
) == NULL
)
1640 gsi_replace (gsi
, gimple_build_nop (), false);
1644 ctx
= new_omp_context (stmt
, outer_ctx
);
1645 if (taskreg_nesting_level
> 1)
1646 ctx
->is_nested
= true;
1647 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1648 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1649 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1650 name
= create_tmp_var_name (".omp_data_s");
1651 name
= build_decl (gimple_location (stmt
),
1652 TYPE_DECL
, name
, ctx
->record_type
);
1653 TYPE_NAME (ctx
->record_type
) = name
;
1654 create_omp_child_function (ctx
, false);
1655 gimple_omp_parallel_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
1657 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt
), ctx
);
1658 scan_omp (gimple_omp_body (stmt
), ctx
);
1660 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1661 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1664 layout_type (ctx
->record_type
);
1665 fixup_child_record_type (ctx
);
1669 /* Scan an OpenMP task directive. */
1672 scan_omp_task (gimple_stmt_iterator
*gsi
, omp_context
*outer_ctx
)
1676 gimple stmt
= gsi_stmt (*gsi
);
1677 location_t loc
= gimple_location (stmt
);
1679 /* Ignore task directives with empty bodies. */
1681 && empty_body_p (gimple_omp_body (stmt
)))
1683 gsi_replace (gsi
, gimple_build_nop (), false);
1687 ctx
= new_omp_context (stmt
, outer_ctx
);
1688 if (taskreg_nesting_level
> 1)
1689 ctx
->is_nested
= true;
1690 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1691 ctx
->default_kind
= OMP_CLAUSE_DEFAULT_SHARED
;
1692 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1693 name
= create_tmp_var_name (".omp_data_s");
1694 name
= build_decl (gimple_location (stmt
),
1695 TYPE_DECL
, name
, ctx
->record_type
);
1696 TYPE_NAME (ctx
->record_type
) = name
;
1697 create_omp_child_function (ctx
, false);
1698 gimple_omp_task_set_child_fn (stmt
, ctx
->cb
.dst_fn
);
1700 scan_sharing_clauses (gimple_omp_task_clauses (stmt
), ctx
);
1702 if (ctx
->srecord_type
)
1704 name
= create_tmp_var_name (".omp_data_a");
1705 name
= build_decl (gimple_location (stmt
),
1706 TYPE_DECL
, name
, ctx
->srecord_type
);
1707 TYPE_NAME (ctx
->srecord_type
) = name
;
1708 create_omp_child_function (ctx
, true);
1711 scan_omp (gimple_omp_body (stmt
), ctx
);
1713 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1715 ctx
->record_type
= ctx
->receiver_decl
= NULL
;
1716 t
= build_int_cst (long_integer_type_node
, 0);
1717 gimple_omp_task_set_arg_size (stmt
, t
);
1718 t
= build_int_cst (long_integer_type_node
, 1);
1719 gimple_omp_task_set_arg_align (stmt
, t
);
1723 tree
*p
, vla_fields
= NULL_TREE
, *q
= &vla_fields
;
1724 /* Move VLA fields to the end. */
1725 p
= &TYPE_FIELDS (ctx
->record_type
);
1727 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p
))
1728 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p
))))
1731 *p
= TREE_CHAIN (*p
);
1732 TREE_CHAIN (*q
) = NULL_TREE
;
1733 q
= &TREE_CHAIN (*q
);
1736 p
= &TREE_CHAIN (*p
);
1738 layout_type (ctx
->record_type
);
1739 fixup_child_record_type (ctx
);
1740 if (ctx
->srecord_type
)
1741 layout_type (ctx
->srecord_type
);
1742 t
= fold_convert_loc (loc
, long_integer_type_node
,
1743 TYPE_SIZE_UNIT (ctx
->record_type
));
1744 gimple_omp_task_set_arg_size (stmt
, t
);
1745 t
= build_int_cst (long_integer_type_node
,
1746 TYPE_ALIGN_UNIT (ctx
->record_type
));
1747 gimple_omp_task_set_arg_align (stmt
, t
);
1752 /* Scan an OpenMP loop directive. */
1755 scan_omp_for (gimple stmt
, omp_context
*outer_ctx
)
1760 ctx
= new_omp_context (stmt
, outer_ctx
);
1762 scan_sharing_clauses (gimple_omp_for_clauses (stmt
), ctx
);
1764 scan_omp (gimple_omp_for_pre_body (stmt
), ctx
);
1765 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
1767 scan_omp_op (gimple_omp_for_index_ptr (stmt
, i
), ctx
);
1768 scan_omp_op (gimple_omp_for_initial_ptr (stmt
, i
), ctx
);
1769 scan_omp_op (gimple_omp_for_final_ptr (stmt
, i
), ctx
);
1770 scan_omp_op (gimple_omp_for_incr_ptr (stmt
, i
), ctx
);
1772 scan_omp (gimple_omp_body (stmt
), ctx
);
1775 /* Scan an OpenMP sections directive. */
1778 scan_omp_sections (gimple stmt
, omp_context
*outer_ctx
)
1782 ctx
= new_omp_context (stmt
, outer_ctx
);
1783 scan_sharing_clauses (gimple_omp_sections_clauses (stmt
), ctx
);
1784 scan_omp (gimple_omp_body (stmt
), ctx
);
1787 /* Scan an OpenMP single directive. */
1790 scan_omp_single (gimple stmt
, omp_context
*outer_ctx
)
1795 ctx
= new_omp_context (stmt
, outer_ctx
);
1796 ctx
->field_map
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
1797 ctx
->record_type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
1798 name
= create_tmp_var_name (".omp_copy_s");
1799 name
= build_decl (gimple_location (stmt
),
1800 TYPE_DECL
, name
, ctx
->record_type
);
1801 TYPE_NAME (ctx
->record_type
) = name
;
1803 scan_sharing_clauses (gimple_omp_single_clauses (stmt
), ctx
);
1804 scan_omp (gimple_omp_body (stmt
), ctx
);
1806 if (TYPE_FIELDS (ctx
->record_type
) == NULL
)
1807 ctx
->record_type
= NULL
;
1809 layout_type (ctx
->record_type
);
1813 /* Check OpenMP nesting restrictions. */
1815 check_omp_nesting_restrictions (gimple stmt
, omp_context
*ctx
)
1817 switch (gimple_code (stmt
))
1819 case GIMPLE_OMP_FOR
:
1820 case GIMPLE_OMP_SECTIONS
:
1821 case GIMPLE_OMP_SINGLE
:
1823 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1824 switch (gimple_code (ctx
->stmt
))
1826 case GIMPLE_OMP_FOR
:
1827 case GIMPLE_OMP_SECTIONS
:
1828 case GIMPLE_OMP_SINGLE
:
1829 case GIMPLE_OMP_ORDERED
:
1830 case GIMPLE_OMP_MASTER
:
1831 case GIMPLE_OMP_TASK
:
1832 if (is_gimple_call (stmt
))
1834 warning (0, "barrier region may not be closely nested inside "
1835 "of work-sharing, critical, ordered, master or "
1836 "explicit task region");
1839 warning (0, "work-sharing region may not be closely nested inside "
1840 "of work-sharing, critical, ordered, master or explicit "
1843 case GIMPLE_OMP_PARALLEL
:
1849 case GIMPLE_OMP_MASTER
:
1850 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1851 switch (gimple_code (ctx
->stmt
))
1853 case GIMPLE_OMP_FOR
:
1854 case GIMPLE_OMP_SECTIONS
:
1855 case GIMPLE_OMP_SINGLE
:
1856 case GIMPLE_OMP_TASK
:
1857 warning (0, "master region may not be closely nested inside "
1858 "of work-sharing or explicit task region");
1860 case GIMPLE_OMP_PARALLEL
:
1866 case GIMPLE_OMP_ORDERED
:
1867 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1868 switch (gimple_code (ctx
->stmt
))
1870 case GIMPLE_OMP_CRITICAL
:
1871 case GIMPLE_OMP_TASK
:
1872 warning (0, "ordered region may not be closely nested inside "
1873 "of critical or explicit task region");
1875 case GIMPLE_OMP_FOR
:
1876 if (find_omp_clause (gimple_omp_for_clauses (ctx
->stmt
),
1877 OMP_CLAUSE_ORDERED
) == NULL
)
1878 warning (0, "ordered region must be closely nested inside "
1879 "a loop region with an ordered clause");
1881 case GIMPLE_OMP_PARALLEL
:
1887 case GIMPLE_OMP_CRITICAL
:
1888 for (; ctx
!= NULL
; ctx
= ctx
->outer
)
1889 if (gimple_code (ctx
->stmt
) == GIMPLE_OMP_CRITICAL
1890 && (gimple_omp_critical_name (stmt
)
1891 == gimple_omp_critical_name (ctx
->stmt
)))
1893 warning (0, "critical region may not be nested inside a critical "
1894 "region with the same name");
1904 /* Helper function scan_omp.
1906 Callback for walk_tree or operators in walk_gimple_stmt used to
1907 scan for OpenMP directives in TP. */
1910 scan_omp_1_op (tree
*tp
, int *walk_subtrees
, void *data
)
1912 struct walk_stmt_info
*wi
= (struct walk_stmt_info
*) data
;
1913 omp_context
*ctx
= (omp_context
*) wi
->info
;
1916 switch (TREE_CODE (t
))
1923 *tp
= remap_decl (t
, &ctx
->cb
);
1927 if (ctx
&& TYPE_P (t
))
1928 *tp
= remap_type (t
, &ctx
->cb
);
1929 else if (!DECL_P (t
))
1933 TREE_TYPE (t
) = remap_type (TREE_TYPE (t
), &ctx
->cb
);
1942 /* Helper function for scan_omp.
1944 Callback for walk_gimple_stmt used to scan for OpenMP directives in
1945 the current statement in GSI. */
1948 scan_omp_1_stmt (gimple_stmt_iterator
*gsi
, bool *handled_ops_p
,
1949 struct walk_stmt_info
*wi
)
1951 gimple stmt
= gsi_stmt (*gsi
);
1952 omp_context
*ctx
= (omp_context
*) wi
->info
;
1954 if (gimple_has_location (stmt
))
1955 input_location
= gimple_location (stmt
);
1957 /* Check the OpenMP nesting restrictions. */
1960 if (is_gimple_omp (stmt
))
1961 check_omp_nesting_restrictions (stmt
, ctx
);
1962 else if (is_gimple_call (stmt
))
1964 tree fndecl
= gimple_call_fndecl (stmt
);
1965 if (fndecl
&& DECL_BUILT_IN_CLASS (fndecl
) == BUILT_IN_NORMAL
1966 && DECL_FUNCTION_CODE (fndecl
) == BUILT_IN_GOMP_BARRIER
)
1967 check_omp_nesting_restrictions (stmt
, ctx
);
1971 *handled_ops_p
= true;
1973 switch (gimple_code (stmt
))
1975 case GIMPLE_OMP_PARALLEL
:
1976 taskreg_nesting_level
++;
1977 scan_omp_parallel (gsi
, ctx
);
1978 taskreg_nesting_level
--;
1981 case GIMPLE_OMP_TASK
:
1982 taskreg_nesting_level
++;
1983 scan_omp_task (gsi
, ctx
);
1984 taskreg_nesting_level
--;
1987 case GIMPLE_OMP_FOR
:
1988 scan_omp_for (stmt
, ctx
);
1991 case GIMPLE_OMP_SECTIONS
:
1992 scan_omp_sections (stmt
, ctx
);
1995 case GIMPLE_OMP_SINGLE
:
1996 scan_omp_single (stmt
, ctx
);
1999 case GIMPLE_OMP_SECTION
:
2000 case GIMPLE_OMP_MASTER
:
2001 case GIMPLE_OMP_ORDERED
:
2002 case GIMPLE_OMP_CRITICAL
:
2003 ctx
= new_omp_context (stmt
, ctx
);
2004 scan_omp (gimple_omp_body (stmt
), ctx
);
2011 *handled_ops_p
= false;
2013 for (var
= gimple_bind_vars (stmt
); var
; var
= TREE_CHAIN (var
))
2014 insert_decl_map (&ctx
->cb
, var
, var
);
2018 *handled_ops_p
= false;
2026 /* Scan all the statements starting at the current statement. CTX
2027 contains context information about the OpenMP directives and
2028 clauses found during the scan. */
2031 scan_omp (gimple_seq body
, omp_context
*ctx
)
2033 location_t saved_location
;
2034 struct walk_stmt_info wi
;
2036 memset (&wi
, 0, sizeof (wi
));
2038 wi
.want_locations
= true;
2040 saved_location
= input_location
;
2041 walk_gimple_seq (body
, scan_omp_1_stmt
, scan_omp_1_op
, &wi
);
2042 input_location
= saved_location
;
2045 /* Re-gimplification and code generation routines. */
2047 /* Build a call to GOMP_barrier. */
2050 build_omp_barrier (void)
2052 return build_call_expr (built_in_decls
[BUILT_IN_GOMP_BARRIER
], 0);
2055 /* If a context was created for STMT when it was scanned, return it. */
2057 static omp_context
*
2058 maybe_lookup_ctx (gimple stmt
)
2061 n
= splay_tree_lookup (all_contexts
, (splay_tree_key
) stmt
);
2062 return n
? (omp_context
*) n
->value
: NULL
;
2066 /* Find the mapping for DECL in CTX or the immediately enclosing
2067 context that has a mapping for DECL.
2069 If CTX is a nested parallel directive, we may have to use the decl
2070 mappings created in CTX's parent context. Suppose that we have the
2071 following parallel nesting (variable UIDs showed for clarity):
2074 #omp parallel shared(iD.1562) -> outer parallel
2075 iD.1562 = iD.1562 + 1;
2077 #omp parallel shared (iD.1562) -> inner parallel
2078 iD.1562 = iD.1562 - 1;
2080 Each parallel structure will create a distinct .omp_data_s structure
2081 for copying iD.1562 in/out of the directive:
2083 outer parallel .omp_data_s.1.i -> iD.1562
2084 inner parallel .omp_data_s.2.i -> iD.1562
2086 A shared variable mapping will produce a copy-out operation before
2087 the parallel directive and a copy-in operation after it. So, in
2088 this case we would have:
2091 .omp_data_o.1.i = iD.1562;
2092 #omp parallel shared(iD.1562) -> outer parallel
2093 .omp_data_i.1 = &.omp_data_o.1
2094 .omp_data_i.1->i = .omp_data_i.1->i + 1;
2096 .omp_data_o.2.i = iD.1562; -> **
2097 #omp parallel shared(iD.1562) -> inner parallel
2098 .omp_data_i.2 = &.omp_data_o.2
2099 .omp_data_i.2->i = .omp_data_i.2->i - 1;
2102 ** This is a problem. The symbol iD.1562 cannot be referenced
2103 inside the body of the outer parallel region. But since we are
2104 emitting this copy operation while expanding the inner parallel
2105 directive, we need to access the CTX structure of the outer
2106 parallel directive to get the correct mapping:
2108 .omp_data_o.2.i = .omp_data_i.1->i
2110 Since there may be other workshare or parallel directives enclosing
2111 the parallel directive, it may be necessary to walk up the context
2112 parent chain. This is not a problem in general because nested
2113 parallelism happens only rarely. */
2116 lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2121 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2122 t
= maybe_lookup_decl (decl
, up
);
2124 gcc_assert (!ctx
->is_nested
|| t
|| is_global_var (decl
));
2126 return t
? t
: decl
;
2130 /* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
2131 in outer contexts. */
2134 maybe_lookup_decl_in_outer_ctx (tree decl
, omp_context
*ctx
)
2139 for (up
= ctx
->outer
, t
= NULL
; up
&& t
== NULL
; up
= up
->outer
)
2140 t
= maybe_lookup_decl (decl
, up
);
2142 return t
? t
: decl
;
2146 /* Construct the initialization value for reduction CLAUSE. */
2149 omp_reduction_init (tree clause
, tree type
)
2151 location_t loc
= OMP_CLAUSE_LOCATION (clause
);
2152 switch (OMP_CLAUSE_REDUCTION_CODE (clause
))
2159 case TRUTH_ORIF_EXPR
:
2160 case TRUTH_XOR_EXPR
:
2162 return fold_convert_loc (loc
, type
, integer_zero_node
);
2165 case TRUTH_AND_EXPR
:
2166 case TRUTH_ANDIF_EXPR
:
2168 return fold_convert_loc (loc
, type
, integer_one_node
);
2171 return fold_convert_loc (loc
, type
, integer_minus_one_node
);
2174 if (SCALAR_FLOAT_TYPE_P (type
))
2176 REAL_VALUE_TYPE max
, min
;
2177 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2180 real_arithmetic (&min
, NEGATE_EXPR
, &max
, NULL
);
2183 real_maxval (&min
, 1, TYPE_MODE (type
));
2184 return build_real (type
, min
);
2188 gcc_assert (INTEGRAL_TYPE_P (type
));
2189 return TYPE_MIN_VALUE (type
);
2193 if (SCALAR_FLOAT_TYPE_P (type
))
2195 REAL_VALUE_TYPE max
;
2196 if (HONOR_INFINITIES (TYPE_MODE (type
)))
2199 real_maxval (&max
, 0, TYPE_MODE (type
));
2200 return build_real (type
, max
);
2204 gcc_assert (INTEGRAL_TYPE_P (type
));
2205 return TYPE_MAX_VALUE (type
);
2213 /* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
2214 from the receiver (aka child) side and initializers for REFERENCE_TYPE
2215 private variables. Initialization statements go in ILIST, while calls
2216 to destructors go in DLIST. */
2219 lower_rec_input_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*dlist
,
2222 gimple_stmt_iterator diter
;
2223 tree c
, dtor
, copyin_seq
, x
, ptr
;
2224 bool copyin_by_ref
= false;
2225 bool lastprivate_firstprivate
= false;
2228 *dlist
= gimple_seq_alloc ();
2229 diter
= gsi_start (*dlist
);
2232 /* Do all the fixed sized types in the first pass, and the variable sized
2233 types in the second pass. This makes sure that the scalar arguments to
2234 the variable sized types are processed before we use them in the
2235 variable sized operations. */
2236 for (pass
= 0; pass
< 2; ++pass
)
2238 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2240 enum omp_clause_code c_kind
= OMP_CLAUSE_CODE (c
);
2243 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2247 case OMP_CLAUSE_PRIVATE
:
2248 if (OMP_CLAUSE_PRIVATE_DEBUG (c
))
2251 case OMP_CLAUSE_SHARED
:
2252 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c
), ctx
) == NULL
)
2254 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c
)));
2257 case OMP_CLAUSE_FIRSTPRIVATE
:
2258 case OMP_CLAUSE_COPYIN
:
2259 case OMP_CLAUSE_REDUCTION
:
2261 case OMP_CLAUSE_LASTPRIVATE
:
2262 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2264 lastprivate_firstprivate
= true;
2273 new_var
= var
= OMP_CLAUSE_DECL (c
);
2274 if (c_kind
!= OMP_CLAUSE_COPYIN
)
2275 new_var
= lookup_decl (var
, ctx
);
2277 if (c_kind
== OMP_CLAUSE_SHARED
|| c_kind
== OMP_CLAUSE_COPYIN
)
2282 else if (is_variable_sized (var
))
2284 /* For variable sized types, we need to allocate the
2285 actual storage here. Call alloca and store the
2286 result in the pointer decl that we created elsewhere. */
2290 if (c_kind
!= OMP_CLAUSE_FIRSTPRIVATE
|| !is_task_ctx (ctx
))
2295 ptr
= DECL_VALUE_EXPR (new_var
);
2296 gcc_assert (TREE_CODE (ptr
) == INDIRECT_REF
);
2297 ptr
= TREE_OPERAND (ptr
, 0);
2298 gcc_assert (DECL_P (ptr
));
2299 x
= TYPE_SIZE_UNIT (TREE_TYPE (new_var
));
2301 /* void *tmp = __builtin_alloca */
2303 = gimple_build_call (built_in_decls
[BUILT_IN_ALLOCA
], 1, x
);
2304 tmp
= create_tmp_var_raw (ptr_type_node
, NULL
);
2305 gimple_add_tmp_var (tmp
);
2306 gimple_call_set_lhs (stmt
, tmp
);
2308 gimple_seq_add_stmt (ilist
, stmt
);
2310 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ptr
), tmp
);
2311 gimplify_assign (ptr
, x
, ilist
);
2314 else if (is_reference (var
))
2316 /* For references that are being privatized for Fortran,
2317 allocate new backing storage for the new pointer
2318 variable. This allows us to avoid changing all the
2319 code that expects a pointer to something that expects
2320 a direct variable. Note that this doesn't apply to
2321 C++, since reference types are disallowed in data
2322 sharing clauses there, except for NRV optimized
2327 x
= TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var
)));
2328 if (c_kind
== OMP_CLAUSE_FIRSTPRIVATE
&& is_task_ctx (ctx
))
2330 x
= build_receiver_ref (var
, false, ctx
);
2331 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2333 else if (TREE_CONSTANT (x
))
2335 const char *name
= NULL
;
2336 if (DECL_NAME (var
))
2337 name
= IDENTIFIER_POINTER (DECL_NAME (new_var
));
2339 x
= create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var
)),
2341 gimple_add_tmp_var (x
);
2342 TREE_ADDRESSABLE (x
) = 1;
2343 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2347 x
= build_call_expr_loc (clause_loc
,
2348 built_in_decls
[BUILT_IN_ALLOCA
], 1, x
);
2351 x
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), x
);
2352 gimplify_assign (new_var
, x
, ilist
);
2354 new_var
= build_fold_indirect_ref_loc (clause_loc
, new_var
);
2356 else if (c_kind
== OMP_CLAUSE_REDUCTION
2357 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2365 switch (OMP_CLAUSE_CODE (c
))
2367 case OMP_CLAUSE_SHARED
:
2368 /* Shared global vars are just accessed directly. */
2369 if (is_global_var (new_var
))
2371 /* Set up the DECL_VALUE_EXPR for shared variables now. This
2372 needs to be delayed until after fixup_child_record_type so
2373 that we get the correct type during the dereference. */
2374 by_ref
= use_pointer_for_field (var
, ctx
);
2375 x
= build_receiver_ref (var
, by_ref
, ctx
);
2376 SET_DECL_VALUE_EXPR (new_var
, x
);
2377 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2379 /* ??? If VAR is not passed by reference, and the variable
2380 hasn't been initialized yet, then we'll get a warning for
2381 the store into the omp_data_s structure. Ideally, we'd be
2382 able to notice this and not store anything at all, but
2383 we're generating code too early. Suppress the warning. */
2385 TREE_NO_WARNING (var
) = 1;
2388 case OMP_CLAUSE_LASTPRIVATE
:
2389 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2393 case OMP_CLAUSE_PRIVATE
:
2394 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_PRIVATE
)
2395 x
= build_outer_var_ref (var
, ctx
);
2396 else if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
2398 if (is_task_ctx (ctx
))
2399 x
= build_receiver_ref (var
, false, ctx
);
2401 x
= build_outer_var_ref (var
, ctx
);
2405 x
= lang_hooks
.decls
.omp_clause_default_ctor (c
, new_var
, x
);
2407 gimplify_and_add (x
, ilist
);
2411 x
= lang_hooks
.decls
.omp_clause_dtor (c
, new_var
);
2414 gimple_seq tseq
= NULL
;
2417 gimplify_stmt (&dtor
, &tseq
);
2418 gsi_insert_seq_before (&diter
, tseq
, GSI_SAME_STMT
);
2422 case OMP_CLAUSE_FIRSTPRIVATE
:
2423 if (is_task_ctx (ctx
))
2425 if (is_reference (var
) || is_variable_sized (var
))
2427 else if (is_global_var (maybe_lookup_decl_in_outer_ctx (var
,
2429 || use_pointer_for_field (var
, NULL
))
2431 x
= build_receiver_ref (var
, false, ctx
);
2432 SET_DECL_VALUE_EXPR (new_var
, x
);
2433 DECL_HAS_VALUE_EXPR_P (new_var
) = 1;
2437 x
= build_outer_var_ref (var
, ctx
);
2438 x
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, new_var
, x
);
2439 gimplify_and_add (x
, ilist
);
2443 case OMP_CLAUSE_COPYIN
:
2444 by_ref
= use_pointer_for_field (var
, NULL
);
2445 x
= build_receiver_ref (var
, by_ref
, ctx
);
2446 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, x
);
2447 append_to_statement_list (x
, ©in_seq
);
2448 copyin_by_ref
|= by_ref
;
2451 case OMP_CLAUSE_REDUCTION
:
2452 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2454 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
2455 x
= build_outer_var_ref (var
, ctx
);
2457 if (is_reference (var
))
2458 x
= build_fold_addr_expr_loc (clause_loc
, x
);
2459 SET_DECL_VALUE_EXPR (placeholder
, x
);
2460 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
2461 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
), ctx
);
2462 gimple_seq_add_seq (ilist
,
2463 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
));
2464 OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c
) = NULL
;
2465 DECL_HAS_VALUE_EXPR_P (placeholder
) = 0;
2469 x
= omp_reduction_init (c
, TREE_TYPE (new_var
));
2470 gcc_assert (TREE_CODE (TREE_TYPE (new_var
)) != ARRAY_TYPE
);
2471 gimplify_assign (new_var
, x
, ilist
);
2481 /* The copyin sequence is not to be executed by the main thread, since
2482 that would result in self-copies. Perhaps not visible to scalars,
2483 but it certainly is to C++ operator=. */
2486 x
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
2487 x
= build2 (NE_EXPR
, boolean_type_node
, x
,
2488 build_int_cst (TREE_TYPE (x
), 0));
2489 x
= build3 (COND_EXPR
, void_type_node
, x
, copyin_seq
, NULL
);
2490 gimplify_and_add (x
, ilist
);
2493 /* If any copyin variable is passed by reference, we must ensure the
2494 master thread doesn't modify it before it is copied over in all
2495 threads. Similarly for variables in both firstprivate and
2496 lastprivate clauses we need to ensure the lastprivate copying
2497 happens after firstprivate copying in all threads. */
2498 if (copyin_by_ref
|| lastprivate_firstprivate
)
2499 gimplify_and_add (build_omp_barrier (), ilist
);
2503 /* Generate code to implement the LASTPRIVATE clauses. This is used for
2504 both parallel and workshare constructs. PREDICATE may be NULL if it's
2508 lower_lastprivate_clauses (tree clauses
, tree predicate
, gimple_seq
*stmt_list
,
2511 tree x
, c
, label
= NULL
;
2512 bool par_clauses
= false;
2514 /* Early exit if there are no lastprivate clauses. */
2515 clauses
= find_omp_clause (clauses
, OMP_CLAUSE_LASTPRIVATE
);
2516 if (clauses
== NULL
)
2518 /* If this was a workshare clause, see if it had been combined
2519 with its parallel. In that case, look for the clauses on the
2520 parallel statement itself. */
2521 if (is_parallel_ctx (ctx
))
2525 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
2528 clauses
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
2529 OMP_CLAUSE_LASTPRIVATE
);
2530 if (clauses
== NULL
)
2538 tree label_true
, arm1
, arm2
;
2540 label
= create_artificial_label (UNKNOWN_LOCATION
);
2541 label_true
= create_artificial_label (UNKNOWN_LOCATION
);
2542 arm1
= TREE_OPERAND (predicate
, 0);
2543 arm2
= TREE_OPERAND (predicate
, 1);
2544 gimplify_expr (&arm1
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
2545 gimplify_expr (&arm2
, stmt_list
, NULL
, is_gimple_val
, fb_rvalue
);
2546 stmt
= gimple_build_cond (TREE_CODE (predicate
), arm1
, arm2
,
2548 gimple_seq_add_stmt (stmt_list
, stmt
);
2549 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label_true
));
2552 for (c
= clauses
; c
;)
2555 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2557 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_LASTPRIVATE
)
2559 var
= OMP_CLAUSE_DECL (c
);
2560 new_var
= lookup_decl (var
, ctx
);
2562 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
))
2564 lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
), ctx
);
2565 gimple_seq_add_seq (stmt_list
,
2566 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
));
2568 OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c
) = NULL
;
2570 x
= build_outer_var_ref (var
, ctx
);
2571 if (is_reference (var
))
2572 new_var
= build_fold_indirect_ref_loc (clause_loc
, new_var
);
2573 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, x
, new_var
);
2574 gimplify_and_add (x
, stmt_list
);
2576 c
= OMP_CLAUSE_CHAIN (c
);
2577 if (c
== NULL
&& !par_clauses
)
2579 /* If this was a workshare clause, see if it had been combined
2580 with its parallel. In that case, continue looking for the
2581 clauses also on the parallel statement itself. */
2582 if (is_parallel_ctx (ctx
))
2586 if (ctx
== NULL
|| !is_parallel_ctx (ctx
))
2589 c
= find_omp_clause (gimple_omp_parallel_clauses (ctx
->stmt
),
2590 OMP_CLAUSE_LASTPRIVATE
);
2596 gimple_seq_add_stmt (stmt_list
, gimple_build_label (label
));
2600 /* Generate code to implement the REDUCTION clauses. */
2603 lower_reduction_clauses (tree clauses
, gimple_seq
*stmt_seqp
, omp_context
*ctx
)
2605 gimple_seq sub_seq
= NULL
;
2610 /* First see if there is exactly one reduction clause. Use OMP_ATOMIC
2611 update in that case, otherwise use a lock. */
2612 for (c
= clauses
; c
&& count
< 2; c
= OMP_CLAUSE_CHAIN (c
))
2613 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_REDUCTION
)
2615 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2617 /* Never use OMP_ATOMIC for array reductions. */
2627 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2629 tree var
, ref
, new_var
;
2630 enum tree_code code
;
2631 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2633 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_REDUCTION
)
2636 var
= OMP_CLAUSE_DECL (c
);
2637 new_var
= lookup_decl (var
, ctx
);
2638 if (is_reference (var
))
2639 new_var
= build_fold_indirect_ref_loc (clause_loc
, new_var
);
2640 ref
= build_outer_var_ref (var
, ctx
);
2641 code
= OMP_CLAUSE_REDUCTION_CODE (c
);
2643 /* reduction(-:var) sums up the partial results, so it acts
2644 identically to reduction(+:var). */
2645 if (code
== MINUS_EXPR
)
2650 tree addr
= build_fold_addr_expr_loc (clause_loc
, ref
);
2652 addr
= save_expr (addr
);
2653 ref
= build1 (INDIRECT_REF
, TREE_TYPE (TREE_TYPE (addr
)), addr
);
2654 x
= fold_build2_loc (clause_loc
, code
, TREE_TYPE (ref
), ref
, new_var
);
2655 x
= build2 (OMP_ATOMIC
, void_type_node
, addr
, x
);
2656 gimplify_and_add (x
, stmt_seqp
);
2660 if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
))
2662 tree placeholder
= OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
);
2664 if (is_reference (var
))
2665 ref
= build_fold_addr_expr_loc (clause_loc
, ref
);
2666 SET_DECL_VALUE_EXPR (placeholder
, ref
);
2667 DECL_HAS_VALUE_EXPR_P (placeholder
) = 1;
2668 lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
), ctx
);
2669 gimple_seq_add_seq (&sub_seq
, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
));
2670 OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c
) = NULL
;
2671 OMP_CLAUSE_REDUCTION_PLACEHOLDER (c
) = NULL
;
2675 x
= build2 (code
, TREE_TYPE (ref
), ref
, new_var
);
2676 ref
= build_outer_var_ref (var
, ctx
);
2677 gimplify_assign (ref
, x
, &sub_seq
);
2681 stmt
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_ATOMIC_START
], 0);
2682 gimple_seq_add_stmt (stmt_seqp
, stmt
);
2684 gimple_seq_add_seq (stmt_seqp
, sub_seq
);
2686 stmt
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_ATOMIC_END
], 0);
2687 gimple_seq_add_stmt (stmt_seqp
, stmt
);
2691 /* Generate code to implement the COPYPRIVATE clauses. */
2694 lower_copyprivate_clauses (tree clauses
, gimple_seq
*slist
, gimple_seq
*rlist
,
2699 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2701 tree var
, new_var
, ref
, x
;
2703 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2705 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYPRIVATE
)
2708 var
= OMP_CLAUSE_DECL (c
);
2709 by_ref
= use_pointer_for_field (var
, NULL
);
2711 ref
= build_sender_ref (var
, ctx
);
2712 x
= new_var
= lookup_decl_in_outer_ctx (var
, ctx
);
2715 x
= build_fold_addr_expr_loc (clause_loc
, new_var
);
2716 x
= fold_convert_loc (clause_loc
, TREE_TYPE (ref
), x
);
2718 gimplify_assign (ref
, x
, slist
);
2720 ref
= build_receiver_ref (var
, false, ctx
);
2723 ref
= fold_convert_loc (clause_loc
,
2724 build_pointer_type (TREE_TYPE (new_var
)),
2726 ref
= build_fold_indirect_ref_loc (clause_loc
, ref
);
2728 if (is_reference (var
))
2730 ref
= fold_convert_loc (clause_loc
, TREE_TYPE (new_var
), ref
);
2731 ref
= build_fold_indirect_ref_loc (clause_loc
, ref
);
2732 new_var
= build_fold_indirect_ref_loc (clause_loc
, new_var
);
2734 x
= lang_hooks
.decls
.omp_clause_assign_op (c
, new_var
, ref
);
2735 gimplify_and_add (x
, rlist
);
2740 /* Generate code to implement the clauses, FIRSTPRIVATE, COPYIN, LASTPRIVATE,
2741 and REDUCTION from the sender (aka parent) side. */
2744 lower_send_clauses (tree clauses
, gimple_seq
*ilist
, gimple_seq
*olist
,
2749 for (c
= clauses
; c
; c
= OMP_CLAUSE_CHAIN (c
))
2751 tree val
, ref
, x
, var
;
2752 bool by_ref
, do_in
= false, do_out
= false;
2753 location_t clause_loc
= OMP_CLAUSE_LOCATION (c
);
2755 switch (OMP_CLAUSE_CODE (c
))
2757 case OMP_CLAUSE_PRIVATE
:
2758 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
2761 case OMP_CLAUSE_FIRSTPRIVATE
:
2762 case OMP_CLAUSE_COPYIN
:
2763 case OMP_CLAUSE_LASTPRIVATE
:
2764 case OMP_CLAUSE_REDUCTION
:
2770 val
= OMP_CLAUSE_DECL (c
);
2771 var
= lookup_decl_in_outer_ctx (val
, ctx
);
2773 if (OMP_CLAUSE_CODE (c
) != OMP_CLAUSE_COPYIN
2774 && is_global_var (var
))
2776 if (is_variable_sized (val
))
2778 by_ref
= use_pointer_for_field (val
, NULL
);
2780 switch (OMP_CLAUSE_CODE (c
))
2782 case OMP_CLAUSE_PRIVATE
:
2783 case OMP_CLAUSE_FIRSTPRIVATE
:
2784 case OMP_CLAUSE_COPYIN
:
2788 case OMP_CLAUSE_LASTPRIVATE
:
2789 if (by_ref
|| is_reference (val
))
2791 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c
))
2798 if (lang_hooks
.decls
.omp_private_outer_ref (val
))
2803 case OMP_CLAUSE_REDUCTION
:
2805 do_out
= !(by_ref
|| is_reference (val
));
2814 ref
= build_sender_ref (val
, ctx
);
2815 x
= by_ref
? build_fold_addr_expr_loc (clause_loc
, var
) : var
;
2816 gimplify_assign (ref
, x
, ilist
);
2817 if (is_task_ctx (ctx
))
2818 DECL_ABSTRACT_ORIGIN (TREE_OPERAND (ref
, 1)) = NULL
;
2823 ref
= build_sender_ref (val
, ctx
);
2824 gimplify_assign (var
, ref
, olist
);
2829 /* Generate code to implement SHARED from the sender (aka parent)
2830 side. This is trickier, since GIMPLE_OMP_PARALLEL_CLAUSES doesn't
2831 list things that got automatically shared. */
2834 lower_send_shared_vars (gimple_seq
*ilist
, gimple_seq
*olist
, omp_context
*ctx
)
2836 tree var
, ovar
, nvar
, f
, x
, record_type
;
2838 if (ctx
->record_type
== NULL
)
2841 record_type
= ctx
->srecord_type
? ctx
->srecord_type
: ctx
->record_type
;
2842 for (f
= TYPE_FIELDS (record_type
); f
; f
= TREE_CHAIN (f
))
2844 ovar
= DECL_ABSTRACT_ORIGIN (f
);
2845 nvar
= maybe_lookup_decl (ovar
, ctx
);
2846 if (!nvar
|| !DECL_HAS_VALUE_EXPR_P (nvar
))
2849 /* If CTX is a nested parallel directive. Find the immediately
2850 enclosing parallel or workshare construct that contains a
2851 mapping for OVAR. */
2852 var
= lookup_decl_in_outer_ctx (ovar
, ctx
);
2854 if (use_pointer_for_field (ovar
, ctx
))
2856 x
= build_sender_ref (ovar
, ctx
);
2857 var
= build_fold_addr_expr (var
);
2858 gimplify_assign (x
, var
, ilist
);
2862 x
= build_sender_ref (ovar
, ctx
);
2863 gimplify_assign (x
, var
, ilist
);
2865 if (!TREE_READONLY (var
)
2866 /* We don't need to receive a new reference to a result
2867 or parm decl. In fact we may not store to it as we will
2868 invalidate any pending RSO and generate wrong gimple
2870 && !((TREE_CODE (var
) == RESULT_DECL
2871 || TREE_CODE (var
) == PARM_DECL
)
2872 && DECL_BY_REFERENCE (var
)))
2874 x
= build_sender_ref (ovar
, ctx
);
2875 gimplify_assign (var
, x
, olist
);
2882 /* A convenience function to build an empty GIMPLE_COND with just the
2886 gimple_build_cond_empty (tree cond
)
2888 enum tree_code pred_code
;
2891 gimple_cond_get_ops_from_tree (cond
, &pred_code
, &lhs
, &rhs
);
2892 return gimple_build_cond (pred_code
, lhs
, rhs
, NULL_TREE
, NULL_TREE
);
2896 /* Build the function calls to GOMP_parallel_start etc to actually
2897 generate the parallel operation. REGION is the parallel region
2898 being expanded. BB is the block where to insert the code. WS_ARGS
2899 will be set if this is a call to a combined parallel+workshare
2900 construct, it contains the list of additional arguments needed by
2901 the workshare construct. */
2904 expand_parallel_call (struct omp_region
*region
, basic_block bb
,
2905 gimple entry_stmt
, tree ws_args
)
2907 tree t
, t1
, t2
, val
, cond
, c
, clauses
;
2908 gimple_stmt_iterator gsi
;
2911 location_t clause_loc
;
2913 clauses
= gimple_omp_parallel_clauses (entry_stmt
);
2915 /* Determine what flavor of GOMP_parallel_start we will be
2917 start_ix
= BUILT_IN_GOMP_PARALLEL_START
;
2918 if (is_combined_parallel (region
))
2920 switch (region
->inner
->type
)
2922 case GIMPLE_OMP_FOR
:
2923 gcc_assert (region
->inner
->sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
2924 start_ix
= BUILT_IN_GOMP_PARALLEL_LOOP_STATIC_START
2925 + (region
->inner
->sched_kind
2926 == OMP_CLAUSE_SCHEDULE_RUNTIME
2927 ? 3 : region
->inner
->sched_kind
);
2929 case GIMPLE_OMP_SECTIONS
:
2930 start_ix
= BUILT_IN_GOMP_PARALLEL_SECTIONS_START
;
2937 /* By default, the value of NUM_THREADS is zero (selected at run time)
2938 and there is no conditional. */
2940 val
= build_int_cst (unsigned_type_node
, 0);
2942 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
2944 cond
= OMP_CLAUSE_IF_EXPR (c
);
2946 c
= find_omp_clause (clauses
, OMP_CLAUSE_NUM_THREADS
);
2949 val
= OMP_CLAUSE_NUM_THREADS_EXPR (c
);
2950 clause_loc
= OMP_CLAUSE_LOCATION (c
);
2953 clause_loc
= gimple_location (entry_stmt
);
2955 /* Ensure 'val' is of the correct type. */
2956 val
= fold_convert_loc (clause_loc
, unsigned_type_node
, val
);
2958 /* If we found the clause 'if (cond)', build either
2959 (cond != 0) or (cond ? val : 1u). */
2962 gimple_stmt_iterator gsi
;
2964 cond
= gimple_boolify (cond
);
2966 if (integer_zerop (val
))
2967 val
= fold_build2_loc (clause_loc
,
2968 EQ_EXPR
, unsigned_type_node
, cond
,
2969 build_int_cst (TREE_TYPE (cond
), 0));
2972 basic_block cond_bb
, then_bb
, else_bb
;
2973 edge e
, e_then
, e_else
;
2974 tree tmp_then
, tmp_else
, tmp_join
, tmp_var
;
2976 tmp_var
= create_tmp_var (TREE_TYPE (val
), NULL
);
2977 if (gimple_in_ssa_p (cfun
))
2979 tmp_then
= make_ssa_name (tmp_var
, NULL
);
2980 tmp_else
= make_ssa_name (tmp_var
, NULL
);
2981 tmp_join
= make_ssa_name (tmp_var
, NULL
);
2990 e
= split_block (bb
, NULL
);
2995 then_bb
= create_empty_bb (cond_bb
);
2996 else_bb
= create_empty_bb (then_bb
);
2997 set_immediate_dominator (CDI_DOMINATORS
, then_bb
, cond_bb
);
2998 set_immediate_dominator (CDI_DOMINATORS
, else_bb
, cond_bb
);
3000 stmt
= gimple_build_cond_empty (cond
);
3001 gsi
= gsi_start_bb (cond_bb
);
3002 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3004 gsi
= gsi_start_bb (then_bb
);
3005 stmt
= gimple_build_assign (tmp_then
, val
);
3006 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3008 gsi
= gsi_start_bb (else_bb
);
3009 stmt
= gimple_build_assign
3010 (tmp_else
, build_int_cst (unsigned_type_node
, 1));
3011 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3013 make_edge (cond_bb
, then_bb
, EDGE_TRUE_VALUE
);
3014 make_edge (cond_bb
, else_bb
, EDGE_FALSE_VALUE
);
3015 e_then
= make_edge (then_bb
, bb
, EDGE_FALLTHRU
);
3016 e_else
= make_edge (else_bb
, bb
, EDGE_FALLTHRU
);
3018 if (gimple_in_ssa_p (cfun
))
3020 gimple phi
= create_phi_node (tmp_join
, bb
);
3021 SSA_NAME_DEF_STMT (tmp_join
) = phi
;
3022 add_phi_arg (phi
, tmp_then
, e_then
, UNKNOWN_LOCATION
);
3023 add_phi_arg (phi
, tmp_else
, e_else
, UNKNOWN_LOCATION
);
3029 gsi
= gsi_start_bb (bb
);
3030 val
= force_gimple_operand_gsi (&gsi
, val
, true, NULL_TREE
,
3031 false, GSI_CONTINUE_LINKING
);
3034 gsi
= gsi_last_bb (bb
);
3035 t
= gimple_omp_parallel_data_arg (entry_stmt
);
3037 t1
= null_pointer_node
;
3039 t1
= build_fold_addr_expr (t
);
3040 t2
= build_fold_addr_expr (gimple_omp_parallel_child_fn (entry_stmt
));
3044 tree args
= tree_cons (NULL
, t2
,
3045 tree_cons (NULL
, t1
,
3046 tree_cons (NULL
, val
, ws_args
)));
3047 t
= build_function_call_expr (UNKNOWN_LOCATION
,
3048 built_in_decls
[start_ix
], args
);
3051 t
= build_call_expr (built_in_decls
[start_ix
], 3, t2
, t1
, val
);
3053 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3054 false, GSI_CONTINUE_LINKING
);
3056 t
= gimple_omp_parallel_data_arg (entry_stmt
);
3058 t
= null_pointer_node
;
3060 t
= build_fold_addr_expr (t
);
3061 t
= build_call_expr_loc (gimple_location (entry_stmt
),
3062 gimple_omp_parallel_child_fn (entry_stmt
), 1, t
);
3063 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3064 false, GSI_CONTINUE_LINKING
);
3066 t
= build_call_expr_loc (gimple_location (entry_stmt
),
3067 built_in_decls
[BUILT_IN_GOMP_PARALLEL_END
], 0);
3068 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3069 false, GSI_CONTINUE_LINKING
);
3073 /* Build the function call to GOMP_task to actually
3074 generate the task operation. BB is the block where to insert the code. */
3077 expand_task_call (basic_block bb
, gimple entry_stmt
)
3079 tree t
, t1
, t2
, t3
, flags
, cond
, c
, clauses
;
3080 gimple_stmt_iterator gsi
;
3081 location_t loc
= gimple_location (entry_stmt
);
3083 clauses
= gimple_omp_task_clauses (entry_stmt
);
3085 c
= find_omp_clause (clauses
, OMP_CLAUSE_IF
);
3087 cond
= gimple_boolify (OMP_CLAUSE_IF_EXPR (c
));
3089 cond
= boolean_true_node
;
3091 c
= find_omp_clause (clauses
, OMP_CLAUSE_UNTIED
);
3092 flags
= build_int_cst (unsigned_type_node
, (c
? 1 : 0));
3094 gsi
= gsi_last_bb (bb
);
3095 t
= gimple_omp_task_data_arg (entry_stmt
);
3097 t2
= null_pointer_node
;
3099 t2
= build_fold_addr_expr_loc (loc
, t
);
3100 t1
= build_fold_addr_expr_loc (loc
, gimple_omp_task_child_fn (entry_stmt
));
3101 t
= gimple_omp_task_copy_fn (entry_stmt
);
3103 t3
= null_pointer_node
;
3105 t3
= build_fold_addr_expr_loc (loc
, t
);
3107 t
= build_call_expr (built_in_decls
[BUILT_IN_GOMP_TASK
], 7, t1
, t2
, t3
,
3108 gimple_omp_task_arg_size (entry_stmt
),
3109 gimple_omp_task_arg_align (entry_stmt
), cond
, flags
);
3111 force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3112 false, GSI_CONTINUE_LINKING
);
3116 /* If exceptions are enabled, wrap the statements in BODY in a MUST_NOT_THROW
3117 catch handler and return it. This prevents programs from violating the
3118 structured block semantics with throws. */
3121 maybe_catch_exception (gimple_seq body
)
3126 if (!flag_exceptions
)
3129 if (lang_protect_cleanup_actions
)
3130 decl
= lang_protect_cleanup_actions ();
3132 decl
= built_in_decls
[BUILT_IN_TRAP
];
3134 g
= gimple_build_eh_must_not_throw (decl
);
3135 g
= gimple_build_try (body
, gimple_seq_alloc_with_stmt (g
),
3138 return gimple_seq_alloc_with_stmt (g
);
3141 /* Chain all the DECLs in LIST by their TREE_CHAIN fields. */
3144 list2chain (tree list
)
3148 for (t
= list
; t
; t
= TREE_CHAIN (t
))
3150 tree var
= TREE_VALUE (t
);
3152 TREE_CHAIN (var
) = TREE_VALUE (TREE_CHAIN (t
));
3154 TREE_CHAIN (var
) = NULL_TREE
;
3157 return list
? TREE_VALUE (list
) : NULL_TREE
;
3161 /* Remove barriers in REGION->EXIT's block. Note that this is only
3162 valid for GIMPLE_OMP_PARALLEL regions. Since the end of a parallel region
3163 is an implicit barrier, any workshare inside the GIMPLE_OMP_PARALLEL that
3164 left a barrier at the end of the GIMPLE_OMP_PARALLEL region can now be
3168 remove_exit_barrier (struct omp_region
*region
)
3170 gimple_stmt_iterator gsi
;
3171 basic_block exit_bb
;
3175 int any_addressable_vars
= -1;
3177 exit_bb
= region
->exit
;
3179 /* If the parallel region doesn't return, we don't have REGION->EXIT
3184 /* The last insn in the block will be the parallel's GIMPLE_OMP_RETURN. The
3185 workshare's GIMPLE_OMP_RETURN will be in a preceding block. The kinds of
3186 statements that can appear in between are extremely limited -- no
3187 memory operations at all. Here, we allow nothing at all, so the
3188 only thing we allow to precede this GIMPLE_OMP_RETURN is a label. */
3189 gsi
= gsi_last_bb (exit_bb
);
3190 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
3192 if (!gsi_end_p (gsi
) && gimple_code (gsi_stmt (gsi
)) != GIMPLE_LABEL
)
3195 FOR_EACH_EDGE (e
, ei
, exit_bb
->preds
)
3197 gsi
= gsi_last_bb (e
->src
);
3198 if (gsi_end_p (gsi
))
3200 stmt
= gsi_stmt (gsi
);
3201 if (gimple_code (stmt
) == GIMPLE_OMP_RETURN
3202 && !gimple_omp_return_nowait_p (stmt
))
3204 /* OpenMP 3.0 tasks unfortunately prevent this optimization
3205 in many cases. If there could be tasks queued, the barrier
3206 might be needed to let the tasks run before some local
3207 variable of the parallel that the task uses as shared
3208 runs out of scope. The task can be spawned either
3209 from within current function (this would be easy to check)
3210 or from some function it calls and gets passed an address
3211 of such a variable. */
3212 if (any_addressable_vars
< 0)
3214 gimple parallel_stmt
= last_stmt (region
->entry
);
3215 tree child_fun
= gimple_omp_parallel_child_fn (parallel_stmt
);
3216 tree local_decls
= DECL_STRUCT_FUNCTION (child_fun
)->local_decls
;
3219 any_addressable_vars
= 0;
3220 for (; local_decls
; local_decls
= TREE_CHAIN (local_decls
))
3221 if (TREE_ADDRESSABLE (TREE_VALUE (local_decls
)))
3223 any_addressable_vars
= 1;
3226 for (block
= gimple_block (stmt
);
3227 !any_addressable_vars
3229 && TREE_CODE (block
) == BLOCK
;
3230 block
= BLOCK_SUPERCONTEXT (block
))
3232 for (local_decls
= BLOCK_VARS (block
);
3234 local_decls
= TREE_CHAIN (local_decls
))
3235 if (TREE_ADDRESSABLE (local_decls
))
3237 any_addressable_vars
= 1;
3240 if (block
== gimple_block (parallel_stmt
))
3244 if (!any_addressable_vars
)
3245 gimple_omp_return_set_nowait (stmt
);
3251 remove_exit_barriers (struct omp_region
*region
)
3253 if (region
->type
== GIMPLE_OMP_PARALLEL
)
3254 remove_exit_barrier (region
);
3258 region
= region
->inner
;
3259 remove_exit_barriers (region
);
3260 while (region
->next
)
3262 region
= region
->next
;
3263 remove_exit_barriers (region
);
3268 /* Optimize omp_get_thread_num () and omp_get_num_threads ()
3269 calls. These can't be declared as const functions, but
3270 within one parallel body they are constant, so they can be
3271 transformed there into __builtin_omp_get_{thread_num,num_threads} ()
3272 which are declared const. Similarly for task body, except
3273 that in untied task omp_get_thread_num () can change at any task
3274 scheduling point. */
3277 optimize_omp_library_calls (gimple entry_stmt
)
3280 gimple_stmt_iterator gsi
;
3282 = DECL_ASSEMBLER_NAME (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
]);
3284 = DECL_ASSEMBLER_NAME (built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
]);
3285 bool untied_task
= (gimple_code (entry_stmt
) == GIMPLE_OMP_TASK
3286 && find_omp_clause (gimple_omp_task_clauses (entry_stmt
),
3287 OMP_CLAUSE_UNTIED
) != NULL
);
3290 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
3292 gimple call
= gsi_stmt (gsi
);
3295 if (is_gimple_call (call
)
3296 && (decl
= gimple_call_fndecl (call
))
3297 && DECL_EXTERNAL (decl
)
3298 && TREE_PUBLIC (decl
)
3299 && DECL_INITIAL (decl
) == NULL
)
3303 if (DECL_NAME (decl
) == thr_num_id
)
3305 /* In #pragma omp task untied omp_get_thread_num () can change
3306 during the execution of the task region. */
3309 built_in
= built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
];
3311 else if (DECL_NAME (decl
) == num_thr_id
)
3312 built_in
= built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
];
3316 if (DECL_ASSEMBLER_NAME (decl
) != DECL_ASSEMBLER_NAME (built_in
)
3317 || gimple_call_num_args (call
) != 0)
3320 if (flag_exceptions
&& !TREE_NOTHROW (decl
))
3323 if (TREE_CODE (TREE_TYPE (decl
)) != FUNCTION_TYPE
3324 || !types_compatible_p (TREE_TYPE (TREE_TYPE (decl
)),
3325 TREE_TYPE (TREE_TYPE (built_in
))))
3328 gimple_call_set_fndecl (call
, built_in
);
3333 /* Expand the OpenMP parallel or task directive starting at REGION. */
3336 expand_omp_taskreg (struct omp_region
*region
)
3338 basic_block entry_bb
, exit_bb
, new_bb
;
3339 struct function
*child_cfun
;
3340 tree child_fn
, block
, t
, ws_args
, *tp
;
3342 gimple_stmt_iterator gsi
;
3343 gimple entry_stmt
, stmt
;
3346 entry_stmt
= last_stmt (region
->entry
);
3347 child_fn
= gimple_omp_taskreg_child_fn (entry_stmt
);
3348 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
3349 /* If this function has been already instrumented, make sure
3350 the child function isn't instrumented again. */
3351 child_cfun
->after_tree_profile
= cfun
->after_tree_profile
;
3353 entry_bb
= region
->entry
;
3354 exit_bb
= region
->exit
;
3356 if (is_combined_parallel (region
))
3357 ws_args
= region
->ws_args
;
3359 ws_args
= NULL_TREE
;
3361 if (child_cfun
->cfg
)
3363 /* Due to inlining, it may happen that we have already outlined
3364 the region, in which case all we need to do is make the
3365 sub-graph unreachable and emit the parallel call. */
3366 edge entry_succ_e
, exit_succ_e
;
3367 gimple_stmt_iterator gsi
;
3369 entry_succ_e
= single_succ_edge (entry_bb
);
3371 gsi
= gsi_last_bb (entry_bb
);
3372 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_PARALLEL
3373 || gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_TASK
);
3374 gsi_remove (&gsi
, true);
3379 exit_succ_e
= single_succ_edge (exit_bb
);
3380 make_edge (new_bb
, exit_succ_e
->dest
, EDGE_FALLTHRU
);
3382 remove_edge_and_dominated_blocks (entry_succ_e
);
3386 /* If the parallel region needs data sent from the parent
3387 function, then the very first statement (except possible
3388 tree profile counter updates) of the parallel body
3389 is a copy assignment .OMP_DATA_I = &.OMP_DATA_O. Since
3390 &.OMP_DATA_O is passed as an argument to the child function,
3391 we need to replace it with the argument as seen by the child
3394 In most cases, this will end up being the identity assignment
3395 .OMP_DATA_I = .OMP_DATA_I. However, if the parallel body had
3396 a function call that has been inlined, the original PARM_DECL
3397 .OMP_DATA_I may have been converted into a different local
3398 variable. In which case, we need to keep the assignment. */
3399 if (gimple_omp_taskreg_data_arg (entry_stmt
))
3401 basic_block entry_succ_bb
= single_succ (entry_bb
);
3402 gimple_stmt_iterator gsi
;
3404 gimple parcopy_stmt
= NULL
;
3406 for (gsi
= gsi_start_bb (entry_succ_bb
); ; gsi_next (&gsi
))
3410 gcc_assert (!gsi_end_p (gsi
));
3411 stmt
= gsi_stmt (gsi
);
3412 if (gimple_code (stmt
) != GIMPLE_ASSIGN
)
3415 if (gimple_num_ops (stmt
) == 2)
3417 tree arg
= gimple_assign_rhs1 (stmt
);
3419 /* We're ignore the subcode because we're
3420 effectively doing a STRIP_NOPS. */
3422 if (TREE_CODE (arg
) == ADDR_EXPR
3423 && TREE_OPERAND (arg
, 0)
3424 == gimple_omp_taskreg_data_arg (entry_stmt
))
3426 parcopy_stmt
= stmt
;
3432 gcc_assert (parcopy_stmt
!= NULL
);
3433 arg
= DECL_ARGUMENTS (child_fn
);
3435 if (!gimple_in_ssa_p (cfun
))
3437 if (gimple_assign_lhs (parcopy_stmt
) == arg
)
3438 gsi_remove (&gsi
, true);
3441 /* ?? Is setting the subcode really necessary ?? */
3442 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (arg
));
3443 gimple_assign_set_rhs1 (parcopy_stmt
, arg
);
3448 /* If we are in ssa form, we must load the value from the default
3449 definition of the argument. That should not be defined now,
3450 since the argument is not used uninitialized. */
3451 gcc_assert (gimple_default_def (cfun
, arg
) == NULL
);
3452 narg
= make_ssa_name (arg
, gimple_build_nop ());
3453 set_default_def (arg
, narg
);
3454 /* ?? Is setting the subcode really necessary ?? */
3455 gimple_omp_set_subcode (parcopy_stmt
, TREE_CODE (narg
));
3456 gimple_assign_set_rhs1 (parcopy_stmt
, narg
);
3457 update_stmt (parcopy_stmt
);
3461 /* Declare local variables needed in CHILD_CFUN. */
3462 block
= DECL_INITIAL (child_fn
);
3463 BLOCK_VARS (block
) = list2chain (child_cfun
->local_decls
);
3464 /* The gimplifier could record temporaries in parallel/task block
3465 rather than in containing function's local_decls chain,
3466 which would mean cgraph missed finalizing them. Do it now. */
3467 for (t
= BLOCK_VARS (block
); t
; t
= TREE_CHAIN (t
))
3468 if (TREE_CODE (t
) == VAR_DECL
3470 && !DECL_EXTERNAL (t
))
3471 varpool_finalize_decl (t
);
3472 DECL_SAVED_TREE (child_fn
) = NULL
;
3473 gimple_set_body (child_fn
, bb_seq (single_succ (entry_bb
)));
3474 TREE_USED (block
) = 1;
3476 /* Reset DECL_CONTEXT on function arguments. */
3477 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= TREE_CHAIN (t
))
3478 DECL_CONTEXT (t
) = child_fn
;
3480 /* Split ENTRY_BB at GIMPLE_OMP_PARALLEL or GIMPLE_OMP_TASK,
3481 so that it can be moved to the child function. */
3482 gsi
= gsi_last_bb (entry_bb
);
3483 stmt
= gsi_stmt (gsi
);
3484 gcc_assert (stmt
&& (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
3485 || gimple_code (stmt
) == GIMPLE_OMP_TASK
));
3486 gsi_remove (&gsi
, true);
3487 e
= split_block (entry_bb
, stmt
);
3489 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
3491 /* Convert GIMPLE_OMP_RETURN into a RETURN_EXPR. */
3494 gsi
= gsi_last_bb (exit_bb
);
3495 gcc_assert (!gsi_end_p (gsi
)
3496 && gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_RETURN
);
3497 stmt
= gimple_build_return (NULL
);
3498 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
3499 gsi_remove (&gsi
, true);
3502 /* Move the parallel region into CHILD_CFUN. */
3504 if (gimple_in_ssa_p (cfun
))
3506 push_cfun (child_cfun
);
3507 init_tree_ssa (child_cfun
);
3508 init_ssa_operands ();
3509 cfun
->gimple_df
->in_ssa_p
= true;
3514 block
= gimple_block (entry_stmt
);
3516 new_bb
= move_sese_region_to_fn (child_cfun
, entry_bb
, exit_bb
, block
);
3518 single_succ_edge (new_bb
)->flags
= EDGE_FALLTHRU
;
3520 /* Remove non-local VAR_DECLs from child_cfun->local_decls list. */
3521 for (tp
= &child_cfun
->local_decls
; *tp
; )
3522 if (DECL_CONTEXT (TREE_VALUE (*tp
)) != cfun
->decl
)
3523 tp
= &TREE_CHAIN (*tp
);
3525 *tp
= TREE_CHAIN (*tp
);
3527 /* Inform the callgraph about the new function. */
3528 DECL_STRUCT_FUNCTION (child_fn
)->curr_properties
3529 = cfun
->curr_properties
;
3530 cgraph_add_new_function (child_fn
, true);
3532 /* Fix the callgraph edges for child_cfun. Those for cfun will be
3533 fixed in a following pass. */
3534 push_cfun (child_cfun
);
3535 save_current
= current_function_decl
;
3536 current_function_decl
= child_fn
;
3538 optimize_omp_library_calls (entry_stmt
);
3539 rebuild_cgraph_edges ();
3541 /* Some EH regions might become dead, see PR34608. If
3542 pass_cleanup_cfg isn't the first pass to happen with the
3543 new child, these dead EH edges might cause problems.
3544 Clean them up now. */
3545 if (flag_exceptions
)
3548 bool changed
= false;
3551 changed
|= gimple_purge_dead_eh_edges (bb
);
3553 cleanup_tree_cfg ();
3555 if (gimple_in_ssa_p (cfun
))
3556 update_ssa (TODO_update_ssa
);
3557 current_function_decl
= save_current
;
3561 /* Emit a library call to launch the children threads. */
3562 if (gimple_code (entry_stmt
) == GIMPLE_OMP_PARALLEL
)
3563 expand_parallel_call (region
, new_bb
, entry_stmt
, ws_args
);
3565 expand_task_call (new_bb
, entry_stmt
);
3566 update_ssa (TODO_update_ssa_only_virtuals
);
3570 /* A subroutine of expand_omp_for. Generate code for a parallel
3571 loop with any schedule. Given parameters:
3573 for (V = N1; V cond N2; V += STEP) BODY;
3575 where COND is "<" or ">", we generate pseudocode
3577 more = GOMP_loop_foo_start (N1, N2, STEP, CHUNK, &istart0, &iend0);
3578 if (more) goto L0; else goto L3;
3585 if (V cond iend) goto L1; else goto L2;
3587 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3590 If this is a combined omp parallel loop, instead of the call to
3591 GOMP_loop_foo_start, we call GOMP_loop_foo_next.
3593 For collapsed loops, given parameters:
3595 for (V1 = N11; V1 cond1 N12; V1 += STEP1)
3596 for (V2 = N21; V2 cond2 N22; V2 += STEP2)
3597 for (V3 = N31; V3 cond3 N32; V3 += STEP3)
3600 we generate pseudocode
3606 count3 = (adj + N32 - N31) / STEP3;
3611 count2 = (adj + N22 - N21) / STEP2;
3616 count1 = (adj + N12 - N11) / STEP1;
3617 count = count1 * count2 * count3;
3618 more = GOMP_loop_foo_start (0, count, 1, CHUNK, &istart0, &iend0);
3619 if (more) goto L0; else goto L3;
3623 V3 = N31 + (T % count3) * STEP3;
3625 V2 = N21 + (T % count2) * STEP2;
3627 V1 = N11 + T * STEP1;
3632 if (V < iend) goto L10; else goto L2;
3635 if (V3 cond3 N32) goto L1; else goto L11;
3639 if (V2 cond2 N22) goto L1; else goto L12;
3645 if (GOMP_loop_foo_next (&istart0, &iend0)) goto L0; else goto L3;
3651 expand_omp_for_generic (struct omp_region
*region
,
3652 struct omp_for_data
*fd
,
3653 enum built_in_function start_fn
,
3654 enum built_in_function next_fn
)
3656 tree type
, istart0
, iend0
, iend
;
3657 tree t
, vmain
, vback
, bias
= NULL_TREE
;
3658 basic_block entry_bb
, cont_bb
, exit_bb
, l0_bb
, l1_bb
, collapse_bb
;
3659 basic_block l2_bb
= NULL
, l3_bb
= NULL
;
3660 gimple_stmt_iterator gsi
;
3662 bool in_combined_parallel
= is_combined_parallel (region
);
3663 bool broken_loop
= region
->cont
== NULL
;
3665 tree
*counts
= NULL
;
3668 gcc_assert (!broken_loop
|| !in_combined_parallel
);
3669 gcc_assert (fd
->iter_type
== long_integer_type_node
3670 || !in_combined_parallel
);
3672 type
= TREE_TYPE (fd
->loop
.v
);
3673 istart0
= create_tmp_var (fd
->iter_type
, ".istart0");
3674 iend0
= create_tmp_var (fd
->iter_type
, ".iend0");
3675 TREE_ADDRESSABLE (istart0
) = 1;
3676 TREE_ADDRESSABLE (iend0
) = 1;
3677 if (gimple_in_ssa_p (cfun
))
3679 add_referenced_var (istart0
);
3680 add_referenced_var (iend0
);
3683 /* See if we need to bias by LLONG_MIN. */
3684 if (fd
->iter_type
== long_long_unsigned_type_node
3685 && TREE_CODE (type
) == INTEGER_TYPE
3686 && !TYPE_UNSIGNED (type
))
3690 if (fd
->loop
.cond_code
== LT_EXPR
)
3693 n2
= fold_build2 (PLUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
3697 n1
= fold_build2 (MINUS_EXPR
, type
, fd
->loop
.n2
, fd
->loop
.step
);
3700 if (TREE_CODE (n1
) != INTEGER_CST
3701 || TREE_CODE (n2
) != INTEGER_CST
3702 || ((tree_int_cst_sgn (n1
) < 0) ^ (tree_int_cst_sgn (n2
) < 0)))
3703 bias
= fold_convert (fd
->iter_type
, TYPE_MIN_VALUE (type
));
3706 entry_bb
= region
->entry
;
3707 cont_bb
= region
->cont
;
3709 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
3710 gcc_assert (broken_loop
3711 || BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
3712 l0_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
3713 l1_bb
= single_succ (l0_bb
);
3716 l2_bb
= create_empty_bb (cont_bb
);
3717 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== l1_bb
);
3718 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
3722 l3_bb
= BRANCH_EDGE (entry_bb
)->dest
;
3723 exit_bb
= region
->exit
;
3725 gsi
= gsi_last_bb (entry_bb
);
3727 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
3728 if (fd
->collapse
> 1)
3730 /* collapsed loops need work for expansion in SSA form. */
3731 gcc_assert (!gimple_in_ssa_p (cfun
));
3732 counts
= (tree
*) alloca (fd
->collapse
* sizeof (tree
));
3733 for (i
= 0; i
< fd
->collapse
; i
++)
3735 tree itype
= TREE_TYPE (fd
->loops
[i
].v
);
3737 if (POINTER_TYPE_P (itype
))
3738 itype
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (itype
), 0);
3739 t
= build_int_cst (itype
, (fd
->loops
[i
].cond_code
== LT_EXPR
3741 t
= fold_build2 (PLUS_EXPR
, itype
,
3742 fold_convert (itype
, fd
->loops
[i
].step
), t
);
3743 t
= fold_build2 (PLUS_EXPR
, itype
, t
,
3744 fold_convert (itype
, fd
->loops
[i
].n2
));
3745 t
= fold_build2 (MINUS_EXPR
, itype
, t
,
3746 fold_convert (itype
, fd
->loops
[i
].n1
));
3747 if (TYPE_UNSIGNED (itype
) && fd
->loops
[i
].cond_code
== GT_EXPR
)
3748 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
3749 fold_build1 (NEGATE_EXPR
, itype
, t
),
3750 fold_build1 (NEGATE_EXPR
, itype
,
3751 fold_convert (itype
,
3752 fd
->loops
[i
].step
)));
3754 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
,
3755 fold_convert (itype
, fd
->loops
[i
].step
));
3756 t
= fold_convert (type
, t
);
3757 if (TREE_CODE (t
) == INTEGER_CST
)
3761 counts
[i
] = create_tmp_var (type
, ".count");
3762 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3763 true, GSI_SAME_STMT
);
3764 stmt
= gimple_build_assign (counts
[i
], t
);
3765 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3767 if (SSA_VAR_P (fd
->loop
.n2
))
3773 t
= fold_build2 (MULT_EXPR
, type
, fd
->loop
.n2
, counts
[i
]);
3774 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3775 true, GSI_SAME_STMT
);
3777 stmt
= gimple_build_assign (fd
->loop
.n2
, t
);
3778 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3782 if (in_combined_parallel
)
3784 /* In a combined parallel loop, emit a call to
3785 GOMP_loop_foo_next. */
3786 t
= build_call_expr (built_in_decls
[next_fn
], 2,
3787 build_fold_addr_expr (istart0
),
3788 build_fold_addr_expr (iend0
));
3792 tree t0
, t1
, t2
, t3
, t4
;
3793 /* If this is not a combined parallel loop, emit a call to
3794 GOMP_loop_foo_start in ENTRY_BB. */
3795 t4
= build_fold_addr_expr (iend0
);
3796 t3
= build_fold_addr_expr (istart0
);
3797 t2
= fold_convert (fd
->iter_type
, fd
->loop
.step
);
3798 if (POINTER_TYPE_P (type
)
3799 && TYPE_PRECISION (type
) != TYPE_PRECISION (fd
->iter_type
))
3801 /* Avoid casting pointers to integer of a different size. */
3803 = lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
), 0);
3804 t1
= fold_convert (fd
->iter_type
, fold_convert (itype
, fd
->loop
.n2
));
3805 t0
= fold_convert (fd
->iter_type
, fold_convert (itype
, fd
->loop
.n1
));
3809 t1
= fold_convert (fd
->iter_type
, fd
->loop
.n2
);
3810 t0
= fold_convert (fd
->iter_type
, fd
->loop
.n1
);
3814 t1
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t1
, bias
);
3815 t0
= fold_build2 (PLUS_EXPR
, fd
->iter_type
, t0
, bias
);
3817 if (fd
->iter_type
== long_integer_type_node
)
3821 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
3822 t
= build_call_expr (built_in_decls
[start_fn
], 6,
3823 t0
, t1
, t2
, t
, t3
, t4
);
3826 t
= build_call_expr (built_in_decls
[start_fn
], 5,
3827 t0
, t1
, t2
, t3
, t4
);
3834 /* The GOMP_loop_ull_*start functions have additional boolean
3835 argument, true for < loops and false for > loops.
3836 In Fortran, the C bool type can be different from
3837 boolean_type_node. */
3838 c_bool_type
= TREE_TYPE (TREE_TYPE (built_in_decls
[start_fn
]));
3839 t5
= build_int_cst (c_bool_type
,
3840 fd
->loop
.cond_code
== LT_EXPR
? 1 : 0);
3843 t
= fold_convert (fd
->iter_type
, fd
->chunk_size
);
3844 t
= build_call_expr (built_in_decls
[start_fn
], 7,
3845 t5
, t0
, t1
, t2
, t
, t3
, t4
);
3848 t
= build_call_expr (built_in_decls
[start_fn
], 6,
3849 t5
, t0
, t1
, t2
, t3
, t4
);
3852 if (TREE_TYPE (t
) != boolean_type_node
)
3853 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
3854 t
, build_int_cst (TREE_TYPE (t
), 0));
3855 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3856 true, GSI_SAME_STMT
);
3857 gsi_insert_after (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
3859 /* Remove the GIMPLE_OMP_FOR statement. */
3860 gsi_remove (&gsi
, true);
3862 /* Iteration setup for sequential loop goes in L0_BB. */
3863 gsi
= gsi_start_bb (l0_bb
);
3866 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
3867 if (POINTER_TYPE_P (type
))
3868 t
= fold_convert (lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
),
3870 t
= fold_convert (type
, t
);
3871 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3872 false, GSI_CONTINUE_LINKING
);
3873 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
3874 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3878 t
= fold_build2 (MINUS_EXPR
, fd
->iter_type
, t
, bias
);
3879 if (POINTER_TYPE_P (type
))
3880 t
= fold_convert (lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
),
3882 t
= fold_convert (type
, t
);
3883 iend
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3884 false, GSI_CONTINUE_LINKING
);
3885 if (fd
->collapse
> 1)
3887 tree tem
= create_tmp_var (type
, ".tem");
3889 stmt
= gimple_build_assign (tem
, fd
->loop
.v
);
3890 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3891 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
3893 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
), itype
;
3895 if (POINTER_TYPE_P (vtype
))
3896 itype
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (vtype
), 0);
3897 t
= fold_build2 (TRUNC_MOD_EXPR
, type
, tem
, counts
[i
]);
3898 t
= fold_convert (itype
, t
);
3899 t
= fold_build2 (MULT_EXPR
, itype
, t
,
3900 fold_convert (itype
, fd
->loops
[i
].step
));
3901 if (POINTER_TYPE_P (vtype
))
3902 t
= fold_build2 (POINTER_PLUS_EXPR
, vtype
,
3903 fd
->loops
[i
].n1
, fold_convert (sizetype
, t
));
3905 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loops
[i
].n1
, t
);
3906 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3907 false, GSI_CONTINUE_LINKING
);
3908 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
3909 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3912 t
= fold_build2 (TRUNC_DIV_EXPR
, type
, tem
, counts
[i
]);
3913 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3914 false, GSI_CONTINUE_LINKING
);
3915 stmt
= gimple_build_assign (tem
, t
);
3916 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3923 /* Code to control the increment and predicate for the sequential
3924 loop goes in the CONT_BB. */
3925 gsi
= gsi_last_bb (cont_bb
);
3926 stmt
= gsi_stmt (gsi
);
3927 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
3928 vmain
= gimple_omp_continue_control_use (stmt
);
3929 vback
= gimple_omp_continue_control_def (stmt
);
3931 if (POINTER_TYPE_P (type
))
3932 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, vmain
,
3933 fold_convert (sizetype
, fd
->loop
.step
));
3935 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
3936 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3937 true, GSI_SAME_STMT
);
3938 stmt
= gimple_build_assign (vback
, t
);
3939 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3941 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, vback
, iend
);
3942 stmt
= gimple_build_cond_empty (t
);
3943 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
3945 /* Remove GIMPLE_OMP_CONTINUE. */
3946 gsi_remove (&gsi
, true);
3948 if (fd
->collapse
> 1)
3950 basic_block last_bb
, bb
;
3953 for (i
= fd
->collapse
- 1; i
>= 0; i
--)
3955 tree vtype
= TREE_TYPE (fd
->loops
[i
].v
);
3957 bb
= create_empty_bb (last_bb
);
3958 gsi
= gsi_start_bb (bb
);
3960 if (i
< fd
->collapse
- 1)
3962 e
= make_edge (last_bb
, bb
, EDGE_FALSE_VALUE
);
3963 e
->probability
= REG_BR_PROB_BASE
/ 8;
3965 t
= fd
->loops
[i
+ 1].n1
;
3966 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3967 false, GSI_CONTINUE_LINKING
);
3968 stmt
= gimple_build_assign (fd
->loops
[i
+ 1].v
, t
);
3969 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3974 set_immediate_dominator (CDI_DOMINATORS
, bb
, last_bb
);
3976 if (POINTER_TYPE_P (vtype
))
3977 t
= fold_build2 (POINTER_PLUS_EXPR
, vtype
,
3979 fold_convert (sizetype
, fd
->loops
[i
].step
));
3981 t
= fold_build2 (PLUS_EXPR
, vtype
, fd
->loops
[i
].v
,
3983 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
3984 false, GSI_CONTINUE_LINKING
);
3985 stmt
= gimple_build_assign (fd
->loops
[i
].v
, t
);
3986 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3990 t
= fd
->loops
[i
].n2
;
3991 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
3992 false, GSI_CONTINUE_LINKING
);
3993 t
= fold_build2 (fd
->loops
[i
].cond_code
, boolean_type_node
,
3995 stmt
= gimple_build_cond_empty (t
);
3996 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
3997 e
= make_edge (bb
, l1_bb
, EDGE_TRUE_VALUE
);
3998 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
4001 make_edge (bb
, l1_bb
, EDGE_FALLTHRU
);
4006 /* Emit code to get the next parallel iteration in L2_BB. */
4007 gsi
= gsi_start_bb (l2_bb
);
4009 t
= build_call_expr (built_in_decls
[next_fn
], 2,
4010 build_fold_addr_expr (istart0
),
4011 build_fold_addr_expr (iend0
));
4012 t
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4013 false, GSI_CONTINUE_LINKING
);
4014 if (TREE_TYPE (t
) != boolean_type_node
)
4015 t
= fold_build2 (NE_EXPR
, boolean_type_node
,
4016 t
, build_int_cst (TREE_TYPE (t
), 0));
4017 stmt
= gimple_build_cond_empty (t
);
4018 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4021 /* Add the loop cleanup function. */
4022 gsi
= gsi_last_bb (exit_bb
);
4023 if (gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4024 t
= built_in_decls
[BUILT_IN_GOMP_LOOP_END_NOWAIT
];
4026 t
= built_in_decls
[BUILT_IN_GOMP_LOOP_END
];
4027 stmt
= gimple_build_call (t
, 0);
4028 gsi_insert_after (&gsi
, stmt
, GSI_SAME_STMT
);
4029 gsi_remove (&gsi
, true);
4031 /* Connect the new blocks. */
4032 find_edge (entry_bb
, l0_bb
)->flags
= EDGE_TRUE_VALUE
;
4033 find_edge (entry_bb
, l3_bb
)->flags
= EDGE_FALSE_VALUE
;
4039 e
= find_edge (cont_bb
, l3_bb
);
4040 ne
= make_edge (l2_bb
, l3_bb
, EDGE_FALSE_VALUE
);
4042 phis
= phi_nodes (l3_bb
);
4043 for (gsi
= gsi_start (phis
); !gsi_end_p (gsi
); gsi_next (&gsi
))
4045 gimple phi
= gsi_stmt (gsi
);
4046 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, ne
),
4047 PHI_ARG_DEF_FROM_EDGE (phi
, e
));
4051 make_edge (cont_bb
, l2_bb
, EDGE_FALSE_VALUE
);
4052 if (fd
->collapse
> 1)
4054 e
= find_edge (cont_bb
, l1_bb
);
4056 e
= make_edge (cont_bb
, collapse_bb
, EDGE_TRUE_VALUE
);
4060 e
= find_edge (cont_bb
, l1_bb
);
4061 e
->flags
= EDGE_TRUE_VALUE
;
4063 e
->probability
= REG_BR_PROB_BASE
* 7 / 8;
4064 find_edge (cont_bb
, l2_bb
)->probability
= REG_BR_PROB_BASE
/ 8;
4065 make_edge (l2_bb
, l0_bb
, EDGE_TRUE_VALUE
);
4067 set_immediate_dominator (CDI_DOMINATORS
, l2_bb
,
4068 recompute_dominator (CDI_DOMINATORS
, l2_bb
));
4069 set_immediate_dominator (CDI_DOMINATORS
, l3_bb
,
4070 recompute_dominator (CDI_DOMINATORS
, l3_bb
));
4071 set_immediate_dominator (CDI_DOMINATORS
, l0_bb
,
4072 recompute_dominator (CDI_DOMINATORS
, l0_bb
));
4073 set_immediate_dominator (CDI_DOMINATORS
, l1_bb
,
4074 recompute_dominator (CDI_DOMINATORS
, l1_bb
));
4079 /* A subroutine of expand_omp_for. Generate code for a parallel
4080 loop with static schedule and no specified chunk size. Given
4083 for (V = N1; V cond N2; V += STEP) BODY;
4085 where COND is "<" or ">", we generate pseudocode
4091 if ((__typeof (V)) -1 > 0 && cond is >)
4092 n = -(adj + N2 - N1) / -STEP;
4094 n = (adj + N2 - N1) / STEP;
4096 q += (q * nthreads != n);
4098 e0 = min(s0 + q, n);
4100 if (s0 >= e0) goto L2; else goto L0;
4106 if (V cond e) goto L1;
4111 expand_omp_for_static_nochunk (struct omp_region
*region
,
4112 struct omp_for_data
*fd
)
4114 tree n
, q
, s0
, e0
, e
, t
, nthreads
, threadid
;
4115 tree type
, itype
, vmain
, vback
;
4116 basic_block entry_bb
, exit_bb
, seq_start_bb
, body_bb
, cont_bb
;
4118 gimple_stmt_iterator gsi
;
4121 itype
= type
= TREE_TYPE (fd
->loop
.v
);
4122 if (POINTER_TYPE_P (type
))
4123 itype
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
), 0);
4125 entry_bb
= region
->entry
;
4126 cont_bb
= region
->cont
;
4127 gcc_assert (EDGE_COUNT (entry_bb
->succs
) == 2);
4128 gcc_assert (BRANCH_EDGE (entry_bb
)->dest
== FALLTHRU_EDGE (cont_bb
)->dest
);
4129 seq_start_bb
= split_edge (FALLTHRU_EDGE (entry_bb
));
4130 body_bb
= single_succ (seq_start_bb
);
4131 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
4132 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
4133 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
4134 exit_bb
= region
->exit
;
4136 /* Iteration space partitioning goes in ENTRY_BB. */
4137 gsi
= gsi_last_bb (entry_bb
);
4138 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_FOR
);
4140 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
], 0);
4141 t
= fold_convert (itype
, t
);
4142 nthreads
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4143 true, GSI_SAME_STMT
);
4145 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
4146 t
= fold_convert (itype
, t
);
4147 threadid
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4148 true, GSI_SAME_STMT
);
4151 = force_gimple_operand_gsi (&gsi
, fold_convert (type
, fd
->loop
.n1
),
4152 true, NULL_TREE
, true, GSI_SAME_STMT
);
4154 = force_gimple_operand_gsi (&gsi
, fold_convert (itype
, fd
->loop
.n2
),
4155 true, NULL_TREE
, true, GSI_SAME_STMT
);
4157 = force_gimple_operand_gsi (&gsi
, fold_convert (itype
, fd
->loop
.step
),
4158 true, NULL_TREE
, true, GSI_SAME_STMT
);
4160 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
4161 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loop
.step
, t
);
4162 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fd
->loop
.n2
);
4163 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, fd
->loop
.n1
));
4164 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
4165 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4166 fold_build1 (NEGATE_EXPR
, itype
, t
),
4167 fold_build1 (NEGATE_EXPR
, itype
, fd
->loop
.step
));
4169 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, fd
->loop
.step
);
4170 t
= fold_convert (itype
, t
);
4171 n
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4173 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, n
, nthreads
);
4174 q
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4176 t
= fold_build2 (MULT_EXPR
, itype
, q
, nthreads
);
4177 t
= fold_build2 (NE_EXPR
, itype
, t
, n
);
4178 t
= fold_build2 (PLUS_EXPR
, itype
, q
, t
);
4179 q
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4181 t
= build2 (MULT_EXPR
, itype
, q
, threadid
);
4182 s0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4184 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, q
);
4185 t
= fold_build2 (MIN_EXPR
, itype
, t
, n
);
4186 e0
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
4188 t
= build2 (GE_EXPR
, boolean_type_node
, s0
, e0
);
4189 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4191 /* Remove the GIMPLE_OMP_FOR statement. */
4192 gsi_remove (&gsi
, true);
4194 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4195 gsi
= gsi_start_bb (seq_start_bb
);
4197 t
= fold_convert (itype
, s0
);
4198 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4199 if (POINTER_TYPE_P (type
))
4200 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4201 fold_convert (sizetype
, t
));
4203 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4204 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4205 false, GSI_CONTINUE_LINKING
);
4206 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4207 gsi_insert_after (&gsi
, stmt
, GSI_CONTINUE_LINKING
);
4209 t
= fold_convert (itype
, e0
);
4210 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4211 if (POINTER_TYPE_P (type
))
4212 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4213 fold_convert (sizetype
, t
));
4215 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4216 e
= force_gimple_operand_gsi (&gsi
, t
, true, NULL_TREE
,
4217 false, GSI_CONTINUE_LINKING
);
4219 /* The code controlling the sequential loop replaces the
4220 GIMPLE_OMP_CONTINUE. */
4221 gsi
= gsi_last_bb (cont_bb
);
4222 stmt
= gsi_stmt (gsi
);
4223 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4224 vmain
= gimple_omp_continue_control_use (stmt
);
4225 vback
= gimple_omp_continue_control_def (stmt
);
4227 if (POINTER_TYPE_P (type
))
4228 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, vmain
,
4229 fold_convert (sizetype
, fd
->loop
.step
));
4231 t
= fold_build2 (PLUS_EXPR
, type
, vmain
, fd
->loop
.step
);
4232 t
= force_gimple_operand_gsi (&gsi
, t
, false, NULL_TREE
,
4233 true, GSI_SAME_STMT
);
4234 stmt
= gimple_build_assign (vback
, t
);
4235 gsi_insert_before (&gsi
, stmt
, GSI_SAME_STMT
);
4237 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, vback
, e
);
4238 gsi_insert_before (&gsi
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4240 /* Remove the GIMPLE_OMP_CONTINUE statement. */
4241 gsi_remove (&gsi
, true);
4243 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4244 gsi
= gsi_last_bb (exit_bb
);
4245 if (!gimple_omp_return_nowait_p (gsi_stmt (gsi
)))
4246 force_gimple_operand_gsi (&gsi
, build_omp_barrier (), false, NULL_TREE
,
4247 false, GSI_SAME_STMT
);
4248 gsi_remove (&gsi
, true);
4250 /* Connect all the blocks. */
4251 find_edge (entry_bb
, seq_start_bb
)->flags
= EDGE_FALSE_VALUE
;
4252 find_edge (entry_bb
, fin_bb
)->flags
= EDGE_TRUE_VALUE
;
4254 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
4255 find_edge (cont_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
4257 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
, entry_bb
);
4258 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
4259 recompute_dominator (CDI_DOMINATORS
, body_bb
));
4260 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
4261 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
4265 /* A subroutine of expand_omp_for. Generate code for a parallel
4266 loop with static schedule and a specified chunk size. Given
4269 for (V = N1; V cond N2; V += STEP) BODY;
4271 where COND is "<" or ">", we generate pseudocode
4277 if ((__typeof (V)) -1 > 0 && cond is >)
4278 n = -(adj + N2 - N1) / -STEP;
4280 n = (adj + N2 - N1) / STEP;
4282 V = threadid * CHUNK * STEP + N1; -- this extra definition of V is
4283 here so that V is defined
4284 if the loop is not entered
4286 s0 = (trip * nthreads + threadid) * CHUNK;
4287 e0 = min(s0 + CHUNK, n);
4288 if (s0 < n) goto L1; else goto L4;
4295 if (V cond e) goto L2; else goto L3;
4303 expand_omp_for_static_chunk (struct omp_region
*region
, struct omp_for_data
*fd
)
4305 tree n
, s0
, e0
, e
, t
;
4306 tree trip_var
, trip_init
, trip_main
, trip_back
, nthreads
, threadid
;
4307 tree type
, itype
, v_main
, v_back
, v_extra
;
4308 basic_block entry_bb
, exit_bb
, body_bb
, seq_start_bb
, iter_part_bb
;
4309 basic_block trip_update_bb
, cont_bb
, fin_bb
;
4310 gimple_stmt_iterator si
;
4314 itype
= type
= TREE_TYPE (fd
->loop
.v
);
4315 if (POINTER_TYPE_P (type
))
4316 itype
= lang_hooks
.types
.type_for_size (TYPE_PRECISION (type
), 0);
4318 entry_bb
= region
->entry
;
4319 se
= split_block (entry_bb
, last_stmt (entry_bb
));
4321 iter_part_bb
= se
->dest
;
4322 cont_bb
= region
->cont
;
4323 gcc_assert (EDGE_COUNT (iter_part_bb
->succs
) == 2);
4324 gcc_assert (BRANCH_EDGE (iter_part_bb
)->dest
4325 == FALLTHRU_EDGE (cont_bb
)->dest
);
4326 seq_start_bb
= split_edge (FALLTHRU_EDGE (iter_part_bb
));
4327 body_bb
= single_succ (seq_start_bb
);
4328 gcc_assert (BRANCH_EDGE (cont_bb
)->dest
== body_bb
);
4329 gcc_assert (EDGE_COUNT (cont_bb
->succs
) == 2);
4330 fin_bb
= FALLTHRU_EDGE (cont_bb
)->dest
;
4331 trip_update_bb
= split_edge (FALLTHRU_EDGE (cont_bb
));
4332 exit_bb
= region
->exit
;
4334 /* Trip and adjustment setup goes in ENTRY_BB. */
4335 si
= gsi_last_bb (entry_bb
);
4336 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_FOR
);
4338 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_NUM_THREADS
], 0);
4339 t
= fold_convert (itype
, t
);
4340 nthreads
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4341 true, GSI_SAME_STMT
);
4343 t
= build_call_expr (built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
4344 t
= fold_convert (itype
, t
);
4345 threadid
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4346 true, GSI_SAME_STMT
);
4349 = force_gimple_operand_gsi (&si
, fold_convert (type
, fd
->loop
.n1
),
4350 true, NULL_TREE
, true, GSI_SAME_STMT
);
4352 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->loop
.n2
),
4353 true, NULL_TREE
, true, GSI_SAME_STMT
);
4355 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->loop
.step
),
4356 true, NULL_TREE
, true, GSI_SAME_STMT
);
4358 = force_gimple_operand_gsi (&si
, fold_convert (itype
, fd
->chunk_size
),
4359 true, NULL_TREE
, true, GSI_SAME_STMT
);
4361 t
= build_int_cst (itype
, (fd
->loop
.cond_code
== LT_EXPR
? -1 : 1));
4362 t
= fold_build2 (PLUS_EXPR
, itype
, fd
->loop
.step
, t
);
4363 t
= fold_build2 (PLUS_EXPR
, itype
, t
, fd
->loop
.n2
);
4364 t
= fold_build2 (MINUS_EXPR
, itype
, t
, fold_convert (itype
, fd
->loop
.n1
));
4365 if (TYPE_UNSIGNED (itype
) && fd
->loop
.cond_code
== GT_EXPR
)
4366 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
,
4367 fold_build1 (NEGATE_EXPR
, itype
, t
),
4368 fold_build1 (NEGATE_EXPR
, itype
, fd
->loop
.step
));
4370 t
= fold_build2 (TRUNC_DIV_EXPR
, itype
, t
, fd
->loop
.step
);
4371 t
= fold_convert (itype
, t
);
4372 n
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4373 true, GSI_SAME_STMT
);
4375 trip_var
= create_tmp_var (itype
, ".trip");
4376 if (gimple_in_ssa_p (cfun
))
4378 add_referenced_var (trip_var
);
4379 trip_init
= make_ssa_name (trip_var
, NULL
);
4380 trip_main
= make_ssa_name (trip_var
, NULL
);
4381 trip_back
= make_ssa_name (trip_var
, NULL
);
4385 trip_init
= trip_var
;
4386 trip_main
= trip_var
;
4387 trip_back
= trip_var
;
4390 stmt
= gimple_build_assign (trip_init
, build_int_cst (itype
, 0));
4391 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4393 t
= fold_build2 (MULT_EXPR
, itype
, threadid
, fd
->chunk_size
);
4394 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4395 if (POINTER_TYPE_P (type
))
4396 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4397 fold_convert (sizetype
, t
));
4399 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4400 v_extra
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4401 true, GSI_SAME_STMT
);
4403 /* Remove the GIMPLE_OMP_FOR. */
4404 gsi_remove (&si
, true);
4406 /* Iteration space partitioning goes in ITER_PART_BB. */
4407 si
= gsi_last_bb (iter_part_bb
);
4409 t
= fold_build2 (MULT_EXPR
, itype
, trip_main
, nthreads
);
4410 t
= fold_build2 (PLUS_EXPR
, itype
, t
, threadid
);
4411 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->chunk_size
);
4412 s0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4413 false, GSI_CONTINUE_LINKING
);
4415 t
= fold_build2 (PLUS_EXPR
, itype
, s0
, fd
->chunk_size
);
4416 t
= fold_build2 (MIN_EXPR
, itype
, t
, n
);
4417 e0
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4418 false, GSI_CONTINUE_LINKING
);
4420 t
= build2 (LT_EXPR
, boolean_type_node
, s0
, n
);
4421 gsi_insert_after (&si
, gimple_build_cond_empty (t
), GSI_CONTINUE_LINKING
);
4423 /* Setup code for sequential iteration goes in SEQ_START_BB. */
4424 si
= gsi_start_bb (seq_start_bb
);
4426 t
= fold_convert (itype
, s0
);
4427 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4428 if (POINTER_TYPE_P (type
))
4429 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4430 fold_convert (sizetype
, t
));
4432 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4433 t
= force_gimple_operand_gsi (&si
, t
, false, NULL_TREE
,
4434 false, GSI_CONTINUE_LINKING
);
4435 stmt
= gimple_build_assign (fd
->loop
.v
, t
);
4436 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4438 t
= fold_convert (itype
, e0
);
4439 t
= fold_build2 (MULT_EXPR
, itype
, t
, fd
->loop
.step
);
4440 if (POINTER_TYPE_P (type
))
4441 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, fd
->loop
.n1
,
4442 fold_convert (sizetype
, t
));
4444 t
= fold_build2 (PLUS_EXPR
, type
, t
, fd
->loop
.n1
);
4445 e
= force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
,
4446 false, GSI_CONTINUE_LINKING
);
4448 /* The code controlling the sequential loop goes in CONT_BB,
4449 replacing the GIMPLE_OMP_CONTINUE. */
4450 si
= gsi_last_bb (cont_bb
);
4451 stmt
= gsi_stmt (si
);
4452 gcc_assert (gimple_code (stmt
) == GIMPLE_OMP_CONTINUE
);
4453 v_main
= gimple_omp_continue_control_use (stmt
);
4454 v_back
= gimple_omp_continue_control_def (stmt
);
4456 if (POINTER_TYPE_P (type
))
4457 t
= fold_build2 (POINTER_PLUS_EXPR
, type
, v_main
,
4458 fold_convert (sizetype
, fd
->loop
.step
));
4460 t
= fold_build2 (PLUS_EXPR
, type
, v_main
, fd
->loop
.step
);
4461 stmt
= gimple_build_assign (v_back
, t
);
4462 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
4464 t
= build2 (fd
->loop
.cond_code
, boolean_type_node
, v_back
, e
);
4465 gsi_insert_before (&si
, gimple_build_cond_empty (t
), GSI_SAME_STMT
);
4467 /* Remove GIMPLE_OMP_CONTINUE. */
4468 gsi_remove (&si
, true);
4470 /* Trip update code goes into TRIP_UPDATE_BB. */
4471 si
= gsi_start_bb (trip_update_bb
);
4473 t
= build_int_cst (itype
, 1);
4474 t
= build2 (PLUS_EXPR
, itype
, trip_main
, t
);
4475 stmt
= gimple_build_assign (trip_back
, t
);
4476 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4478 /* Replace the GIMPLE_OMP_RETURN with a barrier, or nothing. */
4479 si
= gsi_last_bb (exit_bb
);
4480 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)))
4481 force_gimple_operand_gsi (&si
, build_omp_barrier (), false, NULL_TREE
,
4482 false, GSI_SAME_STMT
);
4483 gsi_remove (&si
, true);
4485 /* Connect the new blocks. */
4486 find_edge (iter_part_bb
, seq_start_bb
)->flags
= EDGE_TRUE_VALUE
;
4487 find_edge (iter_part_bb
, fin_bb
)->flags
= EDGE_FALSE_VALUE
;
4489 find_edge (cont_bb
, body_bb
)->flags
= EDGE_TRUE_VALUE
;
4490 find_edge (cont_bb
, trip_update_bb
)->flags
= EDGE_FALSE_VALUE
;
4492 redirect_edge_and_branch (single_succ_edge (trip_update_bb
), iter_part_bb
);
4494 if (gimple_in_ssa_p (cfun
))
4496 gimple_stmt_iterator psi
;
4499 edge_var_map_vector head
;
4503 /* When we redirect the edge from trip_update_bb to iter_part_bb, we
4504 remove arguments of the phi nodes in fin_bb. We need to create
4505 appropriate phi nodes in iter_part_bb instead. */
4506 se
= single_pred_edge (fin_bb
);
4507 re
= single_succ_edge (trip_update_bb
);
4508 head
= redirect_edge_var_map_vector (re
);
4509 ene
= single_succ_edge (entry_bb
);
4511 psi
= gsi_start_phis (fin_bb
);
4512 for (i
= 0; !gsi_end_p (psi
) && VEC_iterate (edge_var_map
, head
, i
, vm
);
4513 gsi_next (&psi
), ++i
)
4516 source_location locus
;
4518 phi
= gsi_stmt (psi
);
4519 t
= gimple_phi_result (phi
);
4520 gcc_assert (t
== redirect_edge_var_map_result (vm
));
4521 nphi
= create_phi_node (t
, iter_part_bb
);
4522 SSA_NAME_DEF_STMT (t
) = nphi
;
4524 t
= PHI_ARG_DEF_FROM_EDGE (phi
, se
);
4525 locus
= gimple_phi_arg_location_from_edge (phi
, se
);
4527 /* A special case -- fd->loop.v is not yet computed in
4528 iter_part_bb, we need to use v_extra instead. */
4529 if (t
== fd
->loop
.v
)
4531 add_phi_arg (nphi
, t
, ene
, locus
);
4532 locus
= redirect_edge_var_map_location (vm
);
4533 add_phi_arg (nphi
, redirect_edge_var_map_def (vm
), re
, locus
);
4535 gcc_assert (!gsi_end_p (psi
) && i
== VEC_length (edge_var_map
, head
));
4536 redirect_edge_var_map_clear (re
);
4539 psi
= gsi_start_phis (fin_bb
);
4540 if (gsi_end_p (psi
))
4542 remove_phi_node (&psi
, false);
4545 /* Make phi node for trip. */
4546 phi
= create_phi_node (trip_main
, iter_part_bb
);
4547 SSA_NAME_DEF_STMT (trip_main
) = phi
;
4548 add_phi_arg (phi
, trip_back
, single_succ_edge (trip_update_bb
),
4550 add_phi_arg (phi
, trip_init
, single_succ_edge (entry_bb
),
4554 set_immediate_dominator (CDI_DOMINATORS
, trip_update_bb
, cont_bb
);
4555 set_immediate_dominator (CDI_DOMINATORS
, iter_part_bb
,
4556 recompute_dominator (CDI_DOMINATORS
, iter_part_bb
));
4557 set_immediate_dominator (CDI_DOMINATORS
, fin_bb
,
4558 recompute_dominator (CDI_DOMINATORS
, fin_bb
));
4559 set_immediate_dominator (CDI_DOMINATORS
, seq_start_bb
,
4560 recompute_dominator (CDI_DOMINATORS
, seq_start_bb
));
4561 set_immediate_dominator (CDI_DOMINATORS
, body_bb
,
4562 recompute_dominator (CDI_DOMINATORS
, body_bb
));
4566 /* Expand the OpenMP loop defined by REGION. */
4569 expand_omp_for (struct omp_region
*region
)
4571 struct omp_for_data fd
;
4572 struct omp_for_data_loop
*loops
;
4575 = (struct omp_for_data_loop
*)
4576 alloca (gimple_omp_for_collapse (last_stmt (region
->entry
))
4577 * sizeof (struct omp_for_data_loop
));
4578 extract_omp_for_data (last_stmt (region
->entry
), &fd
, loops
);
4579 region
->sched_kind
= fd
.sched_kind
;
4581 gcc_assert (EDGE_COUNT (region
->entry
->succs
) == 2);
4582 BRANCH_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
4583 FALLTHRU_EDGE (region
->entry
)->flags
&= ~EDGE_ABNORMAL
;
4586 gcc_assert (EDGE_COUNT (region
->cont
->succs
) == 2);
4587 BRANCH_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
4588 FALLTHRU_EDGE (region
->cont
)->flags
&= ~EDGE_ABNORMAL
;
4591 if (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_STATIC
4594 && region
->cont
!= NULL
)
4596 if (fd
.chunk_size
== NULL
)
4597 expand_omp_for_static_nochunk (region
, &fd
);
4599 expand_omp_for_static_chunk (region
, &fd
);
4603 int fn_index
, start_ix
, next_ix
;
4605 gcc_assert (fd
.sched_kind
!= OMP_CLAUSE_SCHEDULE_AUTO
);
4606 fn_index
= (fd
.sched_kind
== OMP_CLAUSE_SCHEDULE_RUNTIME
)
4607 ? 3 : fd
.sched_kind
;
4608 fn_index
+= fd
.have_ordered
* 4;
4609 start_ix
= BUILT_IN_GOMP_LOOP_STATIC_START
+ fn_index
;
4610 next_ix
= BUILT_IN_GOMP_LOOP_STATIC_NEXT
+ fn_index
;
4611 if (fd
.iter_type
== long_long_unsigned_type_node
)
4613 start_ix
+= BUILT_IN_GOMP_LOOP_ULL_STATIC_START
4614 - BUILT_IN_GOMP_LOOP_STATIC_START
;
4615 next_ix
+= BUILT_IN_GOMP_LOOP_ULL_STATIC_NEXT
4616 - BUILT_IN_GOMP_LOOP_STATIC_NEXT
;
4618 expand_omp_for_generic (region
, &fd
, (enum built_in_function
) start_ix
,
4619 (enum built_in_function
) next_ix
);
4622 update_ssa (TODO_update_ssa_only_virtuals
);
4626 /* Expand code for an OpenMP sections directive. In pseudo code, we generate
4628 v = GOMP_sections_start (n);
4645 v = GOMP_sections_next ();
4650 If this is a combined parallel sections, replace the call to
4651 GOMP_sections_start with call to GOMP_sections_next. */
4654 expand_omp_sections (struct omp_region
*region
)
4656 tree t
, u
, vin
= NULL
, vmain
, vnext
, l2
;
4657 VEC (tree
,heap
) *label_vec
;
4659 basic_block entry_bb
, l0_bb
, l1_bb
, l2_bb
, default_bb
;
4660 gimple_stmt_iterator si
, switch_si
;
4661 gimple sections_stmt
, stmt
, cont
;
4664 struct omp_region
*inner
;
4666 bool exit_reachable
= region
->cont
!= NULL
;
4668 gcc_assert (exit_reachable
== (region
->exit
!= NULL
));
4669 entry_bb
= region
->entry
;
4670 l0_bb
= single_succ (entry_bb
);
4671 l1_bb
= region
->cont
;
4672 l2_bb
= region
->exit
;
4675 if (single_pred_p (l2_bb
) && single_pred (l2_bb
) == l0_bb
)
4676 l2
= gimple_block_label (l2_bb
);
4679 /* This can happen if there are reductions. */
4680 len
= EDGE_COUNT (l0_bb
->succs
);
4681 gcc_assert (len
> 0);
4682 e
= EDGE_SUCC (l0_bb
, len
- 1);
4683 si
= gsi_last_bb (e
->dest
);
4686 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
4687 l2
= gimple_block_label (e
->dest
);
4689 FOR_EACH_EDGE (e
, ei
, l0_bb
->succs
)
4691 si
= gsi_last_bb (e
->dest
);
4693 || gimple_code (gsi_stmt (si
)) != GIMPLE_OMP_SECTION
)
4695 l2
= gimple_block_label (e
->dest
);
4700 default_bb
= create_empty_bb (l1_bb
->prev_bb
);
4704 default_bb
= create_empty_bb (l0_bb
);
4705 l2
= gimple_block_label (default_bb
);
4708 /* We will build a switch() with enough cases for all the
4709 GIMPLE_OMP_SECTION regions, a '0' case to handle the end of more work
4710 and a default case to abort if something goes wrong. */
4711 len
= EDGE_COUNT (l0_bb
->succs
);
4713 /* Use VEC_quick_push on label_vec throughout, since we know the size
4715 label_vec
= VEC_alloc (tree
, heap
, len
);
4717 /* The call to GOMP_sections_start goes in ENTRY_BB, replacing the
4718 GIMPLE_OMP_SECTIONS statement. */
4719 si
= gsi_last_bb (entry_bb
);
4720 sections_stmt
= gsi_stmt (si
);
4721 gcc_assert (gimple_code (sections_stmt
) == GIMPLE_OMP_SECTIONS
);
4722 vin
= gimple_omp_sections_control (sections_stmt
);
4723 if (!is_combined_parallel (region
))
4725 /* If we are not inside a combined parallel+sections region,
4726 call GOMP_sections_start. */
4727 t
= build_int_cst (unsigned_type_node
,
4728 exit_reachable
? len
- 1 : len
);
4729 u
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_START
];
4730 stmt
= gimple_build_call (u
, 1, t
);
4734 /* Otherwise, call GOMP_sections_next. */
4735 u
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_NEXT
];
4736 stmt
= gimple_build_call (u
, 0);
4738 gimple_call_set_lhs (stmt
, vin
);
4739 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4740 gsi_remove (&si
, true);
4742 /* The switch() statement replacing GIMPLE_OMP_SECTIONS_SWITCH goes in
4744 switch_si
= gsi_last_bb (l0_bb
);
4745 gcc_assert (gimple_code (gsi_stmt (switch_si
)) == GIMPLE_OMP_SECTIONS_SWITCH
);
4748 cont
= last_stmt (l1_bb
);
4749 gcc_assert (gimple_code (cont
) == GIMPLE_OMP_CONTINUE
);
4750 vmain
= gimple_omp_continue_control_use (cont
);
4751 vnext
= gimple_omp_continue_control_def (cont
);
4762 t
= build3 (CASE_LABEL_EXPR
, void_type_node
,
4763 build_int_cst (unsigned_type_node
, 0), NULL
, l2
);
4764 VEC_quick_push (tree
, label_vec
, t
);
4768 /* Convert each GIMPLE_OMP_SECTION into a CASE_LABEL_EXPR. */
4769 for (inner
= region
->inner
, casei
= 1;
4771 inner
= inner
->next
, i
++, casei
++)
4773 basic_block s_entry_bb
, s_exit_bb
;
4775 /* Skip optional reduction region. */
4776 if (inner
->type
== GIMPLE_OMP_ATOMIC_LOAD
)
4783 s_entry_bb
= inner
->entry
;
4784 s_exit_bb
= inner
->exit
;
4786 t
= gimple_block_label (s_entry_bb
);
4787 u
= build_int_cst (unsigned_type_node
, casei
);
4788 u
= build3 (CASE_LABEL_EXPR
, void_type_node
, u
, NULL
, t
);
4789 VEC_quick_push (tree
, label_vec
, u
);
4791 si
= gsi_last_bb (s_entry_bb
);
4792 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SECTION
);
4793 gcc_assert (i
< len
|| gimple_omp_section_last_p (gsi_stmt (si
)));
4794 gsi_remove (&si
, true);
4795 single_succ_edge (s_entry_bb
)->flags
= EDGE_FALLTHRU
;
4797 if (s_exit_bb
== NULL
)
4800 si
= gsi_last_bb (s_exit_bb
);
4801 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
4802 gsi_remove (&si
, true);
4804 single_succ_edge (s_exit_bb
)->flags
= EDGE_FALLTHRU
;
4807 /* Error handling code goes in DEFAULT_BB. */
4808 t
= gimple_block_label (default_bb
);
4809 u
= build3 (CASE_LABEL_EXPR
, void_type_node
, NULL
, NULL
, t
);
4810 make_edge (l0_bb
, default_bb
, 0);
4812 stmt
= gimple_build_switch_vec (vmain
, u
, label_vec
);
4813 gsi_insert_after (&switch_si
, stmt
, GSI_SAME_STMT
);
4814 gsi_remove (&switch_si
, true);
4815 VEC_free (tree
, heap
, label_vec
);
4817 si
= gsi_start_bb (default_bb
);
4818 stmt
= gimple_build_call (built_in_decls
[BUILT_IN_TRAP
], 0);
4819 gsi_insert_after (&si
, stmt
, GSI_CONTINUE_LINKING
);
4823 /* Code to get the next section goes in L1_BB. */
4824 si
= gsi_last_bb (l1_bb
);
4825 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CONTINUE
);
4827 stmt
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_SECTIONS_NEXT
], 0);
4828 gimple_call_set_lhs (stmt
, vnext
);
4829 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4830 gsi_remove (&si
, true);
4832 single_succ_edge (l1_bb
)->flags
= EDGE_FALLTHRU
;
4834 /* Cleanup function replaces GIMPLE_OMP_RETURN in EXIT_BB. */
4835 si
= gsi_last_bb (l2_bb
);
4836 if (gimple_omp_return_nowait_p (gsi_stmt (si
)))
4837 t
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_END_NOWAIT
];
4839 t
= built_in_decls
[BUILT_IN_GOMP_SECTIONS_END
];
4840 stmt
= gimple_build_call (t
, 0);
4841 gsi_insert_after (&si
, stmt
, GSI_SAME_STMT
);
4842 gsi_remove (&si
, true);
4845 set_immediate_dominator (CDI_DOMINATORS
, default_bb
, l0_bb
);
4849 /* Expand code for an OpenMP single directive. We've already expanded
4850 much of the code, here we simply place the GOMP_barrier call. */
4853 expand_omp_single (struct omp_region
*region
)
4855 basic_block entry_bb
, exit_bb
;
4856 gimple_stmt_iterator si
;
4857 bool need_barrier
= false;
4859 entry_bb
= region
->entry
;
4860 exit_bb
= region
->exit
;
4862 si
= gsi_last_bb (entry_bb
);
4863 /* The terminal barrier at the end of a GOMP_single_copy sequence cannot
4864 be removed. We need to ensure that the thread that entered the single
4865 does not exit before the data is copied out by the other threads. */
4866 if (find_omp_clause (gimple_omp_single_clauses (gsi_stmt (si
)),
4867 OMP_CLAUSE_COPYPRIVATE
))
4868 need_barrier
= true;
4869 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
);
4870 gsi_remove (&si
, true);
4871 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
4873 si
= gsi_last_bb (exit_bb
);
4874 if (!gimple_omp_return_nowait_p (gsi_stmt (si
)) || need_barrier
)
4875 force_gimple_operand_gsi (&si
, build_omp_barrier (), false, NULL_TREE
,
4876 false, GSI_SAME_STMT
);
4877 gsi_remove (&si
, true);
4878 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
4882 /* Generic expansion for OpenMP synchronization directives: master,
4883 ordered and critical. All we need to do here is remove the entry
4884 and exit markers for REGION. */
4887 expand_omp_synch (struct omp_region
*region
)
4889 basic_block entry_bb
, exit_bb
;
4890 gimple_stmt_iterator si
;
4892 entry_bb
= region
->entry
;
4893 exit_bb
= region
->exit
;
4895 si
= gsi_last_bb (entry_bb
);
4896 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_SINGLE
4897 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_MASTER
4898 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ORDERED
4899 || gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_CRITICAL
);
4900 gsi_remove (&si
, true);
4901 single_succ_edge (entry_bb
)->flags
= EDGE_FALLTHRU
;
4905 si
= gsi_last_bb (exit_bb
);
4906 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_RETURN
);
4907 gsi_remove (&si
, true);
4908 single_succ_edge (exit_bb
)->flags
= EDGE_FALLTHRU
;
4912 /* A subroutine of expand_omp_atomic. Attempt to implement the atomic
4913 operation as a __sync_fetch_and_op builtin. INDEX is log2 of the
4914 size of the data type, and thus usable to find the index of the builtin
4915 decl. Returns false if the expression is not of the proper form. */
4918 expand_omp_atomic_fetch_op (basic_block load_bb
,
4919 tree addr
, tree loaded_val
,
4920 tree stored_val
, int index
)
4922 enum built_in_function base
;
4923 tree decl
, itype
, call
;
4924 enum insn_code
*optab
;
4926 basic_block store_bb
= single_succ (load_bb
);
4927 gimple_stmt_iterator gsi
;
4931 /* We expect to find the following sequences:
4934 GIMPLE_OMP_ATOMIC_LOAD (tmp, mem)
4937 val = tmp OP something; (or: something OP tmp)
4938 GIMPLE_OMP_STORE (val)
4940 ???FIXME: Allow a more flexible sequence.
4941 Perhaps use data flow to pick the statements.
4945 gsi
= gsi_after_labels (store_bb
);
4946 stmt
= gsi_stmt (gsi
);
4947 loc
= gimple_location (stmt
);
4948 if (!is_gimple_assign (stmt
))
4951 if (gimple_code (gsi_stmt (gsi
)) != GIMPLE_OMP_ATOMIC_STORE
)
4954 if (!operand_equal_p (gimple_assign_lhs (stmt
), stored_val
, 0))
4957 /* Check for one of the supported fetch-op operations. */
4958 switch (gimple_assign_rhs_code (stmt
))
4961 case POINTER_PLUS_EXPR
:
4962 base
= BUILT_IN_FETCH_AND_ADD_N
;
4963 optab
= sync_add_optab
;
4966 base
= BUILT_IN_FETCH_AND_SUB_N
;
4967 optab
= sync_add_optab
;
4970 base
= BUILT_IN_FETCH_AND_AND_N
;
4971 optab
= sync_and_optab
;
4974 base
= BUILT_IN_FETCH_AND_OR_N
;
4975 optab
= sync_ior_optab
;
4978 base
= BUILT_IN_FETCH_AND_XOR_N
;
4979 optab
= sync_xor_optab
;
4984 /* Make sure the expression is of the proper form. */
4985 if (operand_equal_p (gimple_assign_rhs1 (stmt
), loaded_val
, 0))
4986 rhs
= gimple_assign_rhs2 (stmt
);
4987 else if (commutative_tree_code (gimple_assign_rhs_code (stmt
))
4988 && operand_equal_p (gimple_assign_rhs2 (stmt
), loaded_val
, 0))
4989 rhs
= gimple_assign_rhs1 (stmt
);
4993 decl
= built_in_decls
[base
+ index
+ 1];
4994 itype
= TREE_TYPE (TREE_TYPE (decl
));
4996 if (optab
[TYPE_MODE (itype
)] == CODE_FOR_nothing
)
4999 gsi
= gsi_last_bb (load_bb
);
5000 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5001 call
= build_call_expr_loc (loc
,
5003 fold_convert_loc (loc
, itype
, rhs
));
5004 call
= fold_convert_loc (loc
, void_type_node
, call
);
5005 force_gimple_operand_gsi (&gsi
, call
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5006 gsi_remove (&gsi
, true);
5008 gsi
= gsi_last_bb (store_bb
);
5009 gcc_assert (gimple_code (gsi_stmt (gsi
)) == GIMPLE_OMP_ATOMIC_STORE
);
5010 gsi_remove (&gsi
, true);
5011 gsi
= gsi_last_bb (store_bb
);
5012 gsi_remove (&gsi
, true);
5014 if (gimple_in_ssa_p (cfun
))
5015 update_ssa (TODO_update_ssa_no_phi
);
5020 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5024 newval = rhs; // with oldval replacing *addr in rhs
5025 oldval = __sync_val_compare_and_swap (addr, oldval, newval);
5026 if (oldval != newval)
5029 INDEX is log2 of the size of the data type, and thus usable to find the
5030 index of the builtin decl. */
5033 expand_omp_atomic_pipeline (basic_block load_bb
, basic_block store_bb
,
5034 tree addr
, tree loaded_val
, tree stored_val
,
5037 tree loadedi
, storedi
, initial
, new_storedi
, old_vali
;
5038 tree type
, itype
, cmpxchg
, iaddr
;
5039 gimple_stmt_iterator si
;
5040 basic_block loop_header
= single_succ (load_bb
);
5044 cmpxchg
= built_in_decls
[BUILT_IN_VAL_COMPARE_AND_SWAP_N
+ index
+ 1];
5045 type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
5046 itype
= TREE_TYPE (TREE_TYPE (cmpxchg
));
5048 if (sync_compare_and_swap
[TYPE_MODE (itype
)] == CODE_FOR_nothing
)
5051 /* Load the initial value, replacing the GIMPLE_OMP_ATOMIC_LOAD. */
5052 si
= gsi_last_bb (load_bb
);
5053 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5055 /* For floating-point values, we'll need to view-convert them to integers
5056 so that we can perform the atomic compare and swap. Simplify the
5057 following code by always setting up the "i"ntegral variables. */
5058 if (!INTEGRAL_TYPE_P (type
) && !POINTER_TYPE_P (type
))
5062 iaddr
= create_tmp_var (build_pointer_type_for_mode (itype
, ptr_mode
,
5065 = force_gimple_operand_gsi (&si
,
5066 fold_convert (TREE_TYPE (iaddr
), addr
),
5067 false, NULL_TREE
, true, GSI_SAME_STMT
);
5068 stmt
= gimple_build_assign (iaddr
, iaddr_val
);
5069 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5070 loadedi
= create_tmp_var (itype
, NULL
);
5071 if (gimple_in_ssa_p (cfun
))
5073 add_referenced_var (iaddr
);
5074 add_referenced_var (loadedi
);
5075 loadedi
= make_ssa_name (loadedi
, NULL
);
5081 loadedi
= loaded_val
;
5084 initial
= force_gimple_operand_gsi (&si
, build_fold_indirect_ref (iaddr
),
5085 true, NULL_TREE
, true, GSI_SAME_STMT
);
5087 /* Move the value to the LOADEDI temporary. */
5088 if (gimple_in_ssa_p (cfun
))
5090 gcc_assert (gimple_seq_empty_p (phi_nodes (loop_header
)));
5091 phi
= create_phi_node (loadedi
, loop_header
);
5092 SSA_NAME_DEF_STMT (loadedi
) = phi
;
5093 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, single_succ_edge (load_bb
)),
5097 gsi_insert_before (&si
,
5098 gimple_build_assign (loadedi
, initial
),
5100 if (loadedi
!= loaded_val
)
5102 gimple_stmt_iterator gsi2
;
5105 x
= build1 (VIEW_CONVERT_EXPR
, type
, loadedi
);
5106 gsi2
= gsi_start_bb (loop_header
);
5107 if (gimple_in_ssa_p (cfun
))
5110 x
= force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
5111 true, GSI_SAME_STMT
);
5112 stmt
= gimple_build_assign (loaded_val
, x
);
5113 gsi_insert_before (&gsi2
, stmt
, GSI_SAME_STMT
);
5117 x
= build2 (MODIFY_EXPR
, TREE_TYPE (loaded_val
), loaded_val
, x
);
5118 force_gimple_operand_gsi (&gsi2
, x
, true, NULL_TREE
,
5119 true, GSI_SAME_STMT
);
5122 gsi_remove (&si
, true);
5124 si
= gsi_last_bb (store_bb
);
5125 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
5128 storedi
= stored_val
;
5131 force_gimple_operand_gsi (&si
,
5132 build1 (VIEW_CONVERT_EXPR
, itype
,
5133 stored_val
), true, NULL_TREE
, true,
5136 /* Build the compare&swap statement. */
5137 new_storedi
= build_call_expr (cmpxchg
, 3, iaddr
, loadedi
, storedi
);
5138 new_storedi
= force_gimple_operand_gsi (&si
,
5139 fold_convert (TREE_TYPE (loadedi
),
5142 true, GSI_SAME_STMT
);
5144 if (gimple_in_ssa_p (cfun
))
5148 old_vali
= create_tmp_var (TREE_TYPE (loadedi
), NULL
);
5149 if (gimple_in_ssa_p (cfun
))
5150 add_referenced_var (old_vali
);
5151 stmt
= gimple_build_assign (old_vali
, loadedi
);
5152 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5154 stmt
= gimple_build_assign (loadedi
, new_storedi
);
5155 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5158 /* Note that we always perform the comparison as an integer, even for
5159 floating point. This allows the atomic operation to properly
5160 succeed even with NaNs and -0.0. */
5161 stmt
= gimple_build_cond_empty
5162 (build2 (NE_EXPR
, boolean_type_node
,
5163 new_storedi
, old_vali
));
5164 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5167 e
= single_succ_edge (store_bb
);
5168 e
->flags
&= ~EDGE_FALLTHRU
;
5169 e
->flags
|= EDGE_FALSE_VALUE
;
5171 e
= make_edge (store_bb
, loop_header
, EDGE_TRUE_VALUE
);
5173 /* Copy the new value to loadedi (we already did that before the condition
5174 if we are not in SSA). */
5175 if (gimple_in_ssa_p (cfun
))
5177 phi
= gimple_seq_first_stmt (phi_nodes (loop_header
));
5178 SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi
, e
), new_storedi
);
5181 /* Remove GIMPLE_OMP_ATOMIC_STORE. */
5182 gsi_remove (&si
, true);
5184 if (gimple_in_ssa_p (cfun
))
5185 update_ssa (TODO_update_ssa_no_phi
);
5190 /* A subroutine of expand_omp_atomic. Implement the atomic operation as:
5192 GOMP_atomic_start ();
5196 The result is not globally atomic, but works so long as all parallel
5197 references are within #pragma omp atomic directives. According to
5198 responses received from omp@openmp.org, appears to be within spec.
5199 Which makes sense, since that's how several other compilers handle
5200 this situation as well.
5201 LOADED_VAL and ADDR are the operands of GIMPLE_OMP_ATOMIC_LOAD we're
5202 expanding. STORED_VAL is the operand of the matching
5203 GIMPLE_OMP_ATOMIC_STORE.
5206 GIMPLE_OMP_ATOMIC_LOAD (loaded_val, addr) with
5210 GIMPLE_OMP_ATOMIC_ATORE (stored_val) with
5215 expand_omp_atomic_mutex (basic_block load_bb
, basic_block store_bb
,
5216 tree addr
, tree loaded_val
, tree stored_val
)
5218 gimple_stmt_iterator si
;
5222 si
= gsi_last_bb (load_bb
);
5223 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_LOAD
);
5225 t
= built_in_decls
[BUILT_IN_GOMP_ATOMIC_START
];
5226 t
= build_function_call_expr (UNKNOWN_LOCATION
, t
, 0);
5227 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5229 stmt
= gimple_build_assign (loaded_val
, build_fold_indirect_ref (addr
));
5230 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5231 gsi_remove (&si
, true);
5233 si
= gsi_last_bb (store_bb
);
5234 gcc_assert (gimple_code (gsi_stmt (si
)) == GIMPLE_OMP_ATOMIC_STORE
);
5236 stmt
= gimple_build_assign (build_fold_indirect_ref (unshare_expr (addr
)),
5238 gsi_insert_before (&si
, stmt
, GSI_SAME_STMT
);
5240 t
= built_in_decls
[BUILT_IN_GOMP_ATOMIC_END
];
5241 t
= build_function_call_expr (UNKNOWN_LOCATION
, t
, 0);
5242 force_gimple_operand_gsi (&si
, t
, true, NULL_TREE
, true, GSI_SAME_STMT
);
5243 gsi_remove (&si
, true);
5245 if (gimple_in_ssa_p (cfun
))
5246 update_ssa (TODO_update_ssa_no_phi
);
5250 /* Expand an GIMPLE_OMP_ATOMIC statement. We try to expand
5251 using expand_omp_atomic_fetch_op. If it failed, we try to
5252 call expand_omp_atomic_pipeline, and if it fails too, the
5253 ultimate fallback is wrapping the operation in a mutex
5254 (expand_omp_atomic_mutex). REGION is the atomic region built
5255 by build_omp_regions_1(). */
5258 expand_omp_atomic (struct omp_region
*region
)
5260 basic_block load_bb
= region
->entry
, store_bb
= region
->exit
;
5261 gimple load
= last_stmt (load_bb
), store
= last_stmt (store_bb
);
5262 tree loaded_val
= gimple_omp_atomic_load_lhs (load
);
5263 tree addr
= gimple_omp_atomic_load_rhs (load
);
5264 tree stored_val
= gimple_omp_atomic_store_val (store
);
5265 tree type
= TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (addr
)));
5266 HOST_WIDE_INT index
;
5268 /* Make sure the type is one of the supported sizes. */
5269 index
= tree_low_cst (TYPE_SIZE_UNIT (type
), 1);
5270 index
= exact_log2 (index
);
5271 if (index
>= 0 && index
<= 4)
5273 unsigned int align
= TYPE_ALIGN_UNIT (type
);
5275 /* __sync builtins require strict data alignment. */
5276 if (exact_log2 (align
) >= index
)
5278 /* When possible, use specialized atomic update functions. */
5279 if ((INTEGRAL_TYPE_P (type
) || POINTER_TYPE_P (type
))
5280 && store_bb
== single_succ (load_bb
))
5282 if (expand_omp_atomic_fetch_op (load_bb
, addr
,
5283 loaded_val
, stored_val
, index
))
5287 /* If we don't have specialized __sync builtins, try and implement
5288 as a compare and swap loop. */
5289 if (expand_omp_atomic_pipeline (load_bb
, store_bb
, addr
,
5290 loaded_val
, stored_val
, index
))
5295 /* The ultimate fallback is wrapping the operation in a mutex. */
5296 expand_omp_atomic_mutex (load_bb
, store_bb
, addr
, loaded_val
, stored_val
);
5300 /* Expand the parallel region tree rooted at REGION. Expansion
5301 proceeds in depth-first order. Innermost regions are expanded
5302 first. This way, parallel regions that require a new function to
5303 be created (e.g., GIMPLE_OMP_PARALLEL) can be expanded without having any
5304 internal dependencies in their body. */
5307 expand_omp (struct omp_region
*region
)
5311 location_t saved_location
;
5313 /* First, determine whether this is a combined parallel+workshare
5315 if (region
->type
== GIMPLE_OMP_PARALLEL
)
5316 determine_parallel_type (region
);
5319 expand_omp (region
->inner
);
5321 saved_location
= input_location
;
5322 if (gimple_has_location (last_stmt (region
->entry
)))
5323 input_location
= gimple_location (last_stmt (region
->entry
));
5325 switch (region
->type
)
5327 case GIMPLE_OMP_PARALLEL
:
5328 case GIMPLE_OMP_TASK
:
5329 expand_omp_taskreg (region
);
5332 case GIMPLE_OMP_FOR
:
5333 expand_omp_for (region
);
5336 case GIMPLE_OMP_SECTIONS
:
5337 expand_omp_sections (region
);
5340 case GIMPLE_OMP_SECTION
:
5341 /* Individual omp sections are handled together with their
5342 parent GIMPLE_OMP_SECTIONS region. */
5345 case GIMPLE_OMP_SINGLE
:
5346 expand_omp_single (region
);
5349 case GIMPLE_OMP_MASTER
:
5350 case GIMPLE_OMP_ORDERED
:
5351 case GIMPLE_OMP_CRITICAL
:
5352 expand_omp_synch (region
);
5355 case GIMPLE_OMP_ATOMIC_LOAD
:
5356 expand_omp_atomic (region
);
5363 input_location
= saved_location
;
5364 region
= region
->next
;
5369 /* Helper for build_omp_regions. Scan the dominator tree starting at
5370 block BB. PARENT is the region that contains BB. If SINGLE_TREE is
5371 true, the function ends once a single tree is built (otherwise, whole
5372 forest of OMP constructs may be built). */
5375 build_omp_regions_1 (basic_block bb
, struct omp_region
*parent
,
5378 gimple_stmt_iterator gsi
;
5382 gsi
= gsi_last_bb (bb
);
5383 if (!gsi_end_p (gsi
) && is_gimple_omp (gsi_stmt (gsi
)))
5385 struct omp_region
*region
;
5386 enum gimple_code code
;
5388 stmt
= gsi_stmt (gsi
);
5389 code
= gimple_code (stmt
);
5390 if (code
== GIMPLE_OMP_RETURN
)
5392 /* STMT is the return point out of region PARENT. Mark it
5393 as the exit point and make PARENT the immediately
5394 enclosing region. */
5395 gcc_assert (parent
);
5398 parent
= parent
->outer
;
5400 else if (code
== GIMPLE_OMP_ATOMIC_STORE
)
5402 /* GIMPLE_OMP_ATOMIC_STORE is analoguous to
5403 GIMPLE_OMP_RETURN, but matches with
5404 GIMPLE_OMP_ATOMIC_LOAD. */
5405 gcc_assert (parent
);
5406 gcc_assert (parent
->type
== GIMPLE_OMP_ATOMIC_LOAD
);
5409 parent
= parent
->outer
;
5412 else if (code
== GIMPLE_OMP_CONTINUE
)
5414 gcc_assert (parent
);
5417 else if (code
== GIMPLE_OMP_SECTIONS_SWITCH
)
5419 /* GIMPLE_OMP_SECTIONS_SWITCH is part of
5420 GIMPLE_OMP_SECTIONS, and we do nothing for it. */
5425 /* Otherwise, this directive becomes the parent for a new
5427 region
= new_omp_region (bb
, code
, parent
);
5432 if (single_tree
&& !parent
)
5435 for (son
= first_dom_son (CDI_DOMINATORS
, bb
);
5437 son
= next_dom_son (CDI_DOMINATORS
, son
))
5438 build_omp_regions_1 (son
, parent
, single_tree
);
5441 /* Builds the tree of OMP regions rooted at ROOT, storing it to
5445 build_omp_regions_root (basic_block root
)
5447 gcc_assert (root_omp_region
== NULL
);
5448 build_omp_regions_1 (root
, NULL
, true);
5449 gcc_assert (root_omp_region
!= NULL
);
5452 /* Expands omp construct (and its subconstructs) starting in HEAD. */
5455 omp_expand_local (basic_block head
)
5457 build_omp_regions_root (head
);
5458 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
5460 fprintf (dump_file
, "\nOMP region tree\n\n");
5461 dump_omp_region (dump_file
, root_omp_region
, 0);
5462 fprintf (dump_file
, "\n");
5465 remove_exit_barriers (root_omp_region
);
5466 expand_omp (root_omp_region
);
5468 free_omp_regions ();
5471 /* Scan the CFG and build a tree of OMP regions. Return the root of
5472 the OMP region tree. */
5475 build_omp_regions (void)
5477 gcc_assert (root_omp_region
== NULL
);
5478 calculate_dominance_info (CDI_DOMINATORS
);
5479 build_omp_regions_1 (ENTRY_BLOCK_PTR
, NULL
, false);
5482 /* Main entry point for expanding OMP-GIMPLE into runtime calls. */
5485 execute_expand_omp (void)
5487 build_omp_regions ();
5489 if (!root_omp_region
)
5494 fprintf (dump_file
, "\nOMP region tree\n\n");
5495 dump_omp_region (dump_file
, root_omp_region
, 0);
5496 fprintf (dump_file
, "\n");
5499 remove_exit_barriers (root_omp_region
);
5501 expand_omp (root_omp_region
);
5503 cleanup_tree_cfg ();
5505 free_omp_regions ();
5510 /* OMP expansion -- the default pass, run before creation of SSA form. */
5513 gate_expand_omp (void)
5515 return (flag_openmp
!= 0 && errorcount
== 0);
5518 struct gimple_opt_pass pass_expand_omp
=
5522 "ompexp", /* name */
5523 gate_expand_omp
, /* gate */
5524 execute_expand_omp
, /* execute */
5527 0, /* static_pass_number */
5528 TV_NONE
, /* tv_id */
5529 PROP_gimple_any
, /* properties_required */
5530 0, /* properties_provided */
5531 0, /* properties_destroyed */
5532 0, /* todo_flags_start */
5533 TODO_dump_func
/* todo_flags_finish */
5537 /* Routines to lower OpenMP directives into OMP-GIMPLE. */
5539 /* Lower the OpenMP sections directive in the current statement in GSI_P.
5540 CTX is the enclosing OMP context for the current statement. */
5543 lower_omp_sections (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5545 tree block
, control
;
5546 gimple_stmt_iterator tgsi
;
5548 gimple stmt
, new_stmt
, bind
, t
;
5549 gimple_seq ilist
, dlist
, olist
, new_body
, body
;
5550 struct gimplify_ctx gctx
;
5552 stmt
= gsi_stmt (*gsi_p
);
5554 push_gimplify_context (&gctx
);
5558 lower_rec_input_clauses (gimple_omp_sections_clauses (stmt
),
5559 &ilist
, &dlist
, ctx
);
5561 tgsi
= gsi_start (gimple_omp_body (stmt
));
5562 for (len
= 0; !gsi_end_p (tgsi
); len
++, gsi_next (&tgsi
))
5565 tgsi
= gsi_start (gimple_omp_body (stmt
));
5567 for (i
= 0; i
< len
; i
++, gsi_next (&tgsi
))
5572 sec_start
= gsi_stmt (tgsi
);
5573 sctx
= maybe_lookup_ctx (sec_start
);
5576 gimple_seq_add_stmt (&body
, sec_start
);
5578 lower_omp (gimple_omp_body (sec_start
), sctx
);
5579 gimple_seq_add_seq (&body
, gimple_omp_body (sec_start
));
5580 gimple_omp_set_body (sec_start
, NULL
);
5584 gimple_seq l
= NULL
;
5585 lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt
), NULL
,
5587 gimple_seq_add_seq (&body
, l
);
5588 gimple_omp_section_set_last (sec_start
);
5591 gimple_seq_add_stmt (&body
, gimple_build_omp_return (false));
5594 block
= make_node (BLOCK
);
5595 bind
= gimple_build_bind (NULL
, body
, block
);
5598 lower_reduction_clauses (gimple_omp_sections_clauses (stmt
), &olist
, ctx
);
5600 block
= make_node (BLOCK
);
5601 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
5603 pop_gimplify_context (new_stmt
);
5604 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
5605 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
5606 if (BLOCK_VARS (block
))
5607 TREE_USED (block
) = 1;
5610 gimple_seq_add_seq (&new_body
, ilist
);
5611 gimple_seq_add_stmt (&new_body
, stmt
);
5612 gimple_seq_add_stmt (&new_body
, gimple_build_omp_sections_switch ());
5613 gimple_seq_add_stmt (&new_body
, bind
);
5615 control
= create_tmp_var (unsigned_type_node
, ".section");
5616 t
= gimple_build_omp_continue (control
, control
);
5617 gimple_omp_sections_set_control (stmt
, control
);
5618 gimple_seq_add_stmt (&new_body
, t
);
5620 gimple_seq_add_seq (&new_body
, olist
);
5621 gimple_seq_add_seq (&new_body
, dlist
);
5623 new_body
= maybe_catch_exception (new_body
);
5625 t
= gimple_build_omp_return
5626 (!!find_omp_clause (gimple_omp_sections_clauses (stmt
),
5627 OMP_CLAUSE_NOWAIT
));
5628 gimple_seq_add_stmt (&new_body
, t
);
5630 gimple_bind_set_body (new_stmt
, new_body
);
5631 gimple_omp_set_body (stmt
, NULL
);
5633 gsi_replace (gsi_p
, new_stmt
, true);
5637 /* A subroutine of lower_omp_single. Expand the simple form of
5638 a GIMPLE_OMP_SINGLE, without a copyprivate clause:
5640 if (GOMP_single_start ())
5642 [ GOMP_barrier (); ] -> unless 'nowait' is present.
5644 FIXME. It may be better to delay expanding the logic of this until
5645 pass_expand_omp. The expanded logic may make the job more difficult
5646 to a synchronization analysis pass. */
5649 lower_omp_single_simple (gimple single_stmt
, gimple_seq
*pre_p
)
5651 location_t loc
= gimple_location (single_stmt
);
5652 tree tlabel
= create_artificial_label (loc
);
5653 tree flabel
= create_artificial_label (loc
);
5657 decl
= built_in_decls
[BUILT_IN_GOMP_SINGLE_START
];
5658 lhs
= create_tmp_var (TREE_TYPE (TREE_TYPE (decl
)), NULL
);
5659 call
= gimple_build_call (decl
, 0);
5660 gimple_call_set_lhs (call
, lhs
);
5661 gimple_seq_add_stmt (pre_p
, call
);
5663 cond
= gimple_build_cond (EQ_EXPR
, lhs
,
5664 fold_convert_loc (loc
, TREE_TYPE (lhs
),
5667 gimple_seq_add_stmt (pre_p
, cond
);
5668 gimple_seq_add_stmt (pre_p
, gimple_build_label (tlabel
));
5669 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
5670 gimple_seq_add_stmt (pre_p
, gimple_build_label (flabel
));
5674 /* A subroutine of lower_omp_single. Expand the simple form of
5675 a GIMPLE_OMP_SINGLE, with a copyprivate clause:
5677 #pragma omp single copyprivate (a, b, c)
5679 Create a new structure to hold copies of 'a', 'b' and 'c' and emit:
5682 if ((copyout_p = GOMP_single_copy_start ()) == NULL)
5688 GOMP_single_copy_end (©out);
5699 FIXME. It may be better to delay expanding the logic of this until
5700 pass_expand_omp. The expanded logic may make the job more difficult
5701 to a synchronization analysis pass. */
5704 lower_omp_single_copy (gimple single_stmt
, gimple_seq
*pre_p
, omp_context
*ctx
)
5706 tree ptr_type
, t
, l0
, l1
, l2
;
5707 gimple_seq copyin_seq
;
5708 location_t loc
= gimple_location (single_stmt
);
5710 ctx
->sender_decl
= create_tmp_var (ctx
->record_type
, ".omp_copy_o");
5712 ptr_type
= build_pointer_type (ctx
->record_type
);
5713 ctx
->receiver_decl
= create_tmp_var (ptr_type
, ".omp_copy_i");
5715 l0
= create_artificial_label (loc
);
5716 l1
= create_artificial_label (loc
);
5717 l2
= create_artificial_label (loc
);
5719 t
= build_call_expr_loc (loc
, built_in_decls
[BUILT_IN_GOMP_SINGLE_COPY_START
], 0);
5720 t
= fold_convert_loc (loc
, ptr_type
, t
);
5721 gimplify_assign (ctx
->receiver_decl
, t
, pre_p
);
5723 t
= build2 (EQ_EXPR
, boolean_type_node
, ctx
->receiver_decl
,
5724 build_int_cst (ptr_type
, 0));
5725 t
= build3 (COND_EXPR
, void_type_node
, t
,
5726 build_and_jump (&l0
), build_and_jump (&l1
));
5727 gimplify_and_add (t
, pre_p
);
5729 gimple_seq_add_stmt (pre_p
, gimple_build_label (l0
));
5731 gimple_seq_add_seq (pre_p
, gimple_omp_body (single_stmt
));
5734 lower_copyprivate_clauses (gimple_omp_single_clauses (single_stmt
), pre_p
,
5737 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
5738 t
= build_call_expr_loc (loc
, built_in_decls
[BUILT_IN_GOMP_SINGLE_COPY_END
],
5740 gimplify_and_add (t
, pre_p
);
5742 t
= build_and_jump (&l2
);
5743 gimplify_and_add (t
, pre_p
);
5745 gimple_seq_add_stmt (pre_p
, gimple_build_label (l1
));
5747 gimple_seq_add_seq (pre_p
, copyin_seq
);
5749 gimple_seq_add_stmt (pre_p
, gimple_build_label (l2
));
5753 /* Expand code for an OpenMP single directive. */
5756 lower_omp_single (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5759 gimple t
, bind
, single_stmt
= gsi_stmt (*gsi_p
);
5760 gimple_seq bind_body
, dlist
;
5761 struct gimplify_ctx gctx
;
5763 push_gimplify_context (&gctx
);
5766 lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt
),
5767 &bind_body
, &dlist
, ctx
);
5768 lower_omp (gimple_omp_body (single_stmt
), ctx
);
5770 gimple_seq_add_stmt (&bind_body
, single_stmt
);
5772 if (ctx
->record_type
)
5773 lower_omp_single_copy (single_stmt
, &bind_body
, ctx
);
5775 lower_omp_single_simple (single_stmt
, &bind_body
);
5777 gimple_omp_set_body (single_stmt
, NULL
);
5779 gimple_seq_add_seq (&bind_body
, dlist
);
5781 bind_body
= maybe_catch_exception (bind_body
);
5783 t
= gimple_build_omp_return
5784 (!!find_omp_clause (gimple_omp_single_clauses (single_stmt
),
5785 OMP_CLAUSE_NOWAIT
));
5786 gimple_seq_add_stmt (&bind_body
, t
);
5788 block
= make_node (BLOCK
);
5789 bind
= gimple_build_bind (NULL
, bind_body
, block
);
5791 pop_gimplify_context (bind
);
5793 gimple_bind_append_vars (bind
, ctx
->block_vars
);
5794 BLOCK_VARS (block
) = ctx
->block_vars
;
5795 gsi_replace (gsi_p
, bind
, true);
5796 if (BLOCK_VARS (block
))
5797 TREE_USED (block
) = 1;
5801 /* Expand code for an OpenMP master directive. */
5804 lower_omp_master (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5806 tree block
, lab
= NULL
, x
;
5807 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
5808 location_t loc
= gimple_location (stmt
);
5810 struct gimplify_ctx gctx
;
5812 push_gimplify_context (&gctx
);
5814 block
= make_node (BLOCK
);
5815 bind
= gimple_build_bind (NULL
, gimple_seq_alloc_with_stmt (stmt
),
5818 x
= build_call_expr_loc (loc
, built_in_decls
[BUILT_IN_OMP_GET_THREAD_NUM
], 0);
5819 x
= build2 (EQ_EXPR
, boolean_type_node
, x
, integer_zero_node
);
5820 x
= build3 (COND_EXPR
, void_type_node
, x
, NULL
, build_and_jump (&lab
));
5822 gimplify_and_add (x
, &tseq
);
5823 gimple_bind_add_seq (bind
, tseq
);
5825 lower_omp (gimple_omp_body (stmt
), ctx
);
5826 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
5827 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
5828 gimple_omp_set_body (stmt
, NULL
);
5830 gimple_bind_add_stmt (bind
, gimple_build_label (lab
));
5832 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
5834 pop_gimplify_context (bind
);
5836 gimple_bind_append_vars (bind
, ctx
->block_vars
);
5837 BLOCK_VARS (block
) = ctx
->block_vars
;
5838 gsi_replace (gsi_p
, bind
, true);
5842 /* Expand code for an OpenMP ordered directive. */
5845 lower_omp_ordered (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5848 gimple stmt
= gsi_stmt (*gsi_p
), bind
, x
;
5849 struct gimplify_ctx gctx
;
5851 push_gimplify_context (&gctx
);
5853 block
= make_node (BLOCK
);
5854 bind
= gimple_build_bind (NULL
, gimple_seq_alloc_with_stmt (stmt
),
5857 x
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_ORDERED_START
], 0);
5858 gimple_bind_add_stmt (bind
, x
);
5860 lower_omp (gimple_omp_body (stmt
), ctx
);
5861 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
5862 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
5863 gimple_omp_set_body (stmt
, NULL
);
5865 x
= gimple_build_call (built_in_decls
[BUILT_IN_GOMP_ORDERED_END
], 0);
5866 gimple_bind_add_stmt (bind
, x
);
5868 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
5870 pop_gimplify_context (bind
);
5872 gimple_bind_append_vars (bind
, ctx
->block_vars
);
5873 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
5874 gsi_replace (gsi_p
, bind
, true);
5878 /* Gimplify a GIMPLE_OMP_CRITICAL statement. This is a relatively simple
5879 substitution of a couple of function calls. But in the NAMED case,
5880 requires that languages coordinate a symbol name. It is therefore
5881 best put here in common code. */
5883 static GTY((param1_is (tree
), param2_is (tree
)))
5884 splay_tree critical_name_mutexes
;
5887 lower_omp_critical (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
5890 tree name
, lock
, unlock
;
5891 gimple stmt
= gsi_stmt (*gsi_p
), bind
;
5892 location_t loc
= gimple_location (stmt
);
5894 struct gimplify_ctx gctx
;
5896 name
= gimple_omp_critical_name (stmt
);
5902 if (!critical_name_mutexes
)
5903 critical_name_mutexes
5904 = splay_tree_new_ggc (splay_tree_compare_pointers
);
5906 n
= splay_tree_lookup (critical_name_mutexes
, (splay_tree_key
) name
);
5911 decl
= create_tmp_var_raw (ptr_type_node
, NULL
);
5913 new_str
= ACONCAT ((".gomp_critical_user_",
5914 IDENTIFIER_POINTER (name
), NULL
));
5915 DECL_NAME (decl
) = get_identifier (new_str
);
5916 TREE_PUBLIC (decl
) = 1;
5917 TREE_STATIC (decl
) = 1;
5918 DECL_COMMON (decl
) = 1;
5919 DECL_ARTIFICIAL (decl
) = 1;
5920 DECL_IGNORED_P (decl
) = 1;
5921 varpool_finalize_decl (decl
);
5923 splay_tree_insert (critical_name_mutexes
, (splay_tree_key
) name
,
5924 (splay_tree_value
) decl
);
5927 decl
= (tree
) n
->value
;
5929 lock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_NAME_START
];
5930 lock
= build_call_expr_loc (loc
, lock
, 1, build_fold_addr_expr_loc (loc
, decl
));
5932 unlock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_NAME_END
];
5933 unlock
= build_call_expr_loc (loc
, unlock
, 1,
5934 build_fold_addr_expr_loc (loc
, decl
));
5938 lock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_START
];
5939 lock
= build_call_expr_loc (loc
, lock
, 0);
5941 unlock
= built_in_decls
[BUILT_IN_GOMP_CRITICAL_END
];
5942 unlock
= build_call_expr_loc (loc
, unlock
, 0);
5945 push_gimplify_context (&gctx
);
5947 block
= make_node (BLOCK
);
5948 bind
= gimple_build_bind (NULL
, gimple_seq_alloc_with_stmt (stmt
), block
);
5950 tbody
= gimple_bind_body (bind
);
5951 gimplify_and_add (lock
, &tbody
);
5952 gimple_bind_set_body (bind
, tbody
);
5954 lower_omp (gimple_omp_body (stmt
), ctx
);
5955 gimple_omp_set_body (stmt
, maybe_catch_exception (gimple_omp_body (stmt
)));
5956 gimple_bind_add_seq (bind
, gimple_omp_body (stmt
));
5957 gimple_omp_set_body (stmt
, NULL
);
5959 tbody
= gimple_bind_body (bind
);
5960 gimplify_and_add (unlock
, &tbody
);
5961 gimple_bind_set_body (bind
, tbody
);
5963 gimple_bind_add_stmt (bind
, gimple_build_omp_return (true));
5965 pop_gimplify_context (bind
);
5966 gimple_bind_append_vars (bind
, ctx
->block_vars
);
5967 BLOCK_VARS (block
) = gimple_bind_vars (bind
);
5968 gsi_replace (gsi_p
, bind
, true);
5972 /* A subroutine of lower_omp_for. Generate code to emit the predicate
5973 for a lastprivate clause. Given a loop control predicate of (V
5974 cond N2), we gate the clause on (!(V cond N2)). The lowered form
5975 is appended to *DLIST, iterator initialization is appended to
5979 lower_omp_for_lastprivate (struct omp_for_data
*fd
, gimple_seq
*body_p
,
5980 gimple_seq
*dlist
, struct omp_context
*ctx
)
5982 tree clauses
, cond
, vinit
;
5983 enum tree_code cond_code
;
5986 cond_code
= fd
->loop
.cond_code
;
5987 cond_code
= cond_code
== LT_EXPR
? GE_EXPR
: LE_EXPR
;
5989 /* When possible, use a strict equality expression. This can let VRP
5990 type optimizations deduce the value and remove a copy. */
5991 if (host_integerp (fd
->loop
.step
, 0))
5993 HOST_WIDE_INT step
= TREE_INT_CST_LOW (fd
->loop
.step
);
5994 if (step
== 1 || step
== -1)
5995 cond_code
= EQ_EXPR
;
5998 cond
= build2 (cond_code
, boolean_type_node
, fd
->loop
.v
, fd
->loop
.n2
);
6000 clauses
= gimple_omp_for_clauses (fd
->for_stmt
);
6002 lower_lastprivate_clauses (clauses
, cond
, &stmts
, ctx
);
6003 if (!gimple_seq_empty_p (stmts
))
6005 gimple_seq_add_seq (&stmts
, *dlist
);
6008 /* Optimize: v = 0; is usually cheaper than v = some_other_constant. */
6009 vinit
= fd
->loop
.n1
;
6010 if (cond_code
== EQ_EXPR
6011 && host_integerp (fd
->loop
.n2
, 0)
6012 && ! integer_zerop (fd
->loop
.n2
))
6013 vinit
= build_int_cst (TREE_TYPE (fd
->loop
.v
), 0);
6015 /* Initialize the iterator variable, so that threads that don't execute
6016 any iterations don't execute the lastprivate clauses by accident. */
6017 gimplify_assign (fd
->loop
.v
, vinit
, body_p
);
6022 /* Lower code for an OpenMP loop directive. */
6025 lower_omp_for (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6028 struct omp_for_data fd
;
6029 gimple stmt
= gsi_stmt (*gsi_p
), new_stmt
;
6030 gimple_seq omp_for_body
, body
, dlist
;
6032 struct gimplify_ctx gctx
;
6034 push_gimplify_context (&gctx
);
6036 lower_omp (gimple_omp_for_pre_body (stmt
), ctx
);
6037 lower_omp (gimple_omp_body (stmt
), ctx
);
6039 block
= make_node (BLOCK
);
6040 new_stmt
= gimple_build_bind (NULL
, NULL
, block
);
6042 /* Move declaration of temporaries in the loop body before we make
6044 omp_for_body
= gimple_omp_body (stmt
);
6045 if (!gimple_seq_empty_p (omp_for_body
)
6046 && gimple_code (gimple_seq_first_stmt (omp_for_body
)) == GIMPLE_BIND
)
6048 tree vars
= gimple_bind_vars (gimple_seq_first_stmt (omp_for_body
));
6049 gimple_bind_append_vars (new_stmt
, vars
);
6052 /* The pre-body and input clauses go before the lowered GIMPLE_OMP_FOR. */
6055 lower_rec_input_clauses (gimple_omp_for_clauses (stmt
), &body
, &dlist
, ctx
);
6056 gimple_seq_add_seq (&body
, gimple_omp_for_pre_body (stmt
));
6058 /* Lower the header expressions. At this point, we can assume that
6059 the header is of the form:
6061 #pragma omp for (V = VAL1; V {<|>|<=|>=} VAL2; V = V [+-] VAL3)
6063 We just need to make sure that VAL1, VAL2 and VAL3 are lowered
6064 using the .omp_data_s mapping, if needed. */
6065 for (i
= 0; i
< gimple_omp_for_collapse (stmt
); i
++)
6067 rhs_p
= gimple_omp_for_initial_ptr (stmt
, i
);
6068 if (!is_gimple_min_invariant (*rhs_p
))
6069 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6071 rhs_p
= gimple_omp_for_final_ptr (stmt
, i
);
6072 if (!is_gimple_min_invariant (*rhs_p
))
6073 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6075 rhs_p
= &TREE_OPERAND (gimple_omp_for_incr (stmt
, i
), 1);
6076 if (!is_gimple_min_invariant (*rhs_p
))
6077 *rhs_p
= get_formal_tmp_var (*rhs_p
, &body
);
6080 /* Once lowered, extract the bounds and clauses. */
6081 extract_omp_for_data (stmt
, &fd
, NULL
);
6083 lower_omp_for_lastprivate (&fd
, &body
, &dlist
, ctx
);
6085 gimple_seq_add_stmt (&body
, stmt
);
6086 gimple_seq_add_seq (&body
, gimple_omp_body (stmt
));
6088 gimple_seq_add_stmt (&body
, gimple_build_omp_continue (fd
.loop
.v
,
6091 /* After the loop, add exit clauses. */
6092 lower_reduction_clauses (gimple_omp_for_clauses (stmt
), &body
, ctx
);
6093 gimple_seq_add_seq (&body
, dlist
);
6095 body
= maybe_catch_exception (body
);
6097 /* Region exit marker goes at the end of the loop body. */
6098 gimple_seq_add_stmt (&body
, gimple_build_omp_return (fd
.have_nowait
));
6100 pop_gimplify_context (new_stmt
);
6102 gimple_bind_append_vars (new_stmt
, ctx
->block_vars
);
6103 BLOCK_VARS (block
) = gimple_bind_vars (new_stmt
);
6104 if (BLOCK_VARS (block
))
6105 TREE_USED (block
) = 1;
6107 gimple_bind_set_body (new_stmt
, body
);
6108 gimple_omp_set_body (stmt
, NULL
);
6109 gimple_omp_for_set_pre_body (stmt
, NULL
);
6110 gsi_replace (gsi_p
, new_stmt
, true);
6113 /* Callback for walk_stmts. Check if the current statement only contains
6114 GIMPLE_OMP_FOR or GIMPLE_OMP_PARALLEL. */
6117 check_combined_parallel (gimple_stmt_iterator
*gsi_p
,
6118 bool *handled_ops_p
,
6119 struct walk_stmt_info
*wi
)
6121 int *info
= (int *) wi
->info
;
6122 gimple stmt
= gsi_stmt (*gsi_p
);
6124 *handled_ops_p
= true;
6125 switch (gimple_code (stmt
))
6129 case GIMPLE_OMP_FOR
:
6130 case GIMPLE_OMP_SECTIONS
:
6131 *info
= *info
== 0 ? 1 : -1;
6140 struct omp_taskcopy_context
6142 /* This field must be at the beginning, as we do "inheritance": Some
6143 callback functions for tree-inline.c (e.g., omp_copy_decl)
6144 receive a copy_body_data pointer that is up-casted to an
6145 omp_context pointer. */
6151 task_copyfn_copy_decl (tree var
, copy_body_data
*cb
)
6153 struct omp_taskcopy_context
*tcctx
= (struct omp_taskcopy_context
*) cb
;
6155 if (splay_tree_lookup (tcctx
->ctx
->sfield_map
, (splay_tree_key
) var
))
6156 return create_tmp_var (TREE_TYPE (var
), NULL
);
6162 task_copyfn_remap_type (struct omp_taskcopy_context
*tcctx
, tree orig_type
)
6164 tree name
, new_fields
= NULL
, type
, f
;
6166 type
= lang_hooks
.types
.make_type (RECORD_TYPE
);
6167 name
= DECL_NAME (TYPE_NAME (orig_type
));
6168 name
= build_decl (gimple_location (tcctx
->ctx
->stmt
),
6169 TYPE_DECL
, name
, type
);
6170 TYPE_NAME (type
) = name
;
6172 for (f
= TYPE_FIELDS (orig_type
); f
; f
= TREE_CHAIN (f
))
6174 tree new_f
= copy_node (f
);
6175 DECL_CONTEXT (new_f
) = type
;
6176 TREE_TYPE (new_f
) = remap_type (TREE_TYPE (f
), &tcctx
->cb
);
6177 TREE_CHAIN (new_f
) = new_fields
;
6178 walk_tree (&DECL_SIZE (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
6179 walk_tree (&DECL_SIZE_UNIT (new_f
), copy_tree_body_r
, &tcctx
->cb
, NULL
);
6180 walk_tree (&DECL_FIELD_OFFSET (new_f
), copy_tree_body_r
,
6183 *pointer_map_insert (tcctx
->cb
.decl_map
, f
) = new_f
;
6185 TYPE_FIELDS (type
) = nreverse (new_fields
);
6190 /* Create task copyfn. */
6193 create_task_copyfn (gimple task_stmt
, omp_context
*ctx
)
6195 struct function
*child_cfun
;
6196 tree child_fn
, t
, c
, src
, dst
, f
, sf
, arg
, sarg
, decl
;
6197 tree record_type
, srecord_type
, bind
, list
;
6198 bool record_needs_remap
= false, srecord_needs_remap
= false;
6200 struct omp_taskcopy_context tcctx
;
6201 struct gimplify_ctx gctx
;
6202 location_t loc
= gimple_location (task_stmt
);
6204 child_fn
= gimple_omp_task_copy_fn (task_stmt
);
6205 child_cfun
= DECL_STRUCT_FUNCTION (child_fn
);
6206 gcc_assert (child_cfun
->cfg
== NULL
);
6207 child_cfun
->dont_save_pending_sizes_p
= 1;
6208 DECL_SAVED_TREE (child_fn
) = alloc_stmt_list ();
6210 /* Reset DECL_CONTEXT on function arguments. */
6211 for (t
= DECL_ARGUMENTS (child_fn
); t
; t
= TREE_CHAIN (t
))
6212 DECL_CONTEXT (t
) = child_fn
;
6214 /* Populate the function. */
6215 push_gimplify_context (&gctx
);
6216 current_function_decl
= child_fn
;
6218 bind
= build3 (BIND_EXPR
, void_type_node
, NULL
, NULL
, NULL
);
6219 TREE_SIDE_EFFECTS (bind
) = 1;
6221 DECL_SAVED_TREE (child_fn
) = bind
;
6222 DECL_SOURCE_LOCATION (child_fn
) = gimple_location (task_stmt
);
6224 /* Remap src and dst argument types if needed. */
6225 record_type
= ctx
->record_type
;
6226 srecord_type
= ctx
->srecord_type
;
6227 for (f
= TYPE_FIELDS (record_type
); f
; f
= TREE_CHAIN (f
))
6228 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
6230 record_needs_remap
= true;
6233 for (f
= TYPE_FIELDS (srecord_type
); f
; f
= TREE_CHAIN (f
))
6234 if (variably_modified_type_p (TREE_TYPE (f
), ctx
->cb
.src_fn
))
6236 srecord_needs_remap
= true;
6240 if (record_needs_remap
|| srecord_needs_remap
)
6242 memset (&tcctx
, '\0', sizeof (tcctx
));
6243 tcctx
.cb
.src_fn
= ctx
->cb
.src_fn
;
6244 tcctx
.cb
.dst_fn
= child_fn
;
6245 tcctx
.cb
.src_node
= cgraph_node (tcctx
.cb
.src_fn
);
6246 tcctx
.cb
.dst_node
= tcctx
.cb
.src_node
;
6247 tcctx
.cb
.src_cfun
= ctx
->cb
.src_cfun
;
6248 tcctx
.cb
.copy_decl
= task_copyfn_copy_decl
;
6249 tcctx
.cb
.eh_lp_nr
= 0;
6250 tcctx
.cb
.transform_call_graph_edges
= CB_CGE_MOVE
;
6251 tcctx
.cb
.decl_map
= pointer_map_create ();
6254 if (record_needs_remap
)
6255 record_type
= task_copyfn_remap_type (&tcctx
, record_type
);
6256 if (srecord_needs_remap
)
6257 srecord_type
= task_copyfn_remap_type (&tcctx
, srecord_type
);
6260 tcctx
.cb
.decl_map
= NULL
;
6262 push_cfun (child_cfun
);
6264 arg
= DECL_ARGUMENTS (child_fn
);
6265 TREE_TYPE (arg
) = build_pointer_type (record_type
);
6266 sarg
= TREE_CHAIN (arg
);
6267 TREE_TYPE (sarg
) = build_pointer_type (srecord_type
);
6269 /* First pass: initialize temporaries used in record_type and srecord_type
6270 sizes and field offsets. */
6271 if (tcctx
.cb
.decl_map
)
6272 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6273 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
6277 decl
= OMP_CLAUSE_DECL (c
);
6278 p
= (tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, decl
);
6281 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6282 sf
= (tree
) n
->value
;
6283 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6284 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6285 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6286 t
= build2 (MODIFY_EXPR
, TREE_TYPE (*p
), *p
, src
);
6287 append_to_statement_list (t
, &list
);
6290 /* Second pass: copy shared var pointers and copy construct non-VLA
6291 firstprivate vars. */
6292 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6293 switch (OMP_CLAUSE_CODE (c
))
6295 case OMP_CLAUSE_SHARED
:
6296 decl
= OMP_CLAUSE_DECL (c
);
6297 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6300 f
= (tree
) n
->value
;
6301 if (tcctx
.cb
.decl_map
)
6302 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6303 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6304 sf
= (tree
) n
->value
;
6305 if (tcctx
.cb
.decl_map
)
6306 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6307 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6308 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6309 dst
= build_fold_indirect_ref_loc (loc
, arg
);
6310 dst
= build3 (COMPONENT_REF
, TREE_TYPE (f
), dst
, f
, NULL
);
6311 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
6312 append_to_statement_list (t
, &list
);
6314 case OMP_CLAUSE_FIRSTPRIVATE
:
6315 decl
= OMP_CLAUSE_DECL (c
);
6316 if (is_variable_sized (decl
))
6318 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6321 f
= (tree
) n
->value
;
6322 if (tcctx
.cb
.decl_map
)
6323 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6324 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6327 sf
= (tree
) n
->value
;
6328 if (tcctx
.cb
.decl_map
)
6329 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6330 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6331 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6332 if (use_pointer_for_field (decl
, NULL
) || is_reference (decl
))
6333 src
= build_fold_indirect_ref_loc (loc
, src
);
6337 dst
= build_fold_indirect_ref_loc (loc
, arg
);
6338 dst
= build3 (COMPONENT_REF
, TREE_TYPE (f
), dst
, f
, NULL
);
6339 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
6340 append_to_statement_list (t
, &list
);
6342 case OMP_CLAUSE_PRIVATE
:
6343 if (! OMP_CLAUSE_PRIVATE_OUTER_REF (c
))
6345 decl
= OMP_CLAUSE_DECL (c
);
6346 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6347 f
= (tree
) n
->value
;
6348 if (tcctx
.cb
.decl_map
)
6349 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6350 n
= splay_tree_lookup (ctx
->sfield_map
, (splay_tree_key
) decl
);
6353 sf
= (tree
) n
->value
;
6354 if (tcctx
.cb
.decl_map
)
6355 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6356 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6357 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6358 if (use_pointer_for_field (decl
, NULL
))
6359 src
= build_fold_indirect_ref_loc (loc
, src
);
6363 dst
= build_fold_indirect_ref_loc (loc
, arg
);
6364 dst
= build3 (COMPONENT_REF
, TREE_TYPE (f
), dst
, f
, NULL
);
6365 t
= build2 (MODIFY_EXPR
, TREE_TYPE (dst
), dst
, src
);
6366 append_to_statement_list (t
, &list
);
6372 /* Last pass: handle VLA firstprivates. */
6373 if (tcctx
.cb
.decl_map
)
6374 for (c
= gimple_omp_task_clauses (task_stmt
); c
; c
= OMP_CLAUSE_CHAIN (c
))
6375 if (OMP_CLAUSE_CODE (c
) == OMP_CLAUSE_FIRSTPRIVATE
)
6379 decl
= OMP_CLAUSE_DECL (c
);
6380 if (!is_variable_sized (decl
))
6382 n
= splay_tree_lookup (ctx
->field_map
, (splay_tree_key
) decl
);
6385 f
= (tree
) n
->value
;
6386 f
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, f
);
6387 gcc_assert (DECL_HAS_VALUE_EXPR_P (decl
));
6388 ind
= DECL_VALUE_EXPR (decl
);
6389 gcc_assert (TREE_CODE (ind
) == INDIRECT_REF
);
6390 gcc_assert (DECL_P (TREE_OPERAND (ind
, 0)));
6391 n
= splay_tree_lookup (ctx
->sfield_map
,
6392 (splay_tree_key
) TREE_OPERAND (ind
, 0));
6393 sf
= (tree
) n
->value
;
6394 sf
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, sf
);
6395 src
= build_fold_indirect_ref_loc (loc
, sarg
);
6396 src
= build3 (COMPONENT_REF
, TREE_TYPE (sf
), src
, sf
, NULL
);
6397 src
= build_fold_indirect_ref_loc (loc
, src
);
6398 dst
= build_fold_indirect_ref_loc (loc
, arg
);
6399 dst
= build3 (COMPONENT_REF
, TREE_TYPE (f
), dst
, f
, NULL
);
6400 t
= lang_hooks
.decls
.omp_clause_copy_ctor (c
, dst
, src
);
6401 append_to_statement_list (t
, &list
);
6402 n
= splay_tree_lookup (ctx
->field_map
,
6403 (splay_tree_key
) TREE_OPERAND (ind
, 0));
6404 df
= (tree
) n
->value
;
6405 df
= *(tree
*) pointer_map_contains (tcctx
.cb
.decl_map
, df
);
6406 ptr
= build_fold_indirect_ref_loc (loc
, arg
);
6407 ptr
= build3 (COMPONENT_REF
, TREE_TYPE (df
), ptr
, df
, NULL
);
6408 t
= build2 (MODIFY_EXPR
, TREE_TYPE (ptr
), ptr
,
6409 build_fold_addr_expr_loc (loc
, dst
));
6410 append_to_statement_list (t
, &list
);
6413 t
= build1 (RETURN_EXPR
, void_type_node
, NULL
);
6414 append_to_statement_list (t
, &list
);
6416 if (tcctx
.cb
.decl_map
)
6417 pointer_map_destroy (tcctx
.cb
.decl_map
);
6418 pop_gimplify_context (NULL
);
6419 BIND_EXPR_BODY (bind
) = list
;
6421 current_function_decl
= ctx
->cb
.src_fn
;
6424 /* Lower the OpenMP parallel or task directive in the current statement
6425 in GSI_P. CTX holds context information for the directive. */
6428 lower_omp_taskreg (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6432 gimple stmt
= gsi_stmt (*gsi_p
);
6433 gimple par_bind
, bind
;
6434 gimple_seq par_body
, olist
, ilist
, par_olist
, par_ilist
, new_body
;
6435 struct gimplify_ctx gctx
;
6436 location_t loc
= gimple_location (stmt
);
6438 clauses
= gimple_omp_taskreg_clauses (stmt
);
6439 par_bind
= gimple_seq_first_stmt (gimple_omp_body (stmt
));
6440 par_body
= gimple_bind_body (par_bind
);
6441 child_fn
= ctx
->cb
.dst_fn
;
6442 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
6443 && !gimple_omp_parallel_combined_p (stmt
))
6445 struct walk_stmt_info wi
;
6448 memset (&wi
, 0, sizeof (wi
));
6451 walk_gimple_seq (par_body
, check_combined_parallel
, NULL
, &wi
);
6453 gimple_omp_parallel_set_combined_p (stmt
, true);
6455 if (ctx
->srecord_type
)
6456 create_task_copyfn (stmt
, ctx
);
6458 push_gimplify_context (&gctx
);
6462 lower_rec_input_clauses (clauses
, &par_ilist
, &par_olist
, ctx
);
6463 lower_omp (par_body
, ctx
);
6464 if (gimple_code (stmt
) == GIMPLE_OMP_PARALLEL
)
6465 lower_reduction_clauses (clauses
, &par_olist
, ctx
);
6467 /* Declare all the variables created by mapping and the variables
6468 declared in the scope of the parallel body. */
6469 record_vars_into (ctx
->block_vars
, child_fn
);
6470 record_vars_into (gimple_bind_vars (par_bind
), child_fn
);
6472 if (ctx
->record_type
)
6475 = create_tmp_var (ctx
->srecord_type
? ctx
->srecord_type
6476 : ctx
->record_type
, ".omp_data_o");
6477 TREE_ADDRESSABLE (ctx
->sender_decl
) = 1;
6478 gimple_omp_taskreg_set_data_arg (stmt
, ctx
->sender_decl
);
6483 lower_send_clauses (clauses
, &ilist
, &olist
, ctx
);
6484 lower_send_shared_vars (&ilist
, &olist
, ctx
);
6486 /* Once all the expansions are done, sequence all the different
6487 fragments inside gimple_omp_body. */
6491 if (ctx
->record_type
)
6493 t
= build_fold_addr_expr_loc (loc
, ctx
->sender_decl
);
6494 /* fixup_child_record_type might have changed receiver_decl's type. */
6495 t
= fold_convert_loc (loc
, TREE_TYPE (ctx
->receiver_decl
), t
);
6496 gimple_seq_add_stmt (&new_body
,
6497 gimple_build_assign (ctx
->receiver_decl
, t
));
6500 gimple_seq_add_seq (&new_body
, par_ilist
);
6501 gimple_seq_add_seq (&new_body
, par_body
);
6502 gimple_seq_add_seq (&new_body
, par_olist
);
6503 new_body
= maybe_catch_exception (new_body
);
6504 gimple_seq_add_stmt (&new_body
, gimple_build_omp_return (false));
6505 gimple_omp_set_body (stmt
, new_body
);
6507 bind
= gimple_build_bind (NULL
, NULL
, gimple_bind_block (par_bind
));
6508 gimple_bind_add_stmt (bind
, stmt
);
6511 gimple_seq_add_stmt (&ilist
, bind
);
6512 gimple_seq_add_seq (&ilist
, olist
);
6513 bind
= gimple_build_bind (NULL
, ilist
, NULL
);
6516 gsi_replace (gsi_p
, bind
, true);
6518 pop_gimplify_context (NULL
);
6521 /* Callback for lower_omp_1. Return non-NULL if *tp needs to be
6522 regimplified. If DATA is non-NULL, lower_omp_1 is outside
6523 of OpenMP context, but with task_shared_vars set. */
6526 lower_omp_regimplify_p (tree
*tp
, int *walk_subtrees
,
6531 /* Any variable with DECL_VALUE_EXPR needs to be regimplified. */
6532 if (TREE_CODE (t
) == VAR_DECL
&& data
== NULL
&& DECL_HAS_VALUE_EXPR_P (t
))
6535 if (task_shared_vars
6537 && bitmap_bit_p (task_shared_vars
, DECL_UID (t
)))
6540 /* If a global variable has been privatized, TREE_CONSTANT on
6541 ADDR_EXPR might be wrong. */
6542 if (data
== NULL
&& TREE_CODE (t
) == ADDR_EXPR
)
6543 recompute_tree_invariant_for_addr_expr (t
);
6545 *walk_subtrees
= !TYPE_P (t
) && !DECL_P (t
);
6550 lower_omp_1 (gimple_stmt_iterator
*gsi_p
, omp_context
*ctx
)
6552 gimple stmt
= gsi_stmt (*gsi_p
);
6553 struct walk_stmt_info wi
;
6555 if (gimple_has_location (stmt
))
6556 input_location
= gimple_location (stmt
);
6558 if (task_shared_vars
)
6559 memset (&wi
, '\0', sizeof (wi
));
6561 /* If we have issued syntax errors, avoid doing any heavy lifting.
6562 Just replace the OpenMP directives with a NOP to avoid
6563 confusing RTL expansion. */
6564 if (errorcount
&& is_gimple_omp (stmt
))
6566 gsi_replace (gsi_p
, gimple_build_nop (), true);
6570 switch (gimple_code (stmt
))
6573 if ((ctx
|| task_shared_vars
)
6574 && (walk_tree (gimple_cond_lhs_ptr (stmt
), lower_omp_regimplify_p
,
6575 ctx
? NULL
: &wi
, NULL
)
6576 || walk_tree (gimple_cond_rhs_ptr (stmt
), lower_omp_regimplify_p
,
6577 ctx
? NULL
: &wi
, NULL
)))
6578 gimple_regimplify_operands (stmt
, gsi_p
);
6581 lower_omp (gimple_catch_handler (stmt
), ctx
);
6583 case GIMPLE_EH_FILTER
:
6584 lower_omp (gimple_eh_filter_failure (stmt
), ctx
);
6587 lower_omp (gimple_try_eval (stmt
), ctx
);
6588 lower_omp (gimple_try_cleanup (stmt
), ctx
);
6591 lower_omp (gimple_bind_body (stmt
), ctx
);
6593 case GIMPLE_OMP_PARALLEL
:
6594 case GIMPLE_OMP_TASK
:
6595 ctx
= maybe_lookup_ctx (stmt
);
6596 lower_omp_taskreg (gsi_p
, ctx
);
6598 case GIMPLE_OMP_FOR
:
6599 ctx
= maybe_lookup_ctx (stmt
);
6601 lower_omp_for (gsi_p
, ctx
);
6603 case GIMPLE_OMP_SECTIONS
:
6604 ctx
= maybe_lookup_ctx (stmt
);
6606 lower_omp_sections (gsi_p
, ctx
);
6608 case GIMPLE_OMP_SINGLE
:
6609 ctx
= maybe_lookup_ctx (stmt
);
6611 lower_omp_single (gsi_p
, ctx
);
6613 case GIMPLE_OMP_MASTER
:
6614 ctx
= maybe_lookup_ctx (stmt
);
6616 lower_omp_master (gsi_p
, ctx
);
6618 case GIMPLE_OMP_ORDERED
:
6619 ctx
= maybe_lookup_ctx (stmt
);
6621 lower_omp_ordered (gsi_p
, ctx
);
6623 case GIMPLE_OMP_CRITICAL
:
6624 ctx
= maybe_lookup_ctx (stmt
);
6626 lower_omp_critical (gsi_p
, ctx
);
6628 case GIMPLE_OMP_ATOMIC_LOAD
:
6629 if ((ctx
|| task_shared_vars
)
6630 && walk_tree (gimple_omp_atomic_load_rhs_ptr (stmt
),
6631 lower_omp_regimplify_p
, ctx
? NULL
: &wi
, NULL
))
6632 gimple_regimplify_operands (stmt
, gsi_p
);
6635 if ((ctx
|| task_shared_vars
)
6636 && walk_gimple_op (stmt
, lower_omp_regimplify_p
,
6638 gimple_regimplify_operands (stmt
, gsi_p
);
6644 lower_omp (gimple_seq body
, omp_context
*ctx
)
6646 location_t saved_location
= input_location
;
6647 gimple_stmt_iterator gsi
= gsi_start (body
);
6648 for (gsi
= gsi_start (body
); !gsi_end_p (gsi
); gsi_next (&gsi
))
6649 lower_omp_1 (&gsi
, ctx
);
6650 input_location
= saved_location
;
6653 /* Main entry point. */
6656 execute_lower_omp (void)
6660 /* This pass always runs, to provide PROP_gimple_lomp.
6661 But there is nothing to do unless -fopenmp is given. */
6662 if (flag_openmp
== 0)
6665 all_contexts
= splay_tree_new (splay_tree_compare_pointers
, 0,
6666 delete_omp_context
);
6668 body
= gimple_body (current_function_decl
);
6669 scan_omp (body
, NULL
);
6670 gcc_assert (taskreg_nesting_level
== 0);
6672 if (all_contexts
->root
)
6674 struct gimplify_ctx gctx
;
6676 if (task_shared_vars
)
6677 push_gimplify_context (&gctx
);
6678 lower_omp (body
, NULL
);
6679 if (task_shared_vars
)
6680 pop_gimplify_context (NULL
);
6685 splay_tree_delete (all_contexts
);
6686 all_contexts
= NULL
;
6688 BITMAP_FREE (task_shared_vars
);
6692 struct gimple_opt_pass pass_lower_omp
=
6696 "omplower", /* name */
6698 execute_lower_omp
, /* execute */
6701 0, /* static_pass_number */
6702 TV_NONE
, /* tv_id */
6703 PROP_gimple_any
, /* properties_required */
6704 PROP_gimple_lomp
, /* properties_provided */
6705 0, /* properties_destroyed */
6706 0, /* todo_flags_start */
6707 TODO_dump_func
/* todo_flags_finish */
6711 /* The following is a utility to diagnose OpenMP structured block violations.
6712 It is not part of the "omplower" pass, as that's invoked too late. It
6713 should be invoked by the respective front ends after gimplification. */
6715 static splay_tree all_labels
;
6717 /* Check for mismatched contexts and generate an error if needed. Return
6718 true if an error is detected. */
6721 diagnose_sb_0 (gimple_stmt_iterator
*gsi_p
,
6722 gimple branch_ctx
, gimple label_ctx
)
6724 if (label_ctx
== branch_ctx
)
6729 Previously we kept track of the label's entire context in diagnose_sb_[12]
6730 so we could traverse it and issue a correct "exit" or "enter" error
6731 message upon a structured block violation.
6733 We built the context by building a list with tree_cons'ing, but there is
6734 no easy counterpart in gimple tuples. It seems like far too much work
6735 for issuing exit/enter error messages. If someone really misses the
6736 distinct error message... patches welcome.
6740 /* Try to avoid confusing the user by producing and error message
6741 with correct "exit" or "enter" verbiage. We prefer "exit"
6742 unless we can show that LABEL_CTX is nested within BRANCH_CTX. */
6743 if (branch_ctx
== NULL
)
6749 if (TREE_VALUE (label_ctx
) == branch_ctx
)
6754 label_ctx
= TREE_CHAIN (label_ctx
);
6759 error ("invalid exit from OpenMP structured block");
6761 error ("invalid entry to OpenMP structured block");
6764 /* If it's obvious we have an invalid entry, be specific about the error. */
6765 if (branch_ctx
== NULL
)
6766 error ("invalid entry to OpenMP structured block");
6768 /* Otherwise, be vague and lazy, but efficient. */
6769 error ("invalid branch to/from an OpenMP structured block");
6771 gsi_replace (gsi_p
, gimple_build_nop (), false);
6775 /* Pass 1: Create a minimal tree of OpenMP structured blocks, and record
6776 where each label is found. */
6779 diagnose_sb_1 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
6780 struct walk_stmt_info
*wi
)
6782 gimple context
= (gimple
) wi
->info
;
6783 gimple inner_context
;
6784 gimple stmt
= gsi_stmt (*gsi_p
);
6786 *handled_ops_p
= true;
6788 switch (gimple_code (stmt
))
6792 case GIMPLE_OMP_PARALLEL
:
6793 case GIMPLE_OMP_TASK
:
6794 case GIMPLE_OMP_SECTIONS
:
6795 case GIMPLE_OMP_SINGLE
:
6796 case GIMPLE_OMP_SECTION
:
6797 case GIMPLE_OMP_MASTER
:
6798 case GIMPLE_OMP_ORDERED
:
6799 case GIMPLE_OMP_CRITICAL
:
6800 /* The minimal context here is just the current OMP construct. */
6801 inner_context
= stmt
;
6802 wi
->info
= inner_context
;
6803 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
6807 case GIMPLE_OMP_FOR
:
6808 inner_context
= stmt
;
6809 wi
->info
= inner_context
;
6810 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
6812 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
6813 diagnose_sb_1
, NULL
, wi
);
6814 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_1
, NULL
, wi
);
6819 splay_tree_insert (all_labels
, (splay_tree_key
) gimple_label_label (stmt
),
6820 (splay_tree_value
) context
);
6830 /* Pass 2: Check each branch and see if its context differs from that of
6831 the destination label's context. */
6834 diagnose_sb_2 (gimple_stmt_iterator
*gsi_p
, bool *handled_ops_p
,
6835 struct walk_stmt_info
*wi
)
6837 gimple context
= (gimple
) wi
->info
;
6839 gimple stmt
= gsi_stmt (*gsi_p
);
6841 *handled_ops_p
= true;
6843 switch (gimple_code (stmt
))
6847 case GIMPLE_OMP_PARALLEL
:
6848 case GIMPLE_OMP_TASK
:
6849 case GIMPLE_OMP_SECTIONS
:
6850 case GIMPLE_OMP_SINGLE
:
6851 case GIMPLE_OMP_SECTION
:
6852 case GIMPLE_OMP_MASTER
:
6853 case GIMPLE_OMP_ORDERED
:
6854 case GIMPLE_OMP_CRITICAL
:
6856 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_2
, NULL
, wi
);
6860 case GIMPLE_OMP_FOR
:
6862 /* gimple_omp_for_{index,initial,final} are all DECLs; no need to
6864 walk_gimple_seq (gimple_omp_for_pre_body (stmt
),
6865 diagnose_sb_2
, NULL
, wi
);
6866 walk_gimple_seq (gimple_omp_body (stmt
), diagnose_sb_2
, NULL
, wi
);
6872 tree lab
= gimple_cond_true_label (stmt
);
6875 n
= splay_tree_lookup (all_labels
,
6876 (splay_tree_key
) lab
);
6877 diagnose_sb_0 (gsi_p
, context
,
6878 n
? (gimple
) n
->value
: NULL
);
6880 lab
= gimple_cond_false_label (stmt
);
6883 n
= splay_tree_lookup (all_labels
,
6884 (splay_tree_key
) lab
);
6885 diagnose_sb_0 (gsi_p
, context
,
6886 n
? (gimple
) n
->value
: NULL
);
6893 tree lab
= gimple_goto_dest (stmt
);
6894 if (TREE_CODE (lab
) != LABEL_DECL
)
6897 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
6898 diagnose_sb_0 (gsi_p
, context
, n
? (gimple
) n
->value
: NULL
);
6905 for (i
= 0; i
< gimple_switch_num_labels (stmt
); ++i
)
6907 tree lab
= CASE_LABEL (gimple_switch_label (stmt
, i
));
6908 n
= splay_tree_lookup (all_labels
, (splay_tree_key
) lab
);
6909 if (n
&& diagnose_sb_0 (gsi_p
, context
, (gimple
) n
->value
))
6916 diagnose_sb_0 (gsi_p
, context
, NULL
);
6927 diagnose_omp_structured_block_errors (void)
6929 struct walk_stmt_info wi
;
6930 gimple_seq body
= gimple_body (current_function_decl
);
6932 all_labels
= splay_tree_new (splay_tree_compare_pointers
, 0, 0);
6934 memset (&wi
, 0, sizeof (wi
));
6935 walk_gimple_seq (body
, diagnose_sb_1
, NULL
, &wi
);
6937 memset (&wi
, 0, sizeof (wi
));
6938 wi
.want_locations
= true;
6939 walk_gimple_seq (body
, diagnose_sb_2
, NULL
, &wi
);
6941 splay_tree_delete (all_labels
);
6948 gate_diagnose_omp_blocks (void)
6950 return flag_openmp
!= 0;
6953 struct gimple_opt_pass pass_diagnose_omp_blocks
=
6957 "*diagnose_omp_blocks", /* name */
6958 gate_diagnose_omp_blocks
, /* gate */
6959 diagnose_omp_structured_block_errors
, /* execute */
6962 0, /* static_pass_number */
6963 TV_NONE
, /* tv_id */
6964 PROP_gimple_any
, /* properties_required */
6965 0, /* properties_provided */
6966 0, /* properties_destroyed */
6967 0, /* todo_flags_start */
6968 0, /* todo_flags_finish */
6972 #include "gt-omp-low.h"