Update gcc-50 to SVN version 221572
[dragonfly.git] / contrib / gcc-5.0 / gcc / omp-low.c
CommitLineData
dda118e3
JM
1/* Lowering pass for OMP directives. Converts OMP directives into explicit
2 calls to the runtime library (libgomp), data marshalling to implement data
3 sharing and copying clauses, offloading to accelerators, and more.
4
5 Contributed by Diego Novillo <dnovillo@redhat.com>
6
7 Copyright (C) 2005-2015 Free Software Foundation, Inc.
8
9This file is part of GCC.
10
11GCC is free software; you can redistribute it and/or modify it under
12the terms of the GNU General Public License as published by the Free
13Software Foundation; either version 3, or (at your option) any later
14version.
15
16GCC is distributed in the hope that it will be useful, but WITHOUT ANY
17WARRANTY; without even the implied warranty of MERCHANTABILITY or
18FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19for more details.
20
21You should have received a copy of the GNU General Public License
22along with GCC; see the file COPYING3. If not see
23<http://www.gnu.org/licenses/>. */
24
25#include "config.h"
26#include "system.h"
27#include "coretypes.h"
28#include "tm.h"
29#include "hash-set.h"
30#include "machmode.h"
31#include "vec.h"
32#include "double-int.h"
33#include "input.h"
34#include "alias.h"
35#include "symtab.h"
36#include "wide-int.h"
37#include "inchash.h"
38#include "tree.h"
39#include "fold-const.h"
40#include "stringpool.h"
41#include "stor-layout.h"
42#include "rtl.h"
43#include "predict.h"
44#include "hard-reg-set.h"
45#include "function.h"
46#include "dominance.h"
47#include "cfg.h"
48#include "cfganal.h"
49#include "basic-block.h"
50#include "tree-ssa-alias.h"
51#include "internal-fn.h"
52#include "gimple-fold.h"
53#include "gimple-expr.h"
54#include "is-a.h"
55#include "gimple.h"
56#include "gimplify.h"
57#include "gimple-iterator.h"
58#include "gimplify-me.h"
59#include "gimple-walk.h"
60#include "tree-iterator.h"
61#include "tree-inline.h"
62#include "langhooks.h"
63#include "diagnostic-core.h"
64#include "gimple-ssa.h"
65#include "hash-map.h"
66#include "plugin-api.h"
67#include "ipa-ref.h"
68#include "cgraph.h"
69#include "tree-cfg.h"
70#include "tree-phinodes.h"
71#include "ssa-iterators.h"
72#include "tree-ssanames.h"
73#include "tree-into-ssa.h"
74#include "hashtab.h"
75#include "flags.h"
76#include "statistics.h"
77#include "real.h"
78#include "fixed-value.h"
79#include "insn-config.h"
80#include "expmed.h"
81#include "dojump.h"
82#include "explow.h"
83#include "calls.h"
84#include "emit-rtl.h"
85#include "varasm.h"
86#include "stmt.h"
87#include "expr.h"
88#include "tree-dfa.h"
89#include "tree-ssa.h"
90#include "tree-pass.h"
91#include "except.h"
92#include "splay-tree.h"
93#include "insn-codes.h"
94#include "optabs.h"
95#include "cfgloop.h"
96#include "target.h"
97#include "common/common-target.h"
98#include "omp-low.h"
99#include "gimple-low.h"
100#include "tree-cfgcleanup.h"
101#include "pretty-print.h"
102#include "alloc-pool.h"
103#include "symbol-summary.h"
104#include "ipa-prop.h"
105#include "tree-nested.h"
106#include "tree-eh.h"
107#include "cilk.h"
108#include "context.h"
109#include "lto-section-names.h"
110#include "gomp-constants.h"
111
112
113/* Lowering of OMP parallel and workshare constructs proceeds in two
114 phases. The first phase scans the function looking for OMP statements
115 and then for variables that must be replaced to satisfy data sharing
116 clauses. The second phase expands code for the constructs, as well as
117 re-gimplifying things when variables have been replaced with complex
118 expressions.
119
120 Final code generation is done by pass_expand_omp. The flowgraph is
121 scanned for regions which are then moved to a new
122 function, to be invoked by the thread library, or offloaded. */
123
124/* OMP region information. Every parallel and workshare
125 directive is enclosed between two markers, the OMP_* directive
126 and a corresponding OMP_RETURN statement. */
127
128struct omp_region
129{
130 /* The enclosing region. */
131 struct omp_region *outer;
132
133 /* First child region. */
134 struct omp_region *inner;
135
136 /* Next peer region. */
137 struct omp_region *next;
138
139 /* Block containing the omp directive as its last stmt. */
140 basic_block entry;
141
142 /* Block containing the OMP_RETURN as its last stmt. */
143 basic_block exit;
144
145 /* Block containing the OMP_CONTINUE as its last stmt. */
146 basic_block cont;
147
148 /* If this is a combined parallel+workshare region, this is a list
149 of additional arguments needed by the combined parallel+workshare
150 library call. */
151 vec<tree, va_gc> *ws_args;
152
153 /* The code for the omp directive of this region. */
154 enum gimple_code type;
155
156 /* Schedule kind, only used for OMP_FOR type regions. */
157 enum omp_clause_schedule_kind sched_kind;
158
159 /* True if this is a combined parallel+workshare region. */
160 bool is_combined_parallel;
161};
162
163/* Levels of parallelism as defined by OpenACC. Increasing numbers
164 correspond to deeper loop nesting levels. */
165#define MASK_GANG 1
166#define MASK_WORKER 2
167#define MASK_VECTOR 4
168
169/* Context structure. Used to store information about each parallel
170 directive in the code. */
171
172typedef struct omp_context
173{
174 /* This field must be at the beginning, as we do "inheritance": Some
175 callback functions for tree-inline.c (e.g., omp_copy_decl)
176 receive a copy_body_data pointer that is up-casted to an
177 omp_context pointer. */
178 copy_body_data cb;
179
180 /* The tree of contexts corresponding to the encountered constructs. */
181 struct omp_context *outer;
182 gimple stmt;
183
184 /* Map variables to fields in a structure that allows communication
185 between sending and receiving threads. */
186 splay_tree field_map;
187 tree record_type;
188 tree sender_decl;
189 tree receiver_decl;
190
191 /* These are used just by task contexts, if task firstprivate fn is
192 needed. srecord_type is used to communicate from the thread
193 that encountered the task construct to task firstprivate fn,
194 record_type is allocated by GOMP_task, initialized by task firstprivate
195 fn and passed to the task body fn. */
196 splay_tree sfield_map;
197 tree srecord_type;
198
199 /* A chain of variables to add to the top-level block surrounding the
200 construct. In the case of a parallel, this is in the child function. */
201 tree block_vars;
202
203 /* A map of reduction pointer variables. For accelerators, each
204 reduction variable is replaced with an array. Each thread, in turn,
205 is assigned to a slot on that array. */
206 splay_tree reduction_map;
207
208 /* Label to which GOMP_cancel{,llation_point} and explicit and implicit
209 barriers should jump to during omplower pass. */
210 tree cancel_label;
211
212 /* What to do with variables with implicitly determined sharing
213 attributes. */
214 enum omp_clause_default_kind default_kind;
215
216 /* Nesting depth of this context. Used to beautify error messages re
217 invalid gotos. The outermost ctx is depth 1, with depth 0 being
218 reserved for the main body of the function. */
219 int depth;
220
221 /* True if this parallel directive is nested within another. */
222 bool is_nested;
223
224 /* True if this construct can be cancelled. */
225 bool cancellable;
226
227 /* For OpenACC loops, a mask of gang, worker and vector used at
228 levels below this one. */
229 int gwv_below;
230 /* For OpenACC loops, a mask of gang, worker and vector used at
231 this level and above. For parallel and kernels clauses, a mask
232 indicating which of num_gangs/num_workers/num_vectors was used. */
233 int gwv_this;
234} omp_context;
235
236/* A structure holding the elements of:
237 for (V = N1; V cond N2; V += STEP) [...] */
238
239struct omp_for_data_loop
240{
241 tree v, n1, n2, step;
242 enum tree_code cond_code;
243};
244
245/* A structure describing the main elements of a parallel loop. */
246
247struct omp_for_data
248{
249 struct omp_for_data_loop loop;
250 tree chunk_size;
251 gomp_for *for_stmt;
252 tree pre, iter_type;
253 int collapse;
254 bool have_nowait, have_ordered;
255 enum omp_clause_schedule_kind sched_kind;
256 struct omp_for_data_loop *loops;
257};
258
259
260static splay_tree all_contexts;
261static int taskreg_nesting_level;
262static int target_nesting_level;
263static struct omp_region *root_omp_region;
264static bitmap task_shared_vars;
265static vec<omp_context *> taskreg_contexts;
266
267static void scan_omp (gimple_seq *, omp_context *);
268static tree scan_omp_1_op (tree *, int *, void *);
269
270#define WALK_SUBSTMTS \
271 case GIMPLE_BIND: \
272 case GIMPLE_TRY: \
273 case GIMPLE_CATCH: \
274 case GIMPLE_EH_FILTER: \
275 case GIMPLE_TRANSACTION: \
276 /* The sub-statements for these should be walked. */ \
277 *handled_ops_p = false; \
278 break;
279
280/* Helper function to get the name of the array containing the partial
281 reductions for OpenACC reductions. */
282static const char *
283oacc_get_reduction_array_id (tree node)
284{
285 const char *id = IDENTIFIER_POINTER (DECL_NAME (node));
286 int len = strlen ("OACC") + strlen (id);
287 char *temp_name = XALLOCAVEC (char, len + 1);
288 snprintf (temp_name, len + 1, "OACC%s", id);
289 return IDENTIFIER_POINTER (get_identifier (temp_name));
290}
291
292/* Determine the number of threads OpenACC threads used to determine the
293 size of the array of partial reductions. Currently, this is num_gangs
294 * vector_length. This value may be different than GOACC_GET_NUM_THREADS,
295 because it is independed of the device used. */
296
297static tree
298oacc_max_threads (omp_context *ctx)
299{
300 tree nthreads, vector_length, gangs, clauses;
301
302 gangs = fold_convert (sizetype, integer_one_node);
303 vector_length = gangs;
304
305 /* The reduction clause may be nested inside a loop directive.
306 Scan for the innermost vector_length clause. */
307 for (omp_context *oc = ctx; oc; oc = oc->outer)
308 {
309 if (gimple_code (oc->stmt) != GIMPLE_OMP_TARGET
310 || (gimple_omp_target_kind (oc->stmt)
311 != GF_OMP_TARGET_KIND_OACC_PARALLEL))
312 continue;
313
314 clauses = gimple_omp_target_clauses (oc->stmt);
315
316 vector_length = find_omp_clause (clauses, OMP_CLAUSE_VECTOR_LENGTH);
317 if (vector_length)
318 vector_length = fold_convert_loc (OMP_CLAUSE_LOCATION (vector_length),
319 sizetype,
320 OMP_CLAUSE_VECTOR_LENGTH_EXPR
321 (vector_length));
322 else
323 vector_length = fold_convert (sizetype, integer_one_node);
324
325 gangs = find_omp_clause (clauses, OMP_CLAUSE_NUM_GANGS);
326 if (gangs)
327 gangs = fold_convert_loc (OMP_CLAUSE_LOCATION (gangs), sizetype,
328 OMP_CLAUSE_NUM_GANGS_EXPR (gangs));
329 else
330 gangs = fold_convert (sizetype, integer_one_node);
331
332 break;
333 }
334
335 nthreads = fold_build2 (MULT_EXPR, sizetype, gangs, vector_length);
336
337 return nthreads;
338}
339
340/* Holds offload tables with decls. */
341vec<tree, va_gc> *offload_funcs, *offload_vars;
342
343/* Convenience function for calling scan_omp_1_op on tree operands. */
344
345static inline tree
346scan_omp_op (tree *tp, omp_context *ctx)
347{
348 struct walk_stmt_info wi;
349
350 memset (&wi, 0, sizeof (wi));
351 wi.info = ctx;
352 wi.want_locations = true;
353
354 return walk_tree (tp, scan_omp_1_op, &wi, NULL);
355}
356
357static void lower_omp (gimple_seq *, omp_context *);
358static tree lookup_decl_in_outer_ctx (tree, omp_context *);
359static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
360
361/* Find an OMP clause of type KIND within CLAUSES. */
362
363tree
364find_omp_clause (tree clauses, enum omp_clause_code kind)
365{
366 for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
367 if (OMP_CLAUSE_CODE (clauses) == kind)
368 return clauses;
369
370 return NULL_TREE;
371}
372
373/* Return true if CTX is for an omp parallel. */
374
375static inline bool
376is_parallel_ctx (omp_context *ctx)
377{
378 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL;
379}
380
381
382/* Return true if CTX is for an omp task. */
383
384static inline bool
385is_task_ctx (omp_context *ctx)
386{
387 return gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
388}
389
390
391/* Return true if CTX is for an omp parallel or omp task. */
392
393static inline bool
394is_taskreg_ctx (omp_context *ctx)
395{
396 return gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL
397 || gimple_code (ctx->stmt) == GIMPLE_OMP_TASK;
398}
399
400
401/* Return true if REGION is a combined parallel+workshare region. */
402
403static inline bool
404is_combined_parallel (struct omp_region *region)
405{
406 return region->is_combined_parallel;
407}
408
409
410/* Extract the header elements of parallel loop FOR_STMT and store
411 them into *FD. */
412
413static void
414extract_omp_for_data (gomp_for *for_stmt, struct omp_for_data *fd,
415 struct omp_for_data_loop *loops)
416{
417 tree t, var, *collapse_iter, *collapse_count;
418 tree count = NULL_TREE, iter_type = long_integer_type_node;
419 struct omp_for_data_loop *loop;
420 int i;
421 struct omp_for_data_loop dummy_loop;
422 location_t loc = gimple_location (for_stmt);
423 bool simd = gimple_omp_for_kind (for_stmt) & GF_OMP_FOR_SIMD;
424 bool distribute = gimple_omp_for_kind (for_stmt)
425 == GF_OMP_FOR_KIND_DISTRIBUTE;
426
427 fd->for_stmt = for_stmt;
428 fd->pre = NULL;
429 fd->collapse = gimple_omp_for_collapse (for_stmt);
430 if (fd->collapse > 1)
431 fd->loops = loops;
432 else
433 fd->loops = &fd->loop;
434
435 fd->have_nowait = distribute || simd;
436 fd->have_ordered = false;
437 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
438 fd->chunk_size = NULL_TREE;
439 if (gimple_omp_for_kind (fd->for_stmt) == GF_OMP_FOR_KIND_CILKFOR)
440 fd->sched_kind = OMP_CLAUSE_SCHEDULE_CILKFOR;
441 collapse_iter = NULL;
442 collapse_count = NULL;
443
444 for (t = gimple_omp_for_clauses (for_stmt); t ; t = OMP_CLAUSE_CHAIN (t))
445 switch (OMP_CLAUSE_CODE (t))
446 {
447 case OMP_CLAUSE_NOWAIT:
448 fd->have_nowait = true;
449 break;
450 case OMP_CLAUSE_ORDERED:
451 fd->have_ordered = true;
452 break;
453 case OMP_CLAUSE_SCHEDULE:
454 gcc_assert (!distribute);
455 fd->sched_kind = OMP_CLAUSE_SCHEDULE_KIND (t);
456 fd->chunk_size = OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (t);
457 break;
458 case OMP_CLAUSE_DIST_SCHEDULE:
459 gcc_assert (distribute);
460 fd->chunk_size = OMP_CLAUSE_DIST_SCHEDULE_CHUNK_EXPR (t);
461 break;
462 case OMP_CLAUSE_COLLAPSE:
463 if (fd->collapse > 1)
464 {
465 collapse_iter = &OMP_CLAUSE_COLLAPSE_ITERVAR (t);
466 collapse_count = &OMP_CLAUSE_COLLAPSE_COUNT (t);
467 }
468 break;
469 default:
470 break;
471 }
472
473 /* FIXME: for now map schedule(auto) to schedule(static).
474 There should be analysis to determine whether all iterations
475 are approximately the same amount of work (then schedule(static)
476 is best) or if it varies (then schedule(dynamic,N) is better). */
477 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_AUTO)
478 {
479 fd->sched_kind = OMP_CLAUSE_SCHEDULE_STATIC;
480 gcc_assert (fd->chunk_size == NULL);
481 }
482 gcc_assert (fd->collapse == 1 || collapse_iter != NULL);
483 if (fd->sched_kind == OMP_CLAUSE_SCHEDULE_RUNTIME)
484 gcc_assert (fd->chunk_size == NULL);
485 else if (fd->chunk_size == NULL)
486 {
487 /* We only need to compute a default chunk size for ordered
488 static loops and dynamic loops. */
489 if (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
490 || fd->have_ordered)
491 fd->chunk_size = (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
492 ? integer_zero_node : integer_one_node;
493 }
494
495 for (i = 0; i < fd->collapse; i++)
496 {
497 if (fd->collapse == 1)
498 loop = &fd->loop;
499 else if (loops != NULL)
500 loop = loops + i;
501 else
502 loop = &dummy_loop;
503
504 loop->v = gimple_omp_for_index (for_stmt, i);
505 gcc_assert (SSA_VAR_P (loop->v));
506 gcc_assert (TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
507 || TREE_CODE (TREE_TYPE (loop->v)) == POINTER_TYPE);
508 var = TREE_CODE (loop->v) == SSA_NAME ? SSA_NAME_VAR (loop->v) : loop->v;
509 loop->n1 = gimple_omp_for_initial (for_stmt, i);
510
511 loop->cond_code = gimple_omp_for_cond (for_stmt, i);
512 loop->n2 = gimple_omp_for_final (for_stmt, i);
513 switch (loop->cond_code)
514 {
515 case LT_EXPR:
516 case GT_EXPR:
517 break;
518 case NE_EXPR:
519 gcc_assert (gimple_omp_for_kind (for_stmt)
520 == GF_OMP_FOR_KIND_CILKSIMD
521 || (gimple_omp_for_kind (for_stmt)
522 == GF_OMP_FOR_KIND_CILKFOR));
523 break;
524 case LE_EXPR:
525 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
526 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, 1);
527 else
528 loop->n2 = fold_build2_loc (loc,
529 PLUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
530 build_int_cst (TREE_TYPE (loop->n2), 1));
531 loop->cond_code = LT_EXPR;
532 break;
533 case GE_EXPR:
534 if (POINTER_TYPE_P (TREE_TYPE (loop->n2)))
535 loop->n2 = fold_build_pointer_plus_hwi_loc (loc, loop->n2, -1);
536 else
537 loop->n2 = fold_build2_loc (loc,
538 MINUS_EXPR, TREE_TYPE (loop->n2), loop->n2,
539 build_int_cst (TREE_TYPE (loop->n2), 1));
540 loop->cond_code = GT_EXPR;
541 break;
542 default:
543 gcc_unreachable ();
544 }
545
546 t = gimple_omp_for_incr (for_stmt, i);
547 gcc_assert (TREE_OPERAND (t, 0) == var);
548 switch (TREE_CODE (t))
549 {
550 case PLUS_EXPR:
551 loop->step = TREE_OPERAND (t, 1);
552 break;
553 case POINTER_PLUS_EXPR:
554 loop->step = fold_convert (ssizetype, TREE_OPERAND (t, 1));
555 break;
556 case MINUS_EXPR:
557 loop->step = TREE_OPERAND (t, 1);
558 loop->step = fold_build1_loc (loc,
559 NEGATE_EXPR, TREE_TYPE (loop->step),
560 loop->step);
561 break;
562 default:
563 gcc_unreachable ();
564 }
565
566 if (simd
567 || (fd->sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
568 && !fd->have_ordered))
569 {
570 if (fd->collapse == 1)
571 iter_type = TREE_TYPE (loop->v);
572 else if (i == 0
573 || TYPE_PRECISION (iter_type)
574 < TYPE_PRECISION (TREE_TYPE (loop->v)))
575 iter_type
576 = build_nonstandard_integer_type
577 (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
578 }
579 else if (iter_type != long_long_unsigned_type_node)
580 {
581 if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
582 iter_type = long_long_unsigned_type_node;
583 else if (TYPE_UNSIGNED (TREE_TYPE (loop->v))
584 && TYPE_PRECISION (TREE_TYPE (loop->v))
585 >= TYPE_PRECISION (iter_type))
586 {
587 tree n;
588
589 if (loop->cond_code == LT_EXPR)
590 n = fold_build2_loc (loc,
591 PLUS_EXPR, TREE_TYPE (loop->v),
592 loop->n2, loop->step);
593 else
594 n = loop->n1;
595 if (TREE_CODE (n) != INTEGER_CST
596 || tree_int_cst_lt (TYPE_MAX_VALUE (iter_type), n))
597 iter_type = long_long_unsigned_type_node;
598 }
599 else if (TYPE_PRECISION (TREE_TYPE (loop->v))
600 > TYPE_PRECISION (iter_type))
601 {
602 tree n1, n2;
603
604 if (loop->cond_code == LT_EXPR)
605 {
606 n1 = loop->n1;
607 n2 = fold_build2_loc (loc,
608 PLUS_EXPR, TREE_TYPE (loop->v),
609 loop->n2, loop->step);
610 }
611 else
612 {
613 n1 = fold_build2_loc (loc,
614 MINUS_EXPR, TREE_TYPE (loop->v),
615 loop->n2, loop->step);
616 n2 = loop->n1;
617 }
618 if (TREE_CODE (n1) != INTEGER_CST
619 || TREE_CODE (n2) != INTEGER_CST
620 || !tree_int_cst_lt (TYPE_MIN_VALUE (iter_type), n1)
621 || !tree_int_cst_lt (n2, TYPE_MAX_VALUE (iter_type)))
622 iter_type = long_long_unsigned_type_node;
623 }
624 }
625
626 if (collapse_count && *collapse_count == NULL)
627 {
628 t = fold_binary (loop->cond_code, boolean_type_node,
629 fold_convert (TREE_TYPE (loop->v), loop->n1),
630 fold_convert (TREE_TYPE (loop->v), loop->n2));
631 if (t && integer_zerop (t))
632 count = build_zero_cst (long_long_unsigned_type_node);
633 else if ((i == 0 || count != NULL_TREE)
634 && TREE_CODE (TREE_TYPE (loop->v)) == INTEGER_TYPE
635 && TREE_CONSTANT (loop->n1)
636 && TREE_CONSTANT (loop->n2)
637 && TREE_CODE (loop->step) == INTEGER_CST)
638 {
639 tree itype = TREE_TYPE (loop->v);
640
641 if (POINTER_TYPE_P (itype))
642 itype = signed_type_for (itype);
643 t = build_int_cst (itype, (loop->cond_code == LT_EXPR ? -1 : 1));
644 t = fold_build2_loc (loc,
645 PLUS_EXPR, itype,
646 fold_convert_loc (loc, itype, loop->step), t);
647 t = fold_build2_loc (loc, PLUS_EXPR, itype, t,
648 fold_convert_loc (loc, itype, loop->n2));
649 t = fold_build2_loc (loc, MINUS_EXPR, itype, t,
650 fold_convert_loc (loc, itype, loop->n1));
651 if (TYPE_UNSIGNED (itype) && loop->cond_code == GT_EXPR)
652 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype,
653 fold_build1_loc (loc, NEGATE_EXPR, itype, t),
654 fold_build1_loc (loc, NEGATE_EXPR, itype,
655 fold_convert_loc (loc, itype,
656 loop->step)));
657 else
658 t = fold_build2_loc (loc, TRUNC_DIV_EXPR, itype, t,
659 fold_convert_loc (loc, itype, loop->step));
660 t = fold_convert_loc (loc, long_long_unsigned_type_node, t);
661 if (count != NULL_TREE)
662 count = fold_build2_loc (loc,
663 MULT_EXPR, long_long_unsigned_type_node,
664 count, t);
665 else
666 count = t;
667 if (TREE_CODE (count) != INTEGER_CST)
668 count = NULL_TREE;
669 }
670 else if (count && !integer_zerop (count))
671 count = NULL_TREE;
672 }
673 }
674
675 if (count
676 && !simd
677 && (fd->sched_kind != OMP_CLAUSE_SCHEDULE_STATIC
678 || fd->have_ordered))
679 {
680 if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
681 iter_type = long_long_unsigned_type_node;
682 else
683 iter_type = long_integer_type_node;
684 }
685 else if (collapse_iter && *collapse_iter != NULL)
686 iter_type = TREE_TYPE (*collapse_iter);
687 fd->iter_type = iter_type;
688 if (collapse_iter && *collapse_iter == NULL)
689 *collapse_iter = create_tmp_var (iter_type, ".iter");
690 if (collapse_count && *collapse_count == NULL)
691 {
692 if (count)
693 *collapse_count = fold_convert_loc (loc, iter_type, count);
694 else
695 *collapse_count = create_tmp_var (iter_type, ".count");
696 }
697
698 if (fd->collapse > 1)
699 {
700 fd->loop.v = *collapse_iter;
701 fd->loop.n1 = build_int_cst (TREE_TYPE (fd->loop.v), 0);
702 fd->loop.n2 = *collapse_count;
703 fd->loop.step = build_int_cst (TREE_TYPE (fd->loop.v), 1);
704 fd->loop.cond_code = LT_EXPR;
705 }
706
707 /* For OpenACC loops, force a chunk size of one, as this avoids the default
708 scheduling where several subsequent iterations are being executed by the
709 same thread. */
710 if (gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_OACC_LOOP)
711 {
712 gcc_assert (fd->chunk_size == NULL_TREE);
713 fd->chunk_size = build_int_cst (TREE_TYPE (fd->loop.v), 1);
714 }
715}
716
717
718/* Given two blocks PAR_ENTRY_BB and WS_ENTRY_BB such that WS_ENTRY_BB
719 is the immediate dominator of PAR_ENTRY_BB, return true if there
720 are no data dependencies that would prevent expanding the parallel
721 directive at PAR_ENTRY_BB as a combined parallel+workshare region.
722
723 When expanding a combined parallel+workshare region, the call to
724 the child function may need additional arguments in the case of
725 GIMPLE_OMP_FOR regions. In some cases, these arguments are
726 computed out of variables passed in from the parent to the child
727 via 'struct .omp_data_s'. For instance:
728
729 #pragma omp parallel for schedule (guided, i * 4)
730 for (j ...)
731
732 Is lowered into:
733
734 # BLOCK 2 (PAR_ENTRY_BB)
735 .omp_data_o.i = i;
736 #pragma omp parallel [child fn: bar.omp_fn.0 ( ..., D.1598)
737
738 # BLOCK 3 (WS_ENTRY_BB)
739 .omp_data_i = &.omp_data_o;
740 D.1667 = .omp_data_i->i;
741 D.1598 = D.1667 * 4;
742 #pragma omp for schedule (guided, D.1598)
743
744 When we outline the parallel region, the call to the child function
745 'bar.omp_fn.0' will need the value D.1598 in its argument list, but
746 that value is computed *after* the call site. So, in principle we
747 cannot do the transformation.
748
749 To see whether the code in WS_ENTRY_BB blocks the combined
750 parallel+workshare call, we collect all the variables used in the
751 GIMPLE_OMP_FOR header check whether they appear on the LHS of any
752 statement in WS_ENTRY_BB. If so, then we cannot emit the combined
753 call.
754
755 FIXME. If we had the SSA form built at this point, we could merely
756 hoist the code in block 3 into block 2 and be done with it. But at
757 this point we don't have dataflow information and though we could
758 hack something up here, it is really not worth the aggravation. */
759
760static bool
761workshare_safe_to_combine_p (basic_block ws_entry_bb)
762{
763 struct omp_for_data fd;
764 gimple ws_stmt = last_stmt (ws_entry_bb);
765
766 if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
767 return true;
768
769 gcc_assert (gimple_code (ws_stmt) == GIMPLE_OMP_FOR);
770
771 extract_omp_for_data (as_a <gomp_for *> (ws_stmt), &fd, NULL);
772
773 if (fd.collapse > 1 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
774 return false;
775 if (fd.iter_type != long_integer_type_node)
776 return false;
777
778 /* FIXME. We give up too easily here. If any of these arguments
779 are not constants, they will likely involve variables that have
780 been mapped into fields of .omp_data_s for sharing with the child
781 function. With appropriate data flow, it would be possible to
782 see through this. */
783 if (!is_gimple_min_invariant (fd.loop.n1)
784 || !is_gimple_min_invariant (fd.loop.n2)
785 || !is_gimple_min_invariant (fd.loop.step)
786 || (fd.chunk_size && !is_gimple_min_invariant (fd.chunk_size)))
787 return false;
788
789 return true;
790}
791
792
793/* Collect additional arguments needed to emit a combined
794 parallel+workshare call. WS_STMT is the workshare directive being
795 expanded. */
796
797static vec<tree, va_gc> *
798get_ws_args_for (gimple par_stmt, gimple ws_stmt)
799{
800 tree t;
801 location_t loc = gimple_location (ws_stmt);
802 vec<tree, va_gc> *ws_args;
803
804 if (gomp_for *for_stmt = dyn_cast <gomp_for *> (ws_stmt))
805 {
806 struct omp_for_data fd;
807 tree n1, n2;
808
809 extract_omp_for_data (for_stmt, &fd, NULL);
810 n1 = fd.loop.n1;
811 n2 = fd.loop.n2;
812
813 if (gimple_omp_for_combined_into_p (for_stmt))
814 {
815 tree innerc
816 = find_omp_clause (gimple_omp_parallel_clauses (par_stmt),
817 OMP_CLAUSE__LOOPTEMP_);
818 gcc_assert (innerc);
819 n1 = OMP_CLAUSE_DECL (innerc);
820 innerc = find_omp_clause (OMP_CLAUSE_CHAIN (innerc),
821 OMP_CLAUSE__LOOPTEMP_);
822 gcc_assert (innerc);
823 n2 = OMP_CLAUSE_DECL (innerc);
824 }
825
826 vec_alloc (ws_args, 3 + (fd.chunk_size != 0));
827
828 t = fold_convert_loc (loc, long_integer_type_node, n1);
829 ws_args->quick_push (t);
830
831 t = fold_convert_loc (loc, long_integer_type_node, n2);
832 ws_args->quick_push (t);
833
834 t = fold_convert_loc (loc, long_integer_type_node, fd.loop.step);
835 ws_args->quick_push (t);
836
837 if (fd.chunk_size)
838 {
839 t = fold_convert_loc (loc, long_integer_type_node, fd.chunk_size);
840 ws_args->quick_push (t);
841 }
842
843 return ws_args;
844 }
845 else if (gimple_code (ws_stmt) == GIMPLE_OMP_SECTIONS)
846 {
847 /* Number of sections is equal to the number of edges from the
848 GIMPLE_OMP_SECTIONS_SWITCH statement, except for the one to
849 the exit of the sections region. */
850 basic_block bb = single_succ (gimple_bb (ws_stmt));
851 t = build_int_cst (unsigned_type_node, EDGE_COUNT (bb->succs) - 1);
852 vec_alloc (ws_args, 1);
853 ws_args->quick_push (t);
854 return ws_args;
855 }
856
857 gcc_unreachable ();
858}
859
860
861/* Discover whether REGION is a combined parallel+workshare region. */
862
863static void
864determine_parallel_type (struct omp_region *region)
865{
866 basic_block par_entry_bb, par_exit_bb;
867 basic_block ws_entry_bb, ws_exit_bb;
868
869 if (region == NULL || region->inner == NULL
870 || region->exit == NULL || region->inner->exit == NULL
871 || region->inner->cont == NULL)
872 return;
873
874 /* We only support parallel+for and parallel+sections. */
875 if (region->type != GIMPLE_OMP_PARALLEL
876 || (region->inner->type != GIMPLE_OMP_FOR
877 && region->inner->type != GIMPLE_OMP_SECTIONS))
878 return;
879
880 /* Check for perfect nesting PAR_ENTRY_BB -> WS_ENTRY_BB and
881 WS_EXIT_BB -> PAR_EXIT_BB. */
882 par_entry_bb = region->entry;
883 par_exit_bb = region->exit;
884 ws_entry_bb = region->inner->entry;
885 ws_exit_bb = region->inner->exit;
886
887 if (single_succ (par_entry_bb) == ws_entry_bb
888 && single_succ (ws_exit_bb) == par_exit_bb
889 && workshare_safe_to_combine_p (ws_entry_bb)
890 && (gimple_omp_parallel_combined_p (last_stmt (par_entry_bb))
891 || (last_and_only_stmt (ws_entry_bb)
892 && last_and_only_stmt (par_exit_bb))))
893 {
894 gimple par_stmt = last_stmt (par_entry_bb);
895 gimple ws_stmt = last_stmt (ws_entry_bb);
896
897 if (region->inner->type == GIMPLE_OMP_FOR)
898 {
899 /* If this is a combined parallel loop, we need to determine
900 whether or not to use the combined library calls. There
901 are two cases where we do not apply the transformation:
902 static loops and any kind of ordered loop. In the first
903 case, we already open code the loop so there is no need
904 to do anything else. In the latter case, the combined
905 parallel loop call would still need extra synchronization
906 to implement ordered semantics, so there would not be any
907 gain in using the combined call. */
908 tree clauses = gimple_omp_for_clauses (ws_stmt);
909 tree c = find_omp_clause (clauses, OMP_CLAUSE_SCHEDULE);
910 if (c == NULL
911 || OMP_CLAUSE_SCHEDULE_KIND (c) == OMP_CLAUSE_SCHEDULE_STATIC
912 || find_omp_clause (clauses, OMP_CLAUSE_ORDERED))
913 {
914 region->is_combined_parallel = false;
915 region->inner->is_combined_parallel = false;
916 return;
917 }
918 }
919
920 region->is_combined_parallel = true;
921 region->inner->is_combined_parallel = true;
922 region->ws_args = get_ws_args_for (par_stmt, ws_stmt);
923 }
924}
925
926
927/* Return true if EXPR is variable sized. */
928
929static inline bool
930is_variable_sized (const_tree expr)
931{
932 return !TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (expr)));
933}
934
935/* Return true if DECL is a reference type. */
936
937static inline bool
938is_reference (tree decl)
939{
940 return lang_hooks.decls.omp_privatize_by_reference (decl);
941}
942
943/* Return the type of a decl. If the decl is reference type,
944 return its base type. */
945static inline tree
946get_base_type (tree decl)
947{
948 tree type = TREE_TYPE (decl);
949 if (is_reference (decl))
950 type = TREE_TYPE (type);
951 return type;
952}
953
954/* Lookup variables. The "maybe" form
955 allows for the variable form to not have been entered, otherwise we
956 assert that the variable must have been entered. */
957
958static inline tree
959lookup_decl (tree var, omp_context *ctx)
960{
961 tree *n = ctx->cb.decl_map->get (var);
962 return *n;
963}
964
965static inline tree
966maybe_lookup_decl (const_tree var, omp_context *ctx)
967{
968 tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
969 return n ? *n : NULL_TREE;
970}
971
972static inline tree
973lookup_field (tree var, omp_context *ctx)
974{
975 splay_tree_node n;
976 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
977 return (tree) n->value;
978}
979
980static inline tree
981lookup_sfield (tree var, omp_context *ctx)
982{
983 splay_tree_node n;
984 n = splay_tree_lookup (ctx->sfield_map
985 ? ctx->sfield_map : ctx->field_map,
986 (splay_tree_key) var);
987 return (tree) n->value;
988}
989
990static inline tree
991maybe_lookup_field (tree var, omp_context *ctx)
992{
993 splay_tree_node n;
994 n = splay_tree_lookup (ctx->field_map, (splay_tree_key) var);
995 return n ? (tree) n->value : NULL_TREE;
996}
997
998static inline tree
999lookup_oacc_reduction (const char *id, omp_context *ctx)
1000{
1001 splay_tree_node n;
1002 n = splay_tree_lookup (ctx->reduction_map, (splay_tree_key) id);
1003 return (tree) n->value;
1004}
1005
1006static inline tree
1007maybe_lookup_oacc_reduction (tree var, omp_context *ctx)
1008{
1009 splay_tree_node n = NULL;
1010 if (ctx->reduction_map)
1011 n = splay_tree_lookup (ctx->reduction_map, (splay_tree_key) var);
1012 return n ? (tree) n->value : NULL_TREE;
1013}
1014
1015/* Return true if DECL should be copied by pointer. SHARED_CTX is
1016 the parallel context if DECL is to be shared. */
1017
1018static bool
1019use_pointer_for_field (tree decl, omp_context *shared_ctx)
1020{
1021 if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
1022 return true;
1023
1024 /* We can only use copy-in/copy-out semantics for shared variables
1025 when we know the value is not accessible from an outer scope. */
1026 if (shared_ctx)
1027 {
1028 gcc_assert (!is_gimple_omp_oacc (shared_ctx->stmt));
1029
1030 /* ??? Trivially accessible from anywhere. But why would we even
1031 be passing an address in this case? Should we simply assert
1032 this to be false, or should we have a cleanup pass that removes
1033 these from the list of mappings? */
1034 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
1035 return true;
1036
1037 /* For variables with DECL_HAS_VALUE_EXPR_P set, we cannot tell
1038 without analyzing the expression whether or not its location
1039 is accessible to anyone else. In the case of nested parallel
1040 regions it certainly may be. */
1041 if (TREE_CODE (decl) != RESULT_DECL && DECL_HAS_VALUE_EXPR_P (decl))
1042 return true;
1043
1044 /* Do not use copy-in/copy-out for variables that have their
1045 address taken. */
1046 if (TREE_ADDRESSABLE (decl))
1047 return true;
1048
1049 /* lower_send_shared_vars only uses copy-in, but not copy-out
1050 for these. */
1051 if (TREE_READONLY (decl)
1052 || ((TREE_CODE (decl) == RESULT_DECL
1053 || TREE_CODE (decl) == PARM_DECL)
1054 && DECL_BY_REFERENCE (decl)))
1055 return false;
1056
1057 /* Disallow copy-in/out in nested parallel if
1058 decl is shared in outer parallel, otherwise
1059 each thread could store the shared variable
1060 in its own copy-in location, making the
1061 variable no longer really shared. */
1062 if (shared_ctx->is_nested)
1063 {
1064 omp_context *up;
1065
1066 for (up = shared_ctx->outer; up; up = up->outer)
1067 if (is_taskreg_ctx (up) && maybe_lookup_decl (decl, up))
1068 break;
1069
1070 if (up)
1071 {
1072 tree c;
1073
1074 for (c = gimple_omp_taskreg_clauses (up->stmt);
1075 c; c = OMP_CLAUSE_CHAIN (c))
1076 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
1077 && OMP_CLAUSE_DECL (c) == decl)
1078 break;
1079
1080 if (c)
1081 goto maybe_mark_addressable_and_ret;
1082 }
1083 }
1084
1085 /* For tasks avoid using copy-in/out. As tasks can be
1086 deferred or executed in different thread, when GOMP_task
1087 returns, the task hasn't necessarily terminated. */
1088 if (is_task_ctx (shared_ctx))
1089 {
1090 tree outer;
1091 maybe_mark_addressable_and_ret:
1092 outer = maybe_lookup_decl_in_outer_ctx (decl, shared_ctx);
1093 if (is_gimple_reg (outer))
1094 {
1095 /* Taking address of OUTER in lower_send_shared_vars
1096 might need regimplification of everything that uses the
1097 variable. */
1098 if (!task_shared_vars)
1099 task_shared_vars = BITMAP_ALLOC (NULL);
1100 bitmap_set_bit (task_shared_vars, DECL_UID (outer));
1101 TREE_ADDRESSABLE (outer) = 1;
1102 }
1103 return true;
1104 }
1105 }
1106
1107 return false;
1108}
1109
1110/* Construct a new automatic decl similar to VAR. */
1111
1112static tree
1113omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
1114{
1115 tree copy = copy_var_decl (var, name, type);
1116
1117 DECL_CONTEXT (copy) = current_function_decl;
1118 DECL_CHAIN (copy) = ctx->block_vars;
1119 ctx->block_vars = copy;
1120
1121 return copy;
1122}
1123
1124static tree
1125omp_copy_decl_1 (tree var, omp_context *ctx)
1126{
1127 return omp_copy_decl_2 (var, DECL_NAME (var), TREE_TYPE (var), ctx);
1128}
1129
1130/* Build COMPONENT_REF and set TREE_THIS_VOLATILE and TREE_READONLY on it
1131 as appropriate. */
1132static tree
1133omp_build_component_ref (tree obj, tree field)
1134{
1135 tree ret = build3 (COMPONENT_REF, TREE_TYPE (field), obj, field, NULL);
1136 if (TREE_THIS_VOLATILE (field))
1137 TREE_THIS_VOLATILE (ret) |= 1;
1138 if (TREE_READONLY (field))
1139 TREE_READONLY (ret) |= 1;
1140 return ret;
1141}
1142
1143/* Build tree nodes to access the field for VAR on the receiver side. */
1144
1145static tree
1146build_receiver_ref (tree var, bool by_ref, omp_context *ctx)
1147{
1148 tree x, field = lookup_field (var, ctx);
1149
1150 /* If the receiver record type was remapped in the child function,
1151 remap the field into the new record type. */
1152 x = maybe_lookup_field (field, ctx);
1153 if (x != NULL)
1154 field = x;
1155
1156 x = build_simple_mem_ref (ctx->receiver_decl);
1157 x = omp_build_component_ref (x, field);
1158 if (by_ref)
1159 x = build_simple_mem_ref (x);
1160
1161 return x;
1162}
1163
1164/* Build tree nodes to access VAR in the scope outer to CTX. In the case
1165 of a parallel, this is a component reference; for workshare constructs
1166 this is some variable. */
1167
1168static tree
1169build_outer_var_ref (tree var, omp_context *ctx)
1170{
1171 tree x;
1172
1173 if (is_global_var (maybe_lookup_decl_in_outer_ctx (var, ctx)))
1174 x = var;
1175 else if (is_variable_sized (var))
1176 {
1177 x = TREE_OPERAND (DECL_VALUE_EXPR (var), 0);
1178 x = build_outer_var_ref (x, ctx);
1179 x = build_simple_mem_ref (x);
1180 }
1181 else if (is_taskreg_ctx (ctx))
1182 {
1183 bool by_ref = use_pointer_for_field (var, NULL);
1184 x = build_receiver_ref (var, by_ref, ctx);
1185 }
1186 else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
1187 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
1188 {
1189 /* #pragma omp simd isn't a worksharing construct, and can reference even
1190 private vars in its linear etc. clauses. */
1191 x = NULL_TREE;
1192 if (ctx->outer && is_taskreg_ctx (ctx))
1193 x = lookup_decl (var, ctx->outer);
1194 else if (ctx->outer)
1195 x = maybe_lookup_decl_in_outer_ctx (var, ctx);
1196 if (x == NULL_TREE)
1197 x = var;
1198 }
1199 else if (ctx->outer)
1200 x = lookup_decl (var, ctx->outer);
1201 else if (is_reference (var))
1202 /* This can happen with orphaned constructs. If var is reference, it is
1203 possible it is shared and as such valid. */
1204 x = var;
1205 else
1206 gcc_unreachable ();
1207
1208 if (is_reference (var))
1209 x = build_simple_mem_ref (x);
1210
1211 return x;
1212}
1213
1214/* Build tree nodes to access the field for VAR on the sender side. */
1215
1216static tree
1217build_sender_ref (tree var, omp_context *ctx)
1218{
1219 tree field = lookup_sfield (var, ctx);
1220 return omp_build_component_ref (ctx->sender_decl, field);
1221}
1222
1223/* Add a new field for VAR inside the structure CTX->SENDER_DECL. */
1224
1225static void
1226install_var_field (tree var, bool by_ref, int mask, omp_context *ctx)
1227{
1228 tree field, type, sfield = NULL_TREE;
1229
1230 gcc_assert ((mask & 1) == 0
1231 || !splay_tree_lookup (ctx->field_map, (splay_tree_key) var));
1232 gcc_assert ((mask & 2) == 0 || !ctx->sfield_map
1233 || !splay_tree_lookup (ctx->sfield_map, (splay_tree_key) var));
1234 gcc_assert ((mask & 3) == 3
1235 || !is_gimple_omp_oacc (ctx->stmt));
1236
1237 type = TREE_TYPE (var);
1238 if (mask & 4)
1239 {
1240 gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
1241 type = build_pointer_type (build_pointer_type (type));
1242 }
1243 else if (by_ref)
1244 type = build_pointer_type (type);
1245 else if ((mask & 3) == 1 && is_reference (var))
1246 type = TREE_TYPE (type);
1247
1248 field = build_decl (DECL_SOURCE_LOCATION (var),
1249 FIELD_DECL, DECL_NAME (var), type);
1250
1251 /* Remember what variable this field was created for. This does have a
1252 side effect of making dwarf2out ignore this member, so for helpful
1253 debugging we clear it later in delete_omp_context. */
1254 DECL_ABSTRACT_ORIGIN (field) = var;
1255 if (type == TREE_TYPE (var))
1256 {
1257 DECL_ALIGN (field) = DECL_ALIGN (var);
1258 DECL_USER_ALIGN (field) = DECL_USER_ALIGN (var);
1259 TREE_THIS_VOLATILE (field) = TREE_THIS_VOLATILE (var);
1260 }
1261 else
1262 DECL_ALIGN (field) = TYPE_ALIGN (type);
1263
1264 if ((mask & 3) == 3)
1265 {
1266 insert_field_into_struct (ctx->record_type, field);
1267 if (ctx->srecord_type)
1268 {
1269 sfield = build_decl (DECL_SOURCE_LOCATION (var),
1270 FIELD_DECL, DECL_NAME (var), type);
1271 DECL_ABSTRACT_ORIGIN (sfield) = var;
1272 DECL_ALIGN (sfield) = DECL_ALIGN (field);
1273 DECL_USER_ALIGN (sfield) = DECL_USER_ALIGN (field);
1274 TREE_THIS_VOLATILE (sfield) = TREE_THIS_VOLATILE (field);
1275 insert_field_into_struct (ctx->srecord_type, sfield);
1276 }
1277 }
1278 else
1279 {
1280 if (ctx->srecord_type == NULL_TREE)
1281 {
1282 tree t;
1283
1284 ctx->srecord_type = lang_hooks.types.make_type (RECORD_TYPE);
1285 ctx->sfield_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
1286 for (t = TYPE_FIELDS (ctx->record_type); t ; t = TREE_CHAIN (t))
1287 {
1288 sfield = build_decl (DECL_SOURCE_LOCATION (var),
1289 FIELD_DECL, DECL_NAME (t), TREE_TYPE (t));
1290 DECL_ABSTRACT_ORIGIN (sfield) = DECL_ABSTRACT_ORIGIN (t);
1291 insert_field_into_struct (ctx->srecord_type, sfield);
1292 splay_tree_insert (ctx->sfield_map,
1293 (splay_tree_key) DECL_ABSTRACT_ORIGIN (t),
1294 (splay_tree_value) sfield);
1295 }
1296 }
1297 sfield = field;
1298 insert_field_into_struct ((mask & 1) ? ctx->record_type
1299 : ctx->srecord_type, field);
1300 }
1301
1302 if (mask & 1)
1303 splay_tree_insert (ctx->field_map, (splay_tree_key) var,
1304 (splay_tree_value) field);
1305 if ((mask & 2) && ctx->sfield_map)
1306 splay_tree_insert (ctx->sfield_map, (splay_tree_key) var,
1307 (splay_tree_value) sfield);
1308}
1309
1310static tree
1311install_var_local (tree var, omp_context *ctx)
1312{
1313 tree new_var = omp_copy_decl_1 (var, ctx);
1314 insert_decl_map (&ctx->cb, var, new_var);
1315 return new_var;
1316}
1317
1318/* Adjust the replacement for DECL in CTX for the new context. This means
1319 copying the DECL_VALUE_EXPR, and fixing up the type. */
1320
1321static void
1322fixup_remapped_decl (tree decl, omp_context *ctx, bool private_debug)
1323{
1324 tree new_decl, size;
1325
1326 new_decl = lookup_decl (decl, ctx);
1327
1328 TREE_TYPE (new_decl) = remap_type (TREE_TYPE (decl), &ctx->cb);
1329
1330 if ((!TREE_CONSTANT (DECL_SIZE (new_decl)) || private_debug)
1331 && DECL_HAS_VALUE_EXPR_P (decl))
1332 {
1333 tree ve = DECL_VALUE_EXPR (decl);
1334 walk_tree (&ve, copy_tree_body_r, &ctx->cb, NULL);
1335 SET_DECL_VALUE_EXPR (new_decl, ve);
1336 DECL_HAS_VALUE_EXPR_P (new_decl) = 1;
1337 }
1338
1339 if (!TREE_CONSTANT (DECL_SIZE (new_decl)))
1340 {
1341 size = remap_decl (DECL_SIZE (decl), &ctx->cb);
1342 if (size == error_mark_node)
1343 size = TYPE_SIZE (TREE_TYPE (new_decl));
1344 DECL_SIZE (new_decl) = size;
1345
1346 size = remap_decl (DECL_SIZE_UNIT (decl), &ctx->cb);
1347 if (size == error_mark_node)
1348 size = TYPE_SIZE_UNIT (TREE_TYPE (new_decl));
1349 DECL_SIZE_UNIT (new_decl) = size;
1350 }
1351}
1352
1353/* The callback for remap_decl. Search all containing contexts for a
1354 mapping of the variable; this avoids having to duplicate the splay
1355 tree ahead of time. We know a mapping doesn't already exist in the
1356 given context. Create new mappings to implement default semantics. */
1357
1358static tree
1359omp_copy_decl (tree var, copy_body_data *cb)
1360{
1361 omp_context *ctx = (omp_context *) cb;
1362 tree new_var;
1363
1364 if (TREE_CODE (var) == LABEL_DECL)
1365 {
1366 new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
1367 DECL_CONTEXT (new_var) = current_function_decl;
1368 insert_decl_map (&ctx->cb, var, new_var);
1369 return new_var;
1370 }
1371
1372 while (!is_taskreg_ctx (ctx))
1373 {
1374 ctx = ctx->outer;
1375 if (ctx == NULL)
1376 return var;
1377 new_var = maybe_lookup_decl (var, ctx);
1378 if (new_var)
1379 return new_var;
1380 }
1381
1382 if (is_global_var (var) || decl_function_context (var) != ctx->cb.src_fn)
1383 return var;
1384
1385 return error_mark_node;
1386}
1387
1388
1389/* Debugging dumps for parallel regions. */
1390void dump_omp_region (FILE *, struct omp_region *, int);
1391void debug_omp_region (struct omp_region *);
1392void debug_all_omp_regions (void);
1393
1394/* Dump the parallel region tree rooted at REGION. */
1395
1396void
1397dump_omp_region (FILE *file, struct omp_region *region, int indent)
1398{
1399 fprintf (file, "%*sbb %d: %s\n", indent, "", region->entry->index,
1400 gimple_code_name[region->type]);
1401
1402 if (region->inner)
1403 dump_omp_region (file, region->inner, indent + 4);
1404
1405 if (region->cont)
1406 {
1407 fprintf (file, "%*sbb %d: GIMPLE_OMP_CONTINUE\n", indent, "",
1408 region->cont->index);
1409 }
1410
1411 if (region->exit)
1412 fprintf (file, "%*sbb %d: GIMPLE_OMP_RETURN\n", indent, "",
1413 region->exit->index);
1414 else
1415 fprintf (file, "%*s[no exit marker]\n", indent, "");
1416
1417 if (region->next)
1418 dump_omp_region (file, region->next, indent);
1419}
1420
1421DEBUG_FUNCTION void
1422debug_omp_region (struct omp_region *region)
1423{
1424 dump_omp_region (stderr, region, 0);
1425}
1426
1427DEBUG_FUNCTION void
1428debug_all_omp_regions (void)
1429{
1430 dump_omp_region (stderr, root_omp_region, 0);
1431}
1432
1433
1434/* Create a new parallel region starting at STMT inside region PARENT. */
1435
1436static struct omp_region *
1437new_omp_region (basic_block bb, enum gimple_code type,
1438 struct omp_region *parent)
1439{
1440 struct omp_region *region = XCNEW (struct omp_region);
1441
1442 region->outer = parent;
1443 region->entry = bb;
1444 region->type = type;
1445
1446 if (parent)
1447 {
1448 /* This is a nested region. Add it to the list of inner
1449 regions in PARENT. */
1450 region->next = parent->inner;
1451 parent->inner = region;
1452 }
1453 else
1454 {
1455 /* This is a toplevel region. Add it to the list of toplevel
1456 regions in ROOT_OMP_REGION. */
1457 region->next = root_omp_region;
1458 root_omp_region = region;
1459 }
1460
1461 return region;
1462}
1463
1464/* Release the memory associated with the region tree rooted at REGION. */
1465
1466static void
1467free_omp_region_1 (struct omp_region *region)
1468{
1469 struct omp_region *i, *n;
1470
1471 for (i = region->inner; i ; i = n)
1472 {
1473 n = i->next;
1474 free_omp_region_1 (i);
1475 }
1476
1477 free (region);
1478}
1479
1480/* Release the memory for the entire omp region tree. */
1481
1482void
1483free_omp_regions (void)
1484{
1485 struct omp_region *r, *n;
1486 for (r = root_omp_region; r ; r = n)
1487 {
1488 n = r->next;
1489 free_omp_region_1 (r);
1490 }
1491 root_omp_region = NULL;
1492}
1493
1494
1495/* Create a new context, with OUTER_CTX being the surrounding context. */
1496
1497static omp_context *
1498new_omp_context (gimple stmt, omp_context *outer_ctx)
1499{
1500 omp_context *ctx = XCNEW (omp_context);
1501
1502 splay_tree_insert (all_contexts, (splay_tree_key) stmt,
1503 (splay_tree_value) ctx);
1504 ctx->stmt = stmt;
1505
1506 if (outer_ctx)
1507 {
1508 ctx->outer = outer_ctx;
1509 ctx->cb = outer_ctx->cb;
1510 ctx->cb.block = NULL;
1511 ctx->depth = outer_ctx->depth + 1;
1512 ctx->reduction_map = outer_ctx->reduction_map;
1513 }
1514 else
1515 {
1516 ctx->cb.src_fn = current_function_decl;
1517 ctx->cb.dst_fn = current_function_decl;
1518 ctx->cb.src_node = cgraph_node::get (current_function_decl);
1519 gcc_checking_assert (ctx->cb.src_node);
1520 ctx->cb.dst_node = ctx->cb.src_node;
1521 ctx->cb.src_cfun = cfun;
1522 ctx->cb.copy_decl = omp_copy_decl;
1523 ctx->cb.eh_lp_nr = 0;
1524 ctx->cb.transform_call_graph_edges = CB_CGE_MOVE;
1525 ctx->depth = 1;
1526 }
1527
1528 ctx->cb.decl_map = new hash_map<tree, tree>;
1529
1530 return ctx;
1531}
1532
1533static gimple_seq maybe_catch_exception (gimple_seq);
1534
1535/* Finalize task copyfn. */
1536
1537static void
1538finalize_task_copyfn (gomp_task *task_stmt)
1539{
1540 struct function *child_cfun;
1541 tree child_fn;
1542 gimple_seq seq = NULL, new_seq;
1543 gbind *bind;
1544
1545 child_fn = gimple_omp_task_copy_fn (task_stmt);
1546 if (child_fn == NULL_TREE)
1547 return;
1548
1549 child_cfun = DECL_STRUCT_FUNCTION (child_fn);
1550 DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
1551
1552 push_cfun (child_cfun);
1553 bind = gimplify_body (child_fn, false);
1554 gimple_seq_add_stmt (&seq, bind);
1555 new_seq = maybe_catch_exception (seq);
1556 if (new_seq != seq)
1557 {
1558 bind = gimple_build_bind (NULL, new_seq, NULL);
1559 seq = NULL;
1560 gimple_seq_add_stmt (&seq, bind);
1561 }
1562 gimple_set_body (child_fn, seq);
1563 pop_cfun ();
1564
1565 /* Inform the callgraph about the new function. */
1566 cgraph_node::add_new_function (child_fn, false);
38c0c85b 1567 cgraph_node::get (child_fn)->parallelized_function = 1;
dda118e3
JM
1568}
1569
1570/* Destroy a omp_context data structures. Called through the splay tree
1571 value delete callback. */
1572
1573static void
1574delete_omp_context (splay_tree_value value)
1575{
1576 omp_context *ctx = (omp_context *) value;
1577
1578 delete ctx->cb.decl_map;
1579
1580 if (ctx->field_map)
1581 splay_tree_delete (ctx->field_map);
1582 if (ctx->sfield_map)
1583 splay_tree_delete (ctx->sfield_map);
38c0c85b
JM
1584 /* Reduction map is copied to nested contexts, so only delete it in the
1585 owner. */
dda118e3 1586 if (ctx->reduction_map
38c0c85b
JM
1587 && gimple_code (ctx->stmt) == GIMPLE_OMP_TARGET
1588 && is_gimple_omp_offloaded (ctx->stmt)
1589 && is_gimple_omp_oacc (ctx->stmt))
dda118e3
JM
1590 splay_tree_delete (ctx->reduction_map);
1591
1592 /* We hijacked DECL_ABSTRACT_ORIGIN earlier. We need to clear it before
1593 it produces corrupt debug information. */
1594 if (ctx->record_type)
1595 {
1596 tree t;
1597 for (t = TYPE_FIELDS (ctx->record_type); t ; t = DECL_CHAIN (t))
1598 DECL_ABSTRACT_ORIGIN (t) = NULL;
1599 }
1600 if (ctx->srecord_type)
1601 {
1602 tree t;
1603 for (t = TYPE_FIELDS (ctx->srecord_type); t ; t = DECL_CHAIN (t))
1604 DECL_ABSTRACT_ORIGIN (t) = NULL;
1605 }
1606
1607 if (is_task_ctx (ctx))
1608 finalize_task_copyfn (as_a <gomp_task *> (ctx->stmt));
1609
1610 XDELETE (ctx);
1611}
1612
1613/* Fix up RECEIVER_DECL with a type that has been remapped to the child
1614 context. */
1615
1616static void
1617fixup_child_record_type (omp_context *ctx)
1618{
1619 tree f, type = ctx->record_type;
1620
1621 /* ??? It isn't sufficient to just call remap_type here, because
1622 variably_modified_type_p doesn't work the way we expect for
1623 record types. Testing each field for whether it needs remapping
1624 and creating a new record by hand works, however. */
1625 for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f))
1626 if (variably_modified_type_p (TREE_TYPE (f), ctx->cb.src_fn))
1627 break;
1628 if (f)
1629 {
1630 tree name, new_fields = NULL;
1631
1632 type = lang_hooks.types.make_type (RECORD_TYPE);
1633 name = DECL_NAME (TYPE_NAME (ctx->record_type));
1634 name = build_decl (DECL_SOURCE_LOCATION (ctx->receiver_decl),
1635 TYPE_DECL, name, type);
1636 TYPE_NAME (type) = name;
1637
1638 for (f = TYPE_FIELDS (ctx->record_type); f ; f = DECL_CHAIN (f))
1639 {
1640 tree new_f = copy_node (f);
1641 DECL_CONTEXT (new_f) = type;
1642 TREE_TYPE (new_f) = remap_type (TREE_TYPE (f), &ctx->cb);
1643 DECL_CHAIN (new_f) = new_fields;
1644 walk_tree (&DECL_SIZE (new_f), copy_tree_body_r, &ctx->cb, NULL);
1645 walk_tree (&DECL_SIZE_UNIT (new_f), copy_tree_body_r,
1646 &ctx->cb, NULL);
1647 walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
1648 &ctx->cb, NULL);
1649 new_fields = new_f;
1650
1651 /* Arrange to be able to look up the receiver field
1652 given the sender field. */
1653 splay_tree_insert (ctx->field_map, (splay_tree_key) f,
1654 (splay_tree_value) new_f);
1655 }
1656 TYPE_FIELDS (type) = nreverse (new_fields);
1657 layout_type (type);
1658 }
1659
1660 TREE_TYPE (ctx->receiver_decl)
1661 = build_qualified_type (build_reference_type (type), TYPE_QUAL_RESTRICT);
1662}
1663
1664/* Instantiate decls as necessary in CTX to satisfy the data sharing
1665 specified by CLAUSES. */
1666
1667static void
1668scan_sharing_clauses (tree clauses, omp_context *ctx)
1669{
1670 tree c, decl;
1671 bool scan_array_reductions = false;
1672
1673 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1674 {
1675 bool by_ref;
1676
1677 switch (OMP_CLAUSE_CODE (c))
1678 {
1679 case OMP_CLAUSE_PRIVATE:
1680 decl = OMP_CLAUSE_DECL (c);
1681 if (OMP_CLAUSE_PRIVATE_OUTER_REF (c))
1682 goto do_private;
1683 else if (!is_variable_sized (decl))
1684 install_var_local (decl, ctx);
1685 break;
1686
1687 case OMP_CLAUSE_SHARED:
1688 decl = OMP_CLAUSE_DECL (c);
1689 /* Ignore shared directives in teams construct. */
1690 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
1691 {
1692 /* Global variables don't need to be copied,
1693 the receiver side will use them directly. */
1694 tree odecl = maybe_lookup_decl_in_outer_ctx (decl, ctx);
1695 if (is_global_var (odecl))
1696 break;
1697 insert_decl_map (&ctx->cb, decl, odecl);
1698 break;
1699 }
1700 gcc_assert (is_taskreg_ctx (ctx));
1701 gcc_assert (!COMPLETE_TYPE_P (TREE_TYPE (decl))
1702 || !is_variable_sized (decl));
1703 /* Global variables don't need to be copied,
1704 the receiver side will use them directly. */
1705 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1706 break;
1707 by_ref = use_pointer_for_field (decl, ctx);
1708 if (! TREE_READONLY (decl)
1709 || TREE_ADDRESSABLE (decl)
1710 || by_ref
1711 || is_reference (decl))
1712 {
1713 install_var_field (decl, by_ref, 3, ctx);
1714 install_var_local (decl, ctx);
1715 break;
1716 }
1717 /* We don't need to copy const scalar vars back. */
1718 OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_FIRSTPRIVATE);
1719 goto do_private;
1720
1721 case OMP_CLAUSE_LASTPRIVATE:
1722 /* Let the corresponding firstprivate clause create
1723 the variable. */
1724 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1725 break;
1726 /* FALLTHRU */
1727
1728 case OMP_CLAUSE_FIRSTPRIVATE:
1729 if (is_gimple_omp_oacc (ctx->stmt))
1730 {
1731 sorry ("clause not supported yet");
1732 break;
1733 }
1734 /* FALLTHRU */
1735 case OMP_CLAUSE_REDUCTION:
1736 case OMP_CLAUSE_LINEAR:
1737 decl = OMP_CLAUSE_DECL (c);
1738 do_private:
1739 if (is_variable_sized (decl))
1740 {
1741 if (is_task_ctx (ctx))
1742 install_var_field (decl, false, 1, ctx);
1743 break;
1744 }
1745 else if (is_taskreg_ctx (ctx))
1746 {
1747 bool global
1748 = is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx));
1749 by_ref = use_pointer_for_field (decl, NULL);
1750
1751 if (is_task_ctx (ctx)
1752 && (global || by_ref || is_reference (decl)))
1753 {
1754 install_var_field (decl, false, 1, ctx);
1755 if (!global)
1756 install_var_field (decl, by_ref, 2, ctx);
1757 }
1758 else if (!global)
1759 install_var_field (decl, by_ref, 3, ctx);
1760 }
1761 install_var_local (decl, ctx);
1762 if (is_gimple_omp_oacc (ctx->stmt)
1763 && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
1764 {
1765 /* Create a decl for the reduction array. */
1766 tree var = OMP_CLAUSE_DECL (c);
1767 tree type = get_base_type (var);
1768 tree ptype = build_pointer_type (type);
1769 tree array = create_tmp_var (ptype,
1770 oacc_get_reduction_array_id (var));
1771 omp_context *c = (ctx->field_map ? ctx : ctx->outer);
1772 install_var_field (array, true, 3, c);
1773 install_var_local (array, c);
1774
1775 /* Insert it into the current context. */
1776 splay_tree_insert (ctx->reduction_map, (splay_tree_key)
1777 oacc_get_reduction_array_id (var),
1778 (splay_tree_value) array);
1779 splay_tree_insert (ctx->reduction_map,
1780 (splay_tree_key) array,
1781 (splay_tree_value) array);
1782 }
1783 break;
1784
1785 case OMP_CLAUSE__LOOPTEMP_:
1786 gcc_assert (is_parallel_ctx (ctx));
1787 decl = OMP_CLAUSE_DECL (c);
1788 install_var_field (decl, false, 3, ctx);
1789 install_var_local (decl, ctx);
1790 break;
1791
1792 case OMP_CLAUSE_COPYPRIVATE:
1793 case OMP_CLAUSE_COPYIN:
1794 decl = OMP_CLAUSE_DECL (c);
1795 by_ref = use_pointer_for_field (decl, NULL);
1796 install_var_field (decl, by_ref, 3, ctx);
1797 break;
1798
1799 case OMP_CLAUSE_DEFAULT:
1800 ctx->default_kind = OMP_CLAUSE_DEFAULT_KIND (c);
1801 break;
1802
1803 case OMP_CLAUSE_FINAL:
1804 case OMP_CLAUSE_IF:
1805 case OMP_CLAUSE_NUM_THREADS:
1806 case OMP_CLAUSE_NUM_TEAMS:
1807 case OMP_CLAUSE_THREAD_LIMIT:
1808 case OMP_CLAUSE_DEVICE:
1809 case OMP_CLAUSE_SCHEDULE:
1810 case OMP_CLAUSE_DIST_SCHEDULE:
1811 case OMP_CLAUSE_DEPEND:
1812 case OMP_CLAUSE__CILK_FOR_COUNT_:
1813 case OMP_CLAUSE_NUM_GANGS:
1814 case OMP_CLAUSE_NUM_WORKERS:
1815 case OMP_CLAUSE_VECTOR_LENGTH:
1816 if (ctx->outer)
1817 scan_omp_op (&OMP_CLAUSE_OPERAND (c, 0), ctx->outer);
1818 break;
1819
1820 case OMP_CLAUSE_TO:
1821 case OMP_CLAUSE_FROM:
1822 case OMP_CLAUSE_MAP:
1823 if (ctx->outer)
1824 scan_omp_op (&OMP_CLAUSE_SIZE (c), ctx->outer);
1825 decl = OMP_CLAUSE_DECL (c);
1826 /* Global variables with "omp declare target" attribute
1827 don't need to be copied, the receiver side will use them
1828 directly. */
1829 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1830 && DECL_P (decl)
1831 && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
1832 && varpool_node::get_create (decl)->offloadable)
1833 break;
1834 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1835 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER)
1836 {
1837 /* Ignore GOMP_MAP_POINTER kind for arrays in regions that are
1838 not offloaded; there is nothing to map for those. */
1839 if (!is_gimple_omp_offloaded (ctx->stmt)
1840 && !POINTER_TYPE_P (TREE_TYPE (decl))
1841 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c))
1842 break;
1843 }
1844 if (DECL_P (decl))
1845 {
1846 if (DECL_SIZE (decl)
1847 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
1848 {
1849 tree decl2 = DECL_VALUE_EXPR (decl);
1850 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
1851 decl2 = TREE_OPERAND (decl2, 0);
1852 gcc_assert (DECL_P (decl2));
1853 install_var_field (decl2, true, 3, ctx);
1854 install_var_local (decl2, ctx);
1855 install_var_local (decl, ctx);
1856 }
1857 else
1858 {
1859 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_MAP
1860 && OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
1861 && !OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c)
1862 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1863 install_var_field (decl, true, 7, ctx);
1864 else
1865 install_var_field (decl, true, 3, ctx);
1866 if (is_gimple_omp_offloaded (ctx->stmt))
1867 install_var_local (decl, ctx);
1868 }
1869 }
1870 else
1871 {
1872 tree base = get_base_address (decl);
1873 tree nc = OMP_CLAUSE_CHAIN (c);
1874 if (DECL_P (base)
1875 && nc != NULL_TREE
1876 && OMP_CLAUSE_CODE (nc) == OMP_CLAUSE_MAP
1877 && OMP_CLAUSE_DECL (nc) == base
1878 && OMP_CLAUSE_MAP_KIND (nc) == GOMP_MAP_POINTER
1879 && integer_zerop (OMP_CLAUSE_SIZE (nc)))
1880 {
1881 OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (c) = 1;
1882 OMP_CLAUSE_MAP_ZERO_BIAS_ARRAY_SECTION (nc) = 1;
1883 }
1884 else
1885 {
1886 if (ctx->outer)
1887 {
1888 scan_omp_op (&OMP_CLAUSE_DECL (c), ctx->outer);
1889 decl = OMP_CLAUSE_DECL (c);
1890 }
1891 gcc_assert (!splay_tree_lookup (ctx->field_map,
1892 (splay_tree_key) decl));
1893 tree field
1894 = build_decl (OMP_CLAUSE_LOCATION (c),
1895 FIELD_DECL, NULL_TREE, ptr_type_node);
1896 DECL_ALIGN (field) = TYPE_ALIGN (ptr_type_node);
1897 insert_field_into_struct (ctx->record_type, field);
1898 splay_tree_insert (ctx->field_map, (splay_tree_key) decl,
1899 (splay_tree_value) field);
1900 }
1901 }
1902 break;
1903
1904 case OMP_CLAUSE_NOWAIT:
1905 case OMP_CLAUSE_ORDERED:
1906 case OMP_CLAUSE_COLLAPSE:
1907 case OMP_CLAUSE_UNTIED:
1908 case OMP_CLAUSE_MERGEABLE:
1909 case OMP_CLAUSE_PROC_BIND:
1910 case OMP_CLAUSE_SAFELEN:
1911 case OMP_CLAUSE_ASYNC:
1912 case OMP_CLAUSE_WAIT:
1913 case OMP_CLAUSE_GANG:
1914 case OMP_CLAUSE_WORKER:
1915 case OMP_CLAUSE_VECTOR:
1916 break;
1917
1918 case OMP_CLAUSE_ALIGNED:
1919 decl = OMP_CLAUSE_DECL (c);
1920 if (is_global_var (decl)
1921 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
1922 install_var_local (decl, ctx);
1923 break;
1924
1925 case OMP_CLAUSE_DEVICE_RESIDENT:
1926 case OMP_CLAUSE_USE_DEVICE:
1927 case OMP_CLAUSE__CACHE_:
1928 case OMP_CLAUSE_INDEPENDENT:
1929 case OMP_CLAUSE_AUTO:
1930 case OMP_CLAUSE_SEQ:
1931 sorry ("Clause not supported yet");
1932 break;
1933
1934 default:
1935 gcc_unreachable ();
1936 }
1937 }
1938
1939 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
1940 {
1941 switch (OMP_CLAUSE_CODE (c))
1942 {
1943 case OMP_CLAUSE_LASTPRIVATE:
1944 /* Let the corresponding firstprivate clause create
1945 the variable. */
1946 if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
1947 scan_array_reductions = true;
1948 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
1949 break;
1950 /* FALLTHRU */
1951
1952 case OMP_CLAUSE_FIRSTPRIVATE:
1953 if (is_gimple_omp_oacc (ctx->stmt))
1954 {
1955 sorry ("clause not supported yet");
1956 break;
1957 }
1958 /* FALLTHRU */
1959 case OMP_CLAUSE_PRIVATE:
1960 case OMP_CLAUSE_REDUCTION:
1961 case OMP_CLAUSE_LINEAR:
1962 decl = OMP_CLAUSE_DECL (c);
1963 if (is_variable_sized (decl))
1964 install_var_local (decl, ctx);
1965 fixup_remapped_decl (decl, ctx,
1966 OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
1967 && OMP_CLAUSE_PRIVATE_DEBUG (c));
1968 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
1969 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
1970 scan_array_reductions = true;
1971 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
1972 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
1973 scan_array_reductions = true;
1974 break;
1975
1976 case OMP_CLAUSE_SHARED:
1977 /* Ignore shared directives in teams construct. */
1978 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
1979 break;
1980 decl = OMP_CLAUSE_DECL (c);
1981 if (! is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
1982 fixup_remapped_decl (decl, ctx, false);
1983 break;
1984
1985 case OMP_CLAUSE_MAP:
1986 if (!is_gimple_omp_offloaded (ctx->stmt))
1987 break;
1988 decl = OMP_CLAUSE_DECL (c);
1989 if (DECL_P (decl)
1990 && is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx))
1991 && varpool_node::get_create (decl)->offloadable)
1992 break;
1993 if (DECL_P (decl))
1994 {
1995 if (OMP_CLAUSE_MAP_KIND (c) == GOMP_MAP_POINTER
1996 && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
1997 && !COMPLETE_TYPE_P (TREE_TYPE (decl)))
1998 {
1999 tree new_decl = lookup_decl (decl, ctx);
2000 TREE_TYPE (new_decl)
2001 = remap_type (TREE_TYPE (decl), &ctx->cb);
2002 }
2003 else if (DECL_SIZE (decl)
2004 && TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
2005 {
2006 tree decl2 = DECL_VALUE_EXPR (decl);
2007 gcc_assert (TREE_CODE (decl2) == INDIRECT_REF);
2008 decl2 = TREE_OPERAND (decl2, 0);
2009 gcc_assert (DECL_P (decl2));
2010 fixup_remapped_decl (decl2, ctx, false);
2011 fixup_remapped_decl (decl, ctx, true);
2012 }
2013 else
2014 fixup_remapped_decl (decl, ctx, false);
2015 }
2016 break;
2017
2018 case OMP_CLAUSE_COPYPRIVATE:
2019 case OMP_CLAUSE_COPYIN:
2020 case OMP_CLAUSE_DEFAULT:
2021 case OMP_CLAUSE_IF:
2022 case OMP_CLAUSE_NUM_THREADS:
2023 case OMP_CLAUSE_NUM_TEAMS:
2024 case OMP_CLAUSE_THREAD_LIMIT:
2025 case OMP_CLAUSE_DEVICE:
2026 case OMP_CLAUSE_SCHEDULE:
2027 case OMP_CLAUSE_DIST_SCHEDULE:
2028 case OMP_CLAUSE_NOWAIT:
2029 case OMP_CLAUSE_ORDERED:
2030 case OMP_CLAUSE_COLLAPSE:
2031 case OMP_CLAUSE_UNTIED:
2032 case OMP_CLAUSE_FINAL:
2033 case OMP_CLAUSE_MERGEABLE:
2034 case OMP_CLAUSE_PROC_BIND:
2035 case OMP_CLAUSE_SAFELEN:
2036 case OMP_CLAUSE_ALIGNED:
2037 case OMP_CLAUSE_DEPEND:
2038 case OMP_CLAUSE__LOOPTEMP_:
2039 case OMP_CLAUSE_TO:
2040 case OMP_CLAUSE_FROM:
2041 case OMP_CLAUSE__CILK_FOR_COUNT_:
2042 case OMP_CLAUSE_ASYNC:
2043 case OMP_CLAUSE_WAIT:
2044 case OMP_CLAUSE_NUM_GANGS:
2045 case OMP_CLAUSE_NUM_WORKERS:
2046 case OMP_CLAUSE_VECTOR_LENGTH:
2047 case OMP_CLAUSE_GANG:
2048 case OMP_CLAUSE_WORKER:
2049 case OMP_CLAUSE_VECTOR:
2050 break;
2051
2052 case OMP_CLAUSE_DEVICE_RESIDENT:
2053 case OMP_CLAUSE_USE_DEVICE:
2054 case OMP_CLAUSE__CACHE_:
2055 case OMP_CLAUSE_INDEPENDENT:
2056 case OMP_CLAUSE_AUTO:
2057 case OMP_CLAUSE_SEQ:
2058 sorry ("Clause not supported yet");
2059 break;
2060
2061 default:
2062 gcc_unreachable ();
2063 }
2064 }
2065
2066 gcc_checking_assert (!scan_array_reductions
2067 || !is_gimple_omp_oacc (ctx->stmt));
2068 if (scan_array_reductions)
2069 for (c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2070 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
2071 && OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
2072 {
2073 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
2074 scan_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
2075 }
2076 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
2077 && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
2078 scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
2079 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
2080 && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
2081 scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
2082}
2083
2084/* Create a new name for omp child function. Returns an identifier. If
2085 IS_CILK_FOR is true then the suffix for the child function is
2086 "_cilk_for_fn." */
2087
2088static tree
2089create_omp_child_function_name (bool task_copy, bool is_cilk_for)
2090{
2091 if (is_cilk_for)
2092 return clone_function_name (current_function_decl, "_cilk_for_fn");
2093 return clone_function_name (current_function_decl,
2094 task_copy ? "_omp_cpyfn" : "_omp_fn");
2095}
2096
2097/* Returns the type of the induction variable for the child function for
2098 _Cilk_for and the types for _high and _low variables based on TYPE. */
2099
2100static tree
2101cilk_for_check_loop_diff_type (tree type)
2102{
2103 if (TYPE_PRECISION (type) <= TYPE_PRECISION (uint32_type_node))
2104 {
2105 if (TYPE_UNSIGNED (type))
2106 return uint32_type_node;
2107 else
2108 return integer_type_node;
2109 }
2110 else
2111 {
2112 if (TYPE_UNSIGNED (type))
2113 return uint64_type_node;
2114 else
2115 return long_long_integer_type_node;
2116 }
2117}
2118
2119/* Build a decl for the omp child function. It'll not contain a body
2120 yet, just the bare decl. */
2121
2122static void
2123create_omp_child_function (omp_context *ctx, bool task_copy)
2124{
2125 tree decl, type, name, t;
2126
2127 tree cilk_for_count
2128 = (flag_cilkplus && gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2129 ? find_omp_clause (gimple_omp_parallel_clauses (ctx->stmt),
2130 OMP_CLAUSE__CILK_FOR_COUNT_) : NULL_TREE;
2131 tree cilk_var_type = NULL_TREE;
2132
2133 name = create_omp_child_function_name (task_copy,
2134 cilk_for_count != NULL_TREE);
2135 if (task_copy)
2136 type = build_function_type_list (void_type_node, ptr_type_node,
2137 ptr_type_node, NULL_TREE);
2138 else if (cilk_for_count)
2139 {
2140 type = TREE_TYPE (OMP_CLAUSE_OPERAND (cilk_for_count, 0));
2141 cilk_var_type = cilk_for_check_loop_diff_type (type);
2142 type = build_function_type_list (void_type_node, ptr_type_node,
2143 cilk_var_type, cilk_var_type, NULL_TREE);
2144 }
2145 else
2146 type = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
2147
2148 decl = build_decl (gimple_location (ctx->stmt), FUNCTION_DECL, name, type);
2149
2150 gcc_checking_assert (!is_gimple_omp_oacc (ctx->stmt)
2151 || !task_copy);
2152 if (!task_copy)
2153 ctx->cb.dst_fn = decl;
2154 else
2155 gimple_omp_task_set_copy_fn (ctx->stmt, decl);
2156
2157 TREE_STATIC (decl) = 1;
2158 TREE_USED (decl) = 1;
2159 DECL_ARTIFICIAL (decl) = 1;
2160 DECL_IGNORED_P (decl) = 0;
2161 TREE_PUBLIC (decl) = 0;
2162 DECL_UNINLINABLE (decl) = 1;
2163 DECL_EXTERNAL (decl) = 0;
2164 DECL_CONTEXT (decl) = NULL_TREE;
2165 DECL_INITIAL (decl) = make_node (BLOCK);
2166 if (cgraph_node::get (current_function_decl)->offloadable)
2167 cgraph_node::get_create (decl)->offloadable = 1;
2168 else
2169 {
2170 omp_context *octx;
2171 for (octx = ctx; octx; octx = octx->outer)
2172 if (is_gimple_omp_offloaded (octx->stmt))
2173 {
2174 cgraph_node::get_create (decl)->offloadable = 1;
2175#ifdef ENABLE_OFFLOADING
2176 g->have_offload = true;
2177#endif
2178 break;
2179 }
2180 }
2181
224ceb26
JM
2182 if (cgraph_node::get_create (decl)->offloadable
2183 && !lookup_attribute ("omp declare target",
2184 DECL_ATTRIBUTES (current_function_decl)))
2185 DECL_ATTRIBUTES (decl)
2186 = tree_cons (get_identifier ("omp target entrypoint"),
2187 NULL_TREE, DECL_ATTRIBUTES (decl));
2188
dda118e3
JM
2189 t = build_decl (DECL_SOURCE_LOCATION (decl),
2190 RESULT_DECL, NULL_TREE, void_type_node);
2191 DECL_ARTIFICIAL (t) = 1;
2192 DECL_IGNORED_P (t) = 1;
2193 DECL_CONTEXT (t) = decl;
2194 DECL_RESULT (decl) = t;
2195
2196 /* _Cilk_for's child function requires two extra parameters called
2197 __low and __high that are set the by Cilk runtime when it calls this
2198 function. */
2199 if (cilk_for_count)
2200 {
2201 t = build_decl (DECL_SOURCE_LOCATION (decl),
2202 PARM_DECL, get_identifier ("__high"), cilk_var_type);
2203 DECL_ARTIFICIAL (t) = 1;
2204 DECL_NAMELESS (t) = 1;
2205 DECL_ARG_TYPE (t) = ptr_type_node;
2206 DECL_CONTEXT (t) = current_function_decl;
2207 TREE_USED (t) = 1;
2208 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2209 DECL_ARGUMENTS (decl) = t;
2210
2211 t = build_decl (DECL_SOURCE_LOCATION (decl),
2212 PARM_DECL, get_identifier ("__low"), cilk_var_type);
2213 DECL_ARTIFICIAL (t) = 1;
2214 DECL_NAMELESS (t) = 1;
2215 DECL_ARG_TYPE (t) = ptr_type_node;
2216 DECL_CONTEXT (t) = current_function_decl;
2217 TREE_USED (t) = 1;
2218 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2219 DECL_ARGUMENTS (decl) = t;
2220 }
2221
2222 tree data_name = get_identifier (".omp_data_i");
2223 t = build_decl (DECL_SOURCE_LOCATION (decl), PARM_DECL, data_name,
2224 ptr_type_node);
2225 DECL_ARTIFICIAL (t) = 1;
2226 DECL_NAMELESS (t) = 1;
2227 DECL_ARG_TYPE (t) = ptr_type_node;
2228 DECL_CONTEXT (t) = current_function_decl;
2229 TREE_USED (t) = 1;
2230 if (cilk_for_count)
2231 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2232 DECL_ARGUMENTS (decl) = t;
2233 if (!task_copy)
2234 ctx->receiver_decl = t;
2235 else
2236 {
2237 t = build_decl (DECL_SOURCE_LOCATION (decl),
2238 PARM_DECL, get_identifier (".omp_data_o"),
2239 ptr_type_node);
2240 DECL_ARTIFICIAL (t) = 1;
2241 DECL_NAMELESS (t) = 1;
2242 DECL_ARG_TYPE (t) = ptr_type_node;
2243 DECL_CONTEXT (t) = current_function_decl;
2244 TREE_USED (t) = 1;
2245 TREE_ADDRESSABLE (t) = 1;
2246 DECL_CHAIN (t) = DECL_ARGUMENTS (decl);
2247 DECL_ARGUMENTS (decl) = t;
2248 }
2249
2250 /* Allocate memory for the function structure. The call to
2251 allocate_struct_function clobbers CFUN, so we need to restore
2252 it afterward. */
2253 push_struct_function (decl);
2254 cfun->function_end_locus = gimple_location (ctx->stmt);
2255 pop_cfun ();
2256}
2257
2258/* Callback for walk_gimple_seq. Check if combined parallel
2259 contains gimple_omp_for_combined_into_p OMP_FOR. */
2260
2261static tree
2262find_combined_for (gimple_stmt_iterator *gsi_p,
2263 bool *handled_ops_p,
2264 struct walk_stmt_info *wi)
2265{
2266 gimple stmt = gsi_stmt (*gsi_p);
2267
2268 *handled_ops_p = true;
2269 switch (gimple_code (stmt))
2270 {
2271 WALK_SUBSTMTS;
2272
2273 case GIMPLE_OMP_FOR:
2274 if (gimple_omp_for_combined_into_p (stmt)
2275 && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_FOR)
2276 {
2277 wi->info = stmt;
2278 return integer_zero_node;
2279 }
2280 break;
2281 default:
2282 break;
2283 }
2284 return NULL;
2285}
2286
2287/* Scan an OpenMP parallel directive. */
2288
2289static void
2290scan_omp_parallel (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
2291{
2292 omp_context *ctx;
2293 tree name;
2294 gomp_parallel *stmt = as_a <gomp_parallel *> (gsi_stmt (*gsi));
2295
2296 /* Ignore parallel directives with empty bodies, unless there
2297 are copyin clauses. */
2298 if (optimize > 0
2299 && empty_body_p (gimple_omp_body (stmt))
2300 && find_omp_clause (gimple_omp_parallel_clauses (stmt),
2301 OMP_CLAUSE_COPYIN) == NULL)
2302 {
2303 gsi_replace (gsi, gimple_build_nop (), false);
2304 return;
2305 }
2306
2307 if (gimple_omp_parallel_combined_p (stmt))
2308 {
2309 struct walk_stmt_info wi;
2310
2311 memset (&wi, 0, sizeof (wi));
2312 wi.val_only = true;
2313 walk_gimple_seq (gimple_omp_body (stmt),
2314 find_combined_for, NULL, &wi);
2315 if (wi.info)
2316 {
2317 gomp_for *for_stmt = as_a <gomp_for *> ((gimple) wi.info);
2318 struct omp_for_data fd;
2319 extract_omp_for_data (for_stmt, &fd, NULL);
2320 /* We need two temporaries with fd.loop.v type (istart/iend)
2321 and then (fd.collapse - 1) temporaries with the same
2322 type for count2 ... countN-1 vars if not constant. */
2323 size_t count = 2, i;
2324 tree type = fd.iter_type;
2325 if (fd.collapse > 1
2326 && TREE_CODE (fd.loop.n2) != INTEGER_CST)
2327 count += fd.collapse - 1;
2328 for (i = 0; i < count; i++)
2329 {
2330 tree temp = create_tmp_var (type);
2331 tree c = build_omp_clause (UNKNOWN_LOCATION,
2332 OMP_CLAUSE__LOOPTEMP_);
2333 insert_decl_map (&outer_ctx->cb, temp, temp);
2334 OMP_CLAUSE_DECL (c) = temp;
2335 OMP_CLAUSE_CHAIN (c) = gimple_omp_parallel_clauses (stmt);
2336 gimple_omp_parallel_set_clauses (stmt, c);
2337 }
2338 }
2339 }
2340
2341 ctx = new_omp_context (stmt, outer_ctx);
2342 taskreg_contexts.safe_push (ctx);
2343 if (taskreg_nesting_level > 1)
2344 ctx->is_nested = true;
2345 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2346 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2347 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2348 name = create_tmp_var_name (".omp_data_s");
2349 name = build_decl (gimple_location (stmt),
2350 TYPE_DECL, name, ctx->record_type);
2351 DECL_ARTIFICIAL (name) = 1;
2352 DECL_NAMELESS (name) = 1;
2353 TYPE_NAME (ctx->record_type) = name;
2354 create_omp_child_function (ctx, false);
2355 gimple_omp_parallel_set_child_fn (stmt, ctx->cb.dst_fn);
2356
2357 scan_sharing_clauses (gimple_omp_parallel_clauses (stmt), ctx);
2358 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2359
2360 if (TYPE_FIELDS (ctx->record_type) == NULL)
2361 ctx->record_type = ctx->receiver_decl = NULL;
2362}
2363
2364/* Scan an OpenMP task directive. */
2365
2366static void
2367scan_omp_task (gimple_stmt_iterator *gsi, omp_context *outer_ctx)
2368{
2369 omp_context *ctx;
2370 tree name, t;
2371 gomp_task *stmt = as_a <gomp_task *> (gsi_stmt (*gsi));
2372
2373 /* Ignore task directives with empty bodies. */
2374 if (optimize > 0
2375 && empty_body_p (gimple_omp_body (stmt)))
2376 {
2377 gsi_replace (gsi, gimple_build_nop (), false);
2378 return;
2379 }
2380
2381 ctx = new_omp_context (stmt, outer_ctx);
2382 taskreg_contexts.safe_push (ctx);
2383 if (taskreg_nesting_level > 1)
2384 ctx->is_nested = true;
2385 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2386 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2387 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2388 name = create_tmp_var_name (".omp_data_s");
2389 name = build_decl (gimple_location (stmt),
2390 TYPE_DECL, name, ctx->record_type);
2391 DECL_ARTIFICIAL (name) = 1;
2392 DECL_NAMELESS (name) = 1;
2393 TYPE_NAME (ctx->record_type) = name;
2394 create_omp_child_function (ctx, false);
2395 gimple_omp_task_set_child_fn (stmt, ctx->cb.dst_fn);
2396
2397 scan_sharing_clauses (gimple_omp_task_clauses (stmt), ctx);
2398
2399 if (ctx->srecord_type)
2400 {
2401 name = create_tmp_var_name (".omp_data_a");
2402 name = build_decl (gimple_location (stmt),
2403 TYPE_DECL, name, ctx->srecord_type);
2404 DECL_ARTIFICIAL (name) = 1;
2405 DECL_NAMELESS (name) = 1;
2406 TYPE_NAME (ctx->srecord_type) = name;
2407 create_omp_child_function (ctx, true);
2408 }
2409
2410 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2411
2412 if (TYPE_FIELDS (ctx->record_type) == NULL)
2413 {
2414 ctx->record_type = ctx->receiver_decl = NULL;
2415 t = build_int_cst (long_integer_type_node, 0);
2416 gimple_omp_task_set_arg_size (stmt, t);
2417 t = build_int_cst (long_integer_type_node, 1);
2418 gimple_omp_task_set_arg_align (stmt, t);
2419 }
2420}
2421
2422
2423/* If any decls have been made addressable during scan_omp,
2424 adjust their fields if needed, and layout record types
2425 of parallel/task constructs. */
2426
2427static void
2428finish_taskreg_scan (omp_context *ctx)
2429{
2430 if (ctx->record_type == NULL_TREE)
2431 return;
2432
2433 /* If any task_shared_vars were needed, verify all
2434 OMP_CLAUSE_SHARED clauses on GIMPLE_OMP_{PARALLEL,TASK}
2435 statements if use_pointer_for_field hasn't changed
2436 because of that. If it did, update field types now. */
2437 if (task_shared_vars)
2438 {
2439 tree c;
2440
2441 for (c = gimple_omp_taskreg_clauses (ctx->stmt);
2442 c; c = OMP_CLAUSE_CHAIN (c))
2443 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED)
2444 {
2445 tree decl = OMP_CLAUSE_DECL (c);
2446
2447 /* Global variables don't need to be copied,
2448 the receiver side will use them directly. */
2449 if (is_global_var (maybe_lookup_decl_in_outer_ctx (decl, ctx)))
2450 continue;
2451 if (!bitmap_bit_p (task_shared_vars, DECL_UID (decl))
2452 || !use_pointer_for_field (decl, ctx))
2453 continue;
2454 tree field = lookup_field (decl, ctx);
2455 if (TREE_CODE (TREE_TYPE (field)) == POINTER_TYPE
2456 && TREE_TYPE (TREE_TYPE (field)) == TREE_TYPE (decl))
2457 continue;
2458 TREE_TYPE (field) = build_pointer_type (TREE_TYPE (decl));
2459 TREE_THIS_VOLATILE (field) = 0;
2460 DECL_USER_ALIGN (field) = 0;
2461 DECL_ALIGN (field) = TYPE_ALIGN (TREE_TYPE (field));
2462 if (TYPE_ALIGN (ctx->record_type) < DECL_ALIGN (field))
2463 TYPE_ALIGN (ctx->record_type) = DECL_ALIGN (field);
2464 if (ctx->srecord_type)
2465 {
2466 tree sfield = lookup_sfield (decl, ctx);
2467 TREE_TYPE (sfield) = TREE_TYPE (field);
2468 TREE_THIS_VOLATILE (sfield) = 0;
2469 DECL_USER_ALIGN (sfield) = 0;
2470 DECL_ALIGN (sfield) = DECL_ALIGN (field);
2471 if (TYPE_ALIGN (ctx->srecord_type) < DECL_ALIGN (sfield))
2472 TYPE_ALIGN (ctx->srecord_type) = DECL_ALIGN (sfield);
2473 }
2474 }
2475 }
2476
2477 if (gimple_code (ctx->stmt) == GIMPLE_OMP_PARALLEL)
2478 {
2479 layout_type (ctx->record_type);
2480 fixup_child_record_type (ctx);
2481 }
2482 else
2483 {
2484 location_t loc = gimple_location (ctx->stmt);
2485 tree *p, vla_fields = NULL_TREE, *q = &vla_fields;
2486 /* Move VLA fields to the end. */
2487 p = &TYPE_FIELDS (ctx->record_type);
2488 while (*p)
2489 if (!TYPE_SIZE_UNIT (TREE_TYPE (*p))
2490 || ! TREE_CONSTANT (TYPE_SIZE_UNIT (TREE_TYPE (*p))))
2491 {
2492 *q = *p;
2493 *p = TREE_CHAIN (*p);
2494 TREE_CHAIN (*q) = NULL_TREE;
2495 q = &TREE_CHAIN (*q);
2496 }
2497 else
2498 p = &DECL_CHAIN (*p);
2499 *p = vla_fields;
2500 layout_type (ctx->record_type);
2501 fixup_child_record_type (ctx);
2502 if (ctx->srecord_type)
2503 layout_type (ctx->srecord_type);
2504 tree t = fold_convert_loc (loc, long_integer_type_node,
2505 TYPE_SIZE_UNIT (ctx->record_type));
2506 gimple_omp_task_set_arg_size (ctx->stmt, t);
2507 t = build_int_cst (long_integer_type_node,
2508 TYPE_ALIGN_UNIT (ctx->record_type));
2509 gimple_omp_task_set_arg_align (ctx->stmt, t);
2510 }
2511}
2512
2513
2514static omp_context *
2515enclosing_target_ctx (omp_context *ctx)
2516{
2517 while (ctx != NULL
2518 && gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
2519 ctx = ctx->outer;
2520 gcc_assert (ctx != NULL);
2521 return ctx;
2522}
2523
2524static bool
2525oacc_loop_or_target_p (gimple stmt)
2526{
2527 enum gimple_code outer_type = gimple_code (stmt);
2528 return ((outer_type == GIMPLE_OMP_TARGET
2529 && ((gimple_omp_target_kind (stmt)
2530 == GF_OMP_TARGET_KIND_OACC_PARALLEL)
2531 || (gimple_omp_target_kind (stmt)
2532 == GF_OMP_TARGET_KIND_OACC_KERNELS)))
2533 || (outer_type == GIMPLE_OMP_FOR
2534 && gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_OACC_LOOP));
2535}
2536
2537/* Scan a GIMPLE_OMP_FOR. */
2538
2539static void
2540scan_omp_for (gomp_for *stmt, omp_context *outer_ctx)
2541{
2542 enum gimple_code outer_type = GIMPLE_ERROR_MARK;
2543 omp_context *ctx;
2544 size_t i;
2545 tree clauses = gimple_omp_for_clauses (stmt);
2546
2547 if (outer_ctx)
2548 outer_type = gimple_code (outer_ctx->stmt);
2549
2550 ctx = new_omp_context (stmt, outer_ctx);
2551
2552 if (is_gimple_omp_oacc (stmt))
2553 {
2554 if (outer_ctx && outer_type == GIMPLE_OMP_FOR)
2555 ctx->gwv_this = outer_ctx->gwv_this;
2556 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2557 {
2558 int val;
2559 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_GANG)
2560 val = MASK_GANG;
2561 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_WORKER)
2562 val = MASK_WORKER;
2563 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR)
2564 val = MASK_VECTOR;
2565 else
2566 continue;
2567 ctx->gwv_this |= val;
2568 if (!outer_ctx)
2569 {
2570 /* Skip; not nested inside a region. */
2571 continue;
2572 }
2573 if (!oacc_loop_or_target_p (outer_ctx->stmt))
2574 {
2575 /* Skip; not nested inside an OpenACC region. */
2576 continue;
2577 }
2578 if (outer_type == GIMPLE_OMP_FOR)
2579 outer_ctx->gwv_below |= val;
2580 if (OMP_CLAUSE_OPERAND (c, 0) != NULL_TREE)
2581 {
2582 omp_context *enclosing = enclosing_target_ctx (outer_ctx);
2583 if (gimple_omp_target_kind (enclosing->stmt)
2584 == GF_OMP_TARGET_KIND_OACC_PARALLEL)
2585 error_at (gimple_location (stmt),
2586 "no arguments allowed to gang, worker and vector clauses inside parallel");
2587 }
2588 }
2589 }
2590
2591 scan_sharing_clauses (clauses, ctx);
2592
2593 scan_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
2594 for (i = 0; i < gimple_omp_for_collapse (stmt); i++)
2595 {
2596 scan_omp_op (gimple_omp_for_index_ptr (stmt, i), ctx);
2597 scan_omp_op (gimple_omp_for_initial_ptr (stmt, i), ctx);
2598 scan_omp_op (gimple_omp_for_final_ptr (stmt, i), ctx);
2599 scan_omp_op (gimple_omp_for_incr_ptr (stmt, i), ctx);
2600 }
2601 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2602
2603 if (is_gimple_omp_oacc (stmt))
2604 {
2605 if (ctx->gwv_this & ctx->gwv_below)
2606 error_at (gimple_location (stmt),
2607 "gang, worker and vector may occur only once in a loop nest");
2608 else if (ctx->gwv_below != 0
2609 && ctx->gwv_this > ctx->gwv_below)
2610 error_at (gimple_location (stmt),
2611 "gang, worker and vector must occur in this order in a loop nest");
2612 if (outer_ctx && outer_type == GIMPLE_OMP_FOR)
2613 outer_ctx->gwv_below |= ctx->gwv_below;
2614 }
2615}
2616
2617/* Scan an OpenMP sections directive. */
2618
2619static void
2620scan_omp_sections (gomp_sections *stmt, omp_context *outer_ctx)
2621{
2622 omp_context *ctx;
2623
2624 ctx = new_omp_context (stmt, outer_ctx);
2625 scan_sharing_clauses (gimple_omp_sections_clauses (stmt), ctx);
2626 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2627}
2628
2629/* Scan an OpenMP single directive. */
2630
2631static void
2632scan_omp_single (gomp_single *stmt, omp_context *outer_ctx)
2633{
2634 omp_context *ctx;
2635 tree name;
2636
2637 ctx = new_omp_context (stmt, outer_ctx);
2638 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2639 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2640 name = create_tmp_var_name (".omp_copy_s");
2641 name = build_decl (gimple_location (stmt),
2642 TYPE_DECL, name, ctx->record_type);
2643 TYPE_NAME (ctx->record_type) = name;
2644
2645 scan_sharing_clauses (gimple_omp_single_clauses (stmt), ctx);
2646 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2647
2648 if (TYPE_FIELDS (ctx->record_type) == NULL)
2649 ctx->record_type = NULL;
2650 else
2651 layout_type (ctx->record_type);
2652}
2653
2654/* Scan a GIMPLE_OMP_TARGET. */
2655
2656static void
2657scan_omp_target (gomp_target *stmt, omp_context *outer_ctx)
2658{
2659 omp_context *ctx;
2660 tree name;
2661 bool offloaded = is_gimple_omp_offloaded (stmt);
2662 tree clauses = gimple_omp_target_clauses (stmt);
2663
2664 ctx = new_omp_context (stmt, outer_ctx);
2665 ctx->field_map = splay_tree_new (splay_tree_compare_pointers, 0, 0);
2666 ctx->default_kind = OMP_CLAUSE_DEFAULT_SHARED;
2667 ctx->record_type = lang_hooks.types.make_type (RECORD_TYPE);
2668 name = create_tmp_var_name (".omp_data_t");
2669 name = build_decl (gimple_location (stmt),
2670 TYPE_DECL, name, ctx->record_type);
2671 DECL_ARTIFICIAL (name) = 1;
2672 DECL_NAMELESS (name) = 1;
2673 TYPE_NAME (ctx->record_type) = name;
2674 if (offloaded)
2675 {
2676 if (is_gimple_omp_oacc (stmt))
2677 ctx->reduction_map = splay_tree_new (splay_tree_compare_pointers,
2678 0, 0);
2679
2680 create_omp_child_function (ctx, false);
2681 gimple_omp_target_set_child_fn (stmt, ctx->cb.dst_fn);
2682 }
2683
2684 if (is_gimple_omp_oacc (stmt))
2685 {
2686 for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
2687 {
2688 if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_GANGS)
2689 ctx->gwv_this |= MASK_GANG;
2690 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_NUM_WORKERS)
2691 ctx->gwv_this |= MASK_WORKER;
2692 else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_VECTOR_LENGTH)
2693 ctx->gwv_this |= MASK_VECTOR;
2694 }
2695 }
2696
2697 scan_sharing_clauses (clauses, ctx);
2698 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2699
2700 if (TYPE_FIELDS (ctx->record_type) == NULL)
2701 ctx->record_type = ctx->receiver_decl = NULL;
2702 else
2703 {
2704 TYPE_FIELDS (ctx->record_type)
2705 = nreverse (TYPE_FIELDS (ctx->record_type));
2706#ifdef ENABLE_CHECKING
2707 tree field;
2708 unsigned int align = DECL_ALIGN (TYPE_FIELDS (ctx->record_type));
2709 for (field = TYPE_FIELDS (ctx->record_type);
2710 field;
2711 field = DECL_CHAIN (field))
2712 gcc_assert (DECL_ALIGN (field) == align);
2713#endif
2714 layout_type (ctx->record_type);
2715 if (offloaded)
2716 fixup_child_record_type (ctx);
2717 }
2718}
2719
2720/* Scan an OpenMP teams directive. */
2721
2722static void
2723scan_omp_teams (gomp_teams *stmt, omp_context *outer_ctx)
2724{
2725 omp_context *ctx = new_omp_context (stmt, outer_ctx);
2726 scan_sharing_clauses (gimple_omp_teams_clauses (stmt), ctx);
2727 scan_omp (gimple_omp_body_ptr (stmt), ctx);
2728}
2729
2730/* Check nesting restrictions. */
2731static bool
2732check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
2733{
2734 /* No nesting of non-OpenACC STMT (that is, an OpenMP one, or a GOMP builtin)
2735 inside an OpenACC CTX. */
2736 if (!(is_gimple_omp (stmt)
2737 && is_gimple_omp_oacc (stmt)))
2738 {
2739 for (omp_context *ctx_ = ctx; ctx_ != NULL; ctx_ = ctx_->outer)
2740 if (is_gimple_omp (ctx_->stmt)
2741 && is_gimple_omp_oacc (ctx_->stmt))
2742 {
2743 error_at (gimple_location (stmt),
2744 "non-OpenACC construct inside of OpenACC region");
2745 return false;
2746 }
2747 }
2748
2749 if (ctx != NULL)
2750 {
2751 if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
2752 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
2753 {
2754 error_at (gimple_location (stmt),
2755 "OpenMP constructs may not be nested inside simd region");
2756 return false;
2757 }
2758 else if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
2759 {
2760 if ((gimple_code (stmt) != GIMPLE_OMP_FOR
2761 || (gimple_omp_for_kind (stmt)
2762 != GF_OMP_FOR_KIND_DISTRIBUTE))
2763 && gimple_code (stmt) != GIMPLE_OMP_PARALLEL)
2764 {
2765 error_at (gimple_location (stmt),
2766 "only distribute or parallel constructs are allowed to "
2767 "be closely nested inside teams construct");
2768 return false;
2769 }
2770 }
2771 }
2772 switch (gimple_code (stmt))
2773 {
2774 case GIMPLE_OMP_FOR:
2775 if (gimple_omp_for_kind (stmt) & GF_OMP_FOR_SIMD)
2776 return true;
2777 if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_DISTRIBUTE)
2778 {
2779 if (ctx != NULL && gimple_code (ctx->stmt) != GIMPLE_OMP_TEAMS)
2780 {
2781 error_at (gimple_location (stmt),
2782 "distribute construct must be closely nested inside "
2783 "teams construct");
2784 return false;
2785 }
2786 return true;
2787 }
2788 /* FALLTHRU */
2789 case GIMPLE_CALL:
2790 if (is_gimple_call (stmt)
2791 && (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2792 == BUILT_IN_GOMP_CANCEL
2793 || DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2794 == BUILT_IN_GOMP_CANCELLATION_POINT))
2795 {
2796 const char *bad = NULL;
2797 const char *kind = NULL;
2798 if (ctx == NULL)
2799 {
2800 error_at (gimple_location (stmt), "orphaned %qs construct",
2801 DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2802 == BUILT_IN_GOMP_CANCEL
2803 ? "#pragma omp cancel"
2804 : "#pragma omp cancellation point");
2805 return false;
2806 }
2807 switch (tree_fits_shwi_p (gimple_call_arg (stmt, 0))
2808 ? tree_to_shwi (gimple_call_arg (stmt, 0))
2809 : 0)
2810 {
2811 case 1:
2812 if (gimple_code (ctx->stmt) != GIMPLE_OMP_PARALLEL)
2813 bad = "#pragma omp parallel";
2814 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2815 == BUILT_IN_GOMP_CANCEL
2816 && !integer_zerop (gimple_call_arg (stmt, 1)))
2817 ctx->cancellable = true;
2818 kind = "parallel";
2819 break;
2820 case 2:
2821 if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
2822 || gimple_omp_for_kind (ctx->stmt) != GF_OMP_FOR_KIND_FOR)
2823 bad = "#pragma omp for";
2824 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2825 == BUILT_IN_GOMP_CANCEL
2826 && !integer_zerop (gimple_call_arg (stmt, 1)))
2827 {
2828 ctx->cancellable = true;
2829 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2830 OMP_CLAUSE_NOWAIT))
2831 warning_at (gimple_location (stmt), 0,
2832 "%<#pragma omp cancel for%> inside "
2833 "%<nowait%> for construct");
2834 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2835 OMP_CLAUSE_ORDERED))
2836 warning_at (gimple_location (stmt), 0,
2837 "%<#pragma omp cancel for%> inside "
2838 "%<ordered%> for construct");
2839 }
2840 kind = "for";
2841 break;
2842 case 4:
2843 if (gimple_code (ctx->stmt) != GIMPLE_OMP_SECTIONS
2844 && gimple_code (ctx->stmt) != GIMPLE_OMP_SECTION)
2845 bad = "#pragma omp sections";
2846 else if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2847 == BUILT_IN_GOMP_CANCEL
2848 && !integer_zerop (gimple_call_arg (stmt, 1)))
2849 {
2850 if (gimple_code (ctx->stmt) == GIMPLE_OMP_SECTIONS)
2851 {
2852 ctx->cancellable = true;
2853 if (find_omp_clause (gimple_omp_sections_clauses
2854 (ctx->stmt),
2855 OMP_CLAUSE_NOWAIT))
2856 warning_at (gimple_location (stmt), 0,
2857 "%<#pragma omp cancel sections%> inside "
2858 "%<nowait%> sections construct");
2859 }
2860 else
2861 {
2862 gcc_assert (ctx->outer
2863 && gimple_code (ctx->outer->stmt)
2864 == GIMPLE_OMP_SECTIONS);
2865 ctx->outer->cancellable = true;
2866 if (find_omp_clause (gimple_omp_sections_clauses
2867 (ctx->outer->stmt),
2868 OMP_CLAUSE_NOWAIT))
2869 warning_at (gimple_location (stmt), 0,
2870 "%<#pragma omp cancel sections%> inside "
2871 "%<nowait%> sections construct");
2872 }
2873 }
2874 kind = "sections";
2875 break;
2876 case 8:
2877 if (gimple_code (ctx->stmt) != GIMPLE_OMP_TASK)
2878 bad = "#pragma omp task";
2879 else
2880 ctx->cancellable = true;
2881 kind = "taskgroup";
2882 break;
2883 default:
2884 error_at (gimple_location (stmt), "invalid arguments");
2885 return false;
2886 }
2887 if (bad)
2888 {
2889 error_at (gimple_location (stmt),
2890 "%<%s %s%> construct not closely nested inside of %qs",
2891 DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2892 == BUILT_IN_GOMP_CANCEL
2893 ? "#pragma omp cancel"
2894 : "#pragma omp cancellation point", kind, bad);
2895 return false;
2896 }
2897 }
2898 /* FALLTHRU */
2899 case GIMPLE_OMP_SECTIONS:
2900 case GIMPLE_OMP_SINGLE:
2901 for (; ctx != NULL; ctx = ctx->outer)
2902 switch (gimple_code (ctx->stmt))
2903 {
2904 case GIMPLE_OMP_FOR:
2905 case GIMPLE_OMP_SECTIONS:
2906 case GIMPLE_OMP_SINGLE:
2907 case GIMPLE_OMP_ORDERED:
2908 case GIMPLE_OMP_MASTER:
2909 case GIMPLE_OMP_TASK:
2910 case GIMPLE_OMP_CRITICAL:
2911 if (is_gimple_call (stmt))
2912 {
2913 if (DECL_FUNCTION_CODE (gimple_call_fndecl (stmt))
2914 != BUILT_IN_GOMP_BARRIER)
2915 return true;
2916 error_at (gimple_location (stmt),
2917 "barrier region may not be closely nested inside "
2918 "of work-sharing, critical, ordered, master or "
2919 "explicit task region");
2920 return false;
2921 }
2922 error_at (gimple_location (stmt),
2923 "work-sharing region may not be closely nested inside "
2924 "of work-sharing, critical, ordered, master or explicit "
2925 "task region");
2926 return false;
2927 case GIMPLE_OMP_PARALLEL:
2928 return true;
2929 default:
2930 break;
2931 }
2932 break;
2933 case GIMPLE_OMP_MASTER:
2934 for (; ctx != NULL; ctx = ctx->outer)
2935 switch (gimple_code (ctx->stmt))
2936 {
2937 case GIMPLE_OMP_FOR:
2938 case GIMPLE_OMP_SECTIONS:
2939 case GIMPLE_OMP_SINGLE:
2940 case GIMPLE_OMP_TASK:
2941 error_at (gimple_location (stmt),
2942 "master region may not be closely nested inside "
2943 "of work-sharing or explicit task region");
2944 return false;
2945 case GIMPLE_OMP_PARALLEL:
2946 return true;
2947 default:
2948 break;
2949 }
2950 break;
2951 case GIMPLE_OMP_ORDERED:
2952 for (; ctx != NULL; ctx = ctx->outer)
2953 switch (gimple_code (ctx->stmt))
2954 {
2955 case GIMPLE_OMP_CRITICAL:
2956 case GIMPLE_OMP_TASK:
2957 error_at (gimple_location (stmt),
2958 "ordered region may not be closely nested inside "
2959 "of critical or explicit task region");
2960 return false;
2961 case GIMPLE_OMP_FOR:
2962 if (find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
2963 OMP_CLAUSE_ORDERED) == NULL)
2964 {
2965 error_at (gimple_location (stmt),
2966 "ordered region must be closely nested inside "
2967 "a loop region with an ordered clause");
2968 return false;
2969 }
2970 return true;
2971 case GIMPLE_OMP_PARALLEL:
2972 error_at (gimple_location (stmt),
2973 "ordered region must be closely nested inside "
2974 "a loop region with an ordered clause");
2975 return false;
2976 default:
2977 break;
2978 }
2979 break;
2980 case GIMPLE_OMP_CRITICAL:
2981 {
2982 tree this_stmt_name
2983 = gimple_omp_critical_name (as_a <gomp_critical *> (stmt));
2984 for (; ctx != NULL; ctx = ctx->outer)
2985 if (gomp_critical *other_crit
2986 = dyn_cast <gomp_critical *> (ctx->stmt))
2987 if (this_stmt_name == gimple_omp_critical_name (other_crit))
2988 {
2989 error_at (gimple_location (stmt),
2990 "critical region may not be nested inside a critical "
2991 "region with the same name");
2992 return false;
2993 }
2994 }
2995 break;
2996 case GIMPLE_OMP_TEAMS:
2997 if (ctx == NULL
2998 || gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET
2999 || gimple_omp_target_kind (ctx->stmt) != GF_OMP_TARGET_KIND_REGION)
3000 {
3001 error_at (gimple_location (stmt),
3002 "teams construct not closely nested inside of target "
3003 "region");
3004 return false;
3005 }
3006 break;
3007 case GIMPLE_OMP_TARGET:
3008 for (; ctx != NULL; ctx = ctx->outer)
3009 {
3010 if (gimple_code (ctx->stmt) != GIMPLE_OMP_TARGET)
3011 {
3012 if (is_gimple_omp (stmt)
3013 && is_gimple_omp_oacc (stmt)
3014 && is_gimple_omp (ctx->stmt))
3015 {
3016 error_at (gimple_location (stmt),
3017 "OpenACC construct inside of non-OpenACC region");
3018 return false;
3019 }
3020 continue;
3021 }
3022
3023 const char *stmt_name, *ctx_stmt_name;
3024 switch (gimple_omp_target_kind (stmt))
3025 {
3026 case GF_OMP_TARGET_KIND_REGION: stmt_name = "target"; break;
3027 case GF_OMP_TARGET_KIND_DATA: stmt_name = "target data"; break;
3028 case GF_OMP_TARGET_KIND_UPDATE: stmt_name = "target update"; break;
3029 case GF_OMP_TARGET_KIND_OACC_PARALLEL: stmt_name = "parallel"; break;
3030 case GF_OMP_TARGET_KIND_OACC_KERNELS: stmt_name = "kernels"; break;
3031 case GF_OMP_TARGET_KIND_OACC_DATA: stmt_name = "data"; break;
3032 case GF_OMP_TARGET_KIND_OACC_UPDATE: stmt_name = "update"; break;
3033 case GF_OMP_TARGET_KIND_OACC_ENTER_EXIT_DATA: stmt_name = "enter/exit data"; break;
3034 default: gcc_unreachable ();
3035 }
3036 switch (gimple_omp_target_kind (ctx->stmt))
3037 {
3038 case GF_OMP_TARGET_KIND_REGION: ctx_stmt_name = "target"; break;
3039 case GF_OMP_TARGET_KIND_DATA: ctx_stmt_name = "target data"; break;
3040 case GF_OMP_TARGET_KIND_OACC_PARALLEL: ctx_stmt_name = "parallel"; break;
3041 case GF_OMP_TARGET_KIND_OACC_KERNELS: ctx_stmt_name = "kernels"; break;
3042 case GF_OMP_TARGET_KIND_OACC_DATA: ctx_stmt_name = "data"; break;
3043 default: gcc_unreachable ();
3044 }
3045
3046 /* OpenACC/OpenMP mismatch? */
3047 if (is_gimple_omp_oacc (stmt)
3048 != is_gimple_omp_oacc (ctx->stmt))
3049 {
3050 error_at (gimple_location (stmt),
3051 "%s %s construct inside of %s %s region",
3052 (is_gimple_omp_oacc (stmt)
3053 ? "OpenACC" : "OpenMP"), stmt_name,
3054 (is_gimple_omp_oacc (ctx->stmt)
3055 ? "OpenACC" : "OpenMP"), ctx_stmt_name);
3056 return false;
3057 }
3058 if (is_gimple_omp_offloaded (ctx->stmt))
3059 {
3060 /* No GIMPLE_OMP_TARGET inside offloaded OpenACC CTX. */
3061 if (is_gimple_omp_oacc (ctx->stmt))
3062 {
3063 error_at (gimple_location (stmt),
3064 "%s construct inside of %s region",
3065 stmt_name, ctx_stmt_name);
3066 return false;
3067 }
3068 else
3069 {
3070 gcc_checking_assert (!is_gimple_omp_oacc (stmt));
3071 warning_at (gimple_location (stmt), 0,
3072 "%s construct inside of %s region",
3073 stmt_name, ctx_stmt_name);
3074 }
3075 }
3076 }
3077 break;
3078 default:
3079 break;
3080 }
3081 return true;
3082}
3083
3084
3085/* Helper function scan_omp.
3086
3087 Callback for walk_tree or operators in walk_gimple_stmt used to
3088 scan for OMP directives in TP. */
3089
3090static tree
3091scan_omp_1_op (tree *tp, int *walk_subtrees, void *data)
3092{
3093 struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
3094 omp_context *ctx = (omp_context *) wi->info;
3095 tree t = *tp;
3096
3097 switch (TREE_CODE (t))
3098 {
3099 case VAR_DECL:
3100 case PARM_DECL:
3101 case LABEL_DECL:
3102 case RESULT_DECL:
3103 if (ctx)
3104 *tp = remap_decl (t, &ctx->cb);
3105 break;
3106
3107 default:
3108 if (ctx && TYPE_P (t))
3109 *tp = remap_type (t, &ctx->cb);
3110 else if (!DECL_P (t))
3111 {
3112 *walk_subtrees = 1;
3113 if (ctx)
3114 {
3115 tree tem = remap_type (TREE_TYPE (t), &ctx->cb);
3116 if (tem != TREE_TYPE (t))
3117 {
3118 if (TREE_CODE (t) == INTEGER_CST)
3119 *tp = wide_int_to_tree (tem, t);
3120 else
3121 TREE_TYPE (t) = tem;
3122 }
3123 }
3124 }
3125 break;
3126 }
3127
3128 return NULL_TREE;
3129}
3130
3131/* Return true if FNDECL is a setjmp or a longjmp. */
3132
3133static bool
3134setjmp_or_longjmp_p (const_tree fndecl)
3135{
3136 if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
3137 && (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_SETJMP
3138 || DECL_FUNCTION_CODE (fndecl) == BUILT_IN_LONGJMP))
3139 return true;
3140
3141 tree declname = DECL_NAME (fndecl);
3142 if (!declname)
3143 return false;
3144 const char *name = IDENTIFIER_POINTER (declname);
3145 return !strcmp (name, "setjmp") || !strcmp (name, "longjmp");
3146}
3147
3148
3149/* Helper function for scan_omp.
3150
3151 Callback for walk_gimple_stmt used to scan for OMP directives in
3152 the current statement in GSI. */
3153
3154static tree
3155scan_omp_1_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
3156 struct walk_stmt_info *wi)
3157{
3158 gimple stmt = gsi_stmt (*gsi);
3159 omp_context *ctx = (omp_context *) wi->info;
3160
3161 if (gimple_has_location (stmt))
3162 input_location = gimple_location (stmt);
3163
3164 /* Check the nesting restrictions. */
3165 bool remove = false;
3166 if (is_gimple_omp (stmt))
3167 remove = !check_omp_nesting_restrictions (stmt, ctx);
3168 else if (is_gimple_call (stmt))
3169 {
3170 tree fndecl = gimple_call_fndecl (stmt);
3171 if (fndecl)
3172 {
3173 if (setjmp_or_longjmp_p (fndecl)
3174 && ctx
3175 && gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
3176 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD)
3177 {
3178 remove = true;
3179 error_at (gimple_location (stmt),
3180 "setjmp/longjmp inside simd construct");
3181 }
3182 else if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL)
3183 switch (DECL_FUNCTION_CODE (fndecl))
3184 {
3185 case BUILT_IN_GOMP_BARRIER:
3186 case BUILT_IN_GOMP_CANCEL:
3187 case BUILT_IN_GOMP_CANCELLATION_POINT:
3188 case BUILT_IN_GOMP_TASKYIELD:
3189 case BUILT_IN_GOMP_TASKWAIT:
3190 case BUILT_IN_GOMP_TASKGROUP_START:
3191 case BUILT_IN_GOMP_TASKGROUP_END:
3192 remove = !check_omp_nesting_restrictions (stmt, ctx);
3193 break;
3194 default:
3195 break;
3196 }
3197 }
3198 }
3199 if (remove)
3200 {
3201 stmt = gimple_build_nop ();
3202 gsi_replace (gsi, stmt, false);
3203 }
3204
3205 *handled_ops_p = true;
3206
3207 switch (gimple_code (stmt))
3208 {
3209 case GIMPLE_OMP_PARALLEL:
3210 taskreg_nesting_level++;
3211 scan_omp_parallel (gsi, ctx);
3212 taskreg_nesting_level--;
3213 break;
3214
3215 case GIMPLE_OMP_TASK:
3216 taskreg_nesting_level++;
3217 scan_omp_task (gsi, ctx);
3218 taskreg_nesting_level--;
3219 break;
3220
3221 case GIMPLE_OMP_FOR:
3222 scan_omp_for (as_a <gomp_for *> (stmt), ctx);
3223 break;
3224
3225 case GIMPLE_OMP_SECTIONS:
3226 scan_omp_sections (as_a <gomp_sections *> (stmt), ctx);
3227 break;
3228
3229 case GIMPLE_OMP_SINGLE:
3230 scan_omp_single (as_a <gomp_single *> (stmt), ctx);
3231 break;
3232
3233 case GIMPLE_OMP_SECTION:
3234 case GIMPLE_OMP_MASTER:
3235 case GIMPLE_OMP_TASKGROUP:
3236 case GIMPLE_OMP_ORDERED:
3237 case GIMPLE_OMP_CRITICAL:
3238 ctx = new_omp_context (stmt, ctx);
3239 scan_omp (gimple_omp_body_ptr (stmt), ctx);
3240 break;
3241
3242 case GIMPLE_OMP_TARGET:
3243 scan_omp_target (as_a <gomp_target *> (stmt), ctx);
3244 break;
3245
3246 case GIMPLE_OMP_TEAMS:
3247 scan_omp_teams (as_a <gomp_teams *> (stmt), ctx);
3248 break;
3249
3250 case GIMPLE_BIND:
3251 {
3252 tree var;
3253
3254 *handled_ops_p = false;
3255 if (ctx)
3256 for (var = gimple_bind_vars (as_a <gbind *> (stmt));
3257 var ;
3258 var = DECL_CHAIN (var))
3259 insert_decl_map (&ctx->cb, var, var);
3260 }
3261 break;
3262 default:
3263 *handled_ops_p = false;
3264 break;
3265 }
3266
3267 return NULL_TREE;
3268}
3269
3270
3271/* Scan all the statements starting at the current statement. CTX
3272 contains context information about the OMP directives and
3273 clauses found during the scan. */
3274
3275static void
3276scan_omp (gimple_seq *body_p, omp_context *ctx)
3277{
3278 location_t saved_location;
3279 struct walk_stmt_info wi;
3280
3281 memset (&wi, 0, sizeof (wi));
3282 wi.info = ctx;
3283 wi.want_locations = true;
3284
3285 saved_location = input_location;
3286 walk_gimple_seq_mod (body_p, scan_omp_1_stmt, scan_omp_1_op, &wi);
3287 input_location = saved_location;
3288}
3289\f
3290/* Re-gimplification and code generation routines. */
3291
3292/* Build a call to GOMP_barrier. */
3293
3294static gimple
3295build_omp_barrier (tree lhs)
3296{
3297 tree fndecl = builtin_decl_explicit (lhs ? BUILT_IN_GOMP_BARRIER_CANCEL
3298 : BUILT_IN_GOMP_BARRIER);
3299 gcall *g = gimple_build_call (fndecl, 0);
3300 if (lhs)
3301 gimple_call_set_lhs (g, lhs);
3302 return g;
3303}
3304
3305/* If a context was created for STMT when it was scanned, return it. */
3306
3307static omp_context *
3308maybe_lookup_ctx (gimple stmt)
3309{
3310 splay_tree_node n;
3311 n = splay_tree_lookup (all_contexts, (splay_tree_key) stmt);
3312 return n ? (omp_context *) n->value : NULL;
3313}
3314
3315
3316/* Find the mapping for DECL in CTX or the immediately enclosing
3317 context that has a mapping for DECL.
3318
3319 If CTX is a nested parallel directive, we may have to use the decl
3320 mappings created in CTX's parent context. Suppose that we have the
3321 following parallel nesting (variable UIDs showed for clarity):
3322
3323 iD.1562 = 0;
3324 #omp parallel shared(iD.1562) -> outer parallel
3325 iD.1562 = iD.1562 + 1;
3326
3327 #omp parallel shared (iD.1562) -> inner parallel
3328 iD.1562 = iD.1562 - 1;
3329
3330 Each parallel structure will create a distinct .omp_data_s structure
3331 for copying iD.1562 in/out of the directive:
3332
3333 outer parallel .omp_data_s.1.i -> iD.1562
3334 inner parallel .omp_data_s.2.i -> iD.1562
3335
3336 A shared variable mapping will produce a copy-out operation before
3337 the parallel directive and a copy-in operation after it. So, in
3338 this case we would have:
3339
3340 iD.1562 = 0;
3341 .omp_data_o.1.i = iD.1562;
3342 #omp parallel shared(iD.1562) -> outer parallel
3343 .omp_data_i.1 = &.omp_data_o.1
3344 .omp_data_i.1->i = .omp_data_i.1->i + 1;
3345
3346 .omp_data_o.2.i = iD.1562; -> **
3347 #omp parallel shared(iD.1562) -> inner parallel
3348 .omp_data_i.2 = &.omp_data_o.2
3349 .omp_data_i.2->i = .omp_data_i.2->i - 1;
3350
3351
3352 ** This is a problem. The symbol iD.1562 cannot be referenced
3353 inside the body of the outer parallel region. But since we are
3354 emitting this copy operation while expanding the inner parallel
3355 directive, we need to access the CTX structure of the outer
3356 parallel directive to get the correct mapping:
3357
3358 .omp_data_o.2.i = .omp_data_i.1->i
3359
3360 Since there may be other workshare or parallel directives enclosing
3361 the parallel directive, it may be necessary to walk up the context
3362 parent chain. This is not a problem in general because nested
3363 parallelism happens only rarely. */
3364
3365static tree
3366lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
3367{
3368 tree t;
3369 omp_context *up;
3370
3371 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
3372 t = maybe_lookup_decl (decl, up);
3373
3374 gcc_assert (!ctx->is_nested || t || is_global_var (decl));
3375
3376 return t ? t : decl;
3377}
3378
3379
3380/* Similar to lookup_decl_in_outer_ctx, but return DECL if not found
3381 in outer contexts. */
3382
3383static tree
3384maybe_lookup_decl_in_outer_ctx (tree decl, omp_context *ctx)
3385{
3386 tree t = NULL;
3387 omp_context *up;
3388
3389 for (up = ctx->outer, t = NULL; up && t == NULL; up = up->outer)
3390 t = maybe_lookup_decl (decl, up);
3391
3392 return t ? t : decl;
3393}
3394
3395
3396/* Construct the initialization value for reduction CLAUSE. */
3397
3398tree
3399omp_reduction_init (tree clause, tree type)
3400{
3401 location_t loc = OMP_CLAUSE_LOCATION (clause);
3402 switch (OMP_CLAUSE_REDUCTION_CODE (clause))
3403 {
3404 case PLUS_EXPR:
3405 case MINUS_EXPR:
3406 case BIT_IOR_EXPR:
3407 case BIT_XOR_EXPR:
3408 case TRUTH_OR_EXPR:
3409 case TRUTH_ORIF_EXPR:
3410 case TRUTH_XOR_EXPR:
3411 case NE_EXPR:
3412 return build_zero_cst (type);
3413
3414 case MULT_EXPR:
3415 case TRUTH_AND_EXPR:
3416 case TRUTH_ANDIF_EXPR:
3417 case EQ_EXPR:
3418 return fold_convert_loc (loc, type, integer_one_node);
3419
3420 case BIT_AND_EXPR:
3421 return fold_convert_loc (loc, type, integer_minus_one_node);
3422
3423 case MAX_EXPR:
3424 if (SCALAR_FLOAT_TYPE_P (type))
3425 {
3426 REAL_VALUE_TYPE max, min;
3427 if (HONOR_INFINITIES (type))
3428 {
3429 real_inf (&max);
3430 real_arithmetic (&min, NEGATE_EXPR, &max, NULL);
3431 }
3432 else
3433 real_maxval (&min, 1, TYPE_MODE (type));
3434 return build_real (type, min);
3435 }
3436 else
3437 {
3438 gcc_assert (INTEGRAL_TYPE_P (type));
3439 return TYPE_MIN_VALUE (type);
3440 }
3441
3442 case MIN_EXPR:
3443 if (SCALAR_FLOAT_TYPE_P (type))
3444 {
3445 REAL_VALUE_TYPE max;
3446 if (HONOR_INFINITIES (type))
3447 real_inf (&max);
3448 else
3449 real_maxval (&max, 0, TYPE_MODE (type));
3450 return build_real (type, max);
3451 }
3452 else
3453 {
3454 gcc_assert (INTEGRAL_TYPE_P (type));
3455 return TYPE_MAX_VALUE (type);
3456 }
3457
3458 default:
3459 gcc_unreachable ();
3460 }
3461}
3462
3463/* Return alignment to be assumed for var in CLAUSE, which should be
3464 OMP_CLAUSE_ALIGNED. */
3465
3466static tree
3467omp_clause_aligned_alignment (tree clause)
3468{
3469 if (OMP_CLAUSE_ALIGNED_ALIGNMENT (clause))
3470 return OMP_CLAUSE_ALIGNED_ALIGNMENT (clause);
3471
3472 /* Otherwise return implementation defined alignment. */
3473 unsigned int al = 1;
3474 machine_mode mode, vmode;
3475 int vs = targetm.vectorize.autovectorize_vector_sizes ();
3476 if (vs)
3477 vs = 1 << floor_log2 (vs);
3478 static enum mode_class classes[]
3479 = { MODE_INT, MODE_VECTOR_INT, MODE_FLOAT, MODE_VECTOR_FLOAT };
3480 for (int i = 0; i < 4; i += 2)
3481 for (mode = GET_CLASS_NARROWEST_MODE (classes[i]);
3482 mode != VOIDmode;
3483 mode = GET_MODE_WIDER_MODE (mode))
3484 {
3485 vmode = targetm.vectorize.preferred_simd_mode (mode);
3486 if (GET_MODE_CLASS (vmode) != classes[i + 1])
3487 continue;
3488 while (vs
3489 && GET_MODE_SIZE (vmode) < vs
3490 && GET_MODE_2XWIDER_MODE (vmode) != VOIDmode)
3491 vmode = GET_MODE_2XWIDER_MODE (vmode);
3492
3493 tree type = lang_hooks.types.type_for_mode (mode, 1);
3494 if (type == NULL_TREE || TYPE_MODE (type) != mode)
3495 continue;
3496 type = build_vector_type (type, GET_MODE_SIZE (vmode)
3497 / GET_MODE_SIZE (mode));
3498 if (TYPE_MODE (type) != vmode)
3499 continue;
3500 if (TYPE_ALIGN_UNIT (type) > al)
3501 al = TYPE_ALIGN_UNIT (type);
3502 }
3503 return build_int_cst (integer_type_node, al);
3504}
3505
3506/* Return maximum possible vectorization factor for the target. */
3507
3508static int
3509omp_max_vf (void)
3510{
3511 if (!optimize
3512 || optimize_debug
3513 || !flag_tree_loop_optimize
3514 || (!flag_tree_loop_vectorize
3515 && (global_options_set.x_flag_tree_loop_vectorize
3516 || global_options_set.x_flag_tree_vectorize)))
3517 return 1;
3518
3519 int vs = targetm.vectorize.autovectorize_vector_sizes ();
3520 if (vs)
3521 {
3522 vs = 1 << floor_log2 (vs);
3523 return vs;
3524 }
3525 machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
3526 if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
3527 return GET_MODE_NUNITS (vqimode);
3528 return 1;
3529}
3530
3531/* Helper function of lower_rec_input_clauses, used for #pragma omp simd
3532 privatization. */
3533
3534static bool
3535lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
3536 tree &idx, tree &lane, tree &ivar, tree &lvar)
3537{
3538 if (max_vf == 0)
3539 {
3540 max_vf = omp_max_vf ();
3541 if (max_vf > 1)
3542 {
3543 tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
3544 OMP_CLAUSE_SAFELEN);
3545 if (c && TREE_CODE (OMP_CLAUSE_SAFELEN_EXPR (c)) != INTEGER_CST)
3546 max_vf = 1;
3547 else if (c && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
3548 max_vf) == -1)
3549 max_vf = tree_to_shwi (OMP_CLAUSE_SAFELEN_EXPR (c));
3550 }
3551 if (max_vf > 1)
3552 {
3553 idx = create_tmp_var (unsigned_type_node);
3554 lane = create_tmp_var (unsigned_type_node);
3555 }
3556 }
3557 if (max_vf == 1)
3558 return false;
3559
3560 tree atype = build_array_type_nelts (TREE_TYPE (new_var), max_vf);
3561 tree avar = create_tmp_var_raw (atype);
3562 if (TREE_ADDRESSABLE (new_var))
3563 TREE_ADDRESSABLE (avar) = 1;
3564 DECL_ATTRIBUTES (avar)
3565 = tree_cons (get_identifier ("omp simd array"), NULL,
3566 DECL_ATTRIBUTES (avar));
3567 gimple_add_tmp_var (avar);
3568 ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, idx,
3569 NULL_TREE, NULL_TREE);
3570 lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, lane,
3571 NULL_TREE, NULL_TREE);
3572 if (DECL_P (new_var))
3573 {
3574 SET_DECL_VALUE_EXPR (new_var, lvar);
3575 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3576 }
3577 return true;
3578}
3579
3580/* Helper function of lower_rec_input_clauses. For a reference
3581 in simd reduction, add an underlying variable it will reference. */
3582
3583static void
3584handle_simd_reference (location_t loc, tree new_vard, gimple_seq *ilist)
3585{
3586 tree z = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_vard)));
3587 if (TREE_CONSTANT (z))
3588 {
3589 const char *name = NULL;
3590 if (DECL_NAME (new_vard))
3591 name = IDENTIFIER_POINTER (DECL_NAME (new_vard));
3592
3593 z = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_vard)), name);
3594 gimple_add_tmp_var (z);
3595 TREE_ADDRESSABLE (z) = 1;
3596 z = build_fold_addr_expr_loc (loc, z);
3597 gimplify_assign (new_vard, z, ilist);
3598 }
3599}
3600
3601/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
3602 from the receiver (aka child) side and initializers for REFERENCE_TYPE
3603 private variables. Initialization statements go in ILIST, while calls
3604 to destructors go in DLIST. */
3605
3606static void
3607lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
3608 omp_context *ctx, struct omp_for_data *fd)
3609{
3610 tree c, dtor, copyin_seq, x, ptr;
3611 bool copyin_by_ref = false;
3612 bool lastprivate_firstprivate = false;
3613 bool reduction_omp_orig_ref = false;
3614 int pass;
3615 bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
3616 && gimple_omp_for_kind (ctx->stmt) & GF_OMP_FOR_SIMD);
3617 int max_vf = 0;
3618 tree lane = NULL_TREE, idx = NULL_TREE;
3619 tree ivar = NULL_TREE, lvar = NULL_TREE;
3620 gimple_seq llist[2] = { NULL, NULL };
3621
3622 copyin_seq = NULL;
3623
3624 /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
3625 with data sharing clauses referencing variable sized vars. That
3626 is unnecessarily hard to support and very unlikely to result in
3627 vectorized code anyway. */
3628 if (is_simd)
3629 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3630 switch (OMP_CLAUSE_CODE (c))
3631 {
3632 case OMP_CLAUSE_LINEAR:
3633 if (OMP_CLAUSE_LINEAR_ARRAY (c))
3634 max_vf = 1;
3635 /* FALLTHRU */
3636 case OMP_CLAUSE_REDUCTION:
3637 case OMP_CLAUSE_PRIVATE:
3638 case OMP_CLAUSE_FIRSTPRIVATE:
3639 case OMP_CLAUSE_LASTPRIVATE:
3640 if (is_variable_sized (OMP_CLAUSE_DECL (c)))
3641 max_vf = 1;
3642 break;
3643 default:
3644 continue;
3645 }
3646
3647 /* Do all the fixed sized types in the first pass, and the variable sized
3648 types in the second pass. This makes sure that the scalar arguments to
3649 the variable sized types are processed before we use them in the
3650 variable sized operations. */
3651 for (pass = 0; pass < 2; ++pass)
3652 {
3653 for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
3654 {
3655 enum omp_clause_code c_kind = OMP_CLAUSE_CODE (c);
3656 tree var, new_var;
3657 bool by_ref;
3658 location_t clause_loc = OMP_CLAUSE_LOCATION (c);
3659
3660 switch (c_kind)
3661 {
3662 case OMP_CLAUSE_PRIVATE:
3663 if (OMP_CLAUSE_PRIVATE_DEBUG (c))
3664 continue;
3665 break;
3666 case OMP_CLAUSE_SHARED:
3667 /* Ignore shared directives in teams construct. */
3668 if (gimple_code (ctx->stmt) == GIMPLE_OMP_TEAMS)
3669 continue;
3670 if (maybe_lookup_decl (OMP_CLAUSE_DECL (c), ctx) == NULL)
3671 {
3672 gcc_assert (is_global_var (OMP_CLAUSE_DECL (c)));
3673 continue;
3674 }
3675 case OMP_CLAUSE_FIRSTPRIVATE:
3676 case OMP_CLAUSE_COPYIN:
3677 case OMP_CLAUSE_LINEAR:
3678 break;
3679 case OMP_CLAUSE_REDUCTION:
3680 if (OMP_CLAUSE_REDUCTION_OMP_ORIG_REF (c))
3681 reduction_omp_orig_ref = true;
3682 break;
3683 case OMP_CLAUSE__LOOPTEMP_:
3684 /* Handle _looptemp_ clauses only on parallel. */
3685 if (fd)
3686 continue;
3687 break;
3688 case OMP_CLAUSE_LASTPRIVATE:
3689 if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
3690 {
3691 lastprivate_firstprivate = true;
3692 if (pass != 0)
3693 continue;
3694 }
3695 /* Even without corresponding firstprivate, if
3696 decl is Fortran allocatable, it needs outer var
3697 reference. */
3698 else if (pass == 0
3699 && lang_hooks.decls.omp_private_outer_ref
3700 (OMP_CLAUSE_DECL (c)))
3701 lastprivate_firstprivate = true;
3702 break;
3703 case OMP_CLAUSE_ALIGNED:
3704 if (pass == 0)
3705 continue;
3706 var = OMP_CLAUSE_DECL (c);
3707 if (TREE_CODE (TREE_TYPE (var)) == POINTER_TYPE
3708 && !is_global_var (var))
3709 {
3710 new_var = maybe_lookup_decl (var, ctx);
3711 if (new_var == NULL_TREE)
3712 new_var = maybe_lookup_decl_in_outer_ctx (var, ctx);
3713 x = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
3714 x = build_call_expr_loc (clause_loc, x, 2, new_var,
3715 omp_clause_aligned_alignment (c));
3716 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
3717 x = build2 (MODIFY_EXPR, TREE_TYPE (new_var), new_var, x);
3718 gimplify_and_add (x, ilist);
3719 }
3720 else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE
3721 && is_global_var (var))
3722 {
3723 tree ptype = build_pointer_type (TREE_TYPE (var)), t, t2;
3724 new_var = lookup_decl (var, ctx);
3725 t = maybe_lookup_decl_in_outer_ctx (var, ctx);
3726 t = build_fold_addr_expr_loc (clause_loc, t);
3727 t2 = builtin_decl_explicit (BUILT_IN_ASSUME_ALIGNED);
3728 t = build_call_expr_loc (clause_loc, t2, 2, t,
3729 omp_clause_aligned_alignment (c));
3730 t = fold_convert_loc (clause_loc, ptype, t);
3731 x = create_tmp_var (ptype);
3732 t = build2 (MODIFY_EXPR, ptype, x, t);
3733 gimplify_and_add (t, ilist);
3734 t = build_simple_mem_ref_loc (clause_loc, x);
3735 SET_DECL_VALUE_EXPR (new_var, t);
3736 DECL_HAS_VALUE_EXPR_P (new_var) = 1;
3737 }
3738 continue;
3739 default:
3740 continue;
3741 }
3742
3743 new_var = var = OMP_CLAUSE_DECL (c);
3744 if (c_kind != OMP_CLAUSE_COPYIN)
3745 new_var = lookup_decl (var, ctx);
3746
3747 if (c_kind == OMP_CLAUSE_SHARED || c_kind == OMP_CLAUSE_COPYIN)
3748 {
3749 if (pass != 0)
3750 continue;
3751 }
3752 else if (is_variable_sized (var))
3753 {
3754 /* For variable sized types, we need to allocate the
3755 actual storage here. Call alloca and store the
3756 result in the pointer decl that we created elsewhere. */
3757 if (pass == 0)
3758 continue;
3759
3760 if (c_kind != OMP_CLAUSE_FIRSTPRIVATE || !is_task_ctx (ctx))
3761 {
3762 gcall *stmt;
3763 tree tmp, atmp;
3764
3765 ptr = DECL_VALUE_EXPR (new_var);
3766 gcc_assert (TREE_CODE (ptr) == INDIRECT_REF);
3767 ptr = TREE_OPERAND (ptr, 0);
3768 gcc_assert (DECL_P (ptr));
3769 x = TYPE_SIZE_UNIT (TREE_TYPE (new_var));
3770
3771 /* void *tmp = __builtin_alloca */
3772 atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
3773 stmt = gimple_build_call (atmp, 1, x);
3774 tmp = create_tmp_var_raw (ptr_type_node);
3775 gimple_add_tmp_var (tmp);
3776 gimple_call_set_lhs (stmt, tmp);
3777
3778 gimple_seq_add_stmt (ilist, stmt);
3779
3780 x = fold_convert_loc (clause_loc, TREE_TYPE (ptr), tmp);
3781 gimplify_assign (ptr, x, ilist);
3782 }
3783 }
3784 else if (is_reference (var))
3785 {
3786 /* For references that are being privatized for Fortran,
3787 allocate new backing storage for the new pointer
3788 variable. This allows us to avoid changing all the
3789 code that expects a pointer to something that expects
3790 a direct variable. */
3791 if (pass == 0)
3792 continue;
3793
3794 x = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (new_var)));
3795 if (c_kind == OMP_CLAUSE_FIRSTPRIVATE && is_task_ctx (ctx))
3796 {
3797 x = build_receiver_ref (var, false, ctx);
3798 x = build_fold_addr_expr_loc (clause_loc, x);
3799 }
3800 else if (TREE_CONSTANT (x))
3801 {
3802 /* For reduction in SIMD loop, defer adding the
3803 initialization of the reference, because if we decide
3804 to use SIMD array for it, the initilization could cause
3805 expansion ICE. */
3806 if (c_kind == OMP_CLAUSE_REDUCTION && is_simd)
3807 x = NULL_TREE;
3808 else
3809 {
3810 const char *name = NULL;
3811 if (DECL_NAME (var))
3812 name = IDENTIFIER_POINTER (DECL_NAME (new_var));
3813
3814 x = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (new_var)),
3815 name);
3816 gimple_add_tmp_var (x);
3817 TREE_ADDRESSABLE (x) = 1;
3818 x = build_fold_addr_expr_loc (clause_loc, x);
3819 }
3820 }
3821 else
3822 {
3823 tree atmp = builtin_decl_explicit (BUILT_IN_ALLOCA);
3824 x = build_call_expr_loc (clause_loc, atmp, 1, x);
3825 }
3826
3827 if (x)
3828 {
3829 x = fold_convert_loc (clause_loc, TREE_TYPE (new_var), x);
3830 gimplify_assign (new_var, x, ilist);
3831 }
3832
3833 new_var = build_simple_mem_ref_loc (clause_loc, new_var);
3834 }